/******************************************************************************* * Copyright (c) 2014 Mentor Graphics and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Mentor Graphics - initial API and implementation *******************************************************************************/ package com.codesourcery.internal.installer.actions; import java.io.File; import java.io.PrintStream; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.equinox.p2.core.IProvisioningAgent; import org.w3c.dom.Document; import org.w3c.dom.Element; import com.codesourcery.installer.IInstallMode; import com.codesourcery.installer.IInstallProduct; import com.codesourcery.installer.Installer; import com.codesourcery.internal.installer.InstallMessages; import com.codesourcery.internal.installer.InstallUtils; /** * Action to install and uninstall Unity launcher (.desktop) files. */ public class UnityShortcutAction extends ShortcutAction { /** Action identifier */ private static final String ID = "com.codesourcery.installer.unityShortcutAction"; /** Dash attribute */ private static final String ATTRIBUTE_LAUNCHER = "launcher"; /** Unity desktop file attribute */ private static final String ATTRIBUTE_DESKTOP = "desktop"; /** <code>true</code> if this a unity desktop file */ protected boolean isDesktopFile = true; /** <code>true</code> if Ubuntu Unity Dash short-cut, <code>false</code> * if desktop short-cut. */ protected boolean isDashShortcut; /** * Constructor */ public UnityShortcutAction() { } /** * Constructor * * @param path Short-cut path * @param removePath Remove path * @param name Short-cut name * @param target Short-cut target * @param iconPath Short-cut icon * @param workingDirectory Short-cut working directory * @param args Short-cut arguments * @param isPanelShortcut <code>true</code> if panel short-cut */ public UnityShortcutAction(IPath path, IPath removePath, String name, IPath target, IPath iconPath, IPath workingDirectory, String[] args, boolean isPanelShortcut) { super(path, removePath, name, target, iconPath, workingDirectory, args); this.isDashShortcut = isPanelShortcut; } /** * Returns the contents of the launcher file. **/ protected String getLauncherContents(IInstallProduct product) { String cmd = getTarget().toOSString(); for (String arg : getArguments()) { cmd += " " + arg; } String fileContents = "[Desktop Entry]\n" //$NON-NLS-1$ + "Type=Application\n" //$NON-NLS-1$ + "Name=" + getName() + "\n" //$NON-NLS-1$ //$NON-NLS-2$ + "Exec=" + cmd + "\n"//$NON-NLS-1$ + "Icon=" + getIconPath() + "\n" //$NON-NLS-1$ + "StartupWMClass=" + InstallUtils.makeFileNameSafe(getName()); //$NON-NLS-1$ return fileContents; } /** * Generates and writes the launcher file to path. */ protected void writeLauncherFile(IPath path, IInstallProduct product) throws CoreException { try { File launcherFile = new File(path.toOSString()); if (launcherFile.exists()) { // Should we error here? launcherFile.delete(); } launcherFile.createNewFile(); launcherFile.setExecutable(true); PrintStream stream = new PrintStream(launcherFile); stream.write(getLauncherContents(product).getBytes()); stream.close(); } catch (Exception e) { Installer.fail(InstallMessages.UnityShortcutAction_0, e); } } /** * Deletes the file at path. */ protected void deleteLauncherFile(IPath path) { File launcherFile = new File(path.toOSString()); launcherFile.delete(); } /** * Returns the launcher name. * * @return Launcher name */ protected String getLauncherName() { return InstallUtils.makeFileNameSafe(getName() + ".desktop"); //$NON-NLS-1$ } /** * Returns the default Unity launcher path ~/.local/share/applications/ **/ protected IPath getDashRegistrationPath() { IPath path = new Path(System.getProperty("user.home")); path = path.append(".local"); path = path.append("share"); path = path.append("applications"); return path; } @Override public void run(IProvisioningAgent agent, IInstallProduct product, IInstallMode mode, IProgressMonitor pm) throws CoreException { try { IPath shortcutPath = null; // Install if (mode.isInstall() && doesTargetExist()) { // Normal short-cut for folders if (isTargetDirectory()) { isDesktopFile = false; super.run(agent, product, mode, pm); } // Desktop file for applications else { isDesktopFile = true; // Register application with Unity by creating a .desktop file in the default // launcher path. This means that the application will show up in the Unity Dash. // TODO: Also install desktop file to launcher panel using DBUS. if (isDashShortcut) { if (!new File (getDashRegistrationPath().append(getLauncherName()).toOSString()).exists()) { new File (getDashRegistrationPath().toOSString()).mkdirs(); shortcutPath = getDashRegistrationPath().append(getLauncherName()); } // This is a desktop link - write .desktop file to ~/Desktop. } else { shortcutPath = getPath().append(getLauncherName()); } if (shortcutPath != null) { pm.beginTask(InstallMessages.CreatingShortcut, 1); pm.setTaskName(InstallMessages.CreatingShortcut); writeLauncherFile(shortcutPath, product); pm.worked(1); } } } // Uninstall else { // Desktop file if (isDesktopFile) { if (isDashShortcut) { if (new File (getDashRegistrationPath().append(getLauncherName()).toOSString()).exists()) { shortcutPath = getDashRegistrationPath().append(getLauncherName()); } } else { shortcutPath = getPath().append(getLauncherName()); } if (shortcutPath != null) { pm.beginTask(InstallMessages.RemovingShortcut, 1); pm.setTaskName(InstallMessages.RemovingShortcut); deleteLauncherFile(shortcutPath); pm.worked(1); } } // Normal short-cut else { super.run(agent, product, mode, pm); } } } finally { pm.done(); } } @Override public void save(Document document, Element element) throws CoreException { super.save(document, element); element.setAttribute(ATTRIBUTE_LAUNCHER, new Boolean(isDashShortcut).toString()); element.setAttribute(ATTRIBUTE_DESKTOP, new Boolean(isDesktopFile).toString()); } @Override public void load(Element element) throws CoreException { super.load(element); String value = element.getAttribute(ATTRIBUTE_LAUNCHER); isDashShortcut = Boolean.parseBoolean(value); value = element.getAttribute(ATTRIBUTE_DESKTOP); isDesktopFile = (value == null ? true : Boolean.parseBoolean(value)); } @Override public String getId() { return ID; } }