FileLink : Téléchargement de fichier et menu contextuel
Par -Alexandre LEGOUT aka LAlex- le 26 septembre 2005, 11:51 - AS2 - Lien permanent
En tant qu'utilisateur, je trouve parfois assez exaspérant de devoir ouvrir, par exemple, un fichier PDF dans mon navigateur. Je préfère largement le télécharger et l'ouvrir avec Acrobat Reader...
Lorsqu'il s'agit d'un lien dans une page HTML, il est facile d'utiliser un clic droit (ou CTRL pour les maceux) pour pouvoir choisir entre l'ouvrir réellement ou le télécharger. Par contre, dans un site Flash c'est plus délicat...
C'es pourquoi j'ai créé vite-fait une petite classe qui permet d'assigner à un clip un menu contextuel qui va permettre soit d'ouvrir, soit de télécharger un fichier déterminé. Elle est basique pour l'instant, mais l'on peut prévoir de la faire évoluer avec quelques options (localisation, cible du getURL, comportement par défaut du onRelease, etc...).
A noter que le téléchargement ne fonctionne que dans un environnement HTTP (cela est du aux restrictions de la classe FileReference), donc on oublie le test dans l'IDE Flash ou dans une page HTML accédée directement depuis le disque dur... ![]()
import flash.net.FileReference;
Et voici son utilisation (celle du bouton ci-dessous)
import mx.utils.Delegate;
/**
* FileLink
*
* @notice Can only be used in HTTP environment due to FileReference restrictions
* @author <a href="http://www.lalex.com/">LAlex</a>
* @version 1.0
* @since
*/
class com.lalex.utils.FileLink {
// File path
private var _path:String;
function FileLink(f:String) {
_path = f;
}
/**
* Assign a link to a movieclip, setting its context menu
*
* @usage fLink.assignTo(myLinkButton, true, true);
* @param clip MovieClip to click to obtain download menu
* @param setRelease Set the onRelease handler of the clip ?
* @param hide Hide context menu builtin items ?
*/
function assignTo(clip:MovieClip, setRelease:Boolean, hide:Boolean) {
hide = !!hide;
setRelease = !!setRelease;
var dl:Function = Delegate.create(this, this.download);
var op:Function = Delegate.create(this, this.open);
var m:ContextMenu = new ContextMenu();
m.customItems.push(new ContextMenuItem("Ouvrir", op));
m.customItems.push(new ContextMenuItem("Télécharger", dl));
if (hide)
m.hideBuiltInItems();
if (setRelease)
clip.onRelease = op;
clip.menu = m;
}
/**
* Open a file in the browser
* Used by a proxy (Delegate) function
*/
private function open() {
getURL(_path);
}
/**
* Dowload the file to the local computer
* Used by a proxy (Delegate) function
*/
private function download() {
var f:FileReference = new FileReference();
f.download(_path);
}
}import com.lalex.utils.FileLink;
var fl:FileLink = new FileLink("files/FileLink.zip");
fl.assignTo(bt, true, true);
Commentaires
Hello

Je n'ai pas compris le !!hide au début de ta méthode assignToClip ? cela revient pas au même que de ne pas le mettre du tout ?
Sinon tu pourrais aussi par exemple détecter si ton clip possède déjà dans son menu contextuel des items et dans ce cas permettre d'ajouter au besoin une barre de séparation avant le ouvrir et le télécharger. Car là tu écrases tout menu contextuel existant et cela peut être un peu génant à l'occasion
Sinon dans Flash 8 j'ai pas vu si il était maintenant possible de déterminer rapidement si tu es dans un IDE, dans une page web etc.. pour ma part j'utilise une classe pour faire cela inspirée à 200% de la classe AS1 de Zwetan "Application"
/* ------ ApplicationName : Application
Package : eka.core
Version : 1.0.0.0
Date : 2005-09-15
Author : ekameleon
URL : <a href="http://www.ekameleon.net" rel="nofollow">http://www.ekameleon.net</a>
Mail : <a href="mailto:contact@ekameleon.net" rel="nofollow">contact@ekameleon.net</a>
METHODS
Application.isWeb : renvoie true si le fichier SWF est chargé
dans une page web avec le protocole HTTP ou HTTPS.
Application.isOnline : renvoie true si le fichier SWF est chargé
depuis internet avec n'importe quel protocole (HTTP, HTTPS ou FTP).
Application.isLocal : renvoie true si le fichier SWF est chargé
depuis un fichier local (c-a-d utilisation du protocole FILE).
Application.isLocalWeb : renvoie true si le fichier est local et si on peut detecter
la présence d'un moyen de communication entre le player flash et
une aide a l'accessiblité.
Note: fonctionne avec IE sur windows, non testé autres navigateurs et autres systemes.
Application.isProjector : renvoie true, si le fichier est local mais
n'est ni le flash IDE ni une page web locale.
Application.getIDEPath : renvoie le chemin du logiciel d'authoring Flash
si le fichier SWF est détecté étant en mode IDE.
THANKS : Zetwan [FMX] flash dans plusieurs environnements.
COPYRIGHT
Cette création est mise à disposition selon le Contrat Paternité
- Pas d'Utilisation Commerciale
- Partage des Conditions Initiales à l'Identique disponible en ligne
<a href="http://creativecommons.org/licenses/by-nc-sa/2.0/fr/" rel="nofollow">http://creativecommons.org/licenses/by-nc-sa/2.0/fr/</a>
ou par courrier postal à Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
------ */
class eka.core.Application {
// ----o Author Properties
public static var className:String = "Application" ;
public static var classPackage:String = "eka.core";
public static var version:String = "1.0.0.0";
public static var author:String = "ekameleon";
public static var link:String = "<a href="http://www.ekameleon.net" rel="nofollow">http://www.ekameleon.net</a>" ;
// ----o Constructor
private function Application() {}
// ----o Methods
static public function getFullPath(Void):String {
return _level0._url ;
}
static public function getProtocol(Void):String {
return Application.getFullPath().split("://")[0] ;
}
static public function isFlashIDE(Void):Boolean {
return( _level0.$appPath != null );
}
static public function isWeb(Void):Boolean {
var protocol:String = Application.getProtocol();
return( (protocol == "http") || (protocol == "https") ) ;
}
static public function isOnline(Void):Boolean {
var protocol:String = Application.getProtocol() ;
return ( (protocol == "ftp") || Application.isWeb() );
}
static public function isLocal(Void):Boolean {
var protocol:String = Application.getProtocol();
return( protocol == "file" );
}
static public function isLocalWeb(Void):Boolean {
var activeX = System.capabilities.hasAccessibility ;
return( Application.isLocal() && (activeX == true) ) ;
}
static public function isProjector(Void):Boolean {
return(
Application.isLocal() &&
!Application.isFlashIDE() &&
!Application.isLocalWeb()
) ;
}
static public function getIDEPath(Void):String {
return (Application.isFlashIDE()) ? _level0.$appPath : "" ;
}
}
Cela peut être intéressant à mon avis de restreindre l'utilisation via un try..catch de tes méthodes en cas d'utilisation dans un environnement pas compatible avec la classe FileReference
Sinon à ce que je vois il y a un système événmentiel pour gérer les HTML error etc.. faudrait voir sinon à mettre un système événmentiel pour notifier l'utlisateur qu'il peut pas utiliser le download où il se trouve ? .. enfin c'est des idées hein 
EKA+
ca a l'air bien pratique comme petite classe, c'est dommage que le telechargement ne fonctionne pas
Voila en fait ca marche nickel chez moi mais il a fallu que je passe l'objet fileReference en tant que membre de la classe fileLink... Et ce n'est pas la premiere fois que je rencontre ce probleme avec cette classe, par contre je ne comprend pas pourquoi si quelqu'un a des explication , merci
Fil des commentaires de ce billet