/*
 * * * Compile_AHK SETTINGS BEGIN * * *


[AHK2EXE]
Exe_File=%In_Dir%\..\FramaUpdate.exe
Execution_Level=2
[VERSION]
Set_Version_Info=1
Company_Name=Framakey
File_Description=Utilitaire de mise à jour d'Asuite et du Kiosk (post SynApps)
File_Version=0.8.0.4
Inc_File_Version=1
Internal_Name=FramaUpdate
Legal_Copyright=(C) 2005-2011 Framakey
Original_Filename=FramaUpdate.exe
Product_Name=FramaUpdate
Product_Version=2.1.0.4
Inc_Product_Version=1
[ICONS]
Icon_1=%In_Dir%\FramaUpdate.ico
Icon_2=0
Icon_3=0
Icon_4=0
Icon_5=0
Icon_6=0
Icon_7=0

* * * Compile_AHK SETTINGS END * * *
*/

; --------------------------------------------------------------------------------------------------
; 									FramaUpdate 0.8.0.0
; --------------------------------------------------------------------------------------------------
; Par fat115
; Utilisant comme base de travail les scripts AutoIt de pyg
; License : GPL
; Ce script permet de créer FramaUpdate.
; Utilitaire de mise à jour d'Asuite et du Kiosk (post SynApps)

; Fonctions du script:
;	Ouvre ASuite.xml, et vérifie que toutes les applis de /Apps y sont présentes sinon le script
;	propose de les ajouter.
;	Il lance également SynApps si le paramètre -synapps est passé.
; 	Et finalement, il vérifie l'existence des dossiers, fichiers, interroge l'utilisateur en cas de
;	défaut et met à jour les chemins.
; Compiler: AutoHotkey_L (1.0.92.2+) (http://www.autohotkey.net/~Lexikos/AutoHotkey_L/).

; $id=FramaUpdate.ahk $date=2013-08-08
; --------------------------------------------------------------------------------------------------

;Copyright (C) 2005-2013 Framakey

;Website: http://www.framakey.org

;This software is OSI Certified Open Source Software.
;OSI Certified is a certification mark of the Open Source Initiative.

;This program is free software; you can redistribute it and/or
;modify it under the terms of the GNU General Public License
;as published by the Free Software Foundation; either version 2
;of the License, or (at your option) any later version.

;This program is distributed in the hope that it will be useful,
;but WITHOUT ANY WARRANTY; without even the implied warranty of
;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
;GNU General Public License for more details.

;You should have received a copy of the GNU General Public License
;along with this program; if not, write to the Free Software
;Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA	02110-1301, USA.
; ----------------------------------------------------
#NoEnv
#SingleInstance IGNORE

#Include %A_ScriptDir%\AhkIncludes
#Include Functions.ahk
#Include ini.ahk
#Include grep.ahk
#Include CalcRelPath.ahk
#Include ConvBoolNum.ahk
#Include FU_Functions.ahk

#NoTrayIcon
SetWorkingDir, %A_ScriptDir%
FileEncoding, UTF-8
StringCaseSense, Locale

MainSection:

; Initialisation
s_ThisAppName := A_ScriptName
StringTrimRight, s_ThisAppName, s_ThisAppName, 4

; Lecture de Framakey2.ini
ini_load(s_FKIniFile, "Framakey2.ini", "UTF-8")
p_AppsDir := ini_getValue(s_FKIniFile, s_ThisAppName, "RelAppsDir")
p_KioskPagesDir := ini_getValue(s_FKIniFile, s_ThisAppName, "RelKioskPagesDir")
p_ASuitePath := ini_getValue(s_FKIniFile, "Main", "RelASuiteDir")
b_SynAppsAvert := ConvB2N(ini_getValue(s_FKIniFile, "Tutorials", "SynAppsAvert"))
p_SynAppsDir := ini_getValue(s_FKIniFile, s_ThisAppName, "RelSynAppsDir")
f_SynAppsLauncher := ini_getValue(s_FKIniFile, s_ThisAppName, "SynAppsLauncher")
b_SortingApps := ConvB2N(ini_getValue(s_FKIniFile, "Main", "IsMainProject"))
f_IniStarter := ini_getValue(s_FKIniFile, "Main", "RelMainLauncherName") . ".ini"
b_UpdateAvert := ConvB2N(ini_getValue(s_FKIniFile, s_ThisAppName, "AskUserBeforeUpdate"))
p_RelKPages2Apps := StringReplace(CalcRelPath(p_KioskPagesDir, p_AppsDir, A_ScriptDir), "\", "/", "All") . "/"

; Lecture de Framakey.ini
ini_load(s_FSIniFile, f_IniStarter, "UTF-8")
b_IsLaunchedAsuite := ConvB2N(ini_getValue(s_FSIniFile, "MainApps", "LaunchFramaSuite"))
b_IsLaunchedKiosk := ConvB2N(ini_getValue(s_FSIniFile, "MainApps", "LaunchFramaKiosk"))

b_NotAvert := !b_SynAppsAvert
f_ASuiteXML := p_ASuitePath . "\ASuite.xml"
f_SynAppsExec := p_SynAppsDir . "\" . f_SynAppsLauncher
s_DebugMsg := ""

; Vérification des paramètres
Gosub VerifParam

; Vérification des chemins
Gosub VerifFoldersFiles

; les vérifications étant faites, on peut calculer les autres lanceurs de SynApps
f_SynAppsUpdaterExec := p_SynAppsDir . "\" . StringReplace(f_SynAppsLauncher, "Portable", "UpdaterPortable")
f_SynAppsInstallerExec := p_SynAppsDir . "\" . StringReplace(f_SynAppsLauncher, "Portable", "InstallerPortable")

; Maintenant on peut associer une sous-routine en testant chacune des variables (humm, il se peut que ça n'évolue jamais)
; En cas d'ajout, penser à ajouter aussi dans VerifFoldersFiles
If b_PreLaunchSynApps
	Gosub SynAppsUpdater
If b_PreLaunchSynAppsUp
	Gosub SynAppsUpdateAll
If b_PreLaunchShare
	Gosub ExportImportDialog

; On ouvre le fichier de conf Asuite et on récupère le nom personnalisé de la fenêtre
f_AsuiteTempXML := p_ASuitePath . "\AsuiteTemp.xml"
; Petite précaution au cas où ASuite soit déjà lancé et que l'utilisateur ait changé le titre
; de la fenêtre : on prend prioritairement les infos dans le fichier de conf temporaire.
IfExist, %f_AsuiteTempXML%
	{
	Process, Exist, asuite.exe
	If ErrorLevel
		FileRead, s_ASuiteXMLContent, %f_AsuiteTempXML%
	Else
		{
		FileMove, %f_AsuiteTempXML%, %f_ASuiteXML%, 1
		FileRead, s_ASuiteXMLContent, %f_ASuiteXML%
		}
	}
Else
	FileRead, s_ASuiteXMLContent, %f_ASuiteXML%
; On récupère le nom personnalisé de la fenêtre dans ASuite(Temp)XML
FoundPos := RegExMatch(s_ASuiteXMLContent, "<CustomTitleString>(.*)</CustomTitleString>", s_CustomTitleXML)
s_ASuiteWindowName := s_CustomTitleXML1

; Récupération des catégories d'Asuite
_Needle = <Category name="(.*?)">
grep(s_ASuiteXMLContent, _Needle, s_ASuiteCat, 1, 1, "`n")
; Extraction des applis du dossier /Apps/ (ou équivalent) déclarés dans ASuite
SplitPath, p_AppsDir, s_ShortAppsDir
_Needle = <PathExe>.*?\\%s_ShortAppsDir%\\.*?\\(.*?)\.exe</PathExe>
grep(s_ASuiteXMLContent, _Needle, s_ASuiteSoft, 1, 1, "`n")

; Récupération des catégories du Kiosk et des correspondances avec les fichiers html
FileRead, s_KioskIndex, %p_KioskPagesDir%\index.html
_Needle = <li page=.*?/(.*?)\.html.*?>(.*?)<
grep(s_KioskIndex, _Needle, s_KioskHtml, 1, 1, "`n")
grep(s_KioskIndex, _Needle, s_KioskCat, 1, 2, "`n")
o_ListKioskCat := Object()
StringSplit, _Cathtml, s_KioskHtml, `n
StringSplit, _Catname, s_KioskCat, `n
; Si le nombre de fichiers trouvés ne correspond pas au nombre de noms de catégories, on sort
If (_Cathtml0 != _Catname0)
	{
	MsgBox, 16, Erreur., Le fichier %p_KioskPagesDir%\index.html parait malformé.`n%s_ThisAppName% ne peut continuer., 5
	ExitApp
	}
Loop, %_Cathtml0%
	{
	o_ListKioskCat.Insert(_Catname%A_Index%, _Cathtml%A_Index%)
	; Libération mémoire
	_Catname%A_Index% =
	_Cathtml%A_Index% =
	}
; Extraction des applis déclarées en se basant sur le nom du fichier lch
s_KioskSoft =
For k, v in o_ListKioskCat
	{
	FileRead, _Tampon, %p_KioskPagesDir%\%v%.html
	_Needle = <div class="app" lch="lch/Apps/(.*?)\.lch"
	grep(_Tampon, _Needle, _Softs, 1, 1, "`n")
	If _Softs
		s_KioskSoft .= (!s_KioskSoft) ? _Softs : "`n" _Softs
	}

; On récupère la liste des dossiers de /Apps
o_ListAppsFolder := Object()
s_ListAllApps := GetPortableApps(p_AppsDir, o_ListAppsFolder)

; Tri des listes des aplis
Sort, s_ASuiteSoft, U
Sort, s_KioskSoft, U
Sort, s_ListAllApps, U
; Traitement pour ASuite
SearchDiffApps(s_ASuiteSoft, s_ListAllApps, s_RemovedAppsASuite, s_NewAppsASuite)
; Traitement pour Kiosk
SearchDiffApps(s_KioskSoft, s_ListAllApps, s_RemovedAppsKiosk, s_NewAppsKiosk)

 ; On vérifie que l'utilisateur veut poursuivre
Gosub AskUser

Gosub CloseASuite

; Si s_RemovedAppsASuite n'est pas vide, on enlève les noeuds correspondants
If s_RemovedAppsASuite
	s_ASuiteXMLContent := RemoveNodes(s_ASuiteXMLContent, s_RemovedAppsASuite)
; Si s_NewAppsASuite n'est pas vide, on créée les noeuds correspondants
If s_NewAppsASuite
	s_ASuiteXMLContent := CreateAddNodes(s_ASuiteXMLContent, s_NewAppsASuite)

; Si s_RemovedAppsKiosk n'est pas vide, on enlève les div correspondants
If s_RemovedAppsKiosk
	RemoveDivKiosk(s_RemovedAppsKiosk)
; Si s_NewAppsKiosk n'est pas vide, on ajoute les div correspondants
If s_NewAppsKiosk
	AddDivKiosk(s_NewAppsKiosk)

FileMove, %f_ASuiteXML%, %f_ASuiteXML%.bak, 1 ;on backup
FileAppend, %s_ASuiteXMLContent%, %f_ASuiteXML%, UTF-8-RAW ; on met en place la version modifiée

; On relance ASuite
If b_IsLaunchedAsuite
	Gosub LaunchASuite

; On rafraichit le Kiosk
If b_IsLaunchedKiosk
	Gosub RefreshKiosk

ini_save(s_FKIniFile, "Framakey2.ini", "UTF-8")

ExitApp
Return


;===============================================================================
; Subroutine Name:	VerifParam
; Description:		Vérification de la validité des paramètres
;===============================================================================
VerifParam:
{
	Loop, %0%
		{
		s_Param%A_Index% := %A_Index%
		; par sécurité, on passe tout en minuscule
		StringLower, Param%A_Index%, s_Param%A_Index%
		If s_Param%A_Index% not in -help,/?,-synapps,-synupdate,-share
			{
			i_MessageIcon := 16
			s_UnknownParam := "Paramètre inconnu : " . s_Param%A_Index%
			Gosub MessageUsage
			}
		If s_Param%A_Index% in -help,/?
			{
			i_MessageIcon := 64
			s_UnknownParam := "Vous avez crié au secours. Voilà un peu d'aide :"
			Gosub MessageUsage
			}
		; On définit une variable pour chacun des paramètres possibles
		If (s_Param%A_Index% = "-synapps")
			b_PreLaunchSynApps := 1
		If (s_Param%A_Index% = "-synupdate")
			b_PreLaunchSynAppsUp := 1
		If (s_Param%A_Index% = "-share")
			b_PreLaunchShare := 1
		}
Return
}

;===============================================================================
; Subroutine Name:	VerifFoldersFiles
; Description:		Vérification de la validité des paramètres
;===============================================================================
VerifFoldersFiles:
{
	IfNotExist, %f_ASuiteXML%
		{
		p_TempPath := ""
		FileSelectFile, p_TempPath, 1, %A_ScriptDir%, Impossible de trouver le fichier de configuration d'ASuite.`nVeuillez le sélectionner :, Configuration ASuite (ASuite.xml)
		If (p_TempPath = "")
			{
			MsgBox, 16, Erreur., Le fichier est introuvable.`n%s_ThisAppName% ne peut continuer., 5
			ExitApp
			}
		; Calcul du chemin relatif
		f_ASuiteXML := CalcRelPath(A_ScriptDir, p_TempPath)
		SplitPath, f_ASuiteXML, , p_ASuitePath
		; On sauve les valeurs dans l'ini
		ini_replaceValue(s_FKIniFile, "Main", "RelASuiteDir", p_ASuitePath)
		}
	IfNotExist, %p_AppsDir%
		{
		p_TempPath := ""
		FileSelectFolder, p_TempPath, *%A_ScriptDir%, 0, Le dossier Apps est introuvable.`nChoisissez le dossier contenant vos applications portables :
		If ErrorLevel
			{
			MsgBox, 16, Erreur., Le dossier est introuvable.`n%s_ThisAppName% ne peut continuer., 5
			ExitApp
			}
		; Calcul du chemin relatif
		p_AppsDir := CalcRelPath(A_ScriptDir, p_TempPath)
		ini_replaceValue(s_FKIniFile, "FramaUpdate", "RelAppsDir", p_AppsDir)
		}
	; Bourrin, on recalcule systématiquement p_Asuite2AppsPath
	p_Asuite2AppsPath := CalcRelPath(p_ASuitePath, p_AppsDir)
	; On ne s'occupe de SynApps que s'il y a besoin
	If (b_PreLaunchSynApps or b_PreLaunchSynAppsUp or b_PreLaunchSynAppsInst)
		{
		IfNotExist, %f_SynAppsExec%
			{
			p_TempPath := ""
			FileSelectFile, p_TempPath, 1, %A_ScriptDir%, Sélectionnez le lanceur portable de SynApps, Lanceur portable (*Portable.exe)
			If !p_TempPath
				{
				; Possibilité de prévoir une récupération automatique de PortableSynApps
				; MsgBox, 4, %s_ThisAppName%, SynAppsPortable n'est apparemment pas présent sur votre Framakey.`nVoulez-vous le récupérer automatiquement ?`n`nAttention : Vous devez être connecté à Internet.
				; IfMsgBox, Yes
				; 	Gosub AutoInstPortSynApps
				; Else IfMsgBox, No
				; 	{
					MsgBox, 16, Erreur., Le fichier est introuvable.`n%s_ThisAppName% ne peut continuer., 5
					ExitApp
				; 	}
				}
			; Calcul du chemin relatif
			f_SynAppsExec := CalcRelPath(A_ScriptDir, p_TempPath)
			SplitPath, f_SynAppsExec, f_SynAppsLauncher, p_RelSynAppsDir
			; On sauve les valeurs dans l'ini
			ini_replaceValue(s_FKIniFile, "FramaUpdate", "RelSynAppsDir", p_RelSynAppsDir)
			ini_replaceValue(s_FKIniFile, "FramaUpdate", "SynAppsLauncher", f_SynAppsLauncher)
			}
		}
Return
}

;===============================================================================
; Subroutine Name:	MessageUsage
; Description:		Pop-up expliquant succinctement les options possibles
;===============================================================================
MessageUsage:
{
	s_HelpMessage := s_UnknownParam . "`n`n"
	s_HelpMessage .= s_ThisAppName . " met à jour le menu en fonction des nouvelles applications`n\n"
	s_HelpMessage .= "Options supportées :`n"
	s_HelpMessage .= "-help : Affiche cet écran d'aide.`n"
	s_HelpMessage .= "/? : Affiche cet écran d'aide aussi.`n"
	s_HelpMessage .= "-synapps : Lance SynApps avant la mise à jour du menu.`n"
	s_HelpMessage .= "-synupdate : Lance les mises à jour des applications via SynApps.`n"
	s_HelpMessage .= "-share : Affiche le dialogue d'import/export des applis.`n"
	MsgBox, %i_MessageIcon%, Options supportées, %s_HelpMessage%
	ExitApp
Return
}

;===============================================================================
; Subroutine Name:	SynAppsUpdater
; Description:		Lancement de SynApps avant la mise à jour du menu
;===============================================================================
SynAppsUpdater:
{
	If b_SynAppsAvert
		Gosub GuiAvertSynApps
	RunWait, %f_SynAppsExec%
Return
}

;===============================================================================
; Subroutine Name:	SynAppsUpdateAll
; Description:		Lancement de SynAppsUpdater
;===============================================================================
SynAppsUpdateAll:
{
	If b_SynAppsAvert
		Gosub GuiAvertSynApps
	; pas la peine de mettre à jour les menus
	Run, %f_SynAppsUpdaterExec%
	ExitApp
Return
}

GuiAvertSynApps:
{
	Gui, Add, CheckBox, x6 y92 w120 h30 Checked%b_NotAvert% vb_Avert, Ne plus m'avertir
	Gui, Add, Button, x266 y92 w80 h30 gMaJAvert, OK
	Gui, Font, S15 CDefault, Verdana
	Gui, Add, Text, x6 y2 w350 h80 +Center, Une fois vos applications ajoutées`, quittez SynApps en cliquant sur la croix en haut.
	; Generated using SmartGUI Creator 4.0
	Gui, Show, Center h130 w360, Avertissement !
	WinWaitClose, Avertissement !
Return
}

MaJAvert:
{
	Gui, Submit
	b_NotAvert := ConvN2B(!b_Avert)
	ini_replaceValue(S_FKIniFile, "Tutorials", "SynAppsAvert", b_NotAvert)
	Gui, Destroy
Return
}


;===============================================================================
; Subroutine Name:	AskUser
;Description:		Demande à l'utilisateur s'il confirme la mise à jour
;===============================================================================
AskUser:
{
	s_Synthese := ""
	If s_NewAppsASuite
		{
		s_Synthese .= "Applications ajoutées à FramASuite :`n"
		s_Synthese .= s_NewAppsASuite . "`n"
		}
	If s_RemovedAppsASuite
		{
		s_Synthese .= "Applications enlevées de FramASuite :`n"
		s_Synthese .= s_RemovedAppsASuite . "`n"
		}
	If s_NewAppsKiosk
		{
		s_Synthese .= "Applications ajoutées au FramaKiosk :`n"
		s_Synthese .= s_NewAppsKiosk . "`n"
		}
	If s_RemovedAppsKiosk
		{
		s_Synthese .= "Applications enlevées du FramaKiosk :`n"
		s_Synthese .= s_RemovedAppsKiosk . "`n"
		}
	If s_Synthese
		s_Synthese .= "Vous pouvez désactiver ce message dans les préférences."
	If (s_Synthese = "")
		{
		MsgBox, 64, %s_ThisAppName%, Aucun changement n'a été détecté., 3
		ExitApp
		}
	If b_UpdateAvert
		{
		MsgBox, 65, %s_ThisAppName%, %s_Synthese%
		IfMsgBox OK ; on continue
			Return
		Else
			ExitApp
		}
Return
}

;===============================================================================
; Subroutine Name:	 CloseASuite
; Description:		Quitte la FramASuite si elle est toujours active
;===============================================================================
CloseASuite:
{
	WinShow, %s_ASuiteWindowName%
	IfWinExist, %s_ASuiteWindowName%
		{
		Progress, B1 ZH0 FM14 CW5b5da9 CTc4c4ff,, Fermeture en cours, %s_ThisAppName%
		WinActivate, %s_ASuiteWindowName%
		Send !f
		Send q
		Process, WaitClose, ASuite.exe, 10
		If ErrorLevel
			{
			Progress, Off
			MsgBox, 48, %s_ThisAppName%, Impossible de fermer toutes les instances d'ASuite.`nVeuillez les fermer manuellement.
			Process, WaitClose, ASuite.exe
			}
		Sleep, 2000
		Progress, Off
		}
Return
}

;===============================================================================
; Subroutine Name:	 LaunchASuite
; Description:		Lance la FramASuite si elle n'est pas déjà active
;===============================================================================
LaunchASuite:
{
	Progress, B1 ZH0 FM14 CW5b5da9 CTc4c4ff,, Démarrage de la FramASuite, %s_ThisAppName%
	Run, %p_ASuitePath%\ASuite.exe
	Sleep, 2000
	Progress, Off
Return
}


;===============================================================================
; Subroutine Name:	RefreshKiosk
; Description:		Recharge le Kiosk s'il est actif
;===============================================================================
RefreshKiosk:
{
	WinShow, FramaKiosk
	IfWinExist, FramaKiosk
		{
		Progress, B1 ZH0 FM14 CW5b5da9 CTc4c4ff,, Rafraichissement du Kiosk, %s_ThisAppName%
		WinActivate, FramaKiosk
		Send ^r
		}
	Sleep, 2000
	Progress, Off
Return
}


;===============================================================================
; Subroutine Name:	AutoInstPortSynApps
; Description:		Installation automatique de PortableSynApps
;===============================================================================
AutoInstPortSynApps:
{
Return
}

; ================================================================================
;					 Gestion de la Fenêtre Export/Import
; ================================================================================
ExportImportDialog:
{
	; On récupère la liste des dossiers de /Apps
	o_ListAppsFolderShare := Object()
	GetPortableApps(p_AppsDir, o_ListAppsFolderShare)
	s_ListAllAppsShare := ""
	; _key contient le nom du lanceur, _value le nom du dossier. On ne récupère que les dossiers, pas besoin des lanceurs qui peuvent être multiples (LibO par exemple)
	For _key, _value in o_ListAppsFolderShare
		s_ListAllAppsShare .=  (!s_ListAllAppsShare) ? _value : "`n" _value
	Sort, s_ListAllAppsShare, U
	; on a maintenant une liste triée ne contenant que des applis uniques
	Gui, Add, Tab, x6 y7 w430 h500 , Export|Import
	Gui, Tab, Export
		{
		Gui, Add, Text, x16 y37 w320 h20 , Sélectionnez les applications à exporter puis cliquez sur le bouton.
		Gui, Add, Button, x346 y37 w80 h20 vb_Export gLanceExport, Exporter
		Gui, Add, Button, x16 y67 w50 h20 vb_ExportAll gExportCheckAll, Tout
		Gui, Add, Button, x76 y67 w50 h20 vb_ExportNone gExportCheckNone, Aucun
		Gui, Add, ListView, x16 y87 w400 h410 Checked Multi Grid vlv_Export, Application
		; remplissage de la ListView avec le nom des applis portables, par défaut on coche
		Loop, parse, s_ListAllAppsShare, `n, `r
			LV_Add("Check", A_LoopField)
		}
	Gui, Tab, Import
		{
		Gui, Add, Text, x16 y37 w150 h20 , Sélectionnez le fichier d'import :
		Gui, Add, Edit, x176 y37 w200 h20 ReadOnly vf_ImportFile,
		Gui, Add, Button, x386 y37 w40 h20 vb_ImportFile gChooseImportfile, ...
		Gui, Add, ListView, x16 y67 w400 h370 Checked Multi Grid vlv_Import , Application
		Gui, Add, Button, x16 y447 w60 h20 vb_ImportAll gImportCheckAll, Tout
		Gui, Add, Button, x86 y447 w60 h20 vb_ImportNone gImportChecknone, Aucun
		Gui, Add, Text, x16 y477 w280 h20 , Sélectionnez les applications voulues puis lancez l'import.
		Gui, Add, Button, x306 y477 w120 h20 vb_Import gLanceImport, Importer
		}
	; Generated using SmartGUI Creator 4.0
	Gui, Show, Center h520 w448, Export - Import
	WinWaitClose, Export - Import
Return
}

; ====================================================
;					 Routines d'export
; ====================================================
ExportImportDialogClose:
ExitApp

ExportCheckAll:
{
	Gui, ListView, lv_Export
	LV_Modify(0, "Check")
Return
}

ExportCheckNone:
{
	Gui, ListView, lv_Export
	LV_Modify(0, "-Check")
Return
}

LanceExport:
{
	Gui, ListView, lv_Export
	s_ListExportApps := ""
	_RowNumber = 0
	Loop
		{
		; On itère sur les lignes cochées
		_RowNumber := LV_GetNext(_RowNumber, "C")
		If Not _RowNumber
			break
		LV_GetText(_Appli, _RowNumber)
		; On concatène l'appli trouvée à la liste
		s_ListExportApps .=  (!s_ListExportApps) ? _Appli : "`n" _Appli
		}
	_File := FileSelectFile("S", A_ScriptDir "\Export_" A_Now ".fmk", "Sélectionnez une destination", "Fichiers échange FramaKey (*.fmk)")
	If !_File
		{
		MsgBox, On verra plus tard alors !
		Return
		}
	Else
		{
		FileDelete, %_File%
		FileAppend, %s_ListExportApps%, %_File%
		If ErrorLevel
			{
			MsgBox, 0, FramaShare, Une erreur s'est produite !, 5
			Return
			}
		Else
			{
			MsgBox, 0, FramaShare, Le fichier a été correctement enregistré., 5
			ExitApp
			}
		}
Return
}

; ====================================================
;					 Routines d'import
; ====================================================
ImportCheckAll:
{
	Gui, ListView, lv_Import
	LV_Modify(0, "Check")
Return
}

ImportCheckNone:
{
	Gui, ListView, lv_Import
	LV_Modify(0, "-Check")
Return
}

LanceImport:
{
	Gui, ListView, lv_Import
	s_ListImportApps := ""
	_RowNumber = 0
	Loop
		{
		; On itère sur les lignes cochées
		_RowNumber := LV_GetNext(_RowNumber, "C")
		If Not _RowNumber
			break
		LV_GetText(_Appli, _RowNumber)
		; On concatène l'appli trouvée à la liste
		s_ListImportApps .=  (!s_ListImportApps) ? _Appli : " " _Appli
		}
	; on ne prévient pas l'utilisateur pour la fermeture de SynApps : 1 - il est sensé savoir ce qu'il fait, 2 - ça poserait problème avec la GUI d'avertissement
	RunWait, %f_SynAppsInstallerExec% %s_ListImportApps%
	; on revient maintenant à la procédure classique de mise à jour des menus du Kiosk et de Asuite
	Gui, Destroy
Return
}

ChooseImportfile:
{
	Gui, ListView, lv_Import
	_File := FileSelectFile(1, A_ScriptDir , "Sélectionnez un fichier à importer", "Fichiers échange FramaKey (*.fmk)")
	If !_File
		{
		MsgBox, On verra plus tard alors !
		Return
		}
	Else
		{
		s_ListImportApps := FileRead(_File)
		; On ajoute uniquement si absent
		Loop, parse, s_ListImportApps, `n, `r
			IfNotInString, s_ListAllAppsShare, %A_LoopField%
				LV_Add("Check", A_LoopField)
		}
	GuiControl, , f_ImportFile, %_File%
		
Return
}




