1  {***********************************************************************}
     2  {                                                                       }
     3  {                     Sx Visual Component Library                       }
     4  
     5  {                                                                       }
     6  {               Copyright (c) 1998,14  Pat'n Xav Software               }
     7  {                                                                       }
     8  {***********************************************************************}
     9  
    10  {***********************************************************************}
    11  { Composant fiche TSxMSPForm :                                          }
    12  {    basé sur SxCustomSimpleForms                                       }
    13  {    fiche sans barre de titre                                          }
    14  {                                                                       }
    15  { version 1.0 : 04/11/2010                                              }
    16  { Adaptation pour MSP : 01/04/2013                                      }
    17  { Explorateur de fichiers MP3 et grille de fichiers MP3                 }
    18  { Grille de fichiers MP3 sélectionés                                    }
    19  { Enregistrement d'une playlist issue de la sélection                   }
    20  { Enregistrement, chargement des derniers paramètres utilisés           }
    21  { Chargement de la dernière PL visualisée au démarrage                  }
    22  { Lecture/Pause d'un ou plusieurs fichiers MP3                          }
    23  { Calcul de la durée de lecture des fichiers sélectionnés               }
    24  { Gestion Checked/no dans les différents cas de figure                  }
    25  {***********************************************************************}
    26  {***********************************************************************}
    27  {           Personnalisation de la CustomSimpleForm pour MSP 3          }
    28  {***********************************************************************}
    29  
    30  (*
    31   * Version 1 : utilitaire de gestion de fichiers musicaux mp3
    32   *             Arborescence de fichiers et grilles de fichiers mp3
    33   *             Filtrage des grille par recherche utilisateur
    34   *             Affichage des propriétés d'un fichier
    35   *             Enregistrement des sélections au format m3u
    36   *             Enregistrement de liste de titres
    37   *             Profils couleurs jour/nuit
    38   *   1.0.1   : Copie des fichiers sélectionnés
    39   *   1.0.2   : Horloge en bas à gauche
    40   *             Affichage sélectif des fichiers sélectionnés
    41   *             Création de sélection avec doublons
    42   *             Calcul de la durée de la sélection
    43   *   1.0.3   : Exécution musicale retardable
    44   *             Panneau d'affichage du titre courant
    45   *             Gestion de la télécommande infrarouge
    46   *   1.0.4   : Trier la sélection selon les titres
    47   *
    48   * Version 2 : restructuration du code source
    49   *   2.0.1   : panneau d'information pour les fichiers de la sélection
    50   *             durée restante de la piste courante
    51   *   2.0.2   : corrections de bugs
    52   *   2.0.3   : <Gestion des préférences, paramétrages de l'affichage>  
    53                 Version installée (Yannick)
    54   *             Menu préférences
    55   *             Affichage des playlists sur 2 niveaux dans l'arborescence de fichiers
    56   *             Gestion des commentaires chorégraphiques
    57   *             Chargement d'un répertoire par drag'n drop
    58   *             Suppression des lignes non sélectionnées (dans la grille sélection)
    59   *             Inverser la sélection
    60   *             Amélioration de l'affichage de l'horloge (composant TSxClock)
    61   *             Affichage des titres / titres de chorégraphie / Choré [Titre] (paramétrable)
    62   *             Affichage du type de danse ...
    63   *             Editeur de recherche avec options de filtarge (titre, chore, artiste...)
    64   *             Paramétrage de la taille de la fonte des grilles
    65   *             Correction du bug d'affichage du viewer
    66   *             Correction des bugs de focalisation
    67   *   2.0.4     <Améliorations de l'IHM>
    68   *             Ajout d'une boite de dialogue "A propos"
    69   *             Ajout d'une fenêtre d'accueil, "patientez" pour les opérations longues
    70   *             Popup grilles : sélectionner depuis / jusqu'à
    71   *             Sauvegarde des options de recherche
    72   *             Correction d'un bug sur les options de recherche
    73   *             Correction d'un bug menu préférence>libellé des pistes
    74   *             Ajout Désélection des doublons par  nom de fichier/titre/chorégraphie
    75   *             Ajout de la gestion des sous-sélections (1..8)
    76   *             Ajout des informations album et année dans les options de recherche
    77   *   2.0.5     <Réglage des pistes>
    78   *             Gestion d'un historique ... EN PROJET ...
    79   *             Correction d'un bug de focalisation (avec le viewer)
    80   *             Affichage plein fenêtre / 50% de la grille (et des viewers)
    81   *             Affichage au format artistes :: titre
    82   *             Ajout d'un menu Sélectionner les seules pistes titrées
    83   *             Ajout menu trier par artistes
    84   *             Affichage de chorégraphies multiples
    85   *             Définition d'un ordre initial avec lequel la grille peut être triée
    86   *             Ajout/modification enregistrer sous > libelles ou titres choreg
    87   *             Ajout enregistrement des chorégraphies
    88   *             Correction bug préférence taille des caractères (des commentaires)
    89   *             Ajout choix d'une PL par raccourcis claviers, télécommande
    90   *             Définition d'items de menus par défaut
    91   *             Ajout de confirmation pour écrasement de fichier, sélection ou vidage
    92   *             (et ajout des options de préférences)
    93   *             Ajout installation des mises à jour automatique
    94   *             Ajout menu recherche, installation des mises à jour
    95   *             Correction bug : envoyer vers... avec doublons (1er ligne = n° 2)
    96   *             Correction bug : affichage de la ligne sélectionnée (au démarrage)
    97   *             Amélioration : comportement des popup des boutons en haut à gauche
    98   *             Correction bug : déplacer la fenêtre depuis la page sélection
    99   *             Correction Bug déplacement de ligne First, Last (colonnes fixes)
   100   *             Déplacement par drag'n drop (mode Ctrl/shift)
   101   *             Ajout : détection d'une PL déplacée 
   102                         (possibilité de choisir le dossier conteneur ...)
   103   *             Ajout : réglage du volume de chaque piste, stocké dans les PL
   104   *             Ajout : réglages du début, fin pour chaque piste, stockés dans les PL
   105   *             Ajout : commande Fade out
   106   *             Ajout : exceptions silencieuses, 
   107                         journalisation, paramétrage de la journalisation
   108   *   2.0.6     <Gestion des groupes i.e. sous-sélections)>
   109   *             Ajout : n° de sous-sélection enregistré dans les PL
   110   *             Ajout : Nommage des sous-sélections 
   111                          (dans les menus, enregistré dans les P.L.)
   112   *             Modification : gestion des touches numériques de la télécommande
   113   *             Ajout mode numérique : sélectionner une sous-sélection
   114   *             Ajout : retirer de la sous-sélection n°
   115   *             Ajout configuration de la télécommande paramétrée
   116   *             Modification : couleurs des zones permettant le déplacement de la fenêtre
   117   *             Modification : hauteur de l'éditeur de la page sélection
   118   *             Modification des préférences de démarrage (Path=MyMusic, couleurs nuit)
   119   *             Ajout : menus de sous-sélections ajoutés au menu popup de la grille
   120   *             Correction bug : suppression de lignes non sélectionnées (menu et SFV)
   121   *             Ajout : popup supprimer cette ligne
   122   *             Modification : à l'ouverture de popup, la ligne courante est mis à jour
   123   *             Ajout : messages d'exception pour les nouvelles procédures et fonctions
   124   *             Modifications : les sous-sélections sont renommées "groupe"
   125   *             Ajout : retirer de tous les groupes
   126   *             Ajout : trier la grille de sélection selon l'âge des fichiers
   127   *             Ajout : coloration des groupes
   128   *             Amélioration du comportement afficher/masquer lignes non sel
   129   *             Ajout : recharger le répertoire music, le dossier playlist
   130   *             Modification : pas de chargement de tout le répertoire PlayList
   131   *             Modification : ajouter à la sélection la ligne courante (même si non select.)
   132   *             Ajout : trier par groupes
   133   *             Modifications : comparaisons sans tenir compte des majuscules
   134   *             Ajout : liste des groupes non vides utilisable comme ens. de sélecteurs
   135   *             Ajout : popup de la liste de groupes "placer en tête" un groupe
   136   *             Correction bug et Amélioration : Scrollbars volume colorées
   137   *             Ajout : afficher / masquer les pistes jouées
   138   *             Ajout : n'afficher que les pistes jouées
   139   *             Amélioration : positionnement sur la dernière ligne recherchée
   140   *   2.0.7     < Console de mixage >
   141   *             Ajout d'une console de mixage pour la page de sélection
   142   *             Correction bug affichage des groupes
   143   *             Modification : raccourcis commandes grilles désactivés si recherche activée
   144   *   2.0.8     < Améliorations >
   145   *             Ajout : sélection si NBP = ou >= à ...
   146   *             Ajout : notations 4, 5 (NBP)
   147   *             Amélioration : utilisation d'un algorithme de tri stable en n log n.
   148   *             Modification : fichier log nommé avec la date et l'heure
   149   *             Ajout : passage du player au mixer de la piste en cours 
   150                         avec fade out si nécessiare
   151   *             Améliorations : raccourcis du menu Play List
   152   *             Ajout : chargement de paquetage de Playlists (extension m6u)
   153   *             Amélioration : boite de visualisation groupes et PL :  buttonbox
   154   *             Ajout, Modification : paramétrage pour activer les raccourcis claviers 
   155                                       quand search...
   156   *             Ajout : effacer tous les journaux
   157   *   2.0.9     < Améliorations >
   158   *             Ajout : affichage du temps restant pour les pistes du mixer
   159   *             Modification : si nummode=nmsubsel, 0 envoie sur nummode=nmgroups
   160   *             Ajout : titrer play list
   161   *             Ajout : renommer la play list sélectionnée
   162   *             Amélioration : redimensionnement du mixer
   163   *             Modification : présentation des instruments de la page sélection
   164   *             Amélioration du mixer
   165   *             Modification PlayingBkColor du browser
   166   *             Correction bug : drag'n drop désactive le click sur les lignes de la grille
   167   *             Modification : la touche '>' permet d'envoyer vers la sélection 
   168                                             (depuis la grille de navigation)
   169   *                            la touche '<' permet de supprimer de la sélection le fichier courant
   170   *                            les touches '>' et '<' ne servent donc plus à aller au suivant/précédent
   171   *             Amélioration : Ctrl+ Click (grille de navigation) permet d'envoyer vers la sélection
   172   *   2.0.10    < Amélioration >
   173   *             Ajout : sauvegarder sous PlayList M3U relocalisable
   174   *   2.0.12    Ajout de la gestion des inforamtions nom chorégraphe, fichier choré, clips vidéo
   175   *             BUG EchangeMenuItem en cours ...
   176   *             Amélioration : la colonne numéro indique par un code couleur si le tag ID3
   177   *             comporte une indication sur l'url d'une vidéo chorégraphie
   178   *             Amélioration : après Cltr+click (envoie vers sélection), 
   179                                la recherche est vidée et focalisée  
   180   *             Ajout paramétrage du chargement des PL : ForceFind.
   181   *                Si un fichier n'est pas trouvé, demande à l'utilisateur de le localiser
   182   *             BUG EchangeMenuItem fixé ... cf. TODO
   183   *             Ajout : paramétrage ajout/remplacement de PL lors du chargement de la sélection
   184   *             Ajout : le dernier répertoire utilisé pour charger la sélection est mémorisé
   185   *             Ajout : les derniers répertoires pour CSV, HTML sont mémorisés
   186   *             Ajout : popmenu charger comme sélection (vide et charge la sélection)
   187   *             Ajout : chargement d'une PL depuis la ligne de commande
   188   *             Amélioration : suppression des doublons nom de fichier non sensible à la casse
   189   *             Amélioration : paquetage PL (m6u) avec path commun (en commentaire PATH=
   190   *             Ajout : analyse ID3 : champ NIVD : niveau de la danse
   191   *   2.0.13    Améliorations pour DJ Henriville (18/5/2014)
   192   *             Ajout chargement possible des pistes d'un fichier .log
   193   *             Prise en charge des fichiers m4u et flac au moyen de players externes
   194   *             Ajout du paramétrage des players externes.
   195   *             Ajout : déplacement des fichiers de la sélection
   196   *             Ajout/amélioration : chargement des fichiers wma pour les PL de la sélection
   197   *             Ajout : modification du libellé (titre) en direct (micro-edit)
   198   *             Ajout : forçage du titre dans le fichier PL
   199   *   2.0.14    Améliorations déduites de la journée Henriville (18/5)
   200   *             Ajout : menu pour modifier le paramètre AlwaysGoNext
   201   *             Ajout du nom du lecteur externe aux items de menu player externe
   202   *             (si exe non trouvé, le paramètre est vidé au démarrage.)
   203   *             Modification : renommage de méthodes d'événements SxMixer2... => SxMixer1...
   204   *             Modification : format du fichier log : # en tête de ligne si pas fichier audio
   205   *             Ajout : date début et fin de lecture de fichier audio dans le log
   206   *             Modification : structure du menu préférences
   207   *             Ajout : lecteur de fichier log
   208   *             Ajout : dialogue d'aide (raccourcis des grilles)
   209   *             Ajout mode sécurisé pour les raccourcis play,pause, stop...
   210   *             Ajout item de menu contextuel "afficher la vidéo associée à une piste"
   211   *             Modification : retour au titre initial, vidage du micro-edit
   212   *             Modification: restructuration du menu enregistrer sous
   213   *             Ajout : enregistrer sous page HTML site
   214   *             Modification : nettoyage du code source (warnings)
   215   *             Correction : bug modification couleurs jour (selection) [1144 Ko]
   216   *   2.0.15    Améliorations déduites de la journée étang Henriville (29/6)
   217   *             Ajout de sons d'ambiance en ressources DLL
   218   *             Amélioration : recharger un répertoire quelconque
   219   *             Ajout : popup sur boutons stop : fade out (1, 3 et 5 s)
   220   *             Amélioration : chargement des fichiers inconnus :  
   221                                 recherche dans tous les rép. connus
   222   *             Ajout : affichage du commentaire biographique 
   223   *             Modification : gestion des items par défaut du menu sélection
   224   *             Amélioration : documentation de la télécommande dans le fichier help
   225   *             Ajout : sélectionner seulement les pistes associées à un clip vidéo
   226   *)
   227  
   228  unit mainMediaSelectionPlayer;
   229  
   230  {$define nSX_ID3_CONST}
   231  {$define NOEXCEPTIONS}
   232  
   233  interface
   234  
   235  uses
   227    ShellAPI, Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
   228    Buttons, ExtCtrls, ImgList, SxCustomFlatButton, SxFlatButton, StdCtrls,
   229    SxCustomPageControl, SxPageControl, ComCtrls, SxCustomFoldersView,
   230    FrmMSP,
   231    SxFoldersView, SxDirectoryTree, Grids, SxStringGrid, SxCustomChoiceGrid,
   232    SxChoiceGrid, CustomSongList, DirectShow9, DSPack, SxScrollBarEx, ActnList, Menus,
   233    SxSaveDialog, SxCmdFlatButton, SxViewer, SxCustomClock, SxClock,
   234    SxCustomSearchEdit, SxSearchEdit,
   235    MSPConst, MSPConfigObj, MSPConfig, SxScrollBar, SxCustomScrollBarEx,
   236    SxCustomMixer, SxMixer, SxCustomButtonBox, SxButtonBox;
   246  
   247  type
   248    TForm = class(Forms.TForm)
   249       procedure WMNCPaint(var Message : TWMNCPaint); message WM_NCPAINT;
   250       procedure WMSize(var Message :  TWMSize); message WM_SIZE;
   251    end;   
   252  
   253    TSxMSPForm = class(TSxMSPFrm)
   254      TopPanel: TPanel;
   255      SysBtnClose: TSpeedButton;
   256      SysBtnMaxNorm: TSpeedButton;
   257      SysBtnMin: TSpeedButton;
   258      ILBtnMaxNorm: TImageList;
   259      PgCtrl: TSxPageControl;
   260      TSBrowser: TSxTabSheet;
   261      TSSelection: TSxTabSheet;
   262      btnSelection: TSxFlatButton;
   263      btnBrowser: TSxFlatButton;
   264      Label1: TLabel;
   265      PanDirTree: TPanel;
   266      SFV: TSxFoldersView;
   267      Splitter1: TSplitter;
   268      PanRightBrowser: TPanel;
   269      SCGBrowser: TSxChoiceGrid;
   270      ILPlayers: TImageList;
   271      PanPlayerBrowser: TPanel;
   272      btnPlay: TSxFlatButton;
   273      btnPause: TSxFlatButton;
   274      btnStop: TSxFlatButton;
   275      btnPrev: TSxFlatButton;
   276      btnNext: TSxFlatButton;
   277      DSTrackBar1: TDSTrackBar;
   278      PanSelection: TPanel;
   279      FilterGraphBrowser: TFilterGraph;
   280      SBVolume: TSxScrollBarEx;
   281      ActionList1: TActionList;
   282      ActionPlay: TAction;
   283      ActionPause: TAction;
   284      ActionStop: TAction;
   285      ActionGoPrev: TAction;
   286      ActionGoNext: TAction;
   287      LbTitre: TLabel;
   288      ActionMute: TAction;
   289      popupBtnBrowser: TPopupMenu;
   290      popupBtnSelection: TPopupMenu;
   291      miSendToSelection: TMenuItem;
   292      ActionSendToSelection: TAction;
   293      popupSaveAs: TMenuItem;
   294      miSaveAsM3U: TMenuItem;
   295      miSaveAsVDJ: TMenuItem;
   296      miSaveAsTitleList: TMenuItem;
   297      ActionSaveAsM3U: TAction;
   298      ActionSaveAsVDJ: TAction;
   299      ActionSaveAsTitleList: TAction;
   300      miEmptyGrid: TMenuItem;
   301      ActionEmptyGrid: TAction;
   302      miLoadPlayList: TMenuItem;
   303      ActionLoadPlayList: TAction;
   304      miEmptyBrowserList: TMenuItem;
   305      PanChk: TPanel;
   306      ChkBrowserList: TCheckBox;
   307      ActionSelectAll: TAction;
   308      popSFV: TPopupMenu;
   309      miSaveBLAs: TMenuItem;
   310      Listedetitres1: TMenuItem;
   311      PlayListVirtualDJ1: TMenuItem;
   312      PlayListM3U1: TMenuItem;
   313      N1: TMenuItem;
   314      N2: TMenuItem;
   315      N3: TMenuItem;
   316      N4: TMenuItem;
   317      miDelPlayList: TMenuItem;
   318      ActionDelPlayList: TAction;
   319      miOpenBrowser: TMenuItem;
   320      ActionOpenExplorer: TAction;
   321      popGrid: TPopupMenu;
   322      miDisplayProperties: TMenuItem;
   323      miReloadFile: TMenuItem;
   324      ActionSearch: TAction;
   325      miAddToSelection: TMenuItem;
   326      N5: TMenuItem;
   327      miVal0: TMenuItem;
   328      miVal1: TMenuItem;
   329      miVal2: TMenuItem;
   330      miVal3: TMenuItem;
   331      ActionChangeNBP: TAction;
   332      btnOneAllBrowser: TSxFlatButton;
   333      ActionOneAll: TAction;
   334      miSelInfo: TMenuItem;
   335      N6: TMenuItem;
   336      FilterGraphTmp: TFilterGraph;
   337      miDuration: TMenuItem;
   338      miCopyFiles: TMenuItem;
   339      N7: TMenuItem;
   340      miFindFile: TMenuItem;
   341      ActionFindFile: TAction;
   342      miUpdateID3s: TMenuItem;
   343      N8: TMenuItem;
   344      miSendToSelectionWD: TMenuItem;
   345      ActionSendToSelectionWD: TAction;
   346      ChkOnlySel: TCheckBox;
   347      FilterGraphSelection: TFilterGraph;
   348      N9: TMenuItem;
   349      miSendThisToSelection: TMenuItem;
   350      miSortGrid: TMenuItem;
   351      PanLeftSelection: TPanel;
   352      CmbTemporisation: TComboBox;
   353      PanRightSelection: TPanel;
   354      Splitter2: TSplitter;
   355      SCGSelection: TSxChoiceGrid;
   356      PanChkSel: TPanel;
   357      ChkSelectionList: TCheckBox;
   358      LbTrackTimeMLeft: TLabel;
   359      LbTrackTimeSLeft: TLabel;
   360      miCopyFilesSFN: TMenuItem;
   361      miCopy: TMenuItem;
   362      miAddnodeToSelection: TMenuItem;
   363      btnPreferences: TSxFlatButton;
   364      popupBtnPreferences: TPopupMenu;
   365      miColors: TMenuItem;
   366      miNuit: TMenuItem;
   367      miJour: TMenuItem;
   368      miAllwaysOnTop: TMenuItem;
   369      miDefinePLRoot: TMenuItem;
   370      miDeleteNonSel: TMenuItem;
   371      miInvertSelection: TMenuItem;
   372      MainClock: TSxClock;
   373      miFntSizes: TMenuItem;
   374      miCmmFntSz: TMenuItem;
   375      miCmmViewerFntSz: TMenuItem;
   376      miAffichageTitre: TMenuItem;
   377      miDisplayTitle: TMenuItem;
   378      miDisplayChore: TMenuItem;
   379      miDisplayCateg: TMenuItem;
   380      N10: TMenuItem;
   381      miPlayListM3UMoved: TMenuItem;
   382      miSortGridByChore: TMenuItem;
   383      EdSearch: TSxSearchEdit;
   384      miDispChoreTitle: TMenuItem;
   385      miTextSize: TMenuItem;
   386      miCSNormal: TMenuItem;
   387      miCSBig: TMenuItem;
   388      miCSVeryBig: TMenuItem;
   389      miCSMini: TMenuItem;
   390      miSortGridByNBP: TMenuItem;
   391      N11: TMenuItem;
   392      miApropos: TMenuItem;
   393      miSelectUntil: TMenuItem;
   394      miSelectFrom: TMenuItem;
   395      miUnselDuplicates: TMenuItem;
   396      miUnselDblByFileName: TMenuItem;
   397      miUnselDblByTitle: TMenuItem;
   398      miUnselDblByChoreg: TMenuItem;
   399      miCheckChoregraphied: TMenuItem;
   400      miSendToSel: TMenuItem;
   401      miDefSelNum1: TMenuItem;
   402      miDefSelNum2: TMenuItem;
   403      miDefSelNum3: TMenuItem;
   404      miDefSelNum4: TMenuItem;
   405      miDefSelNum5: TMenuItem;
   406      miDefSelNum6: TMenuItem;
   407      miSelectSelNum: TMenuItem;
   408      miSelectSelNum1: TMenuItem;
   409      miSelectSelNum2: TMenuItem;
   410      miSelectSelNum3: TMenuItem;
   411      miSelectSelNum4: TMenuItem;
   412      miSelectSelNum5: TMenuItem;
   413      miSelectSelNum6: TMenuItem;
   414      miDefSelNum7: TMenuItem;
   415      miSelectSelNum7: TMenuItem;
   416      miDefSelNum8: TMenuItem;
   417      miSelectSelNum8: TMenuItem;
   418      miSortByAuthor: TMenuItem;
   419      miDispAuthorTitle: TMenuItem;
   420      miCheckTitled: TMenuItem;
   421      N12: TMenuItem;
   422      miSelectIf: TMenuItem;
   423      miSort: TMenuItem;
   424      miSortByInitilaOrder: TMenuItem;
   425      N13: TMenuItem;
   426      N14: TMenuItem;
   427      miDefineInitialOrder: TMenuItem;
   428      miSaveAsChoreList: TMenuItem;
   429      miSaveChoreg: TMenuItem;
   430      miWantConfirm: TMenuItem;
   431      miConfirmChkAll: TMenuItem;
   432      miEmptyConfirm: TMenuItem;
   433      N15: TMenuItem;
   434      N16: TMenuItem;
   435      miConfirmFileExists: TMenuItem;
   436      miDownloadVersion: TMenuItem;
   437      N17: TMenuItem;
   438      miInstallUpdates: TMenuItem;
   439      miDefineVolume: TMenuItem;
   440      miReglagesPiste: TMenuItem;
   441      miDefineStart: TMenuItem;
   442      miDefineStop: TMenuItem;
   443      miInstallMajorUpdates: TMenuItem;
   444      TimerFade: TTimer;
   445      miSaveLog: TMenuItem;
   446      N18: TMenuItem;
   447      miClearLog: TMenuItem;
   448      miLoadFromLog: TMenuItem;
   449      N19: TMenuItem;
   450      miSelSelNum1: TMenuItem;
   451      miSelSelNum2: TMenuItem;
   452      miSelSelNum3: TMenuItem;
   453      miSelSelNum4: TMenuItem;
   454      miSelSelNum5: TMenuItem;
   455      miSelSelNum6: TMenuItem;
   456      miSelSelNum7: TMenuItem;
   457      miSelSelNum8: TMenuItem;
   458      miRenameSelGrp: TMenuItem;
   459      miRenameSubSel8: TMenuItem;
   460      miRenameSubSel7: TMenuItem;
   461      miRenameSubSel6: TMenuItem;
   462      miRenameSubSel5: TMenuItem;
   463      miRenameSubSel4: TMenuItem;
   464      miRenameSubSel3: TMenuItem;
   465      miRenameSubSel2: TMenuItem;
   466      miRenameSubSel1: TMenuItem;
   467      N20: TMenuItem;
   468      N21: TMenuItem;
   469      miInitTrack: TMenuItem;
   470      miClearFromSubSel: TMenuItem;
   471      miClearFromSubSel8: TMenuItem;
   472      miClearFromSubSel7: TMenuItem;
   473      miClearFromSubSel6: TMenuItem;
   474      miClearFromSubSel5: TMenuItem;
   475      miClearFromSubSel4: TMenuItem;
   476      miClearFromSubSel3: TMenuItem;
   477      miClearFromSubSel2: TMenuItem;
   478      miClearFromSubSel1: TMenuItem;
   479      miRestoreKeyCodes: TMenuItem;
   480      miRemoveLine: TMenuItem;
   481      N22: TMenuItem;
   482      N23: TMenuItem;
   483      miClearFromAllSubSel: TMenuItem;
   484      miSortByFileAge: TMenuItem;
   485      miReloadPath: TMenuItem;
   486      PanSelectionTools: TPanel;
   487      SplitterSelEDTV: TSplitter;
   488      RESelection: TRichEdit;
   489      miSortByGroups: TMenuItem;
   490      popupGroups: TPopupMenu;
   491      miMoveTopGroup: TMenuItem;
   492      miShowHidePlayed: TMenuItem;
   493      N24: TMenuItem;
   494      miShowOnlyPlayed: TMenuItem;
   495      SelPgCtrl: TSxPageControl;
   496      SelTSMix: TSxTabSheet;
   497      SelTSMono: TSxTabSheet;
   498      DSTrackBar2: TDSTrackBar;
   499      PanPlayerSelection: TPanel;
   500      btnPlaySel: TSxFlatButton;
   501      btnPauseSel: TSxFlatButton;
   502      BtnStopSel: TSxFlatButton;
   503      btnPrevSel: TSxFlatButton;
   504      btnNextSel: TSxFlatButton;
   505      btnOneAllSelection: TSxFlatButton;
   506      ChkOnlySelSel: TCheckBox;
   507      SBVolumeSel: TSxScrollBarEx;
   508      miSelShowMix: TMenuItem;
   509      miDefineFadeIn: TMenuItem;
   510      miDefineFadeOut: TMenuItem;
   511      N25: TMenuItem;
   512      N26: TMenuItem;
   513      miSelByRating: TMenuItem;
   514      miSelByRating0: TMenuItem;
   515      miSelByRating1: TMenuItem;
   516      miSelByRating2: TMenuItem;
   517      miSelByRating3: TMenuItem;
   518      miSelByRatingSup1: TMenuItem;
   519      miSelByRatingSup2: TMenuItem;
   520      miSelByRatingSup0: TMenuItem;
   521      miVal4: TMenuItem;
   522      miVal5: TMenuItem;
   523      miSelByRating4: TMenuItem;
   524      miSelByRating5: TMenuItem;
   525      miSelByRatingSup3: TMenuItem;
   526      miSelByRatingSup4: TMenuItem;
   527      miLoadPLPackage: TMenuItem;
   528      BBGroups: TSxButtonBox;
   529      miActiveKeys: TMenuItem;
   530      miEraseAllLogs: TMenuItem;
   531      miSetPLTitle: TMenuItem;
   532      miRenamePL: TMenuItem;
   533      SxMixer1: TSxMixer;
   534      miSaveAsM3UReloc: TMenuItem;
   535      miSaveAsCSVChoreTitreArt: TMenuItem;
   536      miSaveAsCSVBestFill: TMenuItem;
   537      miSaveASCSVHTML: TMenuItem;
   538      miSaveASHTMLAdvPL: TMenuItem;
   539      miSaveAsCSVNoClip: TMenuItem;
   540      miForceFind: TMenuItem;
   541      miPLLoadingConfig: TMenuItem;
   542      miPLReplaceMode: TMenuItem;
   543      miLoadAsSelectedPL: TMenuItem;
   544      N27: TMenuItem;
   545      miPlayers: TMenuItem;
   546      miSetPlayer1: TMenuItem;
   547      miSetPlayer2: TMenuItem;
   548      N28: TMenuItem;
   549      miSetAlwaysExternal: TMenuItem;
   550      N29: TMenuItem;
   551      miMoveFiles: TMenuItem;
   552      EdComment: TEdit;
   553      miPlayerParams: TMenuItem;
   554      miAlwaysGoNExt: TMenuItem;
   555      miDisplay: TMenuItem;
   556      miJournalisations: TMenuItem;
   557      N30: TMenuItem;
   558      miReadLog: TMenuItem;
   559      miOpenCurrentLog: TMenuItem;
   560      miHelp: TMenuItem;
   561      miSecureKeyboard: TMenuItem;
   562      miLoadClip: TMenuItem;
   563      miCSV: TMenuItem;
   564      miSaveAsHTMLSite: TMenuItem;
   565      CmbSounds: TComboBox;
   566      miFadeOut: TPopupMenu;
   567      popFadeOut3000: TMenuItem;
   568      popFadeOut5000: TMenuItem;
   569      popFadeOut1000: TMenuItem;
   570      popFadeOut500: TMenuItem;
   571      miCheckHasClip: TMenuItem;
   572      procedure SysBtnCloseClick(Sender: TObject);
   573      procedure SysBtnMaxNormClick(Sender: TObject);
   574      procedure SysBtnMinClick(Sender: TObject);
   575      procedure TopPanelMouseDown(Sender: TObject; Button: TMouseButton;
   576        Shift: TShiftState; X, Y: Integer);
   577      procedure TopPanelMouseMove(Sender: TObject; Shift: TShiftState; X,
   578        Y: Integer);
   579      procedure TopPanelDblClick(Sender: TObject);
   580      procedure FormCreate(Sender: TObject);
   581      procedure btnPagesClick(Sender: TObject);
   582      procedure FormDestroy(Sender: TObject);
   583      procedure SFVAfterSelection(const aNode: TTreeNode;
   584        var aSel: TSxTriVal);
   585      procedure PanRightBrowserResize(Sender: TObject);
   586      procedure PanDirTreeResize(Sender: TObject);
   587      procedure PanSelectionResize(Sender: TObject);
   588      procedure ActionPlayExecute(Sender: TObject);
   589      procedure ActionPauseExecute(Sender: TObject);
   590      procedure ActionStopExecute(Sender: TObject);
   591      procedure ActionGoPrevExecute(Sender: TObject);
   592      procedure ActionGoNextExecute(Sender: TObject);
   593      procedure SBVolumeChange(Sender: TObject);
   594      procedure SCGKeyPress(Sender: TObject; var Key: Char);  
   595      procedure SCGKeyDown(Sender: TObject; var Key: Word;
   596        Shift: TShiftState);
   597      procedure SCGSelectionKeyDown(Sender: TObject; var Key: Word;
   598        Shift: TShiftState);
   599      procedure ActionMuteExecute(Sender: TObject);
   600      procedure btnKeyUp(Sender: TObject; var Key: Word;
   601        Shift: TShiftState);
   602      procedure ActionSendToSelectionExecute(Sender: TObject);  
   603      procedure ActionSendToSelectionWDExecute(Sender: TObject);
   604      procedure ActionSaveAsM3UExecute(Sender: TObject);
   605      procedure ActionSaveAsVDJExecute(Sender: TObject);
   606      procedure ActionSaveAsTitleListExecute(Sender: TObject);
   607      procedure ActionEmptyGridExecute(Sender: TObject);
   608      procedure ActionLoadPlayListExecute(Sender: TObject);
   609      procedure SFVDblClick(Sender: TObject);
   610      procedure ActionSelectAllExecute(Sender: TObject);
   611      procedure ActionDelPlayListExecute(Sender: TObject);
   612      procedure SFVContextPopup(Sender: TObject; MousePos: TPoint;
   613        var Handled: Boolean);
   614      procedure ActionOpenExplorerExecute(Sender: TObject);
   615      procedure miDisplayPropertiesClick(Sender: TObject);
   616      procedure SCGBrowserContextPopup(Sender: TObject; MousePos: TPoint;
   617        var Handled: Boolean);
   618      procedure miReloadFileClick(Sender: TObject);
   619      procedure ActionSearchExecute(Sender: TObject);
   620      procedure EdSearchChange(Sender: TObject);
   621      procedure EdSearchComboChange(Sender: TObject);
   622      procedure EdSearchKeyDown(Sender: TObject; var Key: Word;
   623        Shift: TShiftState);
   624      procedure miAddToSelectionClick(Sender: TObject);
   625      procedure ActionChangeNBPExecute(Sender: TObject);
   626      procedure ActionOneAllExecute(Sender: TObject);
   627      procedure FilterGraphBrowserGraphComplete(sender: TObject;
   628        Result: HRESULT; Renderer: IBaseFilter);
   629      procedure FilterGraphSelectionGraphComplete(sender: TObject;
   630        Result: HRESULT; Renderer: IBaseFilter);
   631      procedure miCopyFilesClick(Sender: TObject);
   632      procedure miDurationClick(Sender: TObject);
   633      procedure ActionFindFileExecute(Sender: TObject);
   634      procedure GridClick(Sender: TObject);
   635      procedure miUpdateID3sClick(Sender: TObject);
   636      procedure FormActivate(Sender: TObject);
   637      procedure ChkOnlySelClick(Sender: TObject);
   638      procedure CmbTemporisationChange(Sender: TObject);
   639      procedure FilterGraphBrowserGraphErrorAbort(sender: TObject;
   640        Result: HRESULT);         
   641      procedure miDefineInitialOrderClick(Sender: TObject);
   642      procedure miSortByInitilaOrderClick(Sender: TObject);
   643      procedure miSortByFileAgeClick(Sender: TObject);
   644      procedure miSortByGroupsClick(Sender: TObject);
   645      procedure miSortGridByTitleClick(Sender: TObject); 
   646      procedure miSortGridByChoreClick(Sender: TObject);  
   647      procedure miSortByAuthorClick(Sender: TObject);
   648      procedure miSortGridByNBPClick(Sender: TObject);
   649      procedure DSTrackBar2Change(Sender: TObject);
   650      procedure miCopyFilesSFNClick(Sender: TObject);
   651      procedure miAddnodeToSelectionClick(Sender: TObject);
   652      procedure btnPreferencesClick(Sender: TObject);
   653      procedure miColorProfilClick(Sender: TObject);
   654      procedure miAllwaysOnTopClick(Sender: TObject);
   655      procedure miDefinePLRootClick(Sender: TObject);
   656      procedure miDeleteNonSelClick(Sender: TObject);
   657      procedure miInvertSelectionClick(Sender: TObject);
   658      procedure PanLeftSelectionResize(Sender: TObject);
   659      procedure miCmmFntSzClick(Sender: TObject);
   660      procedure miCmmViewerFntSzClick(Sender: TObject);
   661      procedure miDisplayTitleClick(Sender: TObject);  
   662      procedure miDispChoreTitleClick(Sender: TObject);
   663      procedure miDisplayChoreClick(Sender: TObject);
   664      procedure miDisplayCategClick(Sender: TObject);
   665      procedure miPlayListM3UMovedClick(Sender: TObject);
   666      procedure miCharSizePrefClick(Sender: TObject);
   667      procedure miAproposClick(Sender: TObject);
   668      procedure miSelectUntilClick(Sender: TObject);
   669      procedure miSelectFromClick(Sender: TObject);
   670      procedure miUnselDblByThatClick(Sender: TObject);
   671      procedure miCheckChoregraphiedClick(Sender: TObject);
   672      procedure miDefSelNumXClick(Sender: TObject);
   673      procedure miSelectSelNumXClick(Sender: TObject);
   674      procedure miDispAuthorTitleClick(Sender: TObject);
   675      procedure miCheckTitledClick(Sender: TObject);
   676      procedure miSaveAsChoreListClick(Sender: TObject);
   677      procedure miSaveChoregClick(Sender: TObject);
   678      procedure miConfirmChkAllClick(Sender: TObject);
   679      procedure miEmptyConfirmClick(Sender: TObject);
   680      procedure miConfirmFileExistsClick(Sender: TObject);
   681      procedure miDownloadVersionClick(Sender: TObject);
   682      procedure miInstallUpdatesClick(Sender: TObject);
   683      procedure miInstallMajorUpdatesClick(Sender: TObject);
   684      procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
   685        Shift: TShiftState; X, Y: Integer);
   686      procedure NoMenuOpenClick(Sender: TObject);
   687      procedure NoMenuOpenMouseUp(Sender: TObject; Button: TMouseButton;
   688        Shift: TShiftState; X, Y: Integer);
   689      procedure SCGSelectionStartDrag(Sender: TObject;
   690        var DragObject: TDragObject);
   691      procedure SCGSelectionDragOver(Sender, Source: TObject; X, Y: Integer;
   692        State: TDragState; var Accept: Boolean);
   693      procedure SCGSelectionDragDrop(Sender, Source: TObject; X, Y: Integer);
   694      procedure SCGSelectionEndDrag(Sender, Target: TObject; X, Y: Integer);
   695      procedure SCGSelectionMouseDown(Sender: TObject; Button: TMouseButton;
   696        Shift: TShiftState; X, Y: Integer);
   697      procedure SCGSelectionMouseUp(Sender: TObject; Button: TMouseButton;
   698        Shift: TShiftState; X, Y: Integer);
   699      procedure miDefineVolumeClick(Sender: TObject); 
   700      procedure miDefineFadeInClick(Sender: TObject);
   701      procedure miDefineFadeOutClick(Sender: TObject);
   702      procedure miDefineStartClick(Sender: TObject);
   703      procedure miDefineStopClick(Sender: TObject);
   704      procedure TimerFadeTimer(Sender: TObject);
   705      procedure miSaveLogClick(Sender: TObject);
   706      procedure miClearLogClick(Sender: TObject);
   707      procedure miLoadFromLogClick(Sender: TObject);
   708      procedure miSelSelNumXClick(Sender: TObject);
   709      procedure miRenameSubSelXClick(Sender: TObject);
   710      procedure miInitTrackClick(Sender: TObject);
   711      procedure miClearFromSubSelXClick(Sender: TObject);
   712      procedure miRestoreKeyCodesClick(Sender: TObject);
   713      procedure popGridPopup(Sender: TObject);
   714      procedure popupBtnSelectionPopup(Sender: TObject);
   715      procedure miRemoveLineClick(Sender: TObject);
   716      procedure miClearFromAllSubSelClick(Sender: TObject);
   717      procedure miReloadPathClick(Sender: TObject);
   718      function SFVAllowAction(const aNode: TTreeNode): Boolean;
   719      procedure BBGroupsClick(Sender: TObject);
   720      procedure miMoveTopGroupClick(Sender: TObject);
   721      procedure miShowHidePlayedClick(Sender: TObject);
   722      procedure miShowOnlyPlayedClick(Sender: TObject);
   723      procedure miSelShowMixClick(Sender: TObject);
   724      procedure SxMixer1Play(var aRow: Integer);
   725      procedure SxMixer1Stop(var aRow: Integer);
   726      procedure PanRightSelectionResize(Sender: TObject);
   727      procedure miSelByRatingClick(Sender: TObject);
   728      procedure miLoadPLPackageClick(Sender: TObject);
   729      procedure miActiveKeysClick(Sender: TObject);
   730      procedure miEraseAllLogsClick(Sender: TObject);
   731      procedure SxMixer1Timer(const aRow: Integer; const pPos, pStop,
   732        tmInterval: Int64);
   733      procedure miSetPLTitleClick(Sender: TObject);
   734      procedure miRenamePLClick(Sender: TObject);
   735      function SxMixer1QueryFile(var aFileName: String; var aRowNum,
   736        Volume: Integer; var aSR: TSndRange): Boolean;
   737      function SxMixer1QueryNextFile(var aFileName: String; var aRowNum,
   738        Volume: Integer; var aSR: TSndRange): Boolean;
   739      function SxMixer1QueryPreviousFile(var aFileName: String; var aRowNum,
   740        Volume: Integer; var aSR: TSndRange): Boolean;
   741      procedure miSaveAsCSVChoreTitreArtClick(Sender: TObject);
   742      procedure miSaveAsCSVBestFillClick(Sender: TObject);
   743      procedure miSaveASHTMLAdvPLClick(Sender: TObject);
   744      procedure miSaveAsCSVNoClipClick(Sender: TObject);
   745      procedure miForceFindClick(Sender: TObject);
   746      procedure miPLReplaceModeClick(Sender: TObject);
   747      procedure miLoadAsSelectedPLClick(Sender: TObject);
   748      procedure miSetPlayerClick(Sender: TObject);
   749      procedure miSetAlwaysExternalClick(Sender: TObject);
   750      procedure miMoveFilesClick(Sender: TObject);
   751      procedure EdCommentClick(Sender: TObject);
   752      procedure EdCommentKeyUp(Sender: TObject; var Key: Word;
   753        Shift: TShiftState);
   754      procedure miAlwaysGoNExtClick(Sender: TObject);
   755      procedure miReadLogClick(Sender: TObject);
   756      procedure miOpenCurrentLogClick(Sender: TObject);
   757      procedure miHelpClick(Sender: TObject);
   758      procedure miSecureKeyboardClick(Sender: TObject);
   759      procedure RESelectionKeyDown(Sender: TObject; var Key: Word;
   760        Shift: TShiftState);
   761      procedure miLoadClipClick(Sender: TObject);
   762      procedure CmbSoundsChange(Sender: TObject);
   763      procedure popFadeOutClick(Sender: TObject);
   764      procedure miCheckHasClipClick(Sender: TObject);
   765    private
   766      FViewer: TSxViewer;
   767      FOnNCDblClick : TNotifyEvent;
   768      procedure SetInitialPositions;
   769      procedure DoEndTemporisation(aSender : TObject);
   770      procedure DoOnWSChange(Sender : TObject);
   771    protected
   772       FSLLog : TStringList;
   773       FIsStoppedForInstall : boolean;
   774       FIsInit : boolean;
   775       FIsTemporised : boolean;
   776       FIsCtrlState : boolean;
   777       FIsTitleShown, FIsCommentShown : boolean;
   778       FCSLBrowser : TCustomSongList;
   779       FCSLSelection : TCustomSongList;
   780       FCurrentPL : TCustomSongList;
   781       FCurrentGrid : TSxCustomChoiceGrid;
   782       FCurrentChk : TCheckBox;
   783       FCurrentChkShow : TCheckBox;
   784       FCurrentFG : TFilterGraph;
   785       FCurrentRightPanel : TPanel;
   786       FCurrentLeftPanel : TPanel;
   787       FCurrentVol : TSxScrollBarEx;
   788       FCurrentTrackBar : TDSTrackBar;
   789       FCurrentBtnPage : TSxFlatButton;
   790       FSelectionLoaded : boolean;
   791       FLastPlayList : string;
   792       FLastPath : string;
   793       FNumMode : TNumericMode;
   794       FIsNoMenuOpen : boolean;
   795       FStartDragIndex : integer;
   796       FKeyIdents : TSxKeyConf;
   797       FHPlayInstance : THandle;
   798       FEnableKey, FEnableKeyParam : boolean;
   799       FSLNames : TStringList;
   800       FIsSpecialSound : boolean;
   801       procedure ChangeMaxNormBitmap; override;
   802       procedure WMDropFiles (var Msg: TWMDropFiles); message WM_DROPFILES;
   803       procedure WMMENUSELECT(var msg: TWMMENUSELECT); message WM_MENUSELECT;
   804       procedure DoOnException(Sender: TObject; E: Exception);
   805    public
   806       procedure AfterConstruction; override;
   807       procedure InitLog;
   808       procedure AddToLog(const Typ : TSxLogType; const s : string);
   809       procedure InitThePageControl;
   810       procedure InitGrids;
   811       procedure FreeGrids;
   812       procedure ClearPLInfosView;
   813       procedure UpdatePLInfosView;
   814       procedure UpdateGroupsView(const lineExistance : boolean);
   815       procedure LoadPlayList(const aFilename : string);
   816       function LoadSelectionFromCmdLine : boolean;
   817       procedure InitProperties;
   818       procedure ManageUpdates(const aNivDetail : integer);
   819       procedure ManageKeyDown(var aKey : word; const Shift: TShiftState);
   820       function LoadConfig : boolean;
   821       procedure ChangeColors(idx : integer);
   822       procedure SetGridCharSize;
   823       procedure SetCurrentPlayList;
   824       procedure SetCurrentFilterGraph;
   825       procedure SetCurrentVolume;
   826       procedure ForceChkBox(const aChecked : boolean);
   827       procedure SetChkBoxAllNone(const nbr : integer);
   828       procedure DisplayCurrentDuration;
   829       procedure StopThatThing(const isCmd : boolean);
   830       procedure DoTemporisation;
   831       procedure StartStopDef(const aFileName : string; pStart, pStop : Int64);
   832       procedure PlayThatThing(const aFileName : string); overload;
   833       procedure PlayThatThing(const num : integer); overload;
   834       procedure PlaySample(const n : integer);
   835       procedure SetThisPL(n : integer);
   836       procedure SelectThisSubSel(const n : integer);
   837       procedure SelectThisBBItem(const n : integer);
   838       procedure SelectThisPL(const n : integer);
   839       procedure ManageNumericCmd(n : integer; const m : integer);
   840       procedure CommentViewerKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
   841       procedure OpenCloseTitleDisplay;
   842       procedure OpenCloseCommentDisplay;
   843       procedure UpdateDisplay(const aKey : integer);
   844       procedure UpdateTitleDisplay(const aKey : integer);
   845       procedure UpdateCommentDisplay(const aKey : integer);
   846       procedure DisplayFullGrid;
   847       procedure FocusCurrentPL;
   848       procedure ShowHideSearchEdit(const visible : boolean);
   849       procedure FadeOut(mSec : integer);
   850       procedure UpdateMenuSubSel;
   851       procedure SetMIPlayerCaption(const aMI : TMEnuItem; const aFileName : string);
   852       property OnNCDblClick : TNotifyEvent read FOnNCDblClick write FOnNCDblClick;
   853    published
   854    end;
   855  
   856  
   857  
   858  
   859  
   860  
   861  
   862  var
   863     SxMSPForm : TSxMSPForm;
   864  
   865  implementation
   866  uses
   867     SxWinFichier, SxWinDrivesAndFolders, FileCtrl,
   868     FmID3Edition, FrmAPropos, FrmWaiting, FrmLogReader,
   869     MMSystem, MSPNet, Math,
   870     res_sons;
   871  
   872  
   873  {$R *.DFM}
   874  
   875  {$R shortcutshelp_1001.res}
   876  
   877  
   878  
   879  (*
   880   * WMNCPaint dessine les zones non client de la fiche
   881   *           en sorte de ne pas avoir de barre de titre
   882   *)
   883  procedure TForm.WMNCPaint(var Message: TWMNCPaint);
   884  var
   885     Canvas:TCanvas;
   886  begin
   887     inherited;
   888     Canvas:=TCanvas.Create;
   889     try
   890        Canvas.Handle := GetWindowDC(Handle);
   891        Canvas.Brush.Style := bsSolid;
   892        Canvas.Brush.Color := Color;
   893        Canvas.FillRect(Rect(0,0,Width,3+BorderWidth));
   894        Canvas.FillRect(Rect(0,Height-3+BorderWidth,Width,Height));
   895        Canvas.FillRect(Rect(0,0,3+BorderWidth,Height));
   896        Canvas.FillRect(Rect(Width-(3+BorderWidth),0,Width,Height));
   897     finally
   898        Canvas.Free;
   899     end;
   900  end;
   901  
   902  procedure TForm.WMSize(var Message :  TWMSize);
   903  begin
   904     inherited;
   905     SendMessage(Handle, WM_NCPAINT, 0, 0);
   906  end;
   907  
   908  
   909  
   910  
   911  
   912  
   913  
   914  (*
   915   * SysBtnCloseClick répond au click sur l'icône de fermeture
   916   *)
   917  procedure TSxMSPForm.SysBtnCloseClick(Sender: TObject);
   918  begin
   919     FIsNoMenuOpen := true;
   920     if CloseQuery then
   921        Close;
   922  end;
   923  
   924  (*
   925   * ChangeMaxNormBitmap dessine le boutn de redimensionnement
   926   *)
   927  procedure TSxMSPForm.ChangeMaxNormBitmap;
   928  var
   929     FBtnMaxNormImage : TBitmap;
   930  begin
   931     FBtnMaxNormImage := TBitmap.Create;
   932     try
   933        ILBtnMaxNorm.GetBitmap(Ord(wsNormal <> WindowState), FBtnMaxNormImage);
   934        if (wsNormal <> WindowState)  then
   935           SysBtnMaxNorm.Hint := 'Restaurer la fenêtre'
   936        else
   937           SysBtnMaxNorm.Hint := 'Maximiser la fenêtre';
   938        SysBtnMaxNorm.Glyph.Dormant;
   939        SysBtnMaxNorm.Glyph.FreeImage;
   940        SysBtnMaxNorm.Glyph.ReleaseHandle;
   941        SysBtnMaxNorm.Glyph.Assign(FBtnMaxNormImage);
   942        FBtnMaxNormImage.Dormant;
   943        FBtnMaxNormImage.FreeImage;
   944        FBtnMaxNormImage.ReleaseHandle;
   945     finally
   946        FBtnMaxNormImage.Free;
   947     end;
   948  end;
   949  
   950  
   951  (*
   952   * SysBtnMaxNormClick répond au click sur le bouton de redimensionnement
   953   *)
   954  procedure TSxMSPForm.SysBtnMaxNormClick(Sender: TObject);
   955  begin
   956     FIsNoMenuOpen := true;
   957     if wsNormal <> WindowState then
   958        WindowState := wsNormal
   959     else
   960        WindowState := wsMaximized;
   961     FPreferences.isMaximized := WindowState = wsMaximized;
   962     ChangeMaxNormBitmap;
   963     Splitter2.Align := alRight;
   964     Splitter2.Align := alLeft;
   965     SplitterSelEDTV.Align := alBottom;
   966     SplitterSelEDTV.Align := alTop;
   967     Splitter1.Align := alRight;
   968     Splitter1.Align := alLeft;
   969     PanRightSelectionResize(Sender);
   970  end;
   971  
   972  (*
   973   * SysBtnMinClick répond au click sur le bouton de minimisation
   974   *)
   975  procedure TSxMSPForm.SysBtnMinClick(Sender: TObject);
   976  begin
   977     FIsNoMenuOpen := true;
   978     Application.Minimize;
   979  end;
   980  
   981  (*
   982   * TopPanelMouseDown répond au mousedown sur la panneau supérieur
   983   *  Cette procédure est utilisée pour déplacer la fiche avec TopPanelMouseMove
   984   *)
   985  procedure TSxMSPForm.TopPanelMouseDown(Sender: TObject;
   986    Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
   987  begin
   988     FPtMouseIni := Mouse.CursorPos;
   989     FPtWndIni := Point(Left, Top);
   990  end;
   991  
   992  (*
   993   * TopPanelMouseMove gère le déplacement de la fiche applicative
   994   *)
   995  procedure TSxMSPForm.TopPanelMouseMove(Sender: TObject;
   996    Shift: TShiftState; X, Y: Integer);
   997  var
   998    Delta : TPoint;
   999    Pt : TPoint;
  1000  begin
  1001     if (ssLeft in Shift) and (wsNormal = WindowState) then
  1002     begin
  1003        Pt := Mouse.CursorPos;
  1004        Delta.x := Pt.x - FPtMouseIni.x;
  1005        Delta.y := Pt.y - FPtMouseIni.y;
  1006        if not FLockedForm then
  1007        begin
  1008           Left := FPtWndIni.x + Delta.x;
  1009           Top := FPtWndIni.y + Delta.y;
  1010        end;
  1011     end;
  1012  end;
  1013  
  1014  (*
  1015   * TopPanelDblClick répond au double-click sur le panneau supérieur
  1016   *  Implémente le comportement normal d'une barre de titre.
  1017   *)
  1018  procedure TSxMSPForm.TopPanelDblClick(Sender: TObject);
  1019  begin
  1020     FIsNoMenuOpen := true;
  1021     SysBtnMaxNormClick(nil);
  1022  end;
  1023  
  1024  procedure TSxMSPForm.AfterConstruction;
  1025  begin
  1026     inherited;
  1027  end;
  1028  
  1029  
  1030  (*
  1031   *
  1032   * Customisation de la SimpleForm pour MSP
  1033   *
  1034   *)
  1035  
  1036  
  1037  (*
  1038   * InitLog initialise la  journalisation
  1039   *)
  1040  procedure TSxMSPForm.InitLog;
  1041  var
  1042     sDt : string;
  1043  begin
  1044     DateTimeToString(sDt, 'c', Now);
  1045     FSLLOG.Add(sDt);
  1046     FSLLOG.Add('');
  1047  end;
  1048  
  1049  (*
  1050   * AddToLog ajoute une ligne au journal
  1051   *)
  1052  procedure TSxMSPForm.AddToLog(const Typ : TSxLogType; const s : string);
  1053  var
  1054     sDt : string;
  1055  begin
  1056     try
  1057        if FPreferences.isJournalized then
  1058        begin
  1059           if Assigned(FSLLOG) then
  1060           begin
  1061              case Typ of
  1062                 CL_FILETOPLAY : begin
  1063                                    DateTimeToString(sDt, 'c', Now);
  1064                                    FSLLOG.Add('# Start : ' + sDt);
  1065                                    FSLLOG.Add(s);
  1066                                 end;
  1067                 CL_DATE : begin
  1068                              DateTimeToString(sDt, 'c', Now);
  1069                              FSLLOG.Add('# Stop : ' + sDt);
  1070                           end;
  1071              else
  1072                 FSLLOG.Add('# ' + s);
  1073              end;
  1074           end
  1075           else
  1076           begin
  1077              ShowHideSearchEdit(false);
  1078              LbTitre.Caption := '# ERREUR : fichier journal non instancié ...';
  1079              FPreferences.isJournalized := false;
  1080           end;
  1081        end;
  1082     except
  1083        on E: Exception do
  1084           LbTitre.Caption := E.Message;
  1085     end;
  1086  end;
  1087  
  1088  (*
  1089   * InitThePageControl initialise la partie principale de l'IHM (les 2 pages)
  1090   * Cette procédure ne charge aucune donnée, n'utilise pas les préférences
  1091   *)
  1092  procedure TSxMSPForm.InitThePageControl;
  1093  begin
  1094     // initialisation du controle Pages du Playeur Sélection
  1095     SelTSMono.InitialIndex := 99;
  1096     SelTSMix.InitialIndex := 99;
  1097     SelTSMono.InitialIndex := C_PG_MONO;
  1098     SelTSMix.InitialIndex := C_PG_MIX;
  1099     SelPgCtrl.SortPages;
  1100     SelPgCtrl.ActivePageIndex := C_PG_MONO;
  1101     // initialisation du Controle Pages principal
  1102     TSBrowser.InitialIndex := 99;
  1103     TSSelection.InitialIndex := 99;
  1104     TSBrowser.InitialIndex := C_PG_BROWSER;
  1105     TSSelection.InitialIndex := C_PG_SELECTION;
  1106     btnBrowser.Tag := C_PG_BROWSER;
  1107     btnSelection.Tag := C_PG_SELECTION;
  1108     PgCtrl.SortPages;
  1109     PgCtrl.ActivePageIndex := C_PG_BROWSER;
  1110     EdSearch.ComboWidth := Canvas.TextWidth('Titre, sous titre, Nom de Fichier')+30;
  1111     EdSearch.Constraints.MinWidth := EdSearch.ComboWidth+10;
  1112     EdSearch.AddCheckedObject('Titre, sous titre, Nom de Fichier', TObject(msoTitleSTF), true);
  1113     EdSearch.AddCheckedObject('Titre', TObject(msoTitle), false);
  1114     EdSearch.AddCheckedObject('Album', TObject(msoAlbum), false);
  1115     EdSearch.AddCheckedObject('Artiste', TObject(msoArtist), true);
  1116     EdSearch.AddCheckedObject('Année', TObject(msoYear), false);
  1117     EdSearch.AddCheckedObject('Chorégraphie', TObject(msoChore), true);
  1118     EdSearch.AddCheckedObject('Catégorie', TObject(msoCateg), false);
  1119     EdSearch.AddCheckedObject('Notation', TObject(msoNBP), false);
  1120     EdSearch.AddCheckedObject('Nom du fichier', TObject(msoFileName), false);
  1121     miUnselDblByFileName.Tag := Integer(mcoFileName);
  1122     miUnselDblByTitle.Tag := Integer(mcoTitle);
  1123     miUnselDblByChoreg.Tag := Integer(mcoChore);
  1124  end;
  1125  
  1126  (*
  1127   * InitGrids initialise les objets de données associés aux grilles
  1128   *)
  1129  procedure TSxMSPForm.InitGrids;
  1130  begin         
  1131     FCSLBrowser := TCustomSongList.Create(SCGBrowser);
  1132     FCSLBrowser.AddExt('.wma');
  1133     FCSLBrowser.AddExt('.mp3');
  1134     FCSLBrowser.AddExt('.m4a');
  1135     FCSLBrowser.AddExt('.flac');
  1136     FCSLBrowser.AddExt('.avi');
  1137     FCSLBrowser.ListEditable := False;
  1138     FCSLBrowser.AltFilterGraph := FilterGraphTmp;
  1139     FCSLBrowser.FilterGraph := FilterGraphBrowser;
  1140     FCSLBrowser.PlayingBkColor := $0098FFCC;
  1141     FCSLSelection := TCustomSongList.Create(SCGSelection);
  1142     FCSLSelection.AddExt('.mp3');
  1143     FCSLSelection.AddExt('.wma');
  1144     FCSLSelection.AddExt('.m4a');
  1145     FCSLSelection.AddExt('.flac');
  1146     FCSLBrowser.AddExt('.mpeg');
  1147     FCSLBrowser.AddExt('.avi');
  1148     FCSLBrowser.AddExt('.mpg');
  1149     FCSLSelection.ListEditable := False;
  1150     FCSLSelection.AltFilterGraph := FilterGraphTmp;
  1151     FCSLSelection.FilterGraph := FilterGraphSelection;
  1152     FCSLSelection.PlayingBkColor := $0033BB22;
  1153     FSelectionLoaded := false;
  1154  end;
  1155  
  1156  (*
  1157   * FreeGrids libère les objets de données associés aux grilles
  1158   *)
  1159  procedure TSxMSPForm.FreeGrids;
  1160  begin
  1161     if Assigned(FCSLBrowser) then
  1162        FCSLBrowser.Destroy;
  1163     FCSLBrowser := nil;
  1164     if Assigned(FCSLSelection) then
  1165        FCSLSelection.Destroy;
  1166     FCSLSelection := nil;
  1167  end;
  1168  
  1169  (*
  1170   * ClearPLInfosView : supprime les boutons des groupes vides
  1171   *)
  1172  procedure TSxMSPForm.ClearPLInfosView;
  1173  var
  1174     j, cnt, p : integer;
  1175  begin
  1176     j := 0;
  1177     cnt := BBGroups.BtnCount;
  1178     while (j < cnt) do
  1179     begin
  1180        p := BBGroups.Buttons[j].Tag;
  1181        if (p < 0) then  
  1182        begin
  1183           BBGroups.DelButton(p);
  1184           dec(cnt);
  1185           Continue;
  1186        end;
  1187        inc(j);
  1188     end;
  1189  end;
  1190  
  1191  (*
  1192   * UpdatePLInfosView met à jour les boutons de groupes
  1193   *)
  1194  procedure TSxMSPForm.UpdatePLInfosView;
  1195  var
  1196     cnt, pid, i, idx : integer;
  1197     btn : TSxFlatBoxedButton;
  1198  begin
  1199     for i := 0 to FCurrentPL.PLInfosCount - 1 do
  1200     begin 
  1201        pid := FCurrentPL.PLIds[i] * -1;
  1202        idx := BBGroups.FindButtonIndex(pid);
  1203        if (-1 = idx) then
  1204        begin
  1205           btn := BBGroups.InsertButton(pid, FCurrentPL.PLTitles[i], '');
  1206           btn.PopupMenu := nil;
  1207        end
  1208        else
  1209           BBGroups.Buttons[idx].Caption := FCurrentPL.PLTitles[i];
  1210     end;
  1211  end;
  1212  
  1213  procedure TSxMSPForm.UpdateGroupsView(const lineExistance : boolean);
  1214  var
  1215     p, i, j, idgrp : integer;
  1216  begin
  1217     UpdatePLInfosView;
  1218     idgrp := 1;
  1219     if lineExistance then
  1220        for i := 1 to C_GRPMAX-1 do
  1221        begin
  1222           p := BBGroups.FindButtonIndex(idgrp);
  1223           if (0 < FCurrentPL.GrpCounters[i]) then
  1224           begin
  1225              if (p < 0) then
  1226                 BBGroups.AddButton(idgrp, FCurrentPL.GrpTitle[i], '');
  1227           end
  1228           else
  1229           begin
  1230              if (p >= 0) then
  1231                 BBGroups.DelButton(idgrp);
  1232           end;
  1233           idgrp := idgrp shl 1;
  1234        end
  1235     else
  1236        for i := 0 to BBGroups.BtnCount - 1 do
  1237        begin
  1238           idgrp := 1;
  1239           j := 0;
  1240           p := BBGroups.Buttons[i].Tag;
  1241           while (p <> idgrp) do
  1242           begin
  1243              idgrp := idgrp shr 1;
  1244              inc(j);
  1245           end;
  1246           BBGroups.Buttons[i].Caption := FCurrentPL.GrpTitle[j];
  1247        end;
  1248  end;
  1249  
  1250  (*
  1251   * LoadPlayList charge une liste de lecture
  1252   *  l'argument peut être un fichier log, PL ou GPL
  1253   *)
  1254  procedure TSxMSPForm.LoadPlayList(const aFilename : string);
  1255  begin
  1256     if (ExtractFileExt(LowerCase(aFileName)) = '.log') then
  1257        FCurrentPL.LoadGridFromFile(aFilename,
  1258                                    FPreferences.AllowDoublons,
  1259                                    FPreferences.isForceFind)
  1260     else
  1261     begin
  1262        FCurrentPL.LoadGridFromPlayList(aFilename,
  1263                                        FPreferences.AllowDoublons,
  1264                                        FPreferences.isForceFind,
  1265                                        FPreferences.isPrettyFind);
  1266        FLastPlayList := aFilename;
  1267     end;
  1268     FSelectionLoaded := true;
  1269     FCurrentPL.DoOnResize(nil);
  1270     UpdateMenuSubSel;
  1271     if (FCurrentPL = FCSLSelection) then
  1272        UpdateGroupsView(true);
  1273  end;
  1274  
  1275  (*
  1276   * LoadSelectionFromCmdLine charge une liste de lecture
  1277   * depuis la ligne de commande
  1278   *)
  1279  function TSxMSPForm.LoadSelectionFromCmdLine : boolean;
  1280  var
  1281     aFileName, aExt : string;
  1282  begin
  1283     if ParamCount >= 1 then
  1284     begin
  1285        aFileName := ParamStr(1);
  1286        aExt := LowerCase(ExtractFileExt(aFileName));
  1287     end
  1288     else
  1289        aFileName := ''; 
  1290     if FileExists(aFileName) and ((aExt = '.m3u') or (aExt = '.m6u')) then
  1291     try
  1292        try
  1293           btnPagesClick(btnSelection);
  1294           LoadPlayList(aFileName);
  1295        except
  1296           on e: exception do
  1297              DoOnException(Self, e);
  1298        end;
  1299     finally
  1300        result := true;
  1301     end
  1302     else
  1303        result := false;
  1304  end;
  1305  
  1306  
  1307  (*
  1308   * InitProperties initialise les préférence et des indicateurs globaux
  1309   * Cette procédure définit les propriétés par défaut
  1310   *)
  1311  procedure TSxMSPForm.InitProperties;
  1312  begin    
  1313     FLastPlayList := '';
  1314     FEnableKey := true;
  1315     FEnableKeyParam := true;
  1316     FNumMode := nmPlay;
  1317     with FPreferences do
  1318     begin
  1319        isPlayAllBrowser := false;
  1320        isPlayAllSelection := false;
  1321        isTransparent := false;
  1322        isAlwaysGoNext := true;
  1323        isForceFind := false;
  1324        isPLReplaceMode := true;
  1325        LastSelPath := ExtractFilePath(ParamStr(0));
  1326     end;
  1327     FIsTemporised := false;
  1328     FIsCtrlState := false;  // flag "est ctrl enfoncé" pour télécommande IR = VK_MULTIPLY
  1329     FIsTitleShown := false;
  1330     FIsCommentShown := false;
  1331     FPreferences.ViewFntSize := 110;
  1332     FPreferences.AllowDoublons := true;
  1333     FLastPath := GetWindowsFolder(CSIDL_MYMUSIC);
  1334  end;
  1335  
  1336  (*
  1337   * ManageUpdates gère les mises à jour
  1338   *)
  1339  procedure TSxMSPForm.ManageUpdates(const aNivDetail : integer);
  1340  var
  1341     res : integer;
  1342  const
  1343     C_MSGUPDT : array[boolean] of string = ('Recherche des mises à jour', 
  1344                                             'Recherche des mises à jour importantes');
  1345  begin
  1346     FIsNoMenuOpen := true;
  1347     ShowMainSplash(0, 100, 0, $00FBB055);
  1348     WaitingPosMainSplash(10, '', C_MSGUPDT[aNivDetail>1]);
  1349     res := NewVersionExists(aNivDetail, nil);
  1350     if (res = 1) then
  1351     begin
  1352        WaitingPosMainSplash(3, '', 'Installation d''une nouvelle version ...',
  1353                             'Redémarrage automatique dans 120 secondes.', clRed);
  1354        FPreferences.isAutoUpdate := InstallNewVersion(nil);
  1355        WaitingPosMainSplash(6, '', 'Installation d''une nouvelle version ...',
  1356                             'Redémarrage automatique dans quelques secondes.', clRed);
  1357        CloseMainSplash(1000);
  1358        Application.Terminate;
  1359     end
  1360     else
  1361     begin
  1362        if (res = -1) then
  1363           WaitingPosMainSplash(100, 'Echec lors de la connection au serveur ...', 
  1364                                'réessayez ultérieurement ...')
  1365        else
  1366           WaitingPosMainSplash(100, 'Version à jour ...', 
  1367                                'pour vous servir ...');
  1368        CloseMainSplash(3000);
  1369     end;
  1370  end;
  1371  
  1372  (*
  1373   * LoadConfig : Chargement et définition de la configuration
  1374   *)
  1375  function TSxMSPForm.LoadConfig : boolean;
  1376     function ParamInit : boolean;
  1377     var
  1378        i : integer;
  1379        res : boolean;
  1380     begin
  1381        res := false;
  1382        for i := 0 to ParamCount - 1 do
  1383           res := res or (ParamStr(i) = '-init') or (ParamStr(i) = 'init');
  1384        result := res;
  1385     end;
  1386  var
  1387     aPath, aPLFilename : string;
  1388     aNode : TTreeNode;
  1389     sopt : TSxMMSearchOption;
  1390     chk : boolean;
  1391     res : integer;
  1392  begin
  1393     result := false;
  1394     FIsStoppedForInstall := false;
  1395     WaitingPosMainSplash(6, '', 'Paramétrage de l''application...');
  1396     aPath := IncludeTrailingBackSlash(ExtractfilePath(ParamStr(0)));
  1397     if FLastPath = '' then
  1398        FLastPath := aPath;
  1399     aPLFilename := '';
  1400     WaitingPosMainSplash(6, '', 'Définitions du clavier/télécommande...');
  1401     InitDefaultKeyConf(FKeyIdents);
  1402     WaitingPosMainSplash(6, '', 'Chargement des préférences...');
  1403     FPreferences := MSPConfig.LoadConfig(FLastPath, aPLFilename, FKeyIdents, FCSLBrowser);
  1404     FIsInit := false;
  1405     if FPreferences.isAutoUpdate then
  1406     begin
  1407        miDownloadVersion.Checked := true;
  1408        WaitingPosMainSplash(6, '', 'Recherche d''une nouvelle version ...');
  1409        FIsInit := false and ParamInit;
  1410        res := NewVersionExists(1, nil);
  1411        if (1 = res) and not FisInit then
  1412        begin
  1413           WaitingPosMainSplash(3, '', 'Installation d''une nouvelle version ...',
  1414                                   'Redémarrage automatique dans 120 secondes.', clRed);
  1415           FPreferences.isAutoUpdate := InstallNewVersion(nil);
  1416           WaitingPosMainSplash(6, '', 'Installation d''une nouvelle version ...',
  1417                                   'Redémarrage automatique dans quelques secondes.', clRed);
  1418           CloseMainSplash(0);
  1419           FIsStoppedForInstall := true;
  1420           Exit;
  1421        end
  1422        else if (res = -1) then
  1423           WaitingPosMainSplash(6, 'connection impossible au serveur ...', '')
  1424        else
  1425           WaitingPosMainSplash(6, 'Version à jour ...', '');
  1426        if FIsInit then
  1427        begin
  1428           ClearInstallFiles(FPreferences.isClearAll);
  1429           FPreferences.isMaximized := true;
  1430           result := true;
  1431        end;
  1432     end;
  1433     WaitingPosMainSplash(6, '', 'Préférences d''affichage ...');
  1434     if FPreferences.isDayTime then
  1435        miColorProfilClick(miJour)
  1436     else
  1437        miColorProfilClick(miNuit);
  1438     SetGridCharSize;
  1439     if FPreferences.isAllwaysOnTop then 
  1440     begin
  1441        FormStyle := fsStayOnTop;
  1442        miAllwaysOnTop.Checked := true;
  1443     end;
  1444     // Préférences du player player externe
  1445     WaitingPosMainSplash(6, '', 'Préférences du lecteur ...');
  1446     if FPreferences.isAlwaysExternalPlayer then
  1447        miSetAlwaysExternal.Checked := true;
  1448     miAlwaysGoNExt.Checked := FPreferences.isAlwaysGoNext;
  1449     SetMIPlayerCaption(miSetPlayer1, FPreferences.Player1);
  1450     SetMIPlayerCaption(miSetPlayer2, FPreferences.Player2);
  1451     WaitingPosMainSplash(6, '', 'Préférences de lecture des PL ...');
  1452     btnOneAllBrowser.Up := not FPreferences.isPlayAllBrowser;
  1453     if FPreferences.isPlayAllBrowser then
  1454        btnOneAllBrowser.ImageIndex := C_ALL
  1455     else
  1456        btnOneAllBrowser.ImageIndex := C_ONE;
  1457     btnOneAllSelection.Up := not FPreferences.isPlayAllBrowser;
  1458     if FPreferences.isPlayAllSelection then
  1459        btnOneAllSelection.ImageIndex := C_ALL
  1460     else
  1461        btnOneAllSelection.ImageIndex := C_ONE;
  1462     WaitingPosMainSplash(6, '', 'Préférences d''affichage des PL ...');
  1463     miDisplayTitle.Checked := (FPreferences.LineDisplay = C_DISP_TITLE);
  1464     miDisplayChore.Checked := (FPreferences.LineDisplay = C_DISP_CHORE);
  1465     FCSLBrowser.LineDisplay := FPreferences.LineDisplay;
  1466     FCSLSelection.LineDisplay := FPreferences.LineDisplay;
  1467     miDisplayCateg.Checked := FPreferences.DisplayCateg;
  1468     FCSLBrowser.DisplayCateg := FPreferences.DisplayCateg;
  1469     FCSLSelection.DisplayCateg := FPreferences.DisplayCateg;
  1470     WaitingPosMainSplash(6, '', 'Préférences de sécurité ...');
  1471     miConfirmChkAll.Checked := FPreferences.isChkAllConfirmed;
  1472     miEmptyConfirm.Checked := FPreferences.isEmptyConfirmed;
  1473     miConfirmFileExists.Checked := FPreferences.isRewriteConfirmed;
  1474     miSaveLog.Checked := FPreferences.isJournalized;
  1475     miActiveKeys.Checked := FPreferences.isKeysAlwaysActive;
  1476     WaitingPosMainSplash(6, '', 'Préférences de chargement des PL ...');
  1477     miForceFind.Checked := FPreferences.isForceFind;
  1478     miPLReplaceMode.Checked := FPreferences.isPLReplaceMode;
  1479     // options de recherche
  1480     WaitingPosMainSplash(6, '', 'Préférences des options de recherche ...');
  1481     for sopt := Low(TSxMMSearchOption) to High(TSxMMSearchOption) do
  1482     begin
  1483        //chkdef := (sopt = msoTitleSTF) or (sopt = msoChore) or (sopt = msoArtist);
  1484        chk := sopt in FCSLBrowser.SearchOptions;
  1485        if chk then
  1486           FCSLSelection.SearchOptions := FCurrentPL.SearchOptions + [sopt]
  1487        else
  1488           FCSLSelection.SearchOptions := FCurrentPL.SearchOptions - [sopt];
  1489        EdSearch.CheckByObject(TObject(sopt), chk);
  1490     end;
  1491     LoadSounds(CmbSounds, FSLNames);
  1492     // Chargement des fichiers multimedias
  1493     try
  1494        WaitingPosMainSplash(7, '', 'Chargement du dernier répertoire utilisé ...');
  1495        aNode := SFV.GetNodeFromPath(FLastPath);
  1496        FCurrentPL.LoadGridFromPath(FLastPath);
  1497        WaitingPosMainSplash(7, '', 'Dernière Playlist chargée.');
  1498        if Assigned(aNode) then
  1499        begin
  1500           SFV.Selected := aNode;
  1501           SFV.Selected.Expand(false);
  1502        end;
  1503        WaitingPosMainSplash(9, '', 'Dernier répertoire...');
  1504        if not LoadSelectionFromCmdLine and FileExists(aPLFilename) then
  1505        begin
  1506           btnPagesClick(btnSelection);
  1507           LoadPlayList(aPLFilename);
  1508           UpdatePLInfosView();
  1509        end;
  1510        WaitingPosMainSplash(10, '', 'Dernier répertoire chargé...');
  1511        SCGBrowser.ClickCell(SCGBrowser, C_COL_NUM, 1);
  1512        SCGSelection.ClickCell(SCGSelection, C_COL_NUM, 1);
  1513     finally
  1514        result := true;
  1515     end;
  1516  end;
  1517  
  1518  
  1519  Const
  1520     C_ID_BKCOLOR = 0;
  1521     C_ID_BKMOVECOLOR = 1;
  1522     C_ID_EDITCOLOR = 2;
  1523     C_ID_ROW1COLOR = 3;
  1524     C_ID_ROW2COLOR = 4;
  1525     C_ID_FIXEDCOLOR = 5;
  1526     C_ID_BTNCOLOR = 6;
  1527     C_ID_FONTCOLOR = 7;
  1528     C_ID_FONTCLOCK = 8;
  1529     C_ID_NUIT = 0;
  1530     C_ID_JOUR = 1;                                
  1531     C_COLORS : array[0..1,0..8] of TColor =  (($00483022, $00473327, clBlue,$004B3934, $005B483C, 
  1532                                                $00614330,$003F332E, $00FCE6BC, $00F5E8C2),
  1533                                               ($00FCE8B4, $00FFFAC4, clSilver, $00FCE8B4, 
  1534                                                $00B5E8FD, $00FBB97D,$00FBB97D, 0, 0));
  1535  
  1536  
  1537  (*
  1538   * SetGridCharSize définit la taille des caractères des grilles PL
  1539   *)
  1540  procedure TSxMSPForm.SetGridCharSize;
  1541  begin
  1542      SCGBrowser.Font.Size := FPreferences.GridCharSize;  
  1543      SCGBrowser.Font := SCGBrowser.Font;
  1544      SCGSelection.Font.Size := FPreferences.GridCharSize;
  1545      RESelection.Font.Size := FPreferences.CommentSize;
  1546      SCGBrowser.Invalidate;
  1547      SCGSelection.Invalidate;
  1548      if (FPreferences.GridCharSize <= 8) then
  1549         miCSMini.Checked := true
  1550      else if (FPreferences.GridCharSize = 12) then
  1551         miCSNormal.Checked := true
  1552      else if (FPreferences.GridCharSize = 14) then
  1553         miCSBig.Checked := true
  1554      else if (FPreferences.GridCharSize >= 18) then
  1555         miCSVeryBig.Checked := true
  1556  end;
  1557  
  1558  (*
  1559   * ChangeColors gère le changement de style de couleur de l'application
  1560   *)
  1561  procedure TSxMSPForm.ChangeColors(idx : integer);
  1562  begin
  1563     if idx < 0 then idx := 0;
  1564     SplitterSelEDTV.Color := C_COLORS[idx, C_ID_BTNCOLOR];
  1565     TopPanel.Color := C_COLORS[idx, C_ID_BKMOVECOLOR];
  1566     btnBrowser.ColorUp := C_COLORS[idx, C_ID_BTNCOLOR];
  1567     btnSelection.ColorUp := C_COLORS[idx, C_ID_BTNCOLOR];
  1568     LbTitre.Font.Color := C_COLORS[idx, C_ID_FONTCOLOR];
  1569     btnBrowser.Font.Color := C_COLORS[idx, C_ID_FONTCOLOR];
  1570     btnSelection.Font.Color := C_COLORS[idx, C_ID_FONTCOLOR];
  1571     PanDirTree.Color := C_COLORS[idx, C_ID_BKMOVECOLOR];
  1572     SFV.Color := C_COLORS[idx, C_ID_BKCOLOR];
  1573     SFV.Font.Color := C_COLORS[idx, C_ID_FONTCOLOR];
  1574     SFV.ItemsColor[0] := C_COLORS[idx, C_ID_FONTCOLOR];
  1575     PanRightBrowser.Color := C_COLORS[idx, C_ID_BKMOVECOLOR];
  1576     SCGBrowser.Color := C_COLORS[idx, C_ID_BKCOLOR];
  1577     SCGBrowser.Color1 := C_COLORS[idx, C_ID_ROW1COLOR];
  1578     SCGBrowser.Color2 := C_COLORS[idx, C_ID_ROW2COLOR];
  1579     SCGBrowser.FixedColor := C_COLORS[idx, C_ID_FIXEDCOLOR];
  1580     PanChk.Color := C_COLORS[idx, C_ID_FIXEDCOLOR];         
  1581     PanChkSel.Color := C_COLORS[idx, C_ID_FIXEDCOLOR];
  1582     SCGBrowser.FixedColor2 := C_COLORS[idx, C_ID_FIXEDCOLOR];
  1583     SCGBrowser.Font.Color := C_COLORS[idx, C_ID_FONTCOLOR];
  1584     SCGBrowser.ButtonTextColor := C_COLORS[idx, C_ID_FONTCOLOR];
  1585     SCGBrowser.EditionColor := C_COLORS[idx, C_ID_EDITCOLOR];
  1586     SCGBrowser.SelectedColor := C_COLORS[idx, C_ID_FONTCOLOR];
  1587     PanPlayerBrowser.Color := C_COLORS[idx, C_ID_BKCOLOR];
  1588     btnOneAllBrowser.ColorUp := C_COLORS[idx, C_ID_BTNCOLOR];
  1589     btnOneAllSelection.ColorUp := C_COLORS[idx, C_ID_BTNCOLOR];
  1590     btnPlay.ColorUp := C_COLORS[idx, C_ID_BTNCOLOR];
  1591     btnPause.ColorUp := C_COLORS[idx, C_ID_BTNCOLOR];
  1592     btnStop.ColorUp := C_COLORS[idx, C_ID_BTNCOLOR];
  1593     btnPrev.ColorUp := C_COLORS[idx, C_ID_BTNCOLOR];
  1594     btnNext.ColorUp := C_COLORS[idx, C_ID_BTNCOLOR];
  1595     SBVolume.Brush.Color := C_COLORS[idx, C_ID_FIXEDCOLOR];
  1596     SBVolume.Brush.Style := bsSolid;
  1597     MainClock.Color := C_COLORS[idx, C_ID_FONTCLOCK];
  1598     MainClock.BkColor := C_COLORS[idx, C_ID_BKCOLOR];
  1599     //
  1600     PanSelection.Color := C_COLORS[idx, C_ID_BKMOVECOLOR];
  1601     PanLeftSelection.Color := C_COLORS[idx, C_ID_BKMOVECOLOR];
  1602     PanRightSelection.Color := C_COLORS[idx, C_ID_BKMOVECOLOR];
  1603     PanSelectionTools.Color := C_COLORS[idx, C_ID_BKMOVECOLOR];
  1604     RESelection.Color := C_COLORS[idx, C_ID_BKCOLOR];
  1605     RESelection.Font.Color := C_COLORS[idx, C_ID_FONTCLOCK];
  1606     BBGroups.Color := C_COLORS[idx, C_ID_BKCOLOR];
  1607     BBGroups.ButtonColorDown := C_COLORS[idx, C_ID_BKCOLOR];
  1608     BBGroups.ButtonColorUp := C_COLORS[idx, C_ID_BTNCOLOR];
  1609     BBGroups.FontColor := C_COLORS[idx, C_ID_FONTCLOCK];
  1610     LbTrackTimeMLeft.Font.Color := C_COLORS[idx, C_ID_FONTCLOCK];
  1611     LbTrackTimeSLeft.Font.Color := C_COLORS[idx, C_ID_FONTCLOCK];
  1612     SCGSelection.Color := C_COLORS[idx, C_ID_BKCOLOR];
  1613     SCGSelection.Color1 := C_COLORS[idx, C_ID_ROW1COLOR];
  1614     SCGSelection.Color2 := C_COLORS[idx, C_ID_ROW2COLOR];
  1615     SCGSelection.FixedColor := C_COLORS[idx, C_ID_FIXEDCOLOR];
  1616     SCGSelection.FixedColor2 := C_COLORS[idx, C_ID_FIXEDCOLOR];
  1617     SCGSelection.Font.Color := C_COLORS[idx, C_ID_FONTCOLOR];
  1618     SCGSelection.ButtonTextColor := C_COLORS[idx, C_ID_FONTCOLOR];
  1619     SCGSelection.EditionColor := C_COLORS[idx, C_ID_EDITCOLOR];
  1620     SelTSMono.Color := C_COLORS[idx, C_ID_BKCOLOR];
  1621     SelTSMix.Color := C_COLORS[idx, C_ID_BKCOLOR];
  1622     SCGSelection.SelectedColor := C_COLORS[idx, C_ID_FONTCOLOR];
  1623     PanPlayerSelection.Color := C_COLORS[idx, C_ID_BKCOLOR];
  1624     SxMixer1.Color := C_COLORS[idx, C_ID_BKCOLOR];
  1625     btnPlaySel.ColorUp := C_COLORS[idx, C_ID_BTNCOLOR];
  1626     btnPauseSel.ColorUp := C_COLORS[idx, C_ID_BTNCOLOR];
  1627     btnStopSel.ColorUp := C_COLORS[idx, C_ID_BTNCOLOR];
  1628     btnPrevSel.ColorUp := C_COLORS[idx, C_ID_BTNCOLOR];
  1629     btnNextSel.ColorUp := C_COLORS[idx, C_ID_BTNCOLOR];
  1630     SBVolumeSel.Color := C_COLORS[idx, C_ID_FIXEDCOLOR];
  1631     SBVolumeSel.ButtonBgColor := C_COLORS[idx, C_ID_BTNCOLOR];
  1632     SBVolumeSel.ButtonColor := C_COLORS[idx, C_ID_FONTCOLOR];
  1633     SBVolumeSel.SliderColor := C_COLORS[idx, C_ID_FONTCOLOR];
  1634     SBVolume.Color := C_COLORS[idx, C_ID_FIXEDCOLOR];
  1635     SBVolume.ButtonBgColor := C_COLORS[idx, C_ID_BTNCOLOR];
  1636     SBVolume.ButtonColor := C_COLORS[idx, C_ID_FONTCOLOR];
  1637     SBVolume.SliderColor := C_COLORS[idx, C_ID_FONTCOLOR];
  1638     FCSLBrowser.IsLight := (idx = 1);
  1639     FCSLSelection.IsLight := (idx = 1);
  1640     FCSLBrowser.GroupBkColor := C_COLORS[idx, C_ID_BKCOLOR];
  1641     FCSLSelection.GroupBkColor := C_COLORS[idx, C_ID_BKCOLOR];
  1642  end;
  1643  
  1644  (*
  1645   * WMDropFiles gère la dépose de fichiers sur la fiche applicative
  1646   *)
  1647  procedure TSxMSPForm.WMDropFiles (var Msg: TWMDropFiles);
  1648  var
  1649     CFileName: array[0..2048] of Char;
  1650     NomFic : string;
  1651     i : integer;
  1652  begin
  1653     try
  1654     for i := 0 to  DragQueryFile(Msg.Drop, $FFFFFFFF, nil, 0) do
  1655        if (DragQueryFile(Msg.Drop, i, CFileName, MAX_PATH) > 0) Then
  1656        begin
  1657           NomFic := String( CFileName );
  1658           try
  1659              if DirectoryExists(NomFic) then
  1660                 FCurrentPL.LoadGridFromPath(NomFic)
  1661              else
  1662              begin
  1663                 if SxHasThatExt(NomFic, '.mp3;.wma;.m4a;.flac;*.avi') then
  1664                    FCurrentPL.AddNewFile(NomFic, 0, 0, 0, C_SNDSET_NULL, C_SNDRANGE_NULL, false)
  1665                 else if SxHasThatExt(NomFic, '.m3u;.m6u') then //(aExt = '.m3u') then
  1666                    LoadPlayList(NomFic);
  1667              end;
  1668              if (FCurrentPL = FCSLSelection) then
  1669                 UpdateGroupsView(true);
  1670           except
  1671              MessageBox(handle,'Format non supporté...','Attention...',MB_OK);
  1672           end;
  1673        end;
  1674     finally
  1675        DragFinish( Msg.Drop );
  1676     end;
  1677  end;
  1678  
  1679  (*
  1680   * WMMENUSELECT réponde au message de sélection de menu
  1681   *)
  1682  procedure TSxMSPForm.WMMENUSELECT(var msg: TWMMENUSELECT);
  1683  begin
  1684    FIsNoMenuOpen :=  ((msg.MenuFlag and $FFFF > 0) and
  1685                        (msg.Menu = 0));
  1686  end;
  1687  
  1688  (*
  1689   * DoOnException gère les affichages lors d'exceptions
  1690   *)
  1691  procedure TSxMSPForm.DoOnException(Sender: TObject; E: Exception);
  1692  begin
  1693     if FPreferences.isJournalized then
  1694        AddToLog(CL_ERROR, E.Message);
  1695  {$IFDEF NOEXCEPTIONS}
  1696     LbTitre.Caption := E.Message;
  1697  {$ENDIF}
  1698  end;
  1699  
  1700  
  1701  (*
  1702   * FormCreate : Construction de la fiche, initialisations
  1703   *)
  1704  procedure TSxMSPForm.FormCreate(Sender: TObject);
  1705  begin
  1706     try
  1707        FSLNames := nil;
  1708        FIsSpecialSound := false;
  1709        SetNoBeeps;
  1710        FSLLOG := TStringList.Create;
  1711        InitLog;
  1712        Application.OnException := DoOnException;
  1713        FViewer := nil;
  1714        InitProperties;
  1715        SFV.ItemsColor[1] := $001518FF;
  1716        SFV.ItemsColor[2] := $00F5E8C2;
  1717        FIsNoMenuOpen := true;
  1718        SFV.AddSpecialFolderTree('Mes Documents', CSIDL_MYDOCUMENTS);
  1719        SFV.AddSpecialFolderTree('Ma Musique', CSIDL_MYMUSIC);
  1720        SFV.AddSpecialFolderTree('Musique', CSIDL_COMMON_MUSIC);
  1721        //SFV.AddSpecialFolderTree('Vidéos', CSIDL_COMMON_VIDEO);
  1722        WaitingPosMainSplash(1, '', 'Initialisations...');
  1723        InitGrids;
  1724        WaitingPosMainSplash(2, '', 'Grille Initialisée');
  1725        InitThePageControl;
  1726        WaitingPosMainSplash(3, '', 'Classeur initialisé');
  1727        SetCurrentPlayList;
  1728        SetCurrentFilterGraph;
  1729        WaitingPosMainSplash(5, '', 'Direct Sound initialisé');
  1730        SetCurrentVolume;
  1731        ChangeColors(C_ID_NUIT);
  1732        if LoadConfig then
  1733        begin
  1734           WaitingPosMainSplash(11, '', 'Lecture du répertoire des PL...');
  1735           SFV.AddPlayListRoot;
  1736           SFV.ReloadPlayListNode(FPreferences.DefaultPLPath);
  1737           WaitingPosMainSplash(11, '', 'Redimensionnements...');
  1738           PanRightBrowserResize(nil);
  1739           PanDirTreeResize(nil);
  1740           Application.ProcessMessages;
  1741           DragAcceptFiles(Handle, True);
  1742           SetInitialPositions;
  1743           WaitingPosMainSplash(12, '', 'Initialisations terminées.');
  1744           if FPreferences.isTransparent then
  1745              SetTransparentForm(Handle, 250);
  1746        end
  1747        else
  1748           Application.Terminate;
  1749     finally
  1750        CloseMainSplash(0);
  1751     end;
  1752  end;
  1753  
  1754  (*
  1755   * btnPagesClick : Gestion du changement de page
  1756   *)
  1757  procedure TSxMSPForm.btnPagesClick(Sender: TObject);
  1758  begin
  1759     try
  1760     if PgCtrl.ActivePageIndex <> TSxFlatButton(Sender).Tag then
  1761     begin
  1762        FIsNoMenuOpen := true;
  1763        PgCtrl.ActivePageIndex := TSxFlatButton(Sender).Tag;
  1764        SetCurrentPlayList;
  1765        SetCurrentFilterGraph;
  1766        SetCurrentVolume;
  1767        if (FCurrentPL = FCSLSelection) then
  1768           UpdateGroupsView(true);
  1769     end
  1770     else if FIsNoMenuOpen then
  1771     begin
  1772        FIsNoMenuOpen := false;
  1773        FCurrentBtnPage.PopUp;
  1774     end
  1775     else
  1776        FIsNoMenuOpen := true;
  1777     except
  1778        on E:Exception do
  1779           raise Exception.Create(CE_BTNPAGE_CLICK+E.Message);
  1780     end;
  1781  end;
  1782  
  1783  (*
  1784   * FormDestroy : Destruction de la fiche et finalisations, enregistrement des config
  1785   *)
  1786  procedure TSxMSPForm.FormDestroy(Sender: TObject);
  1787  var
  1788     sDt : string;
  1789  begin
  1790     try
  1791        if Assigned(FViewer) then
  1792        begin
  1793           FViewer.Destroy;
  1794           FViewer := nil;
  1795        end;
  1796        if not FIsStoppedForInstall then
  1797        begin
  1798           FilterGraphBrowser.cleargraph;
  1799           FilterGraphBrowser.Active := false;
  1800           FilterGraphSelection.cleargraph;
  1801           FilterGraphSelection.Active := false;
  1802           FilterGraphTmp.cleargraph;
  1803           FilterGraphTmp.Active := false;
  1804        end;
  1805        SaveConfig(Preferences, FLastPath, FLastPlayList, FKeyIdents, FCSLBrowser);
  1806        FreeGrids;
  1807     finally
  1808        SetBeeps;
  1809        if Assigned(FSLLog) then
  1810        begin
  1811           if FPreferences.isJournalized then
  1812           begin
  1813              DateTimeToString(sDt, 'yyyymmdd-hhnn', Now);
  1814              FSLLog.SaveToFile(IncludeTrailingBackSlash(ExtractfilePath(ParamStr(0)))+C_LOG_FILE+sDt+'.log');
  1815           end;
  1816           FSLLog.Free;
  1817           FSLLog := nil;
  1818        end;
  1819     end;
  1820     if Assigned(FSLNames) then
  1821     begin
  1822        FSLNames.Free;
  1823        FSLNames := nil;
  1824     end;
  1825  end;
  1826  
  1827  
  1828  
  1829  (*
  1830   * SFVAfterSelection : Chargement, suppression des fichiers
  1831                         d'un répertoire sélectionné/désélectionné
  1832   *)
  1833  procedure TSxMSPForm.SFVAfterSelection(const aNode: TTreeNode; var aSel: TSxTriVal);
  1834  var
  1835     s : string;
  1836  begin
  1837     s := SFV.DoPath(aNode);
  1838     if (s <> '') then
  1839     try
  1840        ShowMainSplash(0, 100, 0, $00FBB055);
  1841        if (aSel > 0) then
  1842        begin
  1843           FCSLBrowser.LoadGridFromPath(s);
  1844           ForceChkBox(false);
  1845        end
  1846        else
  1847           FCSLBrowser.RemovePathFiles(s);
  1848     finally
  1849        CloseMainSplash(0);
  1850     end;
  1851  end;
  1852  
  1853  (*
  1854   * SetInitialPositions : Définition des positions initiales des composants
  1855   *)
  1856  procedure TSxMSPForm.SetInitialPositions;
  1857  begin
  1858      SCGBrowser.Height := PanRightBrowser.ClientHeight - 40-22;
  1859      DSTrackBar1.Top := PanRightBrowser.ClientHeight - 40-20;
  1860      DSTrackBar1.Width := SCGBrowser.Width -10;
  1861      PanPlayerBrowser.Top := PanRightBrowser.ClientHeight - 40;
  1862      SBVolume.Top := PanPlayerBrowser.Top;
  1863      SCGSelection.Height := PanRightSelection.ClientHeight -100; //- 40-22;
  1864      SelPgCtrl.Top := 334-15; //334;
  1865      SelPgCtrl.Height := 100; //53;
  1866      CmbTemporisation.Top := PanRightSelection.ClientHeight - 35-20+3;
  1867      LbTrackTimeMLeft.Top := CmbTemporisation.Top+2;
  1868      LbTrackTimeSLeft.Top := LbTrackTimeMLeft.Top;
  1869  end;
  1870  
  1871  procedure TSxMSPForm.PanRightBrowserResize(Sender: TObject);
  1872  begin
  1873     //
  1874  end;
  1875  
  1876  (*
  1877   * PanDirTreeResize gère l'IHM lors du redimensionnement de l'arbre
  1878   *)
  1879  procedure TSxMSPForm.PanDirTreeResize(Sender: TObject);
  1880  begin
  1881     SFV.Height := PanDirTree.ClientHeight - 40;
  1882     MainClock.Top := PanDirTree.ClientHeight - 25;
  1883  end;
  1884  
  1885  (*
  1886   * PanSelectionResize gère le redimensionnement de la page sélection
  1887   *)
  1888  procedure TSxMSPForm.PanSelectionResize(Sender: TObject);
  1889  begin
  1890      FCSLSelection.DoOnResize(nil);
  1891  end;
  1892  
  1893  (*
  1894   * Définition des champs Current selon la page active
  1895   *)
  1896  procedure TSxMSPForm.SetCurrentPlayList;
  1897  begin
  1898     if PgCtrl.ActivePageIndex = 1 then
  1899     begin
  1900        FCurrentPL := FCSLSelection;
  1901        FCurrentGrid := SCGSelection;
  1902        FCurrentBtnPage := btnSelection;
  1903        FCurrentChk := ChkSelectionList;
  1904        FCurrentChkShow := ChkOnlySelSel;
  1905        FCurrentRightPanel := PanRightSelection;
  1906        FCurrentLeftPanel := PanLeftSelection;
  1907        MainClock.Parent := PanLeftSelection;
  1908        MainClock.Top := PanLeftSelection.ClientHeight -25;
  1909     end
  1910     else
  1911     begin
  1912        FCurrentPL := FCSLBrowser;
  1913        FCurrentGrid := SCGBrowser;
  1914        FCurrentBtnPage := btnBrowser;
  1915        FCurrentChk := ChkBrowserList;
  1916        FCurrentChkShow := ChkOnlySel;
  1917        FCurrentRightPanel := PanRightBrowser;
  1918        FCurrentLeftPanel := PanDirTree;
  1919        MainClock.Parent := PanDirTree;
  1920        MainClock.Top := PanDirTree.ClientHeight -25;
  1921     end;
  1922     MainClock.left := 3;
  1923     if Active then
  1924        FocusCurrentPL;
  1925  end;
  1926  
  1927  (*
  1928   * SetCurrentFilterGraph définit le graphe de filtre courant
  1929   *)
  1930  procedure TSxMSPForm.SetCurrentFilterGraph;
  1931  begin
  1932     if PgCtrl.ActivePageIndex = 1 then
  1933        FCurrentFG := FilterGraphSelection
  1934     else
  1935        FCurrentFG := FilterGraphBrowser;
  1936  end;
  1937  
  1938  (*
  1939   * SetCurrentVolume définit le contrôle de volume courant
  1940   *)
  1941  procedure TSxMSPForm.SetCurrentVolume;
  1942  begin
  1943     if PgCtrl.ActivePageIndex = 1 then
  1944     begin
  1945        FCurrentVol := SBVolumeSel;
  1946        FCurrentTrackBar := DSTrackBar2;
  1947     end
  1948     else
  1949     begin
  1950        FCurrentVol := SBVolume;
  1951        FCurrentTrackBar := DSTrackBar1;
  1952     end;
  1953  end;
  1954  
  1955  (*
  1956   * DoEndTemporisation répond à un événement de fin de temporisation
  1957   *)
  1958  procedure TSxMSPForm.DoEndTemporisation(aSender : TObject);
  1959  begin
  1960     FIsTemporised := false;
  1961  end;
  1962  
  1963  (*
  1964   * StopThatThing gère l'arrêt d'un graphe de filtres (.i.e d'un lecteur)
  1965   *)
  1966  procedure TSxMSPForm.StopThatThing(const isCmd : boolean);
  1967  var
  1968    stRes : longbool;
  1969  begin
  1970     Application.ProcessMessages;
  1971     if FHPlayInstance <> 0 then
  1972     begin
  1973        stRes := TerminateProcess(FHPlayInstance, 0);
  1974        if not stRes then
  1975           TopPanel.Caption := 'not stopped';
  1976     end
  1977     else
  1978     begin
  1979        FIsTemporised := false;
  1980        LbTitre.Caption := '';
  1981        FCurrentFG.Stop;
  1982     end;
  1983     FHPlayInstance := 0;
  1984     FCurrentFG.Cleargraph;
  1985     FCurrentTrackBar.Position := 0;
  1986     FCurrentFG.active := false;
  1987     FCurrentPL.MarqueCurrent(false);
  1988     if isCmd then
  1989     begin
  1990        miColors.Enabled := true;
  1991        UpdateDisplay(Ord('S'));
  1992     end;
  1993  end;
  1994  
  1995  (*
  1996   * DoTemporisation démarre une temporisation
  1997   *)
  1998  procedure TSxMSPForm.DoTemporisation;
  1999  var
  2000    aTimer : TTimer;
  2001    len : integer;
  2002  begin
  2003     FIsTemporised := true;
  2004     len := StrToInt(CmbTemporisation.Items[CmbTemporisation.ItemIndex]) * 1000;
  2005     aTimer := TTimer.Create(nil);
  2006     try
  2007        aTimer.Enabled := false;
  2008        aTimer.Interval := len;
  2009        aTimer.OnTimer := DoEndTemporisation;
  2010        aTimer.Enabled := true;
  2011        while FIsTemporised do
  2012           Application.ProcessMessages;
  2013     finally
  2014        aTimer.Destroy;
  2015     end;
  2016  end;
  2017  
  2018  (*
  2019   * StartStopDef définit les  propriété de début, fin de piste
  2020   *)
  2021  procedure TSxMSPForm.StartStopDef(const aFileName : string; pStart, pStop : Int64);
  2022  var
  2023     aMS : IMediaSeeking;
  2024  begin
  2025     // pour éviter de mixer 2 sources ...
  2026     FCurrentFG.ClearGraph;
  2027     FCurrentFG.active := true;
  2028     // définition de la source
  2029     FCurrentFG.RenderFile(aFileName);
  2030     if ((pStart > 0) or (pStop > pStart)) then
  2031     // si le début ou la fin de piste est forcée ...
  2032     begin
  2033        // jouer pour obtenir les infos
  2034        FCurrentFG.Play;
  2035        Application.ProcessMessages;
  2036        Application.ProcessMessages;
  2037        // mise en pause une fois les infos obtenues
  2038        FCurrentFG.Pause;
  2039        FCurrentFG.QueryInterface(IMediaSeeking, aMS);
  2040        if Assigned(aMS) then
  2041        // si nous avons l'interface adéquate, ...
  2042        begin
  2043           if pStart < 0 then
  2044              pStart := 0;
  2045           if pStop > pStart then
  2046              aMS.SetPositions(pStart, AM_SEEKING_AbsolutePositioning,
  2047                               pStop, AM_SEEKING_AbsolutePositioning)
  2048           else
  2049              aMS.SetPositions(pStart, AM_SEEKING_AbsolutePositioning,
  2050                               pStop, AM_SEEKING_NoPositioning);
  2051           // on libère l'interface
  2052           aMS := nil;
  2053        end;
  2054     end;
  2055     // et, dans tous les cas, on joue la piste
  2056     FCurrentFG.Play;
  2057  end;
  2058  
  2059  (*
  2060   * PlayThatThing joue une piste dont le nom de fichier est donné
  2061   *)
  2062  procedure TSxMSPForm.PlayThatThing(const aFileName : string);
  2063  var
  2064    //SA, SAT : SECURITY_ATTRIBUTES;
  2065    StartInfo  : TStartupInfo;
  2066    ProcInfo   : TProcessInformation;
  2067  begin
  2068     miColors.Enabled := false;
  2069     if (FCurrentPL.CurrentVolume > -1) then
  2070        FCurrentVol.Position := FCurrentPL.CurrentVolume
  2071     else
  2072     begin
  2073        FCurrentVol.OnChange := nil;
  2074        FCurrentVol.Position := FCurrentFG.Volume;
  2075        FCurrentVol.OnChange := SBVolumeChange;
  2076     end;
  2077     FCurrentTrackBar.FilterGraph := FCurrentFG;
  2078     FCurrentPL.Col := C_COL_NUM;
  2079     if (CmbTemporisation.ItemIndex > 0) then
  2080     begin
  2081        UpdateDisplay(Ord('X'));
  2082        DoTemporisation;
  2083     end;
  2084     //
  2085     FHPlayInstance := 0;
  2086     if SxHasThatExt(aFileName, '.m4a') and FileExists(FPreferences.Player1) then
  2087     begin           
  2088        RunSubProcess(FPreferences.Player2, aFileName, StartInfo, ProcInfo);
  2089        FHPlayInstance := ProcInfo.hProcess;
  2090        if FHPlayInstance <> 0 then
  2091           UpdateDisplay(Ord('X'));
  2092        (*FHPlayInstance := ShellExecute(Handle, '',
  2093                     PChar(FPreferences.Player1), PChar('/play /close "'+aFileName+'"'),
  2094                     '', SW_SHOWMINNOACTIVE); *)
  2095     end
  2096     else if FPreferences.isAlwaysExternalPlayer or not SxHasThatExt(aFileName, '.mp3;.wma') then
  2097     begin
  2098        if FileExists(FPreferences.Player2) then
  2099        begin
  2100           RunSubProcess(FPreferences.Player2, aFileName, StartInfo, ProcInfo);
  2101           FHPlayInstance := ProcInfo.hProcess;
  2102           if FHPlayInstance <> 0 then
  2103              UpdateDisplay(Ord('X'));
  2104           (*FHPlayInstance := ShellExecute(Handle, '',
  2105                        PChar(FPreferences.Player2), PChar('"'+aFileName+'"'),
  2106                        '', SW_SHOWMINNOACTIVE);*)
  2107        end;
  2108     end
  2109     else
  2110     begin
  2111        if not FCurrentFG.active and (aFileName <> '') then
  2112        begin
  2113           FCurrentPL.MarqueCurrent(true);
  2114           StartStopDef(aFilename, FCurrentPL.CurrentStart, FCurrentPL.CurrentStop);
  2115        end
  2116        else
  2117           FCurrentFG.Play;
  2118        if (FCurrentTrackBar.Max = FCurrentTrackBar.Position) then
  2119           UpdateDisplay(Ord('?'))
  2120        else
  2121           UpdateDisplay(Ord('X'));
  2122     end;
  2123  end;
  2124  
  2125  (*
  2126   * PlayThatThing joue une piste dont le numéro est donné
  2127   *)
  2128  procedure TSxMSPForm.PlayThatThing(const num : integer);
  2129  begin
  2130     if (num >= FCurrentGrid.FixedRows) and (num < FCurrentGrid.RowCount) then
  2131     begin
  2132        FCurrentGrid.Row := num;
  2133        PlayThatThing(FCurrentPL.CurrentFileName);
  2134     end;
  2135  end;
  2136  
  2137  (*
  2138   * SetThisPL charge une PL donnée par le numéro d'ordre parmi les PL de l'arbre
  2139   *)
  2140  procedure TSxMSPForm.SetThisPL(n : integer);
  2141  var
  2142     node : TTreeNode;
  2143  begin
  2144     node := SFV.getPlayListRootNode;
  2145     if Assigned(node) then
  2146     begin
  2147        node := node.getFirstChild;
  2148        while Assigned(node) and (n>1) do
  2149        begin
  2150           node := node.getNextSibling;
  2151           dec(n);
  2152        end;
  2153        if Assigned(node) then
  2154        begin
  2155           SFV.SetSelect(node, 0);
  2156           ActionEmptyGridExecute(nil);
  2157           if FileExists(SFV.FileName) then
  2158              LoadPlayList(SFV.FileName);
  2159        end;
  2160     end;
  2161  end;
  2162  
  2163  (*
  2164   * PlaySample joue un son d'ambiance (chargés au démarrage depuis une DLL)
  2165   *)
  2166  procedure TSxMSPForm.PlaySample(const n : integer);
  2167  begin
  2168     if (n >=0) and (n < CmbSounds.Items.Count) then
  2169     begin
  2170        CmbSounds.ItemIndex := n;
  2171        CmbSoundsChange(nil);
  2172     end;
  2173  end;
  2174  
  2175  (*
  2176   * OpenCloseTitleDisplay ouvre/ferme le panneau des titres
  2177   *)
  2178  procedure TSxMSPForm.OpenCloseTitleDisplay;
  2179  begin
  2180     if FIsTitleShown then
  2181     begin
  2182        if Assigned(FViewer) then
  2183           FViewer.Destroy;
  2184        FViewer := nil;
  2185        FIsTitleShown := false;
  2186        FocusCurrentPL;
  2187     end
  2188     else
  2189     begin
  2190        if FIsCommentShown then
  2191           OpenCloseCommentDisplay;
  2192        FViewer := TSxViewer.Create(FCurrentGrid);
  2193        FViewer.FntSize := FPreferences.ViewFntSize;
  2194        FViewer.OnKeyPress := SCGKeyPress;
  2195        FViewer.OnKeyDown := FCurrentGrid.OnKeyDown;
  2196        FIsTitleShown := true;
  2197        UpdateTitleDisplay(Ord('*'));
  2198     end;
  2199  end;
  2200  
  2201  (*
  2202   * OpenCloseTitleDisplay ouvre/ferme le panneau des  commentaires
  2203   *)
  2204  procedure TSxMSPForm.OpenCloseCommentDisplay;
  2205  begin
  2206     if FIsCommentShown then
  2207     begin
  2208        if Assigned(FViewer) then
  2209           FViewer.Destroy;
  2210        FViewer := nil;
  2211        FocusCurrentPL;
  2212        FIsCommentShown := false;
  2213     end
  2214     else
  2215     begin
  2216        if FIsTitleShown then
  2217           OpenCloseTitleDisplay;
  2218        FViewer := TSxViewer.Create(FCurrentGrid);
  2219        FViewer.FntSize := FPreferences.ViewFntSize;
  2220        FViewer.OnKeyPress := SCGKeyPress;
  2221        FViewer.OnKeyDown := CommentViewerKeyDown;
  2222        FIsCommentShown := true;
  2223        UpdateCommentDisplay(Ord('*'));
  2224     end;
  2225  end;
  2226  
  2227  (*
  2228   * UpdateDisplay met à jour le titre/commentaire
  2229   * (centralise les demandes de mise à jour)
  2230   *)
  2231  procedure TSxMSPForm.UpdateDisplay(const aKey : integer);
  2232  begin
  2233     if FIsTitleShown then
  2234        UpdateTitleDisplay(aKey)
  2235     else if FIsCommentShown then
  2236        UpdateCommentDisplay(aKey)
  2237     else
  2238        FocusCurrentPL;
  2239  end;
  2240  
  2241  (*
  2242   * UpdateTitleDisplay met à jour le panneau du titre
  2243   *)
  2244  procedure TSxMSPForm.UpdateTitleDisplay(const aKey : integer);
  2245  const
  2246    aCoul : array[0..3] of TColor = ($000000BB, $00BB0000, $00AA00AA, $00AAAA00);
  2247  begin
  2248     if FIsTitleShown and (FCurrentGrid.Row >= FCurrentGrid.FixedRows) then
  2249     begin
  2250        FViewer.FntColor := aCoul[FCurrentGrid.Row mod 4];
  2251        FViewer.Texte := FCurrentPL.CurrentTitle;
  2252        FViewer.Key := aKey;
  2253        FViewer.PlayNum := FCurrentPL.PlayingIndex;
  2254        FViewer.Num := FCurrentGrid.Row;
  2255        FViewer.SetFocus;
  2256        FViewer.Invalidate;
  2257     end
  2258     else
  2259        FocusCurrentPL;
  2260  end;
  2261  
  2262  (*
  2263   * UpdateCommentDisplay met à jour le panneau du commentaire
  2264   *)
  2265  procedure TSxMSPForm.UpdateCommentDisplay(const aKey : integer);
  2266  const
  2267    aCoul : array[0..3] of TColor = ($000000BB, $00BB0000, $00AA00AA, $00AAAA00);
  2268  begin
  2269     if FIsCommentShown and (FCurrentGrid.Row >= FCurrentGrid.FixedRows) then
  2270     begin
  2271        FViewer.FntColor := aCoul[FCurrentGrid.Row mod 4];
  2272        FViewer.FntSize := FPreferences.CommentViewerSize;
  2273        if FCSLBrowser = FCurrentPL then
  2274           FViewer.Texte := FCurrentPL.CurrentTitle
  2275        else
  2276           FViewer.Texte := RESelection.Text;
  2277        FViewer.Key := aKey;
  2278        FViewer.Num := FCurrentGrid.Row;
  2279        FViewer.SetFocus;
  2280        FViewer.Invalidate;
  2281     end
  2282     else
  2283        FocusCurrentPL;
  2284  end;
  2285  
  2286  (*
  2287   * DisplayFullGrid bascule l'affichage de la grille en pleine page/demi page
  2288   *)
  2289  procedure TSxMSPForm.DisplayFullGrid;
  2290  begin
  2291     if FCurrentLeftPanel.Width > 0 then
  2292        FCurrentLeftPanel.Width := 0
  2293     else
  2294        FCurrentLeftPanel.Width := ClientWidth shr 1;
  2295     if Assigned(FCurrentLeftPanel.OnResize) then
  2296        FCurrentLeftPanel.OnResize(nil);
  2297     if Assigned(FCurrentRightPanel.OnResize) then
  2298        FCurrentRightPanel.OnResize(nil);
  2299  end;
  2300  
  2301  (*
  2302   * ActionPlayExecute définit l'action correspondante à Play
  2303   * Si une piste est jouée, elle est arrêtée
  2304   * Si une piste est en pause elle est redémarrée
  2305   *)
  2306  procedure TSxMSPForm.ActionPlayExecute(Sender: TObject);
  2307  var
  2308     aFileName : string;
  2309  begin
  2310     FIsNoMenuOpen := true;
  2311     FIsTemporised := false;
  2312     if FCurrentPL.isValidRow then
  2313     begin
  2314        if (miSelShowMix.Tag = 1) then
  2315        begin
  2316        end
  2317        else
  2318        if FCurrentFG.State <> gsPaused then
  2319        begin
  2320           StopThatThing(false);
  2321           aFileName := FCurrentPL.CurrentFileName;
  2322           LbTitre.Caption := ExtractFileName(aFileName);
  2323           AddToLog(CL_FILETOPLAY, aFileName);
  2324           PlayThatThing(aFileName);
  2325        end
  2326        else
  2327           PlayThatThing('');
  2328     end;
  2329  end;
  2330  
  2331  (*
  2332   * ActionPauseExecutemet en pause/sort d'une pause une piste
  2333   *)
  2334  procedure TSxMSPForm.ActionPauseExecute(Sender: TObject);
  2335  begin
  2336     if FIsTemporised then
  2337     begin
  2338        FIsTemporised := false;
  2339        Exit;
  2340     end;
  2341     if not FCurrentFG.Active or (FCurrentTrackBar.Max = FCurrentTrackBar.Position) then
  2342     begin
  2343        StopThatThing(false);
  2344        ActionPlayExecute(Sender);
  2345     end
  2346     else
  2347     begin
  2348        miColors.Enabled := FCurrentFG.State <> gsPaused;
  2349        if FCurrentFG.State <> gsPaused then
  2350        begin
  2351           FCurrentFG.Pause;
  2352           UpdateDisplay(Ord(' '));
  2353        end
  2354        else
  2355           PlayThatThing('');
  2356     end;
  2357  end;
  2358  
  2359  (*
  2360   * ActionStopExecute arrête une piste
  2361   *)
  2362  procedure TSxMSPForm.ActionStopExecute(Sender: TObject);
  2363  begin
  2364     StopThatThing(true);
  2365  end;
  2366  
  2367  procedure TSxMSPForm.ActionGoPrevExecute(Sender: TObject);
  2368  begin
  2369     FIsTemporised := false;
  2370     if FCurrentPL.Previous then
  2371        ActionPlayExecute(nil);
  2372  end;
  2373  
  2374  (*
  2375   * ActionGoNextExecute joue la piste suivante
  2376   *)
  2377  procedure TSxMSPForm.ActionGoNextExecute(Sender: TObject);
  2378  begin
  2379     FIsNoMenuOpen := true;
  2380     FIsTemporised := false;
  2381     if FCurrentPL.Next then
  2382        ActionPlayExecute(nil);
  2383  end;
  2384  
  2385  (*
  2386   * SBVolumeChange répond à une demande de modification du volume courant
  2387   *)
  2388  procedure TSxMSPForm.SBVolumeChange(Sender: TObject);
  2389  begin
  2390     FIsNoMenuOpen := true;
  2391     FCurrentFG.Volume := FCurrentVol.Position;
  2392  end;
  2393  
  2394  (*
  2395   * SCGKeyPress répond à l'enfoncement d'une touche
  2396   * Cette procédure est utilisée sur les grilles et les zones de saisies
  2397   * hors boite de recherche.
  2398   *)
  2399  procedure TSxMSPForm.SCGKeyPress(Sender: TObject; var Key: Char);
  2400  var
  2401     n : integer;
  2402  begin
  2403     FIsNoMenuOpen := true;
  2404     if FIsCtrlState then
  2405        n := 10
  2406     else
  2407        n := 0;
  2408     if ((not EdSearch.Visible) or FPreferences.isKeysAlwaysActive) and
  2409        ((FCurrentPL.Col = C_COL_NUM) or (not FCurrentPL.ListEditable)) then
  2410     begin
  2411        case Key of
  2412         ' ' : if FEnableKey then ActionPauseExecute(nil);
  2413         'x','X' : if FEnableKey then ActionPlayExecute(nil);
  2414         's','S' : if FEnableKey then ActionStopExecute(nil);
  2415         'm','M' : if FEnableKey then ActionMuteExecute(nil);
  2416         'n','N' : if FEnableKey then begin ActionGoNextExecute(nil);  end;
  2417         'p','P' : if FEnableKey then begin ActionGoPrevExecute(nil);  end;
  2418         '<'     : if FEnableKey then FCSLSelection.RemoveFile(FCurrentPL.CurrentFileName);
  2419         '>'     : ActionSendToSelectionExecute(nil);
  2420         'f', 'F' : ActionSearchExecute(nil);
  2421         't', 'T' : OpenCloseTitleDisplay;
  2422         'c', 'C' : OpenCloseCommentDisplay;
  2423         'g', 'G' : DisplayfullGrid;
  2424         '0','1','2','3','4','5','6','7','8','9' : ManageNumericCmd(Ord(Key)-Ord('0'), n);
  2425         'b', 'B' : btnPagesClick(btnBrowser);
  2426         'l', 'L' : btnPagesClick(btnSelection);
  2427        else
  2428           begin
  2429              FEnableKey := FEnableKeyParam;
  2430              Exit;
  2431           end;
  2432        end;
  2433        Key := #0;
  2434     end;
  2435     FEnableKey := FEnableKeyParam;
  2436  end;
  2437  
  2438  (*
  2439   * SxGetVolume retourne le niveau de volume
  2440   *)
  2441  function SxGetVolume : DWord;
  2442  var
  2443    Volume: DWord;
  2444    MyWaveOutCaps: TWaveOutCaps;
  2445  begin
  2446    if WaveOutGetDevCaps(
  2447      0,
  2448      @MyWaveOutCaps,
  2449      sizeof(MyWaveOutCaps))=MMSYSERR_NOERROR then
  2450    begin
  2451      WaveOutGetVolume(0, @Volume);
  2452      result := Volume
  2453    end
  2454    else
  2455       result := 0;
  2456  end;
  2457  
  2458  (*
  2459   * ManageNumericCmd : Gestion des touches numériques
  2460   * n : valeur de la touche activée
  2461   * m : offset à appliquer
  2462   *)
  2463  procedure TSxMSPForm.ManageNumericCmd(n : integer; const m : integer);
  2464  begin
  2465     if (n = 0) then
  2466        if (FNumMode <> nmSubSel) then
  2467           n := 10
  2468        else
  2469           FNumMode := nmGroups;
  2470     if (FNumMode = nmSample) then
  2471        PlaySample(n+m-1)
  2472     else if (FNumMode = nmPL) then
  2473        SetThisPL(n+m)
  2474     else if (FNumMode = nmSubSel) then
  2475        SelectThisSubSel(n+m)
  2476     else if (FNumMode = nmGroups) then
  2477        SelectThisBBItem(n-1)
  2478     else
  2479        PlayThatThing(n+m);
  2480  end;
  2481  
  2482  
  2483  (*
  2484   * ManageKeyDown gère l'enfoncement de touches (d'une télécommande)
  2485   *)
  2486  procedure TSxMSPForm.ManageKeyDown(var aKey : word; const Shift: TShiftState);
  2487  var
  2488     n : integer;
  2489  begin
  2490     if (aKey = FKeyIdents[kfSwitchSample].Key) and (FKeyIdents[kfSwitchSample].Shift <= Shift) then
  2491        SwithNumMode(FNumMode, nmSample)
  2492     else if (aKey = FKeyIdents[kfCtrlState].Key) and (FKeyIdents[kfCtrlState].Shift <= Shift) then
  2493        FIsCtrlState := not FIsCtrlState
  2494     else if (aKey = FKeyIdents[kfNumModePL].Key) and (FKeyIdents[kfNumModePL].Shift <= Shift) then
  2495        SwithNumMode(FNumMode, nmPL)
  2496     else if (aKey = FKeyIdents[kfNumModeSS].Key) and (FKeyIdents[kfNumModeSS].Shift <= Shift) then
  2497        SwithNumMode(FNumMode, nmSubSel)
  2498     else if (aKey = FKeyIdents[kfPlay].Key) and (FKeyIdents[kfPlay].Shift <= Shift) then
  2499        ActionPlayExecute(nil)
  2500     else if (aKey = FKeyIdents[kfSHSearch].Key) and (FKeyIdents[kfSHSearch].Shift <= Shift) then
  2501        ShowHideSearchEdit(false)
  2502     else if (aKey = FKeyIdents[kfGoNext].Key) and (FKeyIdents[kfGoNext].Shift <= Shift) then
  2503        ActionGoNextExecute(nil)
  2504     else if (aKey = FKeyIdents[kfGoPrev].Key) and (FKeyIdents[kfGoPrev].Shift <= Shift) then
  2505        ActionGoPrevExecute(nil)
  2506     else if (aKey = FKeyIdents[kfStop].Key) and (FKeyIdents[kfStop].Shift <= Shift) then
  2507        ActionStopExecute(nil)
  2508     else if (aKey = FKeyIdents[kfPause].Key) and (FKeyIdents[kfPause].Shift <= Shift) then
  2509        ActionPauseExecute(nil)
  2510     else if (aKey = FKeyIdents[kfPause2].Key) and (FKeyIdents[kfPause2].Shift <= Shift) then
  2511        ActionPauseExecute(nil)
  2512     else if (aKey = FKeyIdents[kfOCTitleDisp].Key) and (FKeyIdents[kfOCTitleDisp].Shift <= Shift) then
  2513        OpenCloseTitleDisplay
  2514     else if (aKey = FKeyIdents[kfOCCmntDisp].Key) and (FKeyIdents[kfOCCmntDisp].Shift <= Shift) then
  2515        OpenCloseCommentDisplay
  2516     else if (aKey = FKeyIdents[kfDispFullGrid].Key) and (FKeyIdents[kfDispFullGrid].Shift <= Shift) then
  2517        DisplayFullGrid
  2518     else if (aKey in [VK_NUMPAD0 .. VK_NUMPAD9]) then
  2519     begin           
  2520        if FIsCtrlState then
  2521           n := 10
  2522        else
  2523           n := 0;
  2524        ManageNumericCmd(aKey-VK_NUMPAD0, n);
  2525     end
  2526     else if (aKey = FKeyIdents[kfFadeOut].Key) and (FKeyIdents[kfFadeOut].Shift <= Shift) then
  2527        FadeOut(3000)
  2528     else if (aKey = FKeyIdents[kfVolUp].Key) and (FKeyIdents[kfVolUp].Shift <= Shift) then
  2529     begin  
  2530        SBVolumeSel.Position := SBVolumeSel.Position + 100;
  2531        LbTitre.Caption := 'vol '+ IntToStr(SxGetVolume);
  2532     end
  2533     else if (aKey = FKeyIdents[kfVolDown].Key) and (FKeyIdents[kfVolDown].Shift <= Shift) then
  2534     begin
  2535        SBVolumeSel.Position := SBVolumeSel.Position - 100;
  2536        LbTitre.Caption := 'vol '+ IntToStr(SxGetVolume);
  2537     end
  2538     else if (aKey = FKeyIdents[kfMute].Key) and (FKeyIdents[kfMute].Shift <= Shift) then
  2539        ActionMuteExecute(nil)
  2540     //else if (aKey = FKeyIdents[kfGroups].Key) and (FKeyIdents[kfGroups].Shift <= Shift) then
  2541     //   BBGroups.SetFocus
  2542     else
  2543        Exit;
  2544     aKey := 0;
  2545  end;
  2546  
  2547  (*
  2548   * CommentViewerKeyDown gère l'enfoncement d'une touche sur le panneau commentaire
  2549   *)
  2550  procedure TSxMSPForm.CommentViewerKeyDown(Sender: TObject; var Key: Word;
  2551                                            Shift: TShiftState);
  2552  var
  2553     c : char;
  2554  begin                  
  2555     FEnableKey := FEnableKeyParam or ((ssAlt in Shift) and (ssCtrl in Shift));
  2556     if not FEnableKeyParam and ((ssAlt in Shift) and (ssCtrl in Shift)) then
  2557     begin
  2558        c := Chr(Key);
  2559        SCGKeyPress(Sender, c);
  2560     end;
  2561     ManageKeyDown(Key, Shift);
  2562  end;
  2563  
  2564  (*
  2565   * SCGKeyDown gère l'enfincement de touches sur une grille (browser)
  2566   *)
  2567  procedure TSxMSPForm.SCGKeyDown(Sender: TObject; var Key: Word;
  2568                                         Shift: TShiftState);
  2569  var
  2570     aKey, oldKey : word;
  2571     c : char;
  2572  begin
  2573     FIsNoMenuOpen := true;
  2574     aKey := ConvertKeyToDefault(FKeyIdents, Key);
  2575     if (FCurrentGrid = SCGBrowser) then
  2576     begin
  2577        FCurrentPL.DoMinimalKeyDown(aKey, Shift);
  2578     end
  2579     else
  2580     begin
  2581        FCurrentPL.DoOnKeyDown(aKey, oldKey, Shift);
  2582        if (ssAlt in Shift) and (ssLeft in Shift) and (not FCurrentGrid.Dragging) then
  2583           FCurrentGrid.BeginDrag(true);
  2584     end;
  2585     if aKey <> 0 then
  2586        ManageKeyDown(Key, Shift);
  2587     if (FCurrentGrid <> SCGBrowser) then
  2588     begin 
  2589        case oldKey of
  2590           VK_UP : UpdateDisplay(oldKey);
  2591           VK_DOWN : UpdateDisplay(oldKey);
  2592           VK_HOME, VK_PRIOR : UpdateDisplay(oldKey);
  2593           VK_END, VK_NEXT  : UpdateDisplay(oldKey);
  2594        else
  2595        end;
  2596     end;
  2597     FEnableKey := FEnableKeyParam or ((ssAlt in Shift) and (ssCtrl in Shift));
  2598     if not FEnableKeyParam and ((ssAlt in Shift) and (ssCtrl in Shift)) then
  2599     begin
  2600        c := Chr(Key);
  2601        SCGKeyPress(Sender, c);
  2602     end;
  2603     Key := 0;
  2604  end;
  2605  
  2606  (*
  2607   * SCGKeyDown gère l'enfincement de touches sur une grille (sélection)
  2608   *)
  2609  procedure TSxMSPForm.SCGSelectionKeyDown(Sender: TObject; var Key: Word;
  2610    Shift: TShiftState);
  2611  var
  2612     aKey, oldKey : word;
  2613  begin
  2614     FIsNoMenuOpen := true;
  2615     aKey := ConvertKeyToDefault(FKeyIdents, Key);
  2616     FCurrentPL.DoOnKeyDown(aKey, oldKey, Shift);
  2617     if (ssAlt in Shift) and (ssLeft in Shift) and (not FCurrentGrid.Dragging) then
  2618        FCurrentGrid.BeginDrag(true);
  2619     ManageKeyDown(Key, Shift);
  2620     case oldKey of
  2621        VK_UP : UpdateDisplay(oldKey);
  2622        VK_DOWN : UpdateDisplay(oldKey);
  2623        VK_HOME, VK_PRIOR : UpdateDisplay(oldKey);
  2624        VK_END, VK_NEXT  : UpdateDisplay(oldKey);
  2625     else
  2626     end;
  2627     Key := 0;
  2628  end;
  2629  
  2630  (*
  2631   * ActionMuteExecute bascule l'état muet/sonore
  2632   *)
  2633  procedure TSxMSPForm.ActionMuteExecute(Sender: TObject);
  2634  begin
  2635     if FCurrentFG.Tag = 0 then
  2636     begin
  2637        FCurrentFG.Tag := FCurrentFG.Volume;
  2638        FCurrentVol.Position := 0;
  2639     end
  2640     else
  2641     begin
  2642        FCurrentVol.Position := FCurrentFG.Tag;
  2643        FCurrentFG.Tag := 0;
  2644     end;
  2645  end;
  2646  
  2647  procedure TSxMSPForm.btnKeyUp(Sender: TObject; var Key: Word;
  2648    Shift: TShiftState);
  2649  begin
  2650     FIsNoMenuOpen := true;
  2651     // pour empecher le beep (no sound !!)
  2652     SystemParametersInfo(SPI_SETBEEP, 0, nil, SPIF_SENDWININICHANGE);
  2653     if ((not EdSearch.Visible) or FPreferences.isKeysAlwaysActive) and
  2654        ((FCurrentPL.Col = C_COL_NUM) or (not FCurrentPL.ListEditable)) then
  2655     begin
  2656        case Chr(Key) of
  2657         ' ' : ActionPauseExecute(nil);
  2658         'x','X' : ActionPlayExecute(nil);
  2659         's','S' : ActionStopExecute(nil);
  2660         'm','M' : ActionMuteExecute(nil);
  2661         '>', 'n','N' : ActionGoNextExecute(nil);
  2662         '<', 'p','P' : ActionGoPrevExecute(nil);
  2663         'f', 'F' : ActionSearchExecute(nil);
  2664         't', 'T' : OpenCloseTitleDisplay;
  2665         'c', 'C' : OpenCloseCommentDisplay;
  2666         'g', 'G' : DisplayfullGrid;
  2667        else
  2668           case Key of
  2669              VK_RETURN : ActionPlayExecute(nil);
  2670              VK_ESCAPE : ShowHideSearchEdit(false);
  2671              178 : ActionStopExecute(nil);
  2672              VK_PAUSE, 179 : ActionPauseExecute(nil);
  2673           else
  2674              begin
  2675                 // pour empecher le beep (no sound !!)
  2676                 SystemParametersInfo(SPI_SETBEEP, 0, nil, SPIF_SENDWININICHANGE);
  2677                 Exit;
  2678              end;
  2679           end;
  2680        end;
  2681        Key := 0;
  2682     end;
  2683  end;
  2684  
  2685  procedure TSxMSPForm.ActionSendToSelectionExecute(Sender: TObject);
  2686  begin
  2687     if FCSLBrowser.isSelectedRow(SCGBrowser.Row) then
  2688        FCSLBrowser.SendToSelection(FCSLSelection, false)
  2689     else
  2690        FCSLBrowser.SendThatRowToSelection(FCSLSelection, SCGBrowser.Row, true);
  2691     FSelectionLoaded := true;
  2692     PanSelectionResize(nil);
  2693     UpdateGroupsView(true);
  2694  end;
  2695  
  2696  procedure TSxMSPForm.ActionSendToSelectionWDExecute(Sender: TObject);
  2697  begin
  2698     FCSLBrowser.SendToSelection(FCSLSelection, true);
  2699     FSelectionLoaded := true;
  2700     PanSelectionResize(nil);
  2701     UpdateGroupsView(true);
  2702  end;
  2703  
  2704  
  2705  procedure TSxMSPForm.ActionSaveAsM3UExecute(Sender: TObject);
  2706  begin
  2707     with TSxSaveDialog.Create(Self) do
  2708     try
  2709        Filter := 'Fichier PlayList M3U|*.m3u';
  2710        DefaultExt := 'm3u';
  2711        if SxFileExists(FLastPlayList) then
  2712        begin
  2713           InitialDir := ExtractFilePath(FLastPlayList);
  2714           FileName := FLastPlayList;
  2715        end
  2716        else
  2717           InitialDir := ExtractFilePath(ParamStr(0));
  2718        if FPreferences.isRewriteConfirmed then
  2719           Options := Options + [ofOverwritePrompt];
  2720        if Execute then
  2721        begin
  2722           FCurrentPL.SaveAsVLCM3UPlayList(FileName, Sender = miSaveAsM3UReloc);
  2723           FLastPlayList := FileName;
  2724           miLoadPlayList.Default := true;
  2725        end;
  2726        SFV.ReloadPlayListNode(InitialDir);
  2727     finally
  2728        Free
  2729     end;
  2730  end;
  2731  
  2732  procedure TSxMSPForm.ActionSaveAsVDJExecute(Sender: TObject);
  2733  begin
  2734     with TSxSaveDialog.Create(Self) do
  2735     try
  2736        Filter := 'Fichier PlayList M3U|*.m3u';
  2737        DefaultExt := 'm3u'; 
  2738        if SxFileExists(FLastPlayList) then
  2739        begin
  2740           InitialDir := ExtractFilePath(FLastPlayList);
  2741           FileName := FLastPlayList;
  2742        end
  2743        else
  2744           InitialDir := ExtractFilePath(ParamStr(0));  
  2745        if FPreferences.isRewriteConfirmed then
  2746           Options := Options + [ofOverwritePrompt];
  2747        if Execute then
  2748        begin
  2749           FCurrentPL.SaveAsVDJList(FileName);
  2750           FLastPlayList := FileName;
  2751        end;
  2752        SFV.ReloadPlayListNode(InitialDir);
  2753     finally
  2754        Free
  2755     end;
  2756  end;
  2757  
  2758  procedure TSxMSPForm.ActionSaveAsTitleListExecute(Sender: TObject);
  2759  begin
  2760     with TSxSaveDialog.Create(Self) do
  2761     try
  2762        Filter := 'Fichier Texte|*.txt';
  2763        DefaultExt := 'txt';
  2764        if SxFileExists(FLastPlayList) then
  2765        begin
  2766           InitialDir := ExtractFilePath(FLastPlayList);
  2767        end
  2768        else
  2769           InitialDir := ExtractFilePath(ParamStr(0));   
  2770        if FPreferences.isRewriteConfirmed then
  2771           Options := Options + [ofOverwritePrompt];
  2772        if Execute then
  2773           FCurrentPL.SaveLinesAsCaptionList(FileName);
  2774     finally
  2775        Free
  2776     end;
  2777  end;
  2778  
  2779  procedure TSxMSPForm.miSaveAsChoreListClick(Sender: TObject);
  2780  begin
  2781     with TSxSaveDialog.Create(Self) do
  2782     try
  2783        Filter := 'Fichier Texte|*.txt';
  2784        DefaultExt := 'txt';
  2785        InitialDir := ExtractFilePath(ParamStr(0));
  2786        if Execute then
  2787           FCurrentPL.SaveAsChoreNameList(FileName);
  2788     finally
  2789        FIsNoMenuOpen := true;
  2790        Free
  2791     end;
  2792  end;
  2793  
  2794  procedure TSxMSPForm.ActionEmptyGridExecute(Sender: TObject);
  2795  begin
  2796     if not FPreferences.isEmptyConfirmed or
  2797        (Sender = nil) or
  2798        (mrYes = MessageDlg('Vider la grille ?', mtWarning, [mbYes,mbNo], 0)) then
  2799     begin
  2800        FCurrentPL.EmptyGrid;
  2801        FCurrentChk.Checked := false;
  2802        FSelectionLoaded := false;
  2803        FIsNoMenuOpen := true;
  2804        UpdateGroupsView(true);
  2805        ClearPLInfosView;
  2806        miLoadPlayList.Default := true;
  2807     end;
  2808  end;
  2809  
  2810  procedure TSxMSPForm.ActionLoadPlayListExecute(Sender: TObject);
  2811  begin
  2812     with TOpenDialog.Create(Self) do
  2813     try
  2814        Filter := 'Play List|*.m3u|Fichier log|*.log';
  2815        DefaultExt := 'm3u';
  2816        InitialDir := FPreferences.LastSelPath;
  2817        if Execute then
  2818        begin
  2819           if FPreferences.isPLReplaceMode then
  2820              ActionEmptyGridExecute(Sender);
  2821           LoadPlayList(FileName);
  2822           popupSaveAs.Default := true;   
  2823           UpdatePLInfosView;
  2824           if LowerCase(ExtractFileExt(FileName)) <> '.log' then
  2825              FPreferences.LastSelPath := ExtractFilePath(FileName);
  2826        end;
  2827     finally
  2828        FIsNoMenuOpen := true;
  2829        Free
  2830     end;
  2831  end;
  2832  
  2833  procedure TSxMSPForm.SFVDblClick(Sender: TObject);
  2834  begin
  2835     FIsNoMenuOpen := true;
  2836     if isThatFolderType(SFV.Selected, fiPlayList) then
  2837     begin
  2838        LoadPlayList(SFV.FileName);
  2839        if not FSelectionLoaded then
  2840           ActionSendToSelectionExecute(nil);
  2841     end
  2842     else if isThatFolderType(SFV.Selected, [fiOpened,  fiClosed, fiCurrent]) then
  2843        FLastPath := SFV.DoPath(SFV.Selected);
  2844     FocusCurrentPL;
  2845     Application.ProcessMessages;
  2846     FCSLBrowser.DoOnResize(nil);
  2847  end;
  2848  
  2849  procedure TSxMSPForm.ActionSelectAllExecute(Sender: TObject);
  2850  const
  2851     C_CHKMSG : array[boolean] of string = ('Désélectionner tout?','Sélectionner tout?');
  2852  begin
  2853     FIsNoMenuOpen := true;
  2854     if  not FPreferences.isChkAllConfirmed or 
  2855         (mrYes = MessageDlg(C_CHKMSG[FCurrentChk.Checked], mtWarning, [mbYes,mbNo], 0)) then
  2856     begin
  2857        if FCurrentGrid.RowCount-1 <> FCurrentPL.CheckLines(FCurrentChk.Checked) then
  2858           FCurrentChk.Checked := false
  2859        else
  2860           FCurrentChk.Checked := true;
  2861        FCurrentPL.ShowHideUnChecked(FCurrentChkShow.Checked);
  2862     end;
  2863  end;
  2864  
  2865  procedure TSxMSPForm.ActionDelPlayListExecute(Sender: TObject);
  2866  begin
  2867     FIsNoMenuOpen := true;
  2868     if FileExists(SFV.FileName) then
  2869        DeleteFile(SFV.FileName);
  2870     SFV.DeleteThatPlayList(SFV.Selected);
  2871  end;
  2872  
  2873  procedure TSxMSPForm.miAddToSelectionClick(Sender: TObject);
  2874  begin
  2875     FIsNoMenuOpen := true;
  2876     if FileExists(SFV.FileName) then
  2877     begin
  2878        btnPagesClick(btnSelection);
  2879        LoadPlayList(SFV.FileName);
  2880        SCGSelection.Invalidate;
  2881     end;
  2882  end;
  2883  
  2884  procedure TSxMSPForm.SFVContextPopup(Sender: TObject; MousePos: TPoint;
  2885    var Handled: Boolean);
  2886  begin
  2887     miDelPlayList.Enabled := isThatFolderType(SFV.Selected, fiPlayList);
  2888     miAddToSelection.Enabled := miDelPlayList.Enabled;
  2889     miOpenBrowser.Enabled := isThatFolderType(SFV.Selected, [fiOpened,  
  2890                                                              fiClosed, 
  2891                                                              fiSelFolder, 
  2892                                                              fiMyDocuments]);
  2893     miAddnodeToSelection.Enabled := miOpenBrowser.Enabled;
  2894     miReloadPath.Enabled := isThatFolderType(SFV.Selected, [fiMusicRoot,
  2895                                                             fiPlayListRoot,
  2896                                                             fiOpened,  fiClosed,
  2897                                                             fiSelFolder]);
  2898     PopSFV.AutoPopup := miDelPlayList.Enabled or 
  2899                         miOpenBrowser.Enabled or 
  2900                         miReloadPath.Enabled;
  2901  end;
  2902  
  2903  procedure TSxMSPForm.ActionOpenExplorerExecute(Sender: TObject);
  2904  var
  2905     aPath : string;
  2906  begin
  2907     FIsNoMenuOpen := true;
  2908     aPath := SFV.Path;  ShowMessage(aPath);
  2909     if DirectoryExists(aPath) then
  2910        ShellExecute(0, 'open', PChar(aPath), '', PChar(aPath), SW_SHOWNORMAL);
  2911  end;
  2912  
  2913  
  2914  
  2915  procedure TSxMSPForm.miDisplayPropertiesClick(Sender: TObject);
  2916  begin   
  2917     AffichePropriete(FCurrentPL.CurrentFileName, Handle);
  2918     FIsNoMenuOpen := true;
  2919  end;
  2920  
  2921  procedure TSxMSPForm.SCGBrowserContextPopup(Sender: TObject;
  2922    MousePos: TPoint; var Handled: Boolean);
  2923  begin
  2924     Handled := not FCurrentPL.isValidRow;
  2925     miSendThisToSelection.Visible := (FCurrentPL <> FCSLSelection);
  2926     N9.Visible := miSendThisToSelection.Visible;
  2927     //
  2928     miDisplayProperties.Visible := (FCurrentPL.Col = C_COL_FILE);
  2929     miReloadFile.Visible := miDisplayProperties.Visible;
  2930     miLoadClip.Visible := (FCurrentPL.Col = C_COL_FILE) and FCurrentPL.isValidRow;
  2931     miLoadClip.Enabled := FCurrentPL.CurrentClipUrl <> '';
  2932     //
  2933     miVal0.Visible := (FCurrentPL.Col = C_COL_NBP);
  2934     N7.Visible := miVal0.Visible;
  2935     N8.Visible := miVal0.Visible;
  2936     miUpdateID3s.Visible := miVal0.Visible;
  2937     {$ifdef SX_ID3_CONST}
  2938     miUpdateID3s.Enabled := false;
  2939     {$endif}
  2940     miVal1.Visible := miVal0.Visible;
  2941     miVal2.Visible := miVal0.Visible;
  2942     miVal3.Visible := miVal0.Visible;
  2943     miVal4.Visible := miVal0.Visible;
  2944     miVal5.Visible := miVal0.Visible;
  2945     miSelInfo.Caption := 'Sélection : ' + IntToStr(FCurrentPL.CheckCount) + ' fichier(s)';
  2946     miDuration.Caption := 'Durée : ' + DurationToStr(FCurrentPL.SelDuration);
  2947  end;
  2948  
  2949  procedure TSxMSPForm.miReloadFileClick(Sender: TObject);
  2950  begin
  2951     FIsNoMenuOpen := true;
  2952     if FCurrentPL.isValidRow then
  2953        FCurrentPL.AddNewFile(FCurrentPL.CurrentFileName,
  2954                              0, -1, 0,
  2955                              C_SNDSET_NULL, C_SNDRANGE_NULL, true);
  2956     GridClick(FCurrentGrid);
  2957  end;
  2958  
  2959  procedure TSxMSPForm.FocusCurrentPL;
  2960  begin
  2961     FCurrentGrid.Visible := true;
  2962     try
  2963        Application.ProcessMessages;
  2964        FocusControl(FCurrentGrid);
  2965        if FCurrentGrid.Col <> C_COL_NBP then
  2966           FCurrentGrid.Col := C_COL_NUM;
  2967     except
  2968        on E:Exception do
  2969           raise Exception.Create(CE_FOCUS_CURRENT_PL+ E.Message);
  2970     end;
  2971  end;
  2972  
  2973  procedure TSxMSPForm.ShowHideSearchEdit(const visible : boolean);
  2974  begin
  2975     FIsNoMenuOpen := true;
  2976     EdSearch.Visible := visible;
  2977     LbTitre.Visible := not visible;
  2978     if EdSearch.Visible then
  2979     begin
  2980        FocusControl(EdSearch);
  2981        EdSearch.SetFocus;
  2982     end
  2983     else
  2984        FocusCurrentPL;
  2985  end;
  2986  
  2987  procedure TSxMSPForm.ActionSearchExecute(Sender: TObject);
  2988  begin
  2989     ShowHideSearchEdit(not EdSearch.Visible);
  2990  end;
  2991  
  2992  procedure TSxMSPForm.EdSearchChange(Sender: TObject);
  2993  begin
  2994     FCurrentChkShow.Checked := false;
  2995     FCurrentPL.DisplaySearchResults(EdSearch.Text);
  2996     EdSearch.SetFocus;
  2997  end;
  2998  
  2999  (*
  3000   * Modifications des options du filtre de recherche
  3001   * Les options sont partagées par les deux grilles
  3002   *)
  3003  procedure TSxMSPForm.EdSearchComboChange(Sender: TObject);
  3004  var
  3005     aOpt : TSxMMSearchOption;
  3006     toAdd : boolean;
  3007  begin
  3008     FIsNoMenuOpen := true;
  3009     if EdSearch.ItemIndex > -1 then
  3010     begin
  3011        aOpt := TSxMMSearchOption(EdSearch.Objects[EdSearch.ItemIndex]);
  3012        toAdd := EdSearch.Checked[EdSearch.ItemIndex];
  3013        FCSLSelection.UpdateSearchOptions(toAdd, [aOpt]);
  3014        FCSLBrowser.UpdateSearchOptions(toAdd, [aOpt]);
  3015        EdSearchChange(nil);
  3016        EdSearch.SetFocus;
  3017     end;
  3018  end;
  3019  
  3020  procedure TSxMSPForm.EdSearchKeyDown(Sender: TObject;
  3021                                       var Key: Word; Shift: TShiftState);
  3022  begin
  3023     if Key = VK_ESCAPE then
  3024     begin
  3025        EdSearch.Text := '';
  3026        ActionSearchExecute(nil);
  3027        Key := 0;
  3028     end;
  3029  end;
  3030  
  3031  
  3032  
  3033  procedure TSxMSPForm.ActionChangeNBPExecute(Sender: TObject);
  3034  begin
  3035     FCurrentPL.NBP := TComponent(Sender).Tag;
  3036  end;
  3037  
  3038  procedure TSxMSPForm.ActionOneAllExecute(Sender: TObject);
  3039  begin
  3040     FIsNoMenuOpen := true;
  3041     TSxFlatButton(Sender).ImageIndex := C_BTN_ONEALL[not TSxFlatButton(Sender).Up];
  3042     if (Sender = btnOneAllBrowser) then
  3043        FPreferences.isPlayAllBrowser := (btnOneAllBrowser.ImageIndex = C_ALL)
  3044     else
  3045        FPreferences.isPlayAllSelection := (btnOneAllSelection.ImageIndex = C_ALL);
  3046     FocusCurrentPL;
  3047  end;
  3048  
  3049  procedure TSxMSPForm.FilterGraphBrowserGraphComplete(sender: TObject;
  3050                                                       Result: HRESULT;
  3051                                                       Renderer: IBaseFilter);
  3052  var
  3053     aFileName: string;
  3054  begin
  3055     FCSLBrowser.MarqueCurrent(false);
  3056     AddToLog(CL_DATE, '');
  3057     if FPreferences.isPlayAllBrowser then
  3058     begin
  3059        if FCSLBrowser.Next then
  3060        begin
  3061           StopThatThing(false);
  3062           aFileName := FCSLBrowser.CurrentFileName;
  3063           LbTitre.Caption := ExtractFileName(aFileName);
  3064           if FCurrentPL = FCSLBrowser then
  3065              PlayThatThing(aFileName);
  3066        end
  3067        else
  3068           StopThatThing(true);
  3069     end
  3070     else
  3071        StopThatThing(false); (*19*)
  3072  end;
  3073  
  3074  procedure TSxMSPForm.FilterGraphSelectionGraphComplete(sender: TObject;
  3075                                                         Result: HRESULT;
  3076                                                         Renderer: IBaseFilter); 
  3077  var
  3078     aFileName: string;
  3079  begin
  3080     if FIsSpecialSound then
  3081     // si le son joué est hors playlist
  3082     begin
  3083        FIsSpecialSound := false;
  3084        Exit;
  3085     end;
  3086     FCSLSelection.MarqueCurrent(false);
  3087     AddToLog(CL_DATE, '');
  3088     FCSLSelection.Col := C_COL_NUM;
  3089     UpdateDisplay(Ord('.'));
  3090     if FPreferences.isPlayAllSelection or FPreferences.isAlwaysGoNext then
  3091     begin
  3092        if FCSLSelection.Next then
  3093        begin
  3094           if FPreferences.isPlayAllSelection then
  3095              StopThatThing(false);
  3096           aFileName := FCSLSelection.CurrentFileName;
  3097           LbTitre.Caption := ExtractFileName(aFileName);
  3098           if FPreferences.isPlayAllSelection then
  3099              PlayThatThing(aFileName);
  3100        end;
  3101     end
  3102     else
  3103        StopThatThing(false); (*19*)
  3104  end;
  3105  
  3106  procedure TSxMSPForm.miCopyFilesClick(Sender: TObject);
  3107  var
  3108     aDir : string;
  3109  begin
  3110     FIsNoMenuOpen := true;
  3111     aDir := GetWindowsFolder(CSIDL_MYMUSIC);
  3112     if SelectDirectory('Destination', aDir, aDir) then
  3113        with TFmWaiting.Create(nil) do
  3114        try
  3115           ShowWaiting(0, FCurrentGrid.RowCount+1, 0, $00FBB055);
  3116           FCurrentPL.CopyFiles(aDir, false, WaitingPosition);
  3117           WaitingPosition(FCurrentGrid.RowCount+1);
  3118        finally
  3119           Release;
  3120        end;
  3121  end;
  3122  
  3123  procedure TSxMSPForm.miCopyFilesSFNClick(Sender: TObject);
  3124  var
  3125     aDir : string;
  3126  begin
  3127     FIsNoMenuOpen := true;
  3128     aDir := GetWindowsFolder(CSIDL_MYMUSIC);
  3129     if SelectDirectory('Destination', aDir, aDir) then  
  3130        with TFmWaiting.Create(nil) do
  3131        try
  3132           ShowWaiting(0, FCurrentGrid.RowCount+1, 0, $00FBB055);
  3133           FCurrentPL.CopyFiles(aDir, true, WaitingPosition);
  3134           WaitingPosition(FCurrentGrid.RowCount+1);
  3135        finally
  3136           Release;
  3137        end;
  3138  end;
  3139  
  3140  procedure TSxMSPForm.miDurationClick(Sender: TObject);
  3141  begin
  3142     FIsNoMenuOpen := true;
  3143     FCurrentPL.SelDuration := FCurrentPL.GetSelectionDuration;
  3144  end;
  3145  
  3146  procedure TSxMSPForm.ActionFindFileExecute(Sender: TObject);
  3147  var
  3148     aPath : string;
  3149  begin
  3150     FIsNoMenuOpen := true;
  3151     if FCurrentPL.isValidRow then
  3152     begin
  3153        aPath := IncludeTrailingBackSlash(ExtractFilePath(FCurrentPL.CurrentFileName));
  3154        ShellExecute(Handle, nil, pchar(aPath),  nil, '', SW_SHOWNORMAL);
  3155     end;
  3156  end;
  3157  
  3158  procedure TSxMSPForm.ForceChkBox(const aChecked : boolean);
  3159  begin
  3160     FCurrentChk.OnClick := nil;
  3161     FCurrentChk.Checked := aChecked;
  3162     FCurrentChk.OnClick := ActionSelectAllExecute;
  3163  end;
  3164  
  3165  procedure TSxMSPForm.SetChkBoxAllNone(const nbr : integer);
  3166  begin
  3167     FIsNoMenuOpen := true;
  3168     FCurrentChk.OnClick := nil;
  3169     if FCurrentGrid.RowCount-1 <> nbr then
  3170        FCurrentChk.Checked := false
  3171     else
  3172        FCurrentChk.Checked := true;  
  3173     FCurrentChk.OnClick := ActionSelectAllExecute;
  3174  end;
  3175  
  3176  procedure TSxMSPForm.DisplayCurrentDuration; 
  3177  var
  3178     tps, m, s : integer;
  3179  begin
  3180     try
  3181        tps := FCurrentPL.GetFileDuration(FCurrentGrid.Row);
  3182        m := tps div 60;
  3183        s := tps - 60*m;
  3184        LbTrackTimeMLeft.Caption := IntToStr(m) + ' :';
  3185        LbTrackTimeSLeft.Caption := IntToStr(s);
  3186        DSTrackBar2.Hint := LbTrackTimeMLeft.Caption + LbTrackTimeSLeft.Caption;
  3187     except
  3188        on E: Exception do
  3189           raise Exception.Create(CE_DISP_CURR_DURATION+E.Message);
  3190     end;
  3191  end;
  3192  
  3193  procedure TSxMSPForm.GridClick(Sender: TObject);
  3194  begin
  3195     FIsNoMenuOpen := true;
  3196     if FCurrentPL.Col = C_COL_SEL then
  3197     begin
  3198        ForceChkBox(false);
  3199        if (FCurrentChkShow.Checked) and
  3200           (FCurrentGrid.Cells[C_COL_SEL, FCurrentGrid.Row] = '0') then
  3201              FCurrentPL.ShowHideThatRow(false, FCurrentGrid.Row);
  3202     end;
  3203     if (FCurrentFG.State = gsPlaying) and FCurrentPL.isPlayingRow then
  3204        FCurrentPL.Col := C_COL_NUM;
  3205     if FCurrentGrid = SCGSelection then
  3206     begin
  3207        FCurrentPL.DisplayComments(RESelection);
  3208        DisplayCurrentDuration;
  3209     end;
  3210     if (FCurrentFG.State <> gsPlaying) and 
  3211        (FCurrentPL.CurrentVolume > -1) then
  3212           FCurrentVol.Position := FCurrentPL.CurrentVolume;
  3213  end;
  3214  
  3215  procedure TSxMSPForm.miUpdateID3sClick(Sender: TObject);
  3216  var
  3217     aArtist, aAlbum, aYear : string;
  3218     ckArtist, ckAlbum, ckYear : boolean;
  3219  begin
  3220     FIsNoMenuOpen := true;
  3221     if TFrmID3Edition.Execute(aArtist, aAlbum, aYear, ckArtist, ckAlbum, ckYear) then
  3222     begin
  3223        FCurrentPL.UpdateID3s(aArtist, aAlbum, aYear, ckArtist, ckAlbum, ckYear);
  3224     end;
  3225  end;
  3226  
  3227  procedure TSxMSPForm.FormActivate(Sender: TObject);
  3228  begin
  3229     if FPreferences.isMaximized then
  3230        WindowState := wsMaximized;
  3231     FocusCurrentPL;
  3232     if FIsInit then
  3233     begin
  3234        FormStyle := fsStayOnTop;
  3235        miAllwaysOnTop.Checked := true;
  3236     end;
  3237  end;
  3238  
  3239  
  3240  
  3241  
  3242  
  3243  procedure TSxMSPForm.ChkOnlySelClick(Sender: TObject);
  3244  begin
  3245     FIsNoMenuOpen := true;
  3246     if not TCheckBox(Sender).Checked then
  3247        EdSearch.Text := '';
  3248     FCurrentPL.Col := 0;
  3249     FCurrentPL.ShowHideUnChecked(TCheckBox(Sender).Checked);
  3250     FocusCurrentPL;
  3251  end;
  3252  
  3253  procedure TSxMSPForm.CmbTemporisationChange(Sender: TObject);
  3254  begin
  3255     FIsNoMenuOpen := true;
  3256     FocusCurrentPL;
  3257  end;
  3258  
  3259  procedure TSxMSPForm.FilterGraphBrowserGraphErrorAbort(sender: TObject;
  3260    Result: HRESULT);
  3261  begin
  3262     FilterGraphBrowser.Active := false;
  3263  end;
  3264  
  3265  (*
  3266   * Gestionnaires des tris
  3267   *)
  3268  
  3269  procedure TSxMSPForm.miDefineInitialOrderClick(Sender: TObject);
  3270  begin
  3271     FIsNoMenuOpen := true;
  3272     FCSLSelection.DefineInitialOrder;
  3273  end;
  3274  
  3275  procedure TSxMSPForm.miSortByInitilaOrderClick(Sender: TObject);
  3276  begin
  3277     FIsNoMenuOpen := true;
  3278      FCSLSelection.SortGridByInitialOrder;
  3279  end;
  3280  
  3281  procedure TSxMSPForm.miSortByFileAgeClick(Sender: TObject);
  3282  begin
  3283     FIsNoMenuOpen := true;
  3284     FCSLSelection.SortGridByFileAge;
  3285  end;
  3286  
  3287  procedure TSxMSPForm.miSortByGroupsClick(Sender: TObject);
  3288  begin
  3289     FIsNoMenuOpen := true;
  3290     FCSLSelection.SortGridByGroups;
  3291  end;
  3292  
  3293  procedure TSxMSPForm.miSortGridByTitleClick(Sender: TObject);
  3294  begin
  3295     FIsNoMenuOpen := true;
  3296     FCSLSelection.SortGridByTitle;
  3297  end;
  3298  
  3299  procedure TSxMSPForm.miSortGridByChoreClick(Sender: TObject);
  3300  begin
  3301     FCSLSelection.SortGridByChore;
  3302  end;
  3303  
  3304  procedure TSxMSPForm.miSortByAuthorClick(Sender: TObject);
  3305  begin
  3306     FIsNoMenuOpen := true;
  3307     FCSLSelection.SortGridByAuthor;
  3308  end;
  3309  
  3310  
  3311  procedure TSxMSPForm.miSortGridByNBPClick(Sender: TObject);
  3312  begin
  3313     FIsNoMenuOpen := true;
  3314     FCSLSelection.SortGridByNBP;
  3315  end;
  3316  
  3317  
  3318  (*
  3319   * Gestionnaire de timeline
  3320   *)
  3321  procedure TSxMSPForm.DSTrackBar2Change(Sender: TObject);
  3322  var
  3323     tps, m, s : integer;
  3324     sm : string;
  3325  begin
  3326     FIsNoMenuOpen := true;
  3327     if DSTrackBar2.Position = 0 then
  3328        tps := FCurrentFG.Duration
  3329     else
  3330        tps := Trunc((FCurrentFG.Duration * 
  3331                      (1.0 -(DSTrackBar2.Position / DSTrackBar2.Max))) / 1000);
  3332     m := tps div 60;
  3333     s := tps - 60*m;
  3334     sm := IntToStr(m) + ' :';
  3335     if (LbTrackTimeMLeft.Caption <> sm) then
  3336        LbTrackTimeMLeft.Caption := sm;
  3337     LbTrackTimeSLeft.Caption := IntToStr(s);
  3338     DSTrackBar2.Hint := LbTrackTimeMLeft.Caption + LbTrackTimeSLeft.Caption;
  3339  end;
  3340  
  3341  
  3342  
  3343  procedure TSxMSPForm.miAddnodeToSelectionClick(Sender: TObject);
  3344  var
  3345     s : string;
  3346  begin
  3347     FIsNoMenuOpen := true;
  3348     s := SFV.DoPath(SFV.Selected);
  3349     if (s <> '') then
  3350     begin
  3351        FCSLSelection.LoadGridFromPath(s);
  3352        FSelectionLoaded := true;
  3353        btnPagesClick(btnSelection);
  3354        SCGSelection.Invalidate;
  3355        ForceChkBox(false);
  3356        btnPagesClick(btnBrowser);
  3357        UpdateGroupsView(true);
  3358     end;
  3359  end;
  3360  
  3361  procedure TSxMSPForm.btnPreferencesClick(Sender: TObject);
  3362  begin
  3363     if FIsNoMenuOpen then
  3364     begin
  3365        FIsNoMenuOpen := false;
  3366        btnPreferences.Popup;
  3367     end
  3368     else
  3369        FIsNoMenuOpen := true;
  3370  end;
  3371  
  3372  procedure TSxMSPForm.miColorProfilClick(Sender: TObject);
  3373  begin
  3374     FIsNoMenuOpen := true;
  3375     FPreferences.isDayTime := (Sender = miJour);
  3376     ChangeColors(Integer(FPreferences.isDayTime));
  3377     TMenuItem(Sender).Checked := true;
  3378  end;
  3379  
  3380  procedure TSxMSPForm.miAllwaysOnTopClick(Sender: TObject);
  3381  begin
  3382     FIsNoMenuOpen := true;
  3383     miAllwaysOnTop.Checked := not miAllwaysOnTop.Checked;
  3384     FPreferences.isAllwaysOnTop := miAllwaysOnTop.Checked;
  3385     if FPreferences.isAllwaysOnTop then
  3386        FormStyle := fsStayOnTop
  3387     else
  3388        FormStyle := fsNormal;
  3389  end;
  3390  
  3391  procedure TSxMSPForm.miDefinePLRootClick(Sender: TObject);
  3392  var
  3393     aDir : string;
  3394  begin
  3395     FIsNoMenuOpen := true;
  3396     if SelectDirectory(aDir, [], 0) then
  3397     begin
  3398        FPreferences.DefaultPLPath := aDir;
  3399        SFV.ReloadPlayListNode(FPreferences.DefaultPLPath);
  3400     end;
  3401  end;
  3402  
  3403  procedure TSxMSPForm.miDeleteNonSelClick(Sender: TObject);
  3404  begin
  3405     FIsNoMenuOpen := true;
  3406     FCSLSelection.DeleteUnselectedLines;
  3407  end;
  3408  
  3409  procedure TSxMSPForm.miInvertSelectionClick(Sender: TObject);
  3410  begin
  3411     FIsNoMenuOpen := true;
  3412     SetChkBoxAllNone(FCurrentPL.InvertCheck);
  3413  end;
  3414  
  3415  procedure TSxMSPForm.PanLeftSelectionResize(Sender: TObject);
  3416  begin
  3417     FIsNoMenuOpen := true;
  3418     MainClock.Top := PanLeftSelection.ClientHeight - 25;
  3419  end;
  3420  
  3421  procedure TSxMSPForm.miCmmFntSzClick(Sender: TObject);
  3422  begin
  3423     FIsNoMenuOpen := true;
  3424     FPreferences.CommentSize := SxStrToInt(InputBox('Taille des commentaires',
  3425                                                     'taille',
  3426                                                     IntToStr(FPreferences.CommentSize)),
  3427                                                     FPreferences.CommentSize);
  3428     RESelection.Font.Size := FPreferences.CommentSize;
  3429     RESelection.Invalidate;
  3430  end;
  3431  
  3432  procedure TSxMSPForm.miCmmViewerFntSzClick(Sender: TObject);
  3433  begin
  3434     FIsNoMenuOpen := true;
  3435     FPreferences.CommentViewerSize := SxStrToInt(InputBox('Taille des commentaires',
  3436                                                           'taille',
  3437                                                           IntToStr(FPreferences.CommentViewerSize)),
  3438                                                           FPreferences.CommentViewerSize);
  3439  end;
  3440  
  3441  procedure TSxMSPForm.miDisplayTitleClick(Sender: TObject);
  3442  begin
  3443     FIsNoMenuOpen := true;
  3444     FPreferences.LineDisplay := C_DISP_TITLE;
  3445     miDisplayTitle.Checked := true;
  3446     FCSLBrowser.LineDisplay := C_DISP_TITLE;
  3447     FCSLSelection.LineDisplay := C_DISP_TITLE;
  3448  end;
  3449  
  3450  procedure TSxMSPForm.miDisplayChoreClick(Sender: TObject);
  3451  begin
  3452     FIsNoMenuOpen := true;
  3453     FPreferences.LineDisplay := C_DISP_CHORE;
  3454     miDisplayChore.Checked := true;
  3455     FCSLBrowser.LineDisplay := C_DISP_CHORE;
  3456     FCSLSelection.LineDisplay := C_DISP_CHORE;
  3457  end;
  3458  
  3459  procedure TSxMSPForm.miDispChoreTitleClick(Sender: TObject);
  3460  begin
  3461     FIsNoMenuOpen := true;
  3462     FPreferences.LineDisplay := C_DISP_CHORE_TITLE;
  3463     miDispChoreTitle.Checked := true;
  3464     FCSLBrowser.LineDisplay := C_DISP_CHORE_TITLE;
  3465     FCSLSelection.LineDisplay := C_DISP_CHORE_TITLE;
  3466  end;
  3467  
  3468  procedure TSxMSPForm.miDispAuthorTitleClick(Sender: TObject);
  3469  begin
  3470     FIsNoMenuOpen := true;
  3471     FPreferences.LineDisplay := C_DISP_AUTH_TITLE;
  3472     miDispAuthorTitle.Checked := true;
  3473     FCSLBrowser.LineDisplay := C_DISP_AUTH_TITLE;
  3474     FCSLSelection.LineDisplay := C_DISP_AUTH_TITLE;
  3475  end;
  3476  
  3477  procedure TSxMSPForm.miDisplayCategClick(Sender: TObject);
  3478  begin
  3479     FIsNoMenuOpen := true;
  3480     miDisplayCateg.Checked := not miDisplayCateg.Checked;
  3481     FPreferences.DisplayCateg := miDisplayCateg.Checked;
  3482     FCSLBrowser.DisplayCateg := FPreferences.DisplayCateg;
  3483     FCSLSelection.DisplayCateg := FPreferences.DisplayCateg;
  3484  end;
  3485  
  3486  procedure TSxMSPForm.miPlayListM3UMovedClick(Sender: TObject);
  3487  var
  3488     aDir : string;
  3489  begin
  3490     FIsNoMenuOpen := true;
  3491     aDir := ExtractFilePath(FCurrentPL.CurrentFileName);
  3492     if SelectDirectory(aDir, [sdAllowCreate], 0) then
  3493     with TSxSaveDialog.Create(Self) do
  3494     try
  3495        Filter := 'Fichier PlayList M3U|*.m3u';
  3496        DefaultExt := 'm3u';
  3497        InitialDir := ExtractFilePath(ParamStr(0));
  3498        if Execute then
  3499        begin
  3500           FCurrentPL.SaveAsMovedVLCM3UPlayList(FileName, aDir);
  3501           FLastPlayList := FileName;
  3502        end;
  3503        SFV.ReloadPlayListNode(InitialDir);
  3504     finally
  3505        Free
  3506     end;
  3507  end;
  3508  
  3509  
  3510  procedure TSxMSPForm.miCharSizePrefClick(Sender: TObject);
  3511  var
  3512     mi : TMenuItem;
  3513  begin
  3514     FIsNoMenuOpen := true;
  3515     mi := TMenuItem(Sender);
  3516     FPreferences.GridCharSize := mi.Tag;
  3517     SetGridCharSize;
  3518  end;
  3519  
  3520  
  3521  procedure TSxMSPForm.miAproposClick(Sender: TObject);
  3522  begin
  3523     FIsNoMenuOpen := true;
  3524     FrmAPropos.TFmAPropos.Execute(Self);
  3525  end;
  3526  
  3527  procedure TSxMSPForm.miSelectUntilClick(Sender: TObject);
  3528  begin
  3529     FIsNoMenuOpen := true;
  3530     SetChkBoxAllNone(FCurrentPL.CheckLinesFromTo(true, 0, FCurrentGrid.Row));
  3531  end;
  3532  
  3533  procedure TSxMSPForm.miSelectFromClick(Sender: TObject);
  3534  begin
  3535     FIsNoMenuOpen := true;
  3536     SetChkBoxAllNone(FCurrentPL.CheckLinesFromTo(true, 
  3537                                                  FCurrentGrid.Row, 
  3538                                                  FCurrentGrid.RowCount-1));
  3539  end;
  3540  
  3541  procedure TSxMSPForm.miUnselDblByThatClick(Sender: TObject);
  3542  begin
  3543     FIsNoMenuOpen := true;
  3544     SetChkBoxAllNone(FCurrentPL.UncheckDuplicates(TSxMMCheckOption(TMenuItem(Sender).Tag)));
  3545  end;
  3546  
  3547  procedure TSxMSPForm.miCheckChoregraphiedClick(Sender: TObject);
  3548  begin
  3549     FIsNoMenuOpen := true;
  3550     FCurrentPL.CheckLines(true);
  3551     SetChkBoxAllNone(FCurrentPL.CheckOnlyIfchoregraphied);
  3552  end;
  3553  
  3554  
  3555  procedure TSxMSPForm.miCheckHasClipClick(Sender: TObject);
  3556  begin
  3557     FIsNoMenuOpen := true;
  3558     FCurrentPL.CheckLines(true);
  3559     SetChkBoxAllNone(FCurrentPL.CheckOnlyIfHasClip);
  3560  end;
  3561  
  3562  
  3563  procedure TSxMSPForm.miDefSelNumXClick(Sender: TObject);
  3564  begin
  3565     FIsNoMenuOpen := true;
  3566     FCurrentPL.AddSelectionToGrpNum(TMenuItem(Sender).Tag);
  3567     FCurrentGrid.Invalidate;
  3568     UpdateGroupsView(true);
  3569  end;
  3570  
  3571  procedure TSxMSPForm.miSelectSelNumXClick(Sender: TObject);
  3572  begin
  3573     FIsNoMenuOpen := true;
  3574     SetChkBoxAllNone(FCurrentPL.CheckIfSelectionNum(TMenuItem(Sender).Tag));
  3575  end;
  3576  
  3577  
  3578  
  3579  
  3580  
  3581  procedure TSxMSPForm.miCheckTitledClick(Sender: TObject);
  3582  begin
  3583     FIsNoMenuOpen := true;
  3584     FCurrentPL.CheckLines(true);
  3585     SetChkBoxAllNone(FCurrentPL.CheckOnlyIfTitled);
  3586  end;
  3587  
  3588  
  3589  procedure TSxMSPForm.miSaveChoregClick(Sender: TObject);
  3590  begin
  3591     FIsNoMenuOpen := true;
  3592     with TSxSaveDialog.Create(Self) do
  3593     try
  3594        Filter := 'Fichier Texte|*.txt';
  3595        DefaultExt := 'txt';
  3596        InitialDir := ExtractFilePath(ParamStr(0));
  3597        if Execute then
  3598           FCurrentPL.SaveChoregraphies(FileName);
  3599     finally
  3600        Free
  3601     end;
  3602  end;
  3603  
  3604  procedure TSxMSPForm.miConfirmChkAllClick(Sender: TObject);
  3605  begin
  3606     FIsNoMenuOpen := true;
  3607     miConfirmChkAll.Checked := not miConfirmChkAll.Checked;
  3608     FPreferences.isChkAllConfirmed := miConfirmChkAll.Checked;
  3609  end;
  3610  
  3611  procedure TSxMSPForm.miEmptyConfirmClick(Sender: TObject);
  3612  begin
  3613     FIsNoMenuOpen := true;
  3614     miEmptyConfirm.Checked := not miEmptyConfirm.Checked;
  3615     FPreferences.isEmptyConfirmed := miEmptyConfirm.Checked;
  3616  end;
  3617  
  3618  procedure TSxMSPForm.miConfirmFileExistsClick(Sender: TObject);
  3619  begin
  3620     FIsNoMenuOpen := true;
  3621     miConfirmFileExists.Checked := not miConfirmFileExists.Checked;
  3622     FPreferences.isRewriteConfirmed := miConfirmFileExists.Checked;
  3623  end;
  3624  
  3625  procedure TSxMSPForm.miDownloadVersionClick(Sender: TObject);
  3626  begin
  3627     FIsNoMenuOpen := true;
  3628     miDownloadVersion.Checked := C_FORCE_DOWNLOAD or not miDownloadVersion.Checked; ///
  3629     FPreferences.isAutoUpdate := miDownloadVersion.Checked;
  3630  end;
  3631  
  3632  procedure TSxMSPForm.miInstallUpdatesClick(Sender: TObject);
  3633  begin
  3634     ManageUpdates(1);
  3635  end;
  3636  
  3637  procedure TSxMSPForm.miInstallMajorUpdatesClick(Sender: TObject);
  3638  begin
  3639     ManageUpdates(1000);
  3640  end;
  3641  
  3642  procedure TSxMSPForm.FormMouseDown(Sender: TObject; Button: TMouseButton;
  3643    Shift: TShiftState; X, Y: Integer);
  3644  begin
  3645     if Button <> mbRight then
  3646        FIsNoMenuOpen := true;
  3647  end;
  3648  
  3649  procedure TSxMSPForm.NoMenuOpenClick(Sender: TObject);
  3650  begin
  3651     FIsNoMenuOpen := true;
  3652  end;
  3653  
  3654  procedure TSxMSPForm.NoMenuOpenMouseUp(Sender: TObject; Button: TMouseButton;
  3655                                         Shift: TShiftState; X, Y: Integer);
  3656  begin
  3657     FIsNoMenuOpen := true;
  3658     if (FCurrentGrid = SCGBrowser) and (ssCtrl in Shift) then
  3659     begin
  3660        ActionSendToSelectionExecute(nil);
  3661        if EdSearch.Visible then
  3662        begin
  3663           EdSearch.Text := '';
  3664           FocusControl(EdSearch);
  3665           EdSearch.SetFocus;
  3666        end;
  3667     end;
  3668  end;
  3669  
  3670  procedure TSxMSPForm.SCGSelectionStartDrag(Sender: TObject;
  3671                                             var DragObject: TDragObject);
  3672  var
  3673     aCol : integer;
  3674     aCR : TPoint;
  3675  begin
  3676     DragObject := nil;
  3677     if FCurrentPL.isValidRow then
  3678     begin
  3679        aCR := FCurrentGrid.ScreenToClient(Mouse.CursorPos);
  3680        FCurrentGrid.MouseToCell(aCR.x, aCR.y, aCol, FStartDragIndex)
  3681     end
  3682     else
  3683     begin
  3684        FStartDragIndex := -1;
  3685     end;
  3686  end;
  3687  
  3688  procedure TSxMSPForm.SCGSelectionDragOver(Sender, Source: TObject; X, Y: Integer;
  3689                                            State: TDragState; var Accept: Boolean);
  3690  begin
  3691     Accept := FStartDragIndex <> -1;
  3692  end;
  3693  
  3694  procedure TSxMSPForm.SCGSelectionDragDrop(Sender, Source: TObject; X, Y: Integer);
  3695  var
  3696     aCol, aRow : integer;
  3697  begin
  3698     FCurrentGrid.MouseToCell(X, Y, aCol, aRow);
  3699     if FCurrentPL.isValidRow(aRow) then
  3700        FCurrentGrid.MoveLine(FStartDragIndex, aRow, true);
  3701  end;
  3702  
  3703  procedure TSxMSPForm.SCGSelectionEndDrag(Sender, Target: TObject; X, Y: Integer);
  3704  begin
  3705     //FCurrentGrid.Cursor := crDefault;
  3706  end;
  3707  
  3708  procedure TSxMSPForm.SCGSelectionMouseDown(Sender: TObject; Button: TMouseButton;
  3709                                             Shift: TShiftState; X, Y: Integer);
  3710  begin
  3711     if (ssAlt in Shift) and (ssLeft in Shift) and (not FCurrentGrid.Dragging) then
  3712        FCurrentGrid.BeginDrag(true);
  3713  end;
  3714  
  3715  procedure TSxMSPForm.SCGSelectionMouseUp(Sender: TObject; Button: TMouseButton;
  3716                                           Shift: TShiftState; X, Y: Integer);
  3717  begin
  3718     NoMenuOpenMouseUp(Sender, button, Shift, X, Y);
  3719  end;
  3720  
  3721  procedure TSxMSPForm.miDefineVolumeClick(Sender: TObject);
  3722  begin
  3723     if FCurrentPL.isValidRow then
  3724        FCurrentPL.CurrentVolume := FCurrentVol.Position;
  3725  end;
  3726  
  3727  procedure TSxMSPForm.miDefineFadeInClick(Sender: TObject);
  3728  begin
  3729     if FCurrentPL.isValidRow then
  3730        FCurrentPL.CurrentFadeIn := FCurrentPL.CurrentPosition;
  3731  end;
  3732  
  3733  procedure TSxMSPForm.miDefineFadeOutClick(Sender: TObject);
  3734  begin
  3735     if FCurrentPL.isValidRow then
  3736        FCurrentPL.CurrentFadeOut := FCurrentPL.CurrentPosition;
  3737  end;
  3738  
  3739  procedure TSxMSPForm.miDefineStartClick(Sender: TObject);
  3740  begin
  3741     if FCurrentPL.isValidRow then
  3742        FCurrentPL.CurrentStart := FCurrentPL.CurrentPosition;
  3743  end;
  3744  
  3745  procedure TSxMSPForm.miDefineStopClick(Sender: TObject);
  3746  begin
  3747     if FCurrentPL.isValidRow then
  3748        FCurrentPL.CurrentStop := FCurrentPL.CurrentPosition;
  3749  end;
  3750  
  3751  
  3752  
  3753  procedure TSxMSPForm.FadeOut(mSec: integer);
  3754  begin
  3755     if Assigned(FCurrentPL) then
  3756     begin
  3757        FCurrentPL.FadeInfos.tmLeft := mSec;
  3758        FCurrentPL.FadeInfos.volStep := (100 * FCurrentVol.Position) div mSec;
  3759        TimerFade.Enabled := True;
  3760     end;
  3761  end;
  3762  
  3763  procedure TSxMSPForm.TimerFadeTimer(Sender: TObject);
  3764  begin
  3765     if Assigned(FCurrentPL) then
  3766     begin
  3767        Dec(FCurrentPL.FadeInfos.tmLeft, TimerFade.Interval);
  3768        if FCurrentVol.Position >= FCurrentPL.FadeInfos.volStep then
  3769           FCurrentVol.Position := FCurrentVol.Position - FCurrentPL.FadeInfos.volStep
  3770        else
  3771        begin
  3772           TimerFade.Enabled := false;
  3773           FCurrentFG.Stop;
  3774           FCurrentFG.OnGraphComplete(FCurrentFG, 0, nil);
  3775        end;
  3776     end
  3777     else
  3778        TimerFade.Enabled := false;
  3779  end;
  3780  
  3781  procedure TSxMSPForm.miSaveLogClick(Sender: TObject);
  3782  begin
  3783     miSaveLog.Checked := not miSaveLog.Checked;
  3784     FPreferences.isJournalized := miSaveLog.Checked;
  3785  end;
  3786  
  3787  procedure TSxMSPForm.miClearLogClick(Sender: TObject);
  3788  begin
  3789     if Assigned(FSLLog) then
  3790     begin
  3791        FSLLog.Clear;
  3792        InitLog;
  3793     end;
  3794  end;
  3795  
  3796  procedure TSxMSPForm.miLoadFromLogClick(Sender: TObject);
  3797  var
  3798     i : integer;
  3799  begin
  3800     if Assigned(FSLLog) then
  3801     begin
  3802        FCSLSelection.EmptyGrid;
  3803        for i := 0 to FSLLog.Count-1 do
  3804           if FileExists(FSLLOg.Strings[i]) then
  3805              FCSLSelection.AddNewFile(FSLLOg.Strings[i], 0, 0, 0,
  3806                                       C_SNDSET_NULL, C_SNDRANGE_NULL, false);
  3807     end;
  3808  end;
  3809  
  3810  procedure TSxMSPForm.SelectThisSubSel(const n : integer);
  3811  begin
  3812     SetChkBoxAllNone(FCurrentPL.CheckIfOnlyIfSelectionNum(n));
  3813  end;
  3814  
  3815  procedure TSxMSPForm.SelectThisBBItem(const n : integer);
  3816  begin
  3817     if (BBGroups.BtnCount > 0) then
  3818        BBGroups.Buttons[n mod BBGroups.BtnCount].Click;
  3819  end;
  3820  
  3821  procedure TSxMSPForm.SelectThisPL(const n : integer);
  3822  begin
  3823     SetChkBoxAllNone(FCurrentPL.CheckIfOnlyIfPLId(n));
  3824  end;
  3825  
  3826  procedure TSxMSPForm.miSelSelNumXClick(Sender: TObject);
  3827  begin
  3828     FIsNoMenuOpen := true;
  3829     SelectThisSubSel(TMenuItem(Sender).Tag);
  3830     FCurrentPL.ShowHideUnChecked(FCurrentChkShow.Checked);
  3831  end;
  3832  
  3833  procedure TSxMSPForm.miRenameSubSelXClick(Sender: TObject);
  3834  var
  3835     s1, s : string;
  3836     n : integer;
  3837  begin
  3838     try
  3839        FIsNoMenuOpen := true;
  3840        n := TMenuItem(Sender).Tag;
  3841        s1 := FCurrentPL.GrpTitle[n];
  3842        s := InputBox('Définition du Titre de groupe', 'Titre :', s1);
  3843        FCurrentPL.GrpTitle[n] := s;
  3844        UpdateMenuSubSel;
  3845        UpdateGroupsView(false);
  3846     except
  3847        on E: Exception do
  3848           raise Exception.Create(CE_MENU_SS_RENAME+E.Message);
  3849     end;
  3850  end;
  3851  
  3852  procedure TSxMSPForm.UpdateMenuSubSel;
  3853  var
  3854     s : string;
  3855     i : integer;
  3856     Cmp : TComponent;
  3857  begin
  3858     try
  3859        for i := 1 to 8 do
  3860        begin
  3861           s := FCurrentPL.GrpTitle[i];
  3862           cmp := FindComponent('miSelSelNum'+IntToStr(i));
  3863           if Assigned(cmp) then
  3864              TMenuItem(cmp).Caption := 'les éléments de ' + s;
  3865           cmp := FindComponent('miDefSelNum'+IntToStr(i));
  3866           if Assigned(cmp) then
  3867              TMenuItem(cmp).Caption := s;
  3868           cmp := FindComponent('miSelectSelNum'+IntToStr(i));
  3869           if Assigned(cmp) then
  3870              TMenuItem(cmp).Caption := s;
  3871           cmp := FindComponent('miRenameSubSel'+IntToStr(i));
  3872           if Assigned(cmp) then
  3873              TMenuItem(cmp).Caption := s;
  3874              cmp := FindComponent('miClearFromSubSel'+IntToStr(i));
  3875           if Assigned(cmp) then
  3876              TMenuItem(cmp).Caption := s;
  3877        end;
  3878     except
  3879        on E: Exception do
  3880           raise Exception.Create(CE_MENU_SS_UPDATE+E.Message);
  3881     end;
  3882  end;
  3883  
  3884  procedure TSxMSPForm.miInitTrackClick(Sender: TObject);
  3885  begin
  3886     if FCurrentPL.isValidRow then
  3887     begin
  3888        FCurrentPL.CurrentStop := -1;
  3889        FCurrentPL.CurrentStart := -1;
  3890        FCurrentPL.CurrentVolume := -1;
  3891     end;
  3892  end;
  3893  
  3894  procedure TSxMSPForm.miClearFromSubSelXClick(Sender: TObject);
  3895  begin
  3896     FIsNoMenuOpen := true;
  3897     FCurrentPL.ClearSelectionFromGrpNum(TMenuItem(Sender).Tag);
  3898     UpdateGroupsView(true);
  3899  end;
  3900  
  3901  procedure TSxMSPForm.miRestoreKeyCodesClick(Sender: TObject);
  3902  begin     
  3903     FIsNoMenuOpen := true;
  3904     InitDefaultKeyConf(FKeyIdents);
  3905  end;
  3906  
  3907  (*
  3908   * EchangeMenuItem déplace les éléments du popup bts sel vers le popup grid et
  3909   *                 vice-versa ...
  3910   * TODO : résoudre le bug FindItem
  3911   *   Situation : le btn sel est cliqué après l'un des 2 autres ou après click grid
  3912   *               le bug survient lors du premier accès seulement.
  3913   *)
  3914  procedure EchangeMenuItem(const popFrom : TPopUpMenu;
  3915                            const mi : TMenuItem;
  3916                            const popTo : TPopUpMenu;
  3917                            const miToIns : TMenuItem;
  3918                            const visible : boolean);
  3919  var
  3920     n : integer;
  3921     fndMI : TMenuItem;
  3922  begin
  3923     try
  3924        fndMI := nil;
  3925        try
  3926           if Assigned(mi) then
  3927              fndMI := popFrom.FindItem(mi.Handle, fkHandle);
  3928        except
  3929           on E : Exception do
  3930              Exit;
  3931        end;
  3932        if Assigned(fndMI) then
  3933        begin
  3934           n := popTo.Items.IndexOf(miToIns);
  3935           if (n >= 0) then
  3936           begin
  3937              try
  3938                 popFrom.Items.Remove(mi);
  3939              except
  3940                 on e : exception do
  3941                    raise Exception.Create('Remove error '+e.Message);
  3942              end;
  3943              try
  3944                 popTo.Items.Insert(Max(0,Min(n,popTo.Items.Count-1)), mi);
  3945              except
  3946                 on e : exception do
  3947                    raise Exception.Create('Insert error '+e.Message);
  3948              end;
  3949           end
  3950           else
  3951              raise Exception.Create('Menu toIns introuvable : ' + miToIns.Caption);
  3952        end;
  3953        if Assigned(mi) then
  3954           mi.Visible := visible;
  3955     except
  3956        On E:Exception do
  3957           raise Exception.Create(CE_MI_ECHANGE + E.Message);
  3958     end;
  3959  end;
  3960  
  3961  procedure TSxMSPForm.popGridPopup(Sender: TObject);
  3962  var
  3963     aCR : TPoint;
  3964     acol, aRow : integer;
  3965     vis : boolean;
  3966  begin
  3967     try
  3968        try
  3969        aCR := FCurrentGrid.ScreenToClient(Mouse.CursorPos);
  3970        FCurrentGrid.MouseToCell(aCR.x, aCR.y, aCol, aRow);
  3971        vis := (aCol < C_COL_NBP);
  3972        FCurrentGrid.Row := aRow;
  3973        except
  3974           on e : exception do
  3975              raise Exception.Create('BK1 ' + e.MEssage);
  3976        end;
  3977        FCurrentGrid.Invalidate;
  3978        EchangeMenuItem(popupBtnSelection, miSelectIf, popGrid, miSelectUntil, vis);
  3979        EchangeMenuItem(popupBtnSelection, miInvertSelection, popGrid, miSelectUntil, vis);
  3980        EchangeMenuItem(popupBtnSelection, miSendToSel, popGrid, miSelectUntil, vis);
  3981        EchangeMenuItem(popupBtnSelection, miSelectSelNum, popGrid, miSelectUntil, vis);
  3982        EchangeMenuItem(popupBtnSelection, miClearFromSubSel, popGrid, miSelectUntil, vis);
  3983     except
  3984        on E:Exception do
  3985        begin
  3986           raise Exception.Create(CE_POPUP_GRID + E.Message);
  3987        end;
  3988     end;
  3989  end;
  3990  
  3991  procedure TSxMSPForm.popupBtnSelectionPopup(Sender: TObject);
  3992  begin
  3993     try
  3994        EchangeMenuItem(popGrid, miClearFromSubSel, popupBtnSelection, N20, true);
  3995        EchangeMenuItem(popGrid, miSelectSelNum, popupBtnSelection, miClearFromSubSel, true);
  3996        EchangeMenuItem(popGrid, miSendToSel, popupBtnSelection, miSelectSelNum, true);
  3997        EchangeMenuItem(popGrid, miInvertSelection, popupBtnSelection, miSendToSel, true);
  3998        EchangeMenuItem(popGrid, miSelectIf, popupBtnSelection, miInvertSelection, true);
  3999     except
  4000        on E:Exception do
  4001           raise Exception.Create(CE_BTNSEL_POPUP + E.Message);
  4002     end;
  4003  end;
  4004  
  4005  procedure TSxMSPForm.miRemoveLineClick(Sender: TObject);
  4006  begin
  4007     try
  4008        if FCurrentPL.isValidRow then
  4009           FCurrentPL.RemoveLine(FCurrentGrid.Row);
  4010     except 
  4011        on E:Exception do
  4012           raise Exception.Create(CE_REMOVE_LINE + E.Message);
  4013     end;
  4014  end;
  4015  
  4016  procedure TSxMSPForm.miClearFromAllSubSelClick(Sender: TObject);
  4017  begin
  4018     FIsNoMenuOpen := true;
  4019     FCurrentPL.ClearSelectionFromGrpNum(MaxInt);
  4020  end;
  4021  
  4022  
  4023  procedure TSxMSPForm.miReloadPathClick(Sender: TObject);
  4024  var
  4025     aNode : TTreeNode;
  4026     aSel: TSxTriVal;
  4027  begin
  4028     if isThatFolderType(SFV.Selected, fiMusicRoot) then
  4029        SFV.ReloadSpecialFolderTree(CSIDL_MYMUSIC)
  4030     else if isThatFolderType(SFV.Selected, fiPlayListRoot) then
  4031        SFV.ReloadPlayListNode(FPreferences.DefaultPLPath)
  4032     else
  4033     begin
  4034        aNode := SFV.Selected;
  4035        SFV.ReloadDirectories(aNode);
  4036        aSel := C_FV_SEL_1;
  4037        SFVAfterSelection(aNode, aSel);
  4038     end;
  4039  
  4040  end;
  4041  
  4042  function TSxMSPForm.SFVAllowAction(const aNode: TTreeNode): Boolean;
  4043  begin
  4044     result := not isThatFolderType(SFV.Selected, fiPlayListRoot);
  4045  end;
  4046  
  4047  
  4048  
  4049  procedure TSxMSPForm.BBGroupsClick(Sender: TObject);
  4050  var
  4051     n : integer;
  4052  begin
  4053     begin
  4054        n := TSxFlatButton(Sender).Tag;
  4055        if n > 0 then
  4056           SelectThisSubSel(n)
  4057        else
  4058           SelectThisPL(n*-1);
  4059     end;
  4060     FCurrentPL.ShowHideUnChecked(FCurrentChkShow.Checked);
  4061     SCGSelection.SetFocus;
  4062  end;
  4063  
  4064  procedure TSxMSPForm.miMoveTopGroupClick(Sender: TObject);
  4065  begin
  4066     if Assigned(BBGroups.Selected) then
  4067        FCurrentPL.MoveGroupAtFirst(integer(BBGroups.Selected.Tag));
  4068  end;
  4069  
  4070  procedure TSxMSPForm.miShowHidePlayedClick(Sender: TObject);
  4071  begin
  4072     FCurrentPL.ShowHidePlayed(miShowHidePlayed.Tag > 0);
  4073     miShowHidePlayed.Tag := -1 * miShowHidePlayed.Tag;
  4074     if miShowHidePlayed.Tag < 0 then
  4075       miShowHidePlayed.Caption := 'Masquer les pistes jouées'
  4076     else
  4077        miShowHidePlayed.Caption := 'Afficher les pistes jouées';
  4078     FocusCurrentPL;
  4079  end;
  4080  
  4081  procedure TSxMSPForm.miShowOnlyPlayedClick(Sender: TObject);
  4082  begin
  4083     FCurrentPL.ShowOnlyIfPlayed; 
  4084     FocusCurrentPL;
  4085  end;
  4086  
  4087  procedure TSxMSPForm.miSelShowMixClick(Sender: TObject);
  4088  begin
  4089     miSelShowMix.Tag := 1 - miSelShowMix.Tag;
  4090     if miSelShowMix.Tag = 1 then
  4091     begin
  4092        miSelShowMix.Caption := 'Masquer la console de mixage';
  4093        if (PanRightSelection.Width < 451) then
  4094           PanRightSelection.Width := 451;
  4095        SCGSelection.Height := PanRightSelection.Height - 103;
  4096        SelPgCtrl.Top := PanRightSelection.Height - 100;
  4097        SelPgCtrl.Height := 100;
  4098        SxMixer1.PlayingColor := $0045BE03;
  4099        SxMixer1.Width := SelPgCtrl.ClientWidth-4;
  4100        if FCurrentFG.Active then
  4101           SxMixer1.BindGraph(FCurrentFG, FCurrentPL.CurrentFileName, FCurrentPL.PlayingIndex);
  4102     end
  4103     else
  4104     begin
  4105        miSelShowMix.Caption := 'Afficher la console de mixage';
  4106        SelPgCtrl.Top := PanRightSelection.Height -100; //- 53;
  4107        SelPgCtrl.Height := 100; //53;
  4108        SCGSelection.Height := PanRightSelection.Height -103; //- 56;
  4109     end;
  4110     SelPgCtrl.ActivePageIndex := miSelShowMix.Tag;
  4111  end;
  4112  
  4113  procedure TSxMSPForm.SxMixer1Play(var aRow: Integer);
  4114  var
  4115     aFileName : string;
  4116  begin
  4117     FCurrentPL.MarqueCurrent(true);
  4118     if FCurrentPL.PlayingIndex >= FCurrentGrid.FixedRows then
  4119     begin
  4120        aFileName := FCurrentGrid.Cells[C_COL_FILE, FCurrentPL.PlayingIndex];
  4121        LbTitre.Caption := ExtractFileName(aFileName);
  4122        AddToLog(CL_FILETOPLAY, aFileName);
  4123        UpdateDisplay(Ord('X'));
  4124     end;
  4125  end;
  4126  
  4127  procedure TSxMSPForm.SxMixer1Stop(var aRow: Integer);
  4128  begin
  4129     //if FCurrentPL.PlayingIndex = aRow then
  4130        FCurrentPL.MarqueCurrent(false);
  4131     UpdateDisplay(Ord('S'));
  4132  end;
  4133  
  4134  procedure TSxMSPForm.PanRightSelectionResize(Sender: TObject);
  4135  begin
  4136     if (miSelShowMix.Tag = 1) and (PgCtrl.ActivePageIndex <> C_PG_BROWSER) then
  4137     begin
  4138        if (PanRightSelection.Width < 451) then
  4139           PanRightSelection.Width := 451;
  4140        SCGSelection.Height := PanRightSelection.Height -100; //- 88;
  4141        SelPgCtrl.Top := PanRightSelection.Height -103; //- 85;
  4142        SelPgCtrl.Height := 100; //85;
  4143        SxMixer1.Width := SelPgCtrl.ClientWidth- 4;
  4144     end
  4145     else
  4146     begin
  4147        SelPgCtrl.Top := PanRightSelection.Height -100; //- 53;
  4148        SelPgCtrl.Height := 100; //53;
  4149        SCGSelection.Height := PanRightSelection.Height -103; //- 56;
  4150     end;
  4151  end;
  4152  
  4153  procedure TSxMSPForm.miSelByRatingClick(Sender: TObject);
  4154  var
  4155     n : integer;
  4156  begin
  4157     FIsNoMenuOpen := true;
  4158     n := TMenuItem(Sender).Tag;
  4159     if (n > 9) then Inc(n);
  4160     FCurrentPL.CheckLines(true);
  4161     SetChkBoxAllNone(FCurrentPL.CheckOnlyIfRating(n mod 10, n>9, false));
  4162  end;
  4163  
  4164  (*
  4165   * miLoadPLPackageClick charge un paquetage de PL
  4166   *)
  4167  procedure TSxMSPForm.miLoadPLPackageClick(Sender: TObject);
  4168  begin
  4169     with TOpenDialog.Create(Self) do
  4170     try
  4171        Filter := 'Play List Group|*.m6u';
  4172        DefaultExt := 'm6u';
  4173        InitialDir := ExtractFilePath(ParamStr(0));
  4174        if Execute then
  4175        begin
  4176           LoadPlayList(FileName);
  4177           popupSaveAs.Default := true;
  4178           UpdatePLInfosView;
  4179        end;
  4180     finally
  4181        FIsNoMenuOpen := true;
  4182        Free
  4183     end;
  4184  end;
  4185  
  4186  procedure TSxMSPForm.miActiveKeysClick(Sender: TObject);
  4187  begin
  4188     FIsNoMenuOpen := true;
  4189     miActiveKeys.Checked := not miActiveKeys.Checked;
  4190     FPreferences.isKeysAlwaysActive := miActiveKeys.Checked;
  4191  end;
  4192  
  4193  (*
  4194   * miEraseAllLogsClick supprime tous les fichiers de journalisation
  4195   *)
  4196  procedure TSxMSPForm.miEraseAllLogsClick(Sender: TObject);
  4197  var
  4198     SR : TSearchRec;
  4199     i : integer;
  4200     aPath : string;
  4201  begin
  4202     aPath := ExtractfilePath(ParamStr(0));
  4203     i := FindFirst(aPath+C_LOG_FILE+'*.log', faAnyFile, SR);
  4204     try
  4205        while (i = 0) do
  4206        begin
  4207           DeleteFile(aPath+SR.Name);
  4208           i := FindNext(SR);
  4209        end;
  4210     finally
  4211        FindClose(SR);
  4212     end;
  4213  end;
  4214  
  4215  (*
  4216   * SxMixer1Timer répond à l'événement timer du mixeur
  4217   *)
  4218  procedure TSxMSPForm.SxMixer1Timer(const aRow: Integer; const pPos, pStop,
  4219    tmInterval: Int64);
  4220  var
  4221     t : int64;
  4222  begin
  4223     if (tmInterval > 0) then
  4224     begin
  4225        t := (pStop - pPos)  div 1000;
  4226        LbTrackTimeMLeft.Caption := IntToStr(t div 60);
  4227        LbTrackTimeSLeft.Caption := IntToStr(t mod 60);
  4228     end
  4229     else
  4230     begin  
  4231        LbTrackTimeMLeft.Caption := '';
  4232        LbTrackTimeSLeft.Caption := '';
  4233     end;
  4234  end;
  4235  
  4236  (*
  4237   * miSetPLTitleClick définit le titre d'une PL
  4238   *)
  4239  procedure TSxMSPForm.miSetPLTitleClick(Sender: TObject);
  4240  var
  4241     s1, s : string;
  4242  begin
  4243     try
  4244        FIsNoMenuOpen := true;
  4245        s1 := FCurrentPL.PLTitle;
  4246        s := InputBox('Définition du Titre de la Play List', 'Titre :', s1);
  4247        FCurrentPL.PLTitle := s;
  4248     except
  4249        on E: Exception do
  4250           raise Exception.Create(CE_MENU_SS_RENAME+E.Message);
  4251     end;
  4252  end;
  4253  
  4254  (*
  4255   * miRenamePLClick renomme une PL depuis la lste de groupes
  4256   *)
  4257  procedure TSxMSPForm.miRenamePLClick(Sender: TObject);
  4258  var
  4259     s1, s : string;
  4260     n : integer;
  4261  begin
  4262     if not Assigned(BBGroups.Selected) or (BBGroups.Selected.Tag >= 0) then
  4263        ShowMessage('Cliquez d''abord sur un bouton de Play List ...')
  4264     else
  4265     try
  4266        FIsNoMenuOpen := true;
  4267        n := FCurrentPL.GetPLIndex(-1 * BBGroups.Selected.Tag);
  4268        s1 := FCurrentPL.PLTitles[n];
  4269        s := InputBox('Définition du Titre de la Play List', 'Titre :', s1);
  4270        if (s <> '') then
  4271        begin
  4272           FCurrentPL.PLTitles[n] := s;
  4273           UpdatePLInfosView;
  4274        end;
  4275     except
  4276        on E: Exception do
  4277           raise Exception.Create(CE_MENU_SS_RENAME+E.Message);
  4278     end;
  4279  end;
  4280  
  4281  
  4282  (*
  4283   *
  4284   * Gestionnaires du mixeur
  4285   *
  4286   *)
  4287  
  4288  (*
  4289   * SxMixer1QueryFile répond à une demande de fichier par le mixeur
  4290   *)
  4291  function TSxMSPForm.SxMixer1QueryFile(var aFileName: String; var aRowNum,
  4292    Volume: Integer; var aSR: TSndRange): Boolean;
  4293  begin
  4294     if not FCurrentPL.isValidRow or FCurrentPL.isPlayingRow then
  4295        FCurrentPL.Next;
  4296     FCurrentPL.MarqueCurrent(true);
  4297     aRowNum := FCurrentPL.PlayingIndex;
  4298     aFileName := FCurrentPL.CurrentFileName;
  4299     Volume := FCurrentPL.CurrentVolume;
  4300     aSR.pStart := FCurrentPL.CurrentStart;
  4301     aSR.pStop := FCurrentPL.CurrentStop;
  4302     aSR.pFadeIn := FCurrentPL.CurrentFadeIn;
  4303     aSR.pFadeOut := FCurrentPL.CurrentFadeOut;
  4304     result := FileExists(aFileName);
  4305  end;
  4306  
  4307  (*
  4308   * SxMixer1QueryNextFile répond à une demnade de fichier suivant par le mixeur
  4309   *)
  4310  function TSxMSPForm.SxMixer1QueryNextFile(var aFileName: String;
  4311    var aRowNum, Volume: Integer; var aSR: TSndRange): Boolean;
  4312  begin
  4313     if FCurrentPL.Next then
  4314     begin
  4315        aRowNum := FCurrentGrid.Row;
  4316        aFileName := FCurrentPL.CurrentFileName;
  4317        Volume := FCurrentPL.CurrentVolume;
  4318        aSR.pStart := FCurrentPL.CurrentStart;
  4319        aSR.pStop := FCurrentPL.CurrentStop;
  4320        aSR.pFadeIn := FCurrentPL.CurrentFadeIn;
  4321        aSR.pFadeOut := FCurrentPL.CurrentFadeOut;
  4322     end
  4323     else
  4324     begin
  4325        aFileName := '';
  4326     end;
  4327     result := FileExists(aFileName);
  4328  end;
  4329  
  4330  (*
  4331   * SxMixer1QueryPreviousFile répond à une demande de fichier suivant par le mixeur
  4332   *)
  4333  function TSxMSPForm.SxMixer1QueryPreviousFile(var aFileName: String;
  4334    var aRowNum, Volume: Integer; var aSR: TSndRange): Boolean;
  4335  begin
  4336     if FCurrentPL.Previous then
  4337     begin
  4338        aRowNum := FCurrentGrid.Row;
  4339        aFileName := FCurrentPL.CurrentFileName;
  4340        Volume := FCurrentPL.CurrentVolume;
  4341        aSR.pStart := FCurrentPL.CurrentStart;
  4342        aSR.pStop := FCurrentPL.CurrentStop;
  4343        aSR.pFadeIn := FCurrentPL.CurrentFadeIn;
  4344        aSR.pFadeOut := FCurrentPL.CurrentFadeOut;
  4345     end
  4346     else
  4347     begin
  4348        aFileName := '';
  4349     end;
  4350     result := FileExists(aFileName);
  4351  end;
  4352  
  4353  (*
  4354   *
  4355   * Fin Gestionnaires du mixeur
  4356   *
  4357   *)
  4358  
  4359  procedure TSxMSPForm.miSaveAsCSVChoreTitreArtClick(Sender: TObject);
  4360  begin
  4361     with TSxSaveDialog.Create(Self) do
  4362     try
  4363        Filter := 'Fichier CSV|*.csv';
  4364        DefaultExt := 'csv';
  4365        InitialDir := FPreferences.CSVPath;
  4366        if Execute then
  4367        begin
  4368           FCurrentPL.SaveAsCSVChoreTitre(FileName, false);
  4369           FPreferences.CSVPath := ExtractFilePath(FileName);
  4370        end;
  4371     finally
  4372        FIsNoMenuOpen := true;
  4373        Free
  4374     end;
  4375  end;
  4376  
  4377  procedure TSxMSPForm.miSaveAsCSVBestFillClick(Sender: TObject);
  4378  begin
  4379     with TSxSaveDialog.Create(Self) do
  4380     try
  4381        Filter := 'Fichier CSV|*.csv';
  4382        DefaultExt := 'csv';
  4383        InitialDir := FPreferences.CSVPath;
  4384        if Execute then
  4385        begin
  4386           FCurrentPL.SaveAsCSVChoreTitre(FileName, true); 
  4387           FPreferences.CSVPath := ExtractFilePath(FileName);
  4388        end;
  4389     finally
  4390        FIsNoMenuOpen := true;
  4391        Free
  4392     end;
  4393  end;
  4394  
  4395  procedure TSxMSPForm.miSaveASHTMLAdvPLClick(Sender: TObject);
  4396  begin
  4397     with TSxSaveDialog.Create(Self) do
  4398     try
  4399        Filter := 'Fichier HTML|*.html';
  4400        DefaultExt := 'html';
  4401        InitialDir := FPreferences.HTMLPath;
  4402        if Execute then
  4403        begin
  4404           FCurrentPL.SaveAsHTMLAdvPL(FileName, TMenuItem(Sender).Tag);
  4405           FPreferences.HTMLPath := ExtractFilePath(FileName);
  4406        end;
  4407     finally
  4408        FIsNoMenuOpen := true;
  4409        Free
  4410     end;
  4411  end;
  4412  
  4413  procedure TSxMSPForm.miSaveAsCSVNoClipClick(Sender: TObject);
  4414  begin
  4415     with TSxSaveDialog.Create(Self) do
  4416     try
  4417        Filter := 'Fichier CSV|*.csv';
  4418        DefaultExt := 'csv';
  4419        InitialDir := FPreferences.CSVPath;
  4420        if Execute then
  4421        begin
  4422           FCurrentPL.SaveAsNoClipCSV(FileName);
  4423           FPreferences.CSVPath := ExtractFilePath(Filename);
  4424        end;
  4425     finally
  4426        FIsNoMenuOpen := true;
  4427        Free
  4428     end;
  4429  end;
  4430  
  4431  procedure TSxMSPForm.miForceFindClick(Sender: TObject);
  4432  begin
  4433     miForceFind.Checked := not miForceFind.Checked;
  4434     FPreferences.isForceFind := miForceFind.Checked;
  4435  end;
  4436  
  4437  procedure TSxMSPForm.miPLReplaceModeClick(Sender: TObject);
  4438  begin
  4439     miPLReplaceMode.Checked := not miPLReplaceMode.Checked;
  4440     FPreferences.isPLReplaceMode := miPLReplaceMode.Checked;
  4441  end;
  4442  
  4443  procedure TSxMSPForm.miLoadAsSelectedPLClick(Sender: TObject);
  4444  begin
  4445     FIsNoMenuOpen := true;
  4446     if FileExists(SFV.FileName) then
  4447     begin
  4448        btnPagesClick(btnSelection);
  4449        ActionEmptyGridExecute(Sender);
  4450        LoadPlayList(SFV.FileName);
  4451        SCGSelection.Invalidate;
  4452     end;
  4453  end;
  4454  
  4455  procedure TSxMSPForm.DoOnWSChange(Sender : TObject);
  4456  begin
  4457    PanDirTree.Width := 440;
  4458  end;
  4459  
  4460  procedure TSxMSPForm.miSetPlayerClick(Sender: TObject);
  4461  begin
  4462     with TOpenDialog.Create(Self) do
  4463     try
  4464        InitialDir := GetProgramFilesFolder(Handle);
  4465        Filter := 'Exécutable(*.exe)|*.exe';
  4466        Options := [ofNoChangeDir,ofPathMustExist,ofFileMustExist,ofEnableSizing];
  4467        if Execute then
  4468        begin
  4469           case TMenuItem(Sender).Tag of
  4470              1 : FPreferences.Player1 := FileName;
  4471              2 : FPreferences.Player2 := FileName;
  4472           end;
  4473           SetMIPlayerCaption(TMenuItem(Sender), FileName);
  4474        end;
  4475     finally
  4476        Free;
  4477     end;
  4478  end;
  4479  
  4480  procedure TSxMSPForm.miSetAlwaysExternalClick(Sender: TObject);
  4481  begin
  4482     miSetAlwaysExternal.Checked := (not miSetAlwaysExternal.Checked) and
  4483                                     FileExists(FPreferences.Player2);
  4484     FPreferences.isAlwaysExternalPlayer := miSetAlwaysExternal.Checked;
  4485  end;
  4486  
  4487  procedure TSxMSPForm.miMoveFilesClick(Sender: TObject);
  4488  var
  4489     aDir : string;
  4490  begin
  4491     FIsNoMenuOpen := true;
  4492     aDir := GetWindowsFolder(CSIDL_MYMUSIC);
  4493     if SelectDirectory('Destination', aDir, aDir) then
  4494        with TFmWaiting.Create(nil) do
  4495        try
  4496           ShowWaiting(0, FCurrentGrid.RowCount+1, 0, $00FBB055);
  4497           FCurrentPL.MoveFiles(aDir, false, WaitingPosition);
  4498           WaitingPosition(FCurrentGrid.RowCount+1);
  4499        finally
  4500           Release;
  4501        end;
  4502  end;
  4503  
  4504  procedure TSxMSPForm.EdCommentClick(Sender: TObject);
  4505  begin
  4506     EdComment.Text := '';
  4507  end;
  4508  
  4509  procedure TSxMSPForm.EdCommentKeyUp(Sender: TObject; var Key: Word;
  4510    Shift: TShiftState);
  4511  begin
  4512     if (ssAlt in Shift) and (ssCtrl in Shift) then
  4513        btnKeyUp(Sender, Key, Shift)
  4514     else if (ssCtrl in Shift) then
  4515     begin
  4516        if (Chr(Key) = 'C') then
  4517        begin
  4518           if (EdComment.Text <> '') then
  4519              SCGSelection.Cells[C_COL_FILE, SCGSelection.Row] := EdComment.Text
  4520           else
  4521              FCurrentPL.SetCurrentBestTitle;
  4522           UpdateTitleDisplay(Ord('-'));
  4523           Key := 0;
  4524        end
  4525        else if (Chr(Key) = 'X') then
  4526        begin
  4527           EdComment.Text := '';
  4528        end;
  4529     end
  4530  end;
  4531  
  4532  procedure TSxMSPForm.miAlwaysGoNExtClick(Sender: TObject);
  4533  begin
  4534     miAlwaysGoNExt.Checked := not miAlwaysGoNExt.Checked;
  4535     FPreferences.isAlwaysGoNext := miAlwaysGoNExt.Checked;
  4536  end;
  4537  
  4538  procedure TSxMSPForm.SetMIPlayerCaption(const aMI: TMEnuItem;
  4539                                          const aFileName: string);
  4540  var
  4541     s: string;
  4542  begin
  4543     s := aMI.Caption;
  4544     s := Copy(s, 1, Pos(')', s)) + ' : ' + ExtractFileName(aFileName);
  4545     aMI.Caption := s;
  4546  end;
  4547  
  4548  procedure TSxMSPForm.miReadLogClick(Sender: TObject);
  4549  begin
  4550     with TOpenDialog.Create(nil) do
  4551     try
  4552        Filter := 'Fichier journal|*.log|Fichiers texte|*.txt;*.ini';
  4553        if Execute then
  4554           TFmLogReader.Execute(Self, 'Journal "'+ExtractFileName(FileName)+'"',
  4555                                0, FileName);
  4556     finally
  4557        Free;
  4558     end;
  4559  end;
  4560  
  4561  procedure TSxMSPForm.miOpenCurrentLogClick(Sender: TObject);
  4562  var
  4563     aPath : string;
  4564  begin
  4565     aPath := IncludeTrailingBackSlash(ExtractFilePath(ParamStr(0)));
  4566     FSLLOG.SaveToFile(aPath+C_TMPLOG);
  4567     Application.ProcessMessages;
  4568     Sleep(200);
  4569     TFmLogReader.Execute(Self, 'Journal en cours',
  4570                          0, aPath+C_TMPLOG);
  4571  end;
  4572  
  4573  procedure TSxMSPForm.miHelpClick(Sender: TObject);
  4574  begin
  4575     TFmLogReader.Execute(Self, 'Help : shortcuts',
  4576                          C_RESID_HELP, '');
  4577  end;
  4578  
  4579  procedure TSxMSPForm.miSecureKeyboardClick(Sender: TObject);
  4580  begin
  4581     FEnableKeyParam := miSecureKeyboard.Checked;  //indicateur sécurisé ou non
  4582     FEnableKey := miSecureKeyboard.Checked; // flag pour chaque keypressed
  4583     miSecureKeyboard.Checked := not miSecureKeyboard.Checked;
  4584  end;
  4585  
  4586  procedure TSxMSPForm.RESelectionKeyDown(Sender: TObject; var Key: Word;
  4587    Shift: TShiftState);
  4588  var
  4589     c : char;
  4590  begin
  4591     FEnableKey := FEnableKeyParam or ((ssAlt in Shift) and (ssCtrl in Shift));
  4592     if not FEnableKeyParam and ((ssAlt in Shift) and (ssCtrl in Shift)) then
  4593     begin
  4594        c := Chr(Key);
  4595        SCGKeyPress(Sender, c);
  4596     end;
  4597  end;
  4598  
  4599  (*
  4600   * miLoadClipClick joue le clip associé à une ligne
  4601   *)
  4602  procedure TSxMSPForm.miLoadClipClick(Sender: TObject);
  4603  var
  4604     s : string;
  4605  begin
  4606     s := FCurrentPL.CurrentClipUrl;
  4607     ShellExecute(Handle, 'open', PChar(s), nil, nil, SW_MAXIMIZE);
  4608  end;
  4609  
  4610  (*
  4611   * CmbSoundsChange joue un son d'ambiance
  4612   *)
  4613  procedure TSxMSPForm.CmbSoundsChange(Sender: TObject);
  4614  begin
  4615     FilterGraphTmp.ClearGraph;
  4616     FilterGraphTmp.Active := false;
  4617     if (CmbSounds.ItemIndex > -1) then
  4618     begin
  4619        FIsSpecialSound := true;              
  4620        FilterGraphTmp.Active := true;
  4621        FilterGraphTmp.RenderFile(FSLNames.Strings[CmbSounds.ItemIndex]);
  4622        FilterGraphTmp.Volume := FCurrentVol.Position;
  4623        FilterGraphTmp.Play;
  4624     end;
  4625  end;
  4626  
  4627  (*
  4628   * popFadeOutClick démarre un fade out
  4629   * en réponse à un click sur un item de pop up
  4630   *)
  4631  procedure TSxMSPForm.popFadeOutClick(Sender: TObject);
  4632  begin
  4633     FadeOut(TMEnuItem(Sender).Tag);
  4634  end;
  4635  
  4636  
  4637  
  4638  end.
  4639  
  4640  
  4641  
  4642