/* ******************************************************************************
* Copyright (c) 2006-2012 XMind Ltd. and others.
*
* This file is a part of XMind 3. XMind releases 3 and
* above are dual-licensed under the Eclipse Public License (EPL),
* which is available at http://www.eclipse.org/legal/epl-v10.html
* and the GNU Lesser General Public License (LGPL),
* which is available at http://www.gnu.org/licenses/lgpl.html
* See http://www.xmind.net/license.html for details.
*
* Contributors:
* XMind Ltd. - initial API and implementation
*******************************************************************************/
package org.xmind.ui.internal.views;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.UUID;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.xmind.core.Core;
import org.xmind.core.IBoundary;
import org.xmind.core.IControlPoint;
import org.xmind.core.IRelationship;
import org.xmind.core.ISheet;
import org.xmind.core.ITopic;
import org.xmind.core.IWorkbook;
import org.xmind.core.io.DirectoryStorage;
import org.xmind.core.io.IStorage;
import org.xmind.core.style.IStyle;
import org.xmind.core.style.IStyleSheet;
import org.xmind.gef.draw2d.graphics.GraphicsUtils;
import org.xmind.gef.image.ImageExportUtils;
import org.xmind.gef.image.ResizeConstants;
import org.xmind.ui.internal.MindMapMessages;
import org.xmind.ui.internal.MindMapUIPlugin;
import org.xmind.ui.mindmap.MindMap;
import org.xmind.ui.mindmap.MindMapImageExporter;
import org.xmind.ui.util.ImageFormat;
public class ThemeFigure extends Figure {
private class ThemePreview {
private IWorkbook previewWorkbook;
private IStorage previewStorage;
private File previewFile;
public ThemePreview(IStyle theme) {
initPreviewStorage();
initPreview();
}
private void initPreviewStorage() {
File root = MindMapUIPlugin.getDefault().getStateLocation()
.toFile();
previewFile = new File(root, ".themePreview"); //$NON-NLS-1$
File dir = new File(previewFile, UUID.randomUUID().toString());
dir.mkdirs();
previewStorage = new DirectoryStorage(dir);
previewWorkbook = Core.getWorkbookBuilder()
.createWorkbook(previewStorage);
// previewWorkbook.setTempStorage(previewStorage);
}
private void initPreview() {
ISheet sheet = previewWorkbook.getPrimarySheet();
createPreviewContents(previewWorkbook, sheet);
}
private void createPreviewContents(IWorkbook workbook, ISheet sheet) {
IStyleSheet styleSheet = workbook.getStyleSheet();
IStyle importStyle = styleSheet.importStyle(theme);
if (importStyle != null)
sheet.setThemeId(importStyle.getId());
ITopic rootTopic = sheet.getRootTopic();
rootTopic.setTitleText(MindMapMessages.TitleText_CentralTopic);
rootTopic.setStructureClass("org.xmind.ui.map.clockwise"); //$NON-NLS-1$
ITopic mainTopic1 = workbook.createTopic();
mainTopic1.setTitleText(
NLS.bind(MindMapMessages.TitleText_MainTopic, 1));
rootTopic.add(mainTopic1);
ITopic subTopic1 = workbook.createTopic();
subTopic1.setTitleText(
NLS.bind(MindMapMessages.TitleText_Subtopic, 1));
mainTopic1.add(subTopic1);
ITopic subTopic2 = workbook.createTopic();
subTopic2.setTitleText(
NLS.bind(MindMapMessages.TitleText_Subtopic, 2));
mainTopic1.add(subTopic2);
ITopic subTopic3 = workbook.createTopic();
subTopic3.setTitleText(
NLS.bind(MindMapMessages.TitleText_Subtopic, 3));
mainTopic1.add(subTopic3);
ITopic floatingTopic = workbook.createTopic();
floatingTopic.setTitleText(MindMapMessages.TitleText_FloatingTopic);
floatingTopic.setPosition(0, -120);
rootTopic.add(floatingTopic, ITopic.DETACHED);
IBoundary boundary = workbook.createBoundary();
boundary.setTitleText(MindMapMessages.TitleText_Boundary);
boundary.setStartIndex(0);
boundary.setEndIndex(0);
rootTopic.addBoundary(boundary);
IRelationship relationship = workbook.createRelationship();
relationship.setTitleText(MindMapMessages.TitleText_Relationship);
relationship.setEnd1Id(mainTopic1.getId());
relationship.setEnd2Id(floatingTopic.getId());
IControlPoint cp1 = relationship.getControlPoint(0);
cp1.setPosition(50, -100);
IControlPoint cp2 = relationship.getControlPoint(1);
cp2.setPosition(100, 0);
sheet.addRelationship(relationship);
}
public void createPreviewImage(int wHint, int hHint, String fileName) {
MindMapImageExporter exporter = new MindMapImageExporter(
Display.getCurrent());
exporter.setSource(new MindMap(previewWorkbook.getPrimarySheet()),
null, null);
exporter.setTargetWorkbook(previewWorkbook);
Image image = exporter.createImage();
int width = image.getBounds().width;
int height = image.getBounds().height;
float scale = (height * 1.0f / width * 1.0f)
/ (hHint * 1.0f / wHint * 1.0f);
if (scale > 1.0) {
hHint = (int) (scale * hHint);
} else {
wHint = (int) (wHint / scale);
}
if (image != null) {
image.dispose();
image = null;
}
MindMapImageExporter exp = new MindMapImageExporter(
Display.getCurrent());
exp.setSource(new MindMap(previewWorkbook.getPrimarySheet()), null,
null);
exp.setTargetWorkbook(previewWorkbook);
exp.setResize(ResizeConstants.RESIZE_MAXPIXELS, wHint, hHint);
image = exp.createImage();
String id = theme.getId();
File dir = new File(previewFile, id);
dir.mkdirs();
File preview = new File(dir, fileName);
OutputStream output = null;
try {
output = new FileOutputStream(preview);
ImageExportUtils.saveImage(image, output,
ImageFormat.BMP.getSWTFormat());
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (image != null) {
image.dispose();
image = null;
}
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
clear();
}
private void clear() {
if (previewStorage != null) {
previewStorage.clear();
previewStorage = null;
}
}
}
private static final Rectangle RECT = new Rectangle();
private IStyle theme = null;
private Image defaultImage = null;
public ThemeFigure() {
}
public IStyle getTheme() {
return theme;
}
public void setTheme(IStyle theme) {
if (theme == this.theme)
return;
this.theme = theme;
repaint();
}
public Image getDefaultImage() {
return defaultImage;
}
public void setDefaultImage(Image defaultImage) {
if (defaultImage == this.defaultImage)
return;
this.defaultImage = defaultImage;
repaint();
}
public Image getPreviewImage(IStyle theme) {
return getImageFromSource(theme, new Rectangle(0, 0, 200, 100));
}
// public boolean isDefault() {
// return isDefault;
// }
//
// public void setDefault(boolean isDefault) {
// if (isDefault == this.isDefault)
// return;
// this.isDefault = isDefault;
// repaint();
// }
public void paint(Graphics graphics) {
GraphicsUtils.fixGradientBugForCarbon(graphics, this);
super.paint(graphics);
}
protected void paintFigure(Graphics graphics) {
super.paintFigure(graphics);
drawTheme(graphics);
}
protected void drawTheme(Graphics graphics) {
if (theme == null)
return;
graphics.setAntialias(SWT.ON);
graphics.setTextAntialias(SWT.ON);
Rectangle r = getClientArea(RECT);
drawTheme(graphics, theme, r);
}
protected void drawTheme(Graphics graphics, IStyle theme, Rectangle r) {
Image image = getImageFromSource(theme, r);
if (image != null)
graphics.drawImage(image, r.x, r.y);
if (defaultImage != null) {
graphics.drawImage(defaultImage, r.x + 1, r.y + 1);
}
}
private Image getImageFromSource(IStyle theme, Rectangle r) {
if (this.theme != theme)
this.theme = theme;
File root = MindMapUIPlugin.getDefault().getStateLocation().toFile();
root = new File(root, ".themePreview"); //$NON-NLS-1$
String id = theme.getId();
File dir = new File(root, id);
String previewName = "preview" + r.width + ".bmp"; //$NON-NLS-1$ //$NON-NLS-2$
String[] list = dir.list();
if (list == null || !Arrays.asList(list).contains(previewName)) {
ThemePreview themePreview = new ThemePreview(theme);
themePreview.createPreviewImage(r.width, r.height, previewName);
}
File preview = new File(dir, previewName);
return new Image(Display.getCurrent(), preview.getAbsolutePath());
}
}