001    /*
002     *  PAVLOV -- Multiple Choice Study System
003     *  Copyright (C) 2000 - 2004 T.J. Willis
004     *
005     *  This program is free software; you can redistribute it and/or
006     *  modify it under the terms of the GNU General Public License
007     *  as published by the Free Software Foundation; either version 2
008     *  of the License, or (at your option) any later version.
009     *
010     *  This program is distributed in the hope that it will be useful,
011     *  but WITHOUT ANY WARRANTY; without even the implied warranty of
012     *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013     *  GNU General Public License for more details.
014     *
015     *  You should have received a copy of the GNU General Public License
016     *  along with this program; if not, write to the Free Software
017     *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
018     *
019     *  $Header: /cvsroot/pavlov/net/sourceforge/bee/TabDelimitedTransferHandler.java,v 1.7 2004/07/01 05:50:19 tj_willis Exp $
020     */
021    package net.sourceforge.bee;
022    import javax.swing.*;
023    import javax.swing.table.*;
024    
025    /**
026     *  Allows a question to be transferred to system clipboard or another
027     *  application as tab delimited text.
028     *
029     *@author     <a href="mailto:"></a>
030     *@created    May 30, 2004
031     *@version    1.0
032     */
033    public class TabDelimitedTransferHandler extends StringTransferHandler {
034            private int[] rows = null;
035            private int addIndex = -1;
036            //Location where items were added
037            private int addCount = 0;
038            //Number of items added.
039            //private ChapterTableModel tmod;
040    
041    
042            /**
043             *  Creates a new <code>TabDelimitedTransferHandler</code> instance.
044             *
045             *@param  tMod  a <code>ChapterTableModel</code> value
046             */
047            public TabDelimitedTransferHandler(ChapterTableModel tMod) {
048                    super();
049                    //this.tmod = tMod;
050            }
051    
052    
053            /**
054             *  Describe <code>exportString</code> method here.
055             *
056             *@param  comp  Description of the Parameter
057             *@return       a <code>String</code> value
058             */
059            protected String exportString(JComponent comp) {
060                    JTable table = (JTable) comp;
061                    rows = table.getSelectedRows();
062                    int colCount = table.getColumnCount();
063    
064                    StringBuffer buff = new StringBuffer();
065    
066                    for (int i = 0; i < rows.length; i++) {
067                            for (int j = 0; j < colCount; j++) {
068                                    Object val = table.getValueAt(rows[i], j);
069                                    buff.append(val == null ? "" : val.toString());
070                                    if (j != colCount - 1) {
071                                            buff.append("\t");
072                                    }
073                            }
074                            if (i != rows.length - 1) {
075                                    buff.append("\n");
076                            }
077                    }
078    
079                    return buff.toString();
080            }
081    
082    
083            /**
084             *  Describe <code>importString</code> method here.
085             *
086             *@param  str   a <code>String</code> value
087             *@param  comp  Description of the Parameter
088             */
089            protected void importString(JComponent comp, String str) {
090                    JTable target = (JTable) comp;
091                    DefaultTableModel model = (DefaultTableModel) target.getModel();
092                    int index = target.getSelectedRow();
093    
094                    //Prevent the user from dropping data back on itself.
095                    //For example, if the user is moving rows #4,#5,#6 and #7 and
096                    //attempts to insert the rows after row #5, this would
097                    //be problematic when removing the original rows.
098                    //So this is not allowed.
099                    if (rows != null && index >= rows[0] - 1 &&
100                                    index <= rows[rows.length - 1]) {
101                            rows = null;
102                            return;
103                    }
104    
105                    int max = model.getRowCount();
106                    if (index < 0) {
107                            index = max;
108                    } else {
109                            index++;
110                            if (index > max) {
111                                    index = max;
112                            }
113                    }
114                    addIndex = index;
115                    String[] values = str.split("\n");
116                    addCount = values.length;
117                    int colCount = target.getColumnCount();
118                    for (int i = 0; i < values.length && i < colCount; i++) {
119                            model.insertRow(index++, values[i].split("\t"));
120                    }
121            }
122    
123    
124            /**
125             *  Describe <code>cleanup</code> method here.
126             *
127             *@param  remove  a <code>boolean</code> value
128             *@param  comp    Description of the Parameter
129             */
130            protected void cleanup(JComponent comp, boolean remove) {
131                    JTable source = (JTable) comp;
132                    if (remove && rows != null) {
133                            DefaultTableModel model =
134                                            (DefaultTableModel) source.getModel();
135    
136                            //If we are moving items around in the same table, we
137                            //need to adjust the rows accordingly, since those
138                            //after the insertion point have moved.
139                            if (addCount > 0) {
140                                    for (int i = 0; i < rows.length; i++) {
141                                            if (rows[i] > addIndex) {
142                                                    rows[i] += addCount;
143                                            }
144                                    }
145                            }
146                            for (int i = rows.length - 1; i >= 0; i--) {
147                                    model.removeRow(rows[i]);
148                            }
149                    }
150                    rows = null;
151                    addCount = 0;
152                    addIndex = -1;
153            }
154    }
155