View Javadoc

1   /*
2    * This file is a part of CAST project.
3    * (c) Copyright 2007, AGH University of Science & Technology
4    * https://caribou.iisg.agh.edu.pl/trac/cast
5    *
6    * Licensed under the Eclipse Public License, Version 1.0 (the "License").
7    * You may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    * http://www.eclipse.org/legal/epl-v10.html
10   */
11  /*
12   * File: ColumnBreaksSelectionComposite.java
13   * Created: 2009-10-10
14   * Author: entrop
15   * $Id$
16   */
17  
18  package pl.edu.agh.cast.importer.wizard.page;
19  
20  import java.util.ArrayList;
21  import java.util.List;
22  import java.util.Set;
23  import java.util.TreeSet;
24  
25  import org.eclipse.swt.SWT;
26  import org.eclipse.swt.custom.ScrolledComposite;
27  import org.eclipse.swt.events.MouseAdapter;
28  import org.eclipse.swt.events.MouseEvent;
29  import org.eclipse.swt.events.PaintEvent;
30  import org.eclipse.swt.events.PaintListener;
31  import org.eclipse.swt.graphics.Font;
32  import org.eclipse.swt.graphics.GC;
33  import org.eclipse.swt.graphics.Point;
34  import org.eclipse.swt.layout.GridData;
35  import org.eclipse.swt.layout.GridLayout;
36  import org.eclipse.swt.widgets.Composite;
37  import org.eclipse.swt.widgets.Display;
38  import org.eclipse.swt.widgets.Label;
39  
40  import pl.edu.agh.cast.importer.wizard.util.Messages;
41  
42  /**
43   * Composite used to retrieve from user information about column breaks indices. Used in
44   * <code>FixedWidthColumnSelectionPage</code>.
45   *
46   * @author AGH CAST Team
47   */
48  public class ColumnBreaksSelectionComposite extends Composite {
49  	private static final int CUT_LINE_WIDTH = 1;
50  
51  	private ScrolledComposite scrolledComposite;
52  
53  	private Label fileContentLbl;
54  
55  	private int charWidth;
56  
57  	private int textWidth;
58  
59  	private Set<Integer> breaks = new TreeSet<Integer>();
60  
61  	/**
62  	 * The constructor.
63  	 *
64  	 * @param parent
65  	 *            parent composite
66  	 */
67  	public ColumnBreaksSelectionComposite(Composite parent) {
68  		super(parent, SWT.NULL);
69  		initGUI();
70  	}
71  
72  	private void initGUI() {
73  		GridLayout thisLayout = new GridLayout();
74  		thisLayout.makeColumnsEqualWidth = true;
75  		this.setLayout(thisLayout);
76  		this.setSize(405, 285);
77  
78  		scrolledComposite = new ScrolledComposite(this, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
79  		GridLayout scrolledCompositeLayout = new GridLayout();
80  		GridData scrolledCompositeLData = new GridData();
81  		scrolledCompositeLData.grabExcessHorizontalSpace = true;
82  		scrolledCompositeLData.grabExcessVerticalSpace = true;
83  		scrolledCompositeLData.horizontalAlignment = GridData.FILL;
84  		scrolledCompositeLData.verticalAlignment = GridData.FILL;
85  		scrolledComposite.setLayoutData(scrolledCompositeLData);
86  		scrolledComposite.setLayout(scrolledCompositeLayout);
87  		scrolledComposite.setExpandHorizontal(true);
88  		scrolledComposite.setExpandVertical(true);
89  		scrolledComposite.setAlwaysShowScrollBars(true);
90  		scrolledComposite.setShowFocusedControl(true);
91  
92  		fileContentLbl = new Label(scrolledComposite, SWT.NONE);
93  		fileContentLbl.setText(""); //$NON-NLS-1$
94  		scrolledComposite.setContent(fileContentLbl);
95  		GridData fileContentLblLData = new GridData();
96  		fileContentLblLData.grabExcessHorizontalSpace = true;
97  		fileContentLblLData.grabExcessVerticalSpace = true;
98  		fileContentLblLData.horizontalAlignment = GridData.FILL;
99  		fileContentLblLData.verticalAlignment = GridData.FILL;
100 		fileContentLbl.setLayoutData(fileContentLblLData);
101 		fileContentLbl.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
102 		fileContentLbl.setFont(new Font(Display.getCurrent(), "Courier", 10, SWT.NONE)); //$NON-NLS-1$
103 
104 		fileContentLbl.addMouseListener(new MouseAdapter() {
105 			@Override
106 			public void mouseDoubleClick(MouseEvent e) {
107 				handleLabelDoubleClick(e.x);
108 			}
109 		});
110 
111 		fileContentLbl.addPaintListener(new PaintListener() {
112 			@Override
113 			public void paintControl(PaintEvent e) {
114 				handlePaintEvent(e.gc);
115 			}
116 		});
117 
118 		charWidth = computeCharWidth();
119 
120 		this.layout();
121 	}
122 
123 	/**
124 	 * Shows file content in <code>fileContentLbl</code> label. Also draws column separation lines.
125 	 *
126 	 * @param inputFileLines
127 	 *            lines of preview file
128 	 * @param cutPoints
129 	 *            column cut indices
130 	 */
131 	public void showFilePreview(List<String> inputFileLines, List<Integer> cutPoints) {
132 		if (inputFileLines == null) {
133 			fileContentLbl.setText(Messages.ColumnBreaksSelectionComposite_PreviewLoadFailed);
134 		} else {
135 			fileContentLbl.setText(linesListToString(inputFileLines));
136 
137 			final Point labelSize = fileContentLbl.computeSize(SWT.DEFAULT, SWT.DEFAULT);
138 			scrolledComposite.setMinSize(labelSize);
139 			textWidth = labelSize.x;
140 
141 			breaks = new TreeSet<Integer>();
142 		}
143 
144 		setColumnBreakIndices(cutPoints);
145 	}
146 
147 	/*
148 	 * -----------------------------------------------------------------------------------------------------------
149 	 * --------------------------EVENT HANDLERS-------------------------------------------------------------------
150 	 * -----------------------------------------------------------------------------------------------------------
151 	 */
152 
153 	private void handleLabelDoubleClick(int x) {
154 		int lineXPos = calculateCutLinePoint(x);
155 
156 		if (lineXPos == textWidth || lineXPos == 0) {
157 			return;
158 		}
159 
160 		if (breaks.contains(lineXPos)) {
161 			breaks.remove(lineXPos);
162 		} else {
163 			breaks.add(lineXPos);
164 		}
165 
166 		fileContentLbl.redraw(getCutRectXCoord(lineXPos), 0, CUT_LINE_WIDTH, fileContentLbl.getSize().y, false);
167 
168 	}
169 
170 	private void handlePaintEvent(GC gc) {
171 		gc.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_RED));
172 		for (Integer pointX : breaks) {
173 			gc.fillRectangle(getCutRectXCoord(pointX), 0, CUT_LINE_WIDTH, fileContentLbl.getSize().y);
174 		}
175 	}
176 
177 	/*----------------------------------------------------------------------------------------------------------*/
178 
179 	/*
180 	 * -----------------------------------------------------------------------------------------------------------
181 	 * --------------------------HELPER METHODS-------------------------------------------------------------------
182 	 * -----------------------------------------------------------------------------------------------------------
183 	 */
184 
185 	private int calculateCutLinePoint(int x) {
186 		int mod = x % charWidth;
187 
188 		int result = x - mod;
189 		if (mod > charWidth / 2) {
190 			result += charWidth;
191 		}
192 		if (x > textWidth) {
193 			result = textWidth;
194 		}
195 
196 		return result;
197 	}
198 
199 	private int getCutRectXCoord(int lineXCoord) {
200 		return lineXCoord - (CUT_LINE_WIDTH / 2);
201 	}
202 
203 	private String linesListToString(List<String> lines) {
204 		final StringBuilder fileContents = new StringBuilder();
205 		for (String line : lines) {
206 			fileContents.append(line);
207 			fileContents.append('\n');
208 		}
209 		return fileContents.toString();
210 	}
211 
212 	private int computeCharWidth() {
213 		final GC gc = new GC(fileContentLbl);
214 		final int width = gc.getFontMetrics().getAverageCharWidth();
215 		gc.dispose();
216 		return width;
217 	}
218 
219 	private void setColumnBreakIndices(List<Integer> indices) {
220 		breaks = new TreeSet<Integer>();
221 		for (Integer index : indices) {
222 			breaks.add(index * charWidth);
223 		}
224 
225 		fileContentLbl.redraw();
226 	}
227 
228 	/*----------------------------------------------------------------------------------------------------------*/
229 
230 	/*
231 	 * -----------------------------------------------------------------------------------------------------------
232 	 * --------------------------GETTERS AND SETTERS--------------------------------------------------------------
233 	 * -----------------------------------------------------------------------------------------------------------
234 	 */
235 
236 	/**
237 	 * Returns selected column breaks indices.
238 	 *
239 	 * @return column break indices
240 	 */
241 	public List<Integer> getColumnBreaksIndices() {
242 		final List<Integer> indices = new ArrayList<Integer>();
243 		for (Integer point : breaks) {
244 			indices.add(point / charWidth);
245 		}
246 		return indices;
247 	}
248 
249 	/*----------------------------------------------------------------------------------------------------------*/
250 }