001: /**
002: * LibreSource
003: * Copyright (C) 2004-2008 Artenum SARL / INRIA
004: * http://www.libresource.org - contact@artenum.com
005: *
006: * This file is part of the LibreSource software,
007: * which can be used and distributed under license conditions.
008: * The license conditions are provided in the LICENSE.TXT file
009: * at the root path of the packaging that enclose this file.
010: * More information can be found at
011: * - http://dev.libresource.org/home/license
012: *
013: * Initial authors :
014: *
015: * Guillaume Bort / INRIA
016: * Francois Charoy / Universite Nancy 2
017: * Julien Forest / Artenum
018: * Claude Godart / Universite Henry Poincare
019: * Florent Jouille / INRIA
020: * Sebastien Jourdain / INRIA / Artenum
021: * Yves Lerumeur / Artenum
022: * Pascal Molli / Universite Henry Poincare
023: * Gerald Oster / INRIA
024: * Mariarosa Penzi / Artenum
025: * Gerard Sookahet / Artenum
026: * Raphael Tani / INRIA
027: *
028: * Contributors :
029: *
030: * Stephane Bagnier / Artenum
031: * Amadou Dia / Artenum-IUP Blois
032: * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
033: */package org.libresource.so6.application.studio.history.viewer.ui;
034:
035: import org.libresource.so6.application.studio.history.viewer.util.CommandFinder;
036: import org.libresource.so6.application.studio.history.viewer.util.FileHistoryPlayer;
037: import org.libresource.so6.application.studio.history.viewer.util.WorkspaceColorManager;
038: import org.libresource.so6.core.command.Command;
039: import org.libresource.so6.core.command.fs.Remove;
040: import org.libresource.so6.core.command.text.AddBlock;
041: import org.libresource.so6.core.command.text.AddTxtFile;
042: import org.libresource.so6.core.command.text.DelBlock;
043:
044: import java.awt.Color;
045: import java.awt.Component;
046: import java.awt.Dimension;
047: import java.awt.Font;
048: import java.awt.GridLayout;
049: import java.awt.Point;
050:
051: import java.io.FileReader;
052: import java.io.LineNumberReader;
053:
054: import java.util.ArrayList;
055: import java.util.Collection;
056: import java.util.Iterator;
057:
058: import javax.swing.AbstractListModel;
059: import javax.swing.BorderFactory;
060: import javax.swing.Box;
061: import javax.swing.BoxLayout;
062: import javax.swing.JLabel;
063: import javax.swing.JList;
064: import javax.swing.JPanel;
065: import javax.swing.JScrollPane;
066: import javax.swing.JTextPane;
067: import javax.swing.ListCellRenderer;
068: import javax.swing.text.JTextComponent;
069:
070: /**
071: * @author jourdain
072: */
073: public class FileHistoryPlayerImplList extends JPanel implements
074: FileHistoryPlayer {
075: private WorkspaceColorManager colorManager;
076: private CommandFinder cmdFinder;
077: private int currentHistoryPoint = 0;
078:
079: //
080: private ArrayList globalFileHistory;
081: private ArrayList highLightSetup;
082: private JList previousView;
083: private JList currentView;
084: private LineTxtAdapter previousModel;
085: private LineTxtAdapter currentModel;
086: private JScrollPane previousViewScroll;
087: private JScrollPane currentViewScroll;
088:
089: public FileHistoryPlayerImplList(CommandFinder cmdFinder)
090: throws Exception {
091: this .cmdFinder = cmdFinder;
092: this .globalFileHistory = new ArrayList();
093: this .highLightSetup = new ArrayList();
094:
095: //
096: computeHistory();
097: this .previousModel = new LineTxtAdapter(null);
098: this .currentModel = new LineTxtAdapter(
099: (ArrayList) globalFileHistory.get(0));
100:
101: //
102: ListRenderer renderer = new ListRenderer();
103: previousView = new JList(previousModel);
104: previousView.setCellRenderer(renderer);
105: currentView = new JList(currentModel);
106: currentView.setCellRenderer(renderer);
107: previousViewScroll = new JScrollPane(previousView);
108: currentViewScroll = new JScrollPane(currentView);
109:
110: //
111: setLayout(new GridLayout(0, 2));
112: add(previousViewScroll);
113: add(currentViewScroll);
114: }
115:
116: private void computeHistory() throws Exception {
117: Command cmd;
118: int index = 0;
119:
120: while ((cmd = cmdFinder.getOp(index++)) != null) {
121: ArrayList currentState = new ArrayList();
122: globalFileHistory.add(currentState);
123:
124: if (index > 1) {
125: currentState.addAll((Collection) globalFileHistory
126: .get(index - 2));
127: }
128:
129: applyCommand(currentState, cmd);
130: }
131: }
132:
133: private void applyCommand(ArrayList document, Command cmd)
134: throws Exception {
135: if (cmd instanceof Remove) {
136: document.clear();
137: } else if (cmd instanceof AddTxtFile) {
138: document.clear();
139:
140: AddTxtFile atf = (AddTxtFile) cmd;
141: FileReader reader = new FileReader(atf.getAttachement());
142: LineNumberReader lnr = new LineNumberReader(reader);
143: String line;
144:
145: while ((line = lnr.readLine()) != null) {
146: document.add(new TextLine(line, cmd.getWsName()));
147: }
148:
149: highLightSetup.add(new HightLightBean(0, 0, 0, document
150: .size(), false));
151: } else if (cmd instanceof AddBlock) {
152: AddBlock ab = (AddBlock) cmd;
153: int insertPoint = ab.getInsertPoint() - 1;
154:
155: for (Iterator i = ab.getContent().iterator(); i.hasNext();) {
156: document.add(insertPoint++, new TextLine((String) i
157: .next(), cmd.getWsName()));
158: }
159:
160: highLightSetup.add(new HightLightBean(
161: ab.getInsertPoint() - 1, 1,
162: ab.getInsertPoint() - 1, ab.getSize(), false));
163: } else if (cmd instanceof DelBlock) {
164: DelBlock db = (DelBlock) cmd;
165: int delPoint = db.getDeletePoint() - 1;
166:
167: for (int i = 0; i < db.getSize(); i++) {
168: document.remove(delPoint);
169: }
170:
171: highLightSetup.add(new HightLightBean(
172: db.getDeletePoint() - 1, db.getSize(), db
173: .getDeletePoint() - 1, 1, true));
174: }
175: }
176:
177: private void hightLightViews() {
178: HightLightBean bean = (HightLightBean) highLightSetup
179: .get(currentHistoryPoint);
180:
181: //scrollView.getViewport().setViewPosition(new Point(0, viewY));
182: int lineHeight = 16;
183: int viewY = bean.getCurrentLinePosition() * lineHeight;
184: int nbLineToShow = Math.max(bean.getPreviousLineNumber(), bean
185: .getCurrentLineNumber());
186: int nbLineVisible = previousViewScroll.getHeight() / lineHeight;
187:
188: if (nbLineVisible > nbLineToShow) {
189: viewY = Math
190: .max(
191: 0,
192: (bean.getCurrentLinePosition() - ((nbLineVisible - nbLineToShow) / 2))
193: * lineHeight);
194: }
195:
196: previousViewScroll.getViewport().setViewPosition(
197: new Point(0, viewY));
198: currentViewScroll.getViewport().setViewPosition(
199: new Point(0, viewY));
200: }
201:
202: public Command viewHistoryState(int index) {
203: if (index > 0) {
204: previousModel.setData((ArrayList) globalFileHistory
205: .get(index - 1));
206: } else {
207: previousModel.setData(null);
208: }
209:
210: currentModel.setData((ArrayList) globalFileHistory.get(index));
211: currentHistoryPoint = index;
212:
213: //
214: hightLightViews();
215:
216: //
217: try {
218: return (Command) cmdFinder.getOp(index);
219: } catch (Exception e) {
220: return null;
221: }
222: }
223:
224: public String getState() throws Exception {
225: StringBuffer buffer = new StringBuffer();
226: ArrayList currentState = (ArrayList) globalFileHistory
227: .get(currentHistoryPoint);
228:
229: for (Iterator i = currentState.iterator(); i.hasNext();) {
230: buffer.append(i.next() + "\n");
231: }
232:
233: return buffer.toString();
234: }
235:
236: public void setWorkspaceColorManager(
237: WorkspaceColorManager colorManager) {
238: this .colorManager = colorManager;
239: }
240:
241: //
242: public class TextLine {
243: private String txt;
244: private String origine;
245:
246: public TextLine(String txtLine, String orignie) {
247: this .txt = txtLine;
248: this .origine = orignie;
249: }
250:
251: public String getOrigine() {
252: return origine;
253: }
254:
255: public String getTxt() {
256: return txt;
257: }
258:
259: public void setOrigine(String string) {
260: origine = string;
261: }
262:
263: public void setTxt(String string) {
264: txt = string;
265: }
266:
267: public String toString() {
268: return txt;
269: }
270: }
271:
272: //
273: public class HightLightBean {
274: private int previousLinePosition;
275: private int previousLineNumber;
276: private int currentLinePosition;
277: private int currentLineNumber;
278: private boolean highLightPrevious;
279:
280: public HightLightBean(int previousLinePosition,
281: int previousLineNumber, int currentLinePosition,
282: int currentLineNumber, boolean highLightPrevious) {
283: this .previousLinePosition = previousLinePosition;
284: this .previousLineNumber = previousLineNumber;
285: this .currentLinePosition = currentLinePosition;
286: this .currentLineNumber = currentLineNumber;
287: this .highLightPrevious = highLightPrevious;
288: }
289:
290: public int getCurrentLineNumber() {
291: return currentLineNumber;
292: }
293:
294: public int getCurrentLinePosition() {
295: return currentLinePosition;
296: }
297:
298: public boolean isHighLightPrevious() {
299: return highLightPrevious;
300: }
301:
302: public int getPreviousLineNumber() {
303: return previousLineNumber;
304: }
305:
306: public int getPreviousLinePosition() {
307: return previousLinePosition;
308: }
309:
310: public void setCurrentLineNumber(int i) {
311: currentLineNumber = i;
312: }
313:
314: public void setCurrentLinePosition(int i) {
315: currentLinePosition = i;
316: }
317:
318: public void setHighLightPreviuos(boolean b) {
319: highLightPrevious = b;
320: }
321:
322: public void setPreviousLineNumber(int i) {
323: previousLineNumber = i;
324: }
325:
326: public void setPreviousLinePosition(int i) {
327: previousLinePosition = i;
328: }
329: }
330:
331: //
332: public class LineTxtAdapter extends AbstractListModel {
333: private ArrayList data;
334:
335: public LineTxtAdapter(ArrayList data) {
336: this .data = data;
337: }
338:
339: public void setData(ArrayList data) {
340: this .data = data;
341: updateAll();
342: }
343:
344: public void updateAll() {
345: fireContentsChanged(this , 0, getSize());
346: hightLightViews();
347: }
348:
349: public int getSize() {
350: if (data == null) {
351: return 0;
352: }
353:
354: return data.size();
355: }
356:
357: public Object getElementAt(int index) {
358: if (data == null) {
359: return null;
360: }
361:
362: return data.get(index);
363: }
364: }
365:
366: public class ListRenderer extends JPanel implements
367: ListCellRenderer {
368: private JLabel lineNumber;
369: private JTextComponent txtLine;
370:
371: public ListRenderer() {
372: setBackground(Color.white);
373: lineNumber = new JLabel();
374: lineNumber.setOpaque(true);
375: lineNumber.setBackground(Color.lightGray);
376: txtLine = new JTextPane();
377: txtLine.setBorder(BorderFactory.createEmptyBorder());
378: txtLine.setOpaque(true);
379:
380: BoxLayout layout = new BoxLayout(this , BoxLayout.LINE_AXIS);
381: setLayout(layout);
382: add(lineNumber);
383: add(Box.createRigidArea(new Dimension(3, 1)));
384: add(txtLine);
385: add(Box.createGlue());
386: }
387:
388: public Component getListCellRendererComponent(JList list,
389: Object value, int index, boolean isSelected,
390: boolean cellHasFocus) {
391: String number = Integer.toString(index + 1);
392:
393: while (number.length() < 4)
394: number = "0" + number;
395:
396: lineNumber.setText(number);
397: txtLine.setText(value.toString());
398:
399: if (colorManager != null) {
400: txtLine.setBackground(colorManager
401: .getColorOfWorkspace(((TextLine) value)
402: .getOrigine()));
403: } else {
404: txtLine.setBackground(Color.white);
405: }
406:
407: lineNumber.setBackground(Color.lightGray);
408:
409: HightLightBean bean = (HightLightBean) highLightSetup
410: .get(currentHistoryPoint);
411: boolean highLight = false;
412:
413: if (list.equals(previousView)) {
414: // previousView list
415: if (bean.isHighLightPrevious()) {
416: if ((bean.getPreviousLinePosition() <= index)
417: && (index < (bean.getPreviousLineNumber() + bean
418: .getPreviousLinePosition()))) {
419: lineNumber.setBackground(Color.cyan);
420: highLight = true;
421: }
422: } else if (bean.getPreviousLinePosition() == index) {
423: lineNumber.setBackground(Color.cyan);
424: }
425: } else { // currentView list
426:
427: if (!bean.isHighLightPrevious()) {
428: if ((bean.getCurrentLinePosition() <= index)
429: && (index < (bean.getCurrentLineNumber() + bean
430: .getCurrentLinePosition()))) {
431: lineNumber.setBackground(Color.cyan);
432: highLight = true;
433: }
434: } else if (bean.getCurrentLinePosition() == index) {
435: lineNumber.setBackground(Color.cyan);
436: }
437: }
438:
439: if (highLight) {
440: txtLine
441: .setFont(txtLine.getFont()
442: .deriveFont(Font.BOLD));
443: } else {
444: txtLine.setFont(txtLine.getFont()
445: .deriveFont(Font.PLAIN));
446: }
447:
448: return this ;
449: }
450:
451: public Dimension getPreferredSize() {
452: return new Dimension(1280, 16);
453: }
454: }
455: }
|