//This file is part of SECONDO. //Copyright (C) 2004, University in Hagen, Department of Computer Science, //Database Systems for New Applications. //SECONDO is free software; you can redistribute it and/or modify //it under the terms of the GNU General Public License as published by //the Free Software Foundation; either version 2 of the License, or //(at your option) any later version. //SECONDO is distributed in the hope that it will be useful, //but WITHOUT ANY WARRANTY; without even the implied warranty of //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //GNU General Public License for more details. //You should have received a copy of the GNU General Public License //along with SECONDO; if not, write to the Free Software //Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package viewer.hoese; import gui.SecondoObject; import gui.idmanager.ID; import java.awt.Color; import java.awt.Component; import java.awt.Font; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.File; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Vector; import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListModel; import javax.swing.JFileChooser; import javax.swing.JList; import javax.swing.ListModel; import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; import sj.lang.ListExpr; import tools.Reporter; import viewer.HoeseViewer; import viewer.hoese.algebras.continuousupdate.RunnableUpdate; /** * This class enhances JList. A list is generated dependant to the types given * back and formatted by the query. */ public class QueryResult extends JList { /** The query command */ public String command; /** The result given back by the query command as a Listexpr */ public ListExpr LEResult; /** A list of the ggraphic objects of this query */ private Vector GraphObjects; /** No. of tuples, no. of attributes of a tuple */ private int TupelCount, AttrCount; /** FileChosser for storing a file **/ private JFileChooser filechooser = new JFileChooser(); /** The id of the stored Secondo-Object */ private ID id; /** Last element of LEResult; */ private ListExpr lastElement; /** return the Id for this QueryResult **/ public ID getId() { return id; } /** the QueryRepresentations for this QueryResult */ // private ViewConfig myViewConfig = null; private Vector ViewConfigs = new Vector(2); /** * stores the interval where Time dependent objects are defined **/ private Interval interval; private Layer resultLayer; private void setLastElement() { ListExpr last = LEResult.second(); while (!last.endOfList()) { last = last.rest(); } lastElement = last; } /** * Add tuples which are received by a continuous update * * @param hoese * The Viewer this QR belongs to * @param tuple * The Tuple which was received * @param modelLimit * The maximum Size of the used ListModel */ public void addTuples(HoeseViewer hoese, ListExpr tuple, Integer tupleLimit) { // For performance reasons, save the last element of the nested-list if (lastElement == null) { setLastElement(); } // Create a temporary QueryResult QueryResult tmp_qr = new QueryResult(new SecondoObject("dummy", LEResult)); // Loop through the provided nested List, and add all tuples while (tuple != null & !tuple.isEmpty()) { ListExpr current = tuple.first(); tuple = tuple.rest(); lastElement = ListExpr.append(lastElement, current); TupelCount++; tmp_qr.addEntry("---------"); LEUtils.analyse(LEResult.first().toString(), 0, 0, LEResult.first(), ListExpr.oneElemList(current), tmp_qr); } // Reduce the NestedList if (tupleLimit > 0) { ListExpr tuples = LEResult.second(); for (int i = tuples.listLength(); i > tupleLimit; i--) { tuples = tuples.rest(); TupelCount--; } LEResult.second().setValueTo(tuples); } // Update the ListModel on the GUI thread SwingUtilities.invokeLater(new RunnableUpdate(this, tmp_qr, hoese, tupleLimit)); } /** * Creates a QueryResult with a command and a result of a query * * @param String * acommand * @param ListExpr * aLEResult */ public QueryResult(SecondoObject so) { super(); String acommand = so.getName(); ListExpr aLEResult = so.toListExpr(); this.id = so.getID(); interval = null; setFont(new Font("Monospaced", Font.PLAIN, 12)); // processing double clicks addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.getButton() != MouseEvent.BUTTON1 && e.getClickCount() == 1) { int index = QueryResult.this.locationToIndex(e.getPoint()); if (index < 0) { return; } Object o = QueryResult.this.getModel().getElementAt(index); if (o != null && (o instanceof Writable)) { if (filechooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) { File F = filechooser.getSelectedFile(); if (F.exists()) { if (Reporter.showQuestion("File " + F + " already exists,\n Overwrite It?") != Reporter.YES) { return; } } boolean ok = false; try { ok = ((Writable) o).writeTo(F); } catch (Exception e4) { Reporter.debug(e4); } if (ok) { Reporter.showInfo("File " + F + " has been written"); } else { Reporter.showError("error in writing file " + F); } } } } if (e.getClickCount() != 2) { return; } Object o = QueryResult.this.getSelectedValue(); if ((o instanceof DsplBase) && (((DsplBase) o).getFrame() != null)) { ((DsplBase) o).getFrame().select(o); ((DsplBase) o).getFrame().show(true); } if ((o instanceof ExternDisplay)) { ExternDisplay BG = (ExternDisplay) o; if (!BG.isExternDisplayed()) { BG.displayExtern(); } } } }); setModel(new DefaultListModel()); setCellRenderer(new QueryRenderer()); setSelectionMode(ListSelectionModel.SINGLE_SELECTION); setBackground(Color.lightGray); command = acommand; LEResult = aLEResult; TupelCount = LEResult.second().listLength(); if (LEResult.first().isAtom()) { AttrCount = 0; } else { try { AttrCount = LEResult.first().second().second().listLength(); } catch (Exception e) { AttrCount = 0; } } GraphObjects = new Vector(50); } /** * Creates a QueryResult for Collections with a command and a result of a * query * * @param String * acommand * @param ListExpr * aLEResult * @param boolean isColl */ public QueryResult(SecondoObject so, boolean isColl) { super(); interval = null; setFont(new Font("Monospaced", Font.PLAIN, 12)); String acommand = so.getName(); ListExpr aLEResult = so.toListExpr(); this.id = so.getID(); // processing double clicks addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.getButton() != MouseEvent.BUTTON1 && e.getClickCount() == 1) { int index = QueryResult.this.locationToIndex(e.getPoint()); if (index < 0) { return; } Object o = QueryResult.this.getModel().getElementAt(index); if (o != null && (o instanceof Writable)) { if (filechooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) { File F = filechooser.getSelectedFile(); if (F.exists()) { if (Reporter.showQuestion("File " + F + " already exists,\n Overwrite It?") != Reporter.YES) { return; } } boolean ok = false; try { ok = ((Writable) o).writeTo(F); } catch (Exception e4) { Reporter.debug(e4); } if (ok) { Reporter.showInfo("File " + F + " has been written"); } else { Reporter.showError("error in writing file " + F); } } } } if (e.getClickCount() != 2) { return; } Object o = QueryResult.this.getSelectedValue(); if ((o instanceof DsplBase) && (((DsplBase) o).getFrame() != null)) { ((DsplBase) o).getFrame().select(o); ((DsplBase) o).getFrame().show(true); } if ((o instanceof ExternDisplay)) { ExternDisplay BG = (ExternDisplay) o; if (!BG.isExternDisplayed()) { BG.displayExtern(); } } } }); setModel(new DefaultListModel()); setCellRenderer(new QueryRenderer()); setSelectionMode(ListSelectionModel.SINGLE_SELECTION); setBackground(Color.lightGray); command = acommand; LEResult = aLEResult; GraphObjects = new Vector(50); } public boolean hasId(ID id) { return this.id.equals(id); } /** get the ViewConfigs for this query */ public ViewConfig[] getViewConfigs() { ViewConfig[] Cfgs = new ViewConfig[ViewConfigs.size()]; for (int i = 0; i < Cfgs.length; i++) Cfgs[i] = (ViewConfig) ViewConfigs.get(i); return Cfgs; } /** get the ViewConfig with specific index */ public ViewConfig getViewConfigAt(int index) { if (index < 0 || index >= ViewConfigs.size()) return null; else return (ViewConfig) ViewConfigs.get(index); } /** set the ViewConfig for this query */ public void addViewConfig(ViewConfig VCfg) { ViewConfigs.add(VCfg); } /** * get the Pos of the ViewConfig with specific AttrName if not exists a * ViewConfig with AttrName -1 is returned */ public int getViewConfigIndex(String AttrName) { int pos = -1; boolean found = false; for (int i = 0; i < ViewConfigs.size() && !found; i++) if (((ViewConfig) ViewConfigs.get(i)).AttrName.equals(AttrName)) { pos = i; found = true; } return pos; } /** * * @return The ListExpr of the picked (selected) list-entry */ public ListExpr getPick() { if (AttrCount == 0) { return LEResult; } int selind = getSelectedIndex(); int TupelNr = (selind / (AttrCount + 1)); int AttrNr = (selind % (AttrCount + 1)); if (AttrNr == AttrCount) return null; // Separator ListExpr TupelList = LEResult.second(); for (int i = 0; i < TupelNr; i++) TupelList = TupelList.rest(); ListExpr AttrList = TupelList.first(); for (int i = 0; i < AttrNr; i++) AttrList = AttrList.rest(); ListExpr TypeList = LEResult.first().second().second(); for (int i = 0; i < AttrNr; i++) TypeList = TypeList.rest(); return ListExpr .twoElemList(TypeList.first().second(), AttrList.first()); } /** * * @return graphical objects of this query-result */ public Vector getGraphObjects() { return GraphObjects; } /** * Adds an object to the end of the result list * * @param entry * The entry object */ public void addEntry(Object entry) { if (entry != null) { if (entry instanceof DsplBase) { if (entry instanceof DsplGraph) { GraphObjects.add(entry); } if (((DsplBase) entry).getFrame() != null) { ((DsplBase) entry).getFrame().addObject(entry); } } } ((DefaultListModel) getModel()).addElement(entry); } /** * Adds a ListModel to the end of the result list * * @param entries * Collection */ public void addEntries(ListModel entries) { if (entries.getSize() == 0) { return; } for (int i = 0; i < entries.getSize(); i++) { Object entry = entries.getElementAt(i); if (entry != null) { if (entry instanceof DsplBase) { if (entry instanceof DsplGraph) { GraphObjects.add(entry); } if (((DsplBase) entry).getFrame() != null) { ((DsplBase) entry).getFrame().addObject(entry); } } } ((DefaultListModel) getModel()).addElement(entry); } } /** * Removes entries from the used models to retain the maximum size Entries * will be removed from the front, it maxSize is greater than zero * * @param maxSize * Maximum Size of the Model * @param hoese * Hoese Viewer */ public void reduceModels(Integer tupleLimit, HoeseViewer hoese) { DefaultListModel model = ((DefaultListModel) getModel()); while (tupleLimit > 0 && model.size() > (tupleLimit * (AttrCount + 1))) { for (int i = 0; i < AttrCount + 1; i++) { Object o = model.remove(0); if (o instanceof DsplGraph) { GraphObjects.remove(o); resultLayer.removeGO((DsplGraph)o); } } } } /** * search the given String in this list and returns the index, the search is * started with offset and go to the end of the list. if the given string is * not containing between offset and end -1 is returned */ public int find(String S, boolean CaseSensitiv, int Offset) { ListModel LM = getModel(); if (LM == null) return -1; String UCS = S.toUpperCase(); boolean found = false; int pos = -1; for (int i = Offset; i < LM.getSize() && !found; i++) { if (CaseSensitiv && LM.getElementAt(i).toString().indexOf(S) >= 0) { pos = i; found = true; } if (!CaseSensitiv && LM.getElementAt(i).toString().toUpperCase().indexOf(UCS) >= 0) { pos = i; found = true; } } return pos; } public boolean equals(Object o) { if (!(o instanceof QueryResult)) return false; else { QueryResult qr = (QueryResult) o; return this.id == qr.id; } } /** * return the command */ public String getCommand() { return command; } /** * Sets the command **/ public void setCommand(String command) { this.command = command; } /** return the ListExpr */ public ListExpr getListExpr() { return LEResult; } /** * computes the TimeBounds from the contained objects. **/ public void computeTimeBounds() { ListModel listModel = getModel(); int size = listModel.getSize(); this.interval = null; for (int i = 0; i < size; i++) { Object o = listModel.getElementAt(i); if (o instanceof Timed) { Interval oInterval = ((Timed) o).getBoundingInterval(); if (oInterval != null) { if (this.interval == null) { this.interval = oInterval.copy(); } else { this.interval.unionInternal(oInterval); } } } } } /** * Returns the interval containing all definition times of object instances * of Timed. If no such time exist, the result is null. **/ public Interval getBoundingInterval() { return interval; } /** * * @return The command of the query as string representation for the query * combobox */ public String toString() { return command; } /** * A class for special rendering of datatypes in the list */ private class QueryRenderer extends DefaultListCellRenderer { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); // if (value instanceof DsplGraph) // setIcon(new ImageIcon("images/labdlg.gif")); setForeground(Color.BLACK); if ((value instanceof DsplGraph) && (value instanceof Timed)) setForeground(Color.magenta); else if (value instanceof DsplGraph) setForeground(Color.red); else if (value instanceof Timed) setForeground(Color.blue); else if (value instanceof DsplBase) setForeground(new Color(0, 100, 0)); if (value instanceof DsplBase) if (!((DsplBase) value).getVisible()) setForeground(Color.gray); if (value instanceof ExternDisplay) { setForeground(new Color(255, 0, 0)); } return this; } } public void setResultLayer(Layer lay) { resultLayer = lay; } public Layer getResultLayer() { return resultLayer; } }