KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > gjt > sp > jedit > browser > VFSDirectoryEntryTableModel


1 /*
2  * VFSDirectoryEntryTableModel.java - VFS directory entry table model
3  * :tabSize=8:indentSize=8:noTabs=false:
4  * :folding=explicit:collapseFolds=1:
5  *
6  * Copyright (C) 2003, 2005 Slava Pestov
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21  */

22
23 package org.gjt.sp.jedit.browser;
24
25 import javax.swing.table.*;
26 import java.util.*;
27 import org.gjt.sp.jedit.io.FileVFS;
28 import org.gjt.sp.jedit.io.VFS;
29 import org.gjt.sp.jedit.io.VFSFile;
30 import org.gjt.sp.jedit.io.VFSManager;
31 import org.gjt.sp.jedit.*;
32 import org.gjt.sp.util.Log;
33 import org.gjt.sp.util.StandardUtilities;
34
35 /**
36  * @author Slava Pestov
37  * @version $Id: VFSDirectoryEntryTableModel.java 7503 2006-10-13 11:22:15Z hertzhaft $
38  * @since jEdit 4.2pre1
39  */

40 public class VFSDirectoryEntryTableModel extends AbstractTableModel
41 {
42     //{{{ VFSDirectoryEntryTableModel constructor
43
public VFSDirectoryEntryTableModel()
44     {
45         extAttrs = new ArrayList<ExtendedAttribute>();
46         sortColumn = 0;
47         ascending = true;
48     } //}}}
49

50     //{{{ setRoot() method
51
public void setRoot(VFS vfs, List<VFSFile> list)
52     {
53         extAttrs.clear();
54         addExtendedAttributes(vfs);
55
56         /* if(files != null && files.length != 0)
57             fireTableRowsDeleted(0,files.length - 1); */

58
59         files = new Entry[list.size()];
60         for(int i = 0; i < files.length; i++)
61         {
62             files[i] = new Entry(list.get(i),0);
63         }
64
65         /* if(files.length != 0)
66             fireTableRowsInserted(0,files.length - 1); */

67
68         Arrays.sort(files, new EntryCompare(getSortAttribute(sortColumn), ascending));
69         fireTableStructureChanged();
70     } //}}}
71

72     //{{{ expand() method
73
public int expand(VFS vfs, Entry entry, List<VFSFile> list)
74     {
75         int startIndex = -1;
76         for(int i = 0; i < files.length; i++)
77         {
78             if(files[i] == entry)
79                 startIndex = i;
80         }
81         if (startIndex != -1)
82             collapse(vfs,startIndex);
83
84         addExtendedAttributes(vfs);
85         entry.expanded = true;
86
87         if(list != null)
88         {
89             // make a large enough destination array
90
Entry[] newFiles = new Entry[files.length + list.size()];
91             Entry[] subdirFiles = new Entry[list.size()];
92
93             for(int i = 0; i < list.size(); i++)
94             {
95                 subdirFiles[i] = new Entry(
96                     list.get(i),entry.level + 1,entry);
97             }
98
99             // sort expanded entries according to current sort params
100
Arrays.sort(subdirFiles, new EntryCompare(
101                 getSortAttribute(sortColumn), ascending));
102             
103             // make room after expanded entry for subdir files
104
int nextIndex = startIndex + 1;
105             System.arraycopy(files,0,newFiles,0,nextIndex);
106             System.arraycopy(subdirFiles,0,newFiles,nextIndex,list.size());
107             System.arraycopy(files,nextIndex,newFiles,nextIndex + list.size(),
108                 files.length - nextIndex);
109
110             this.files = newFiles;
111
112             /* fireTableRowsInserted(startIndex + 1,
113                 startIndex + list.size() + 1); */

114         }
115
116         /* fireTableRowsUpdated(startIndex,startIndex); */
117
118         fireTableStructureChanged();
119
120         return startIndex;
121     } //}}}
122

123     //{{{ collapse() method
124
public void collapse(VFS vfs, int index)
125     {
126         Entry entry = files[index];
127         if(!entry.expanded)
128             return;
129
130         entry.expanded = false;
131
132         int lastIndex = index + 1;
133         while(lastIndex < files.length)
134         {
135             Entry e = files[lastIndex];
136
137             if(e.level <= entry.level)
138                 break;
139
140             lastIndex++;
141
142             if(e.expanded)
143             {
144                 removeExtendedAttributes(VFSManager.getVFSForPath(
145                     e.dirEntry.getPath()));
146             }
147         }
148
149         removeExtendedAttributes(vfs);
150
151         Entry[] newFiles = new Entry[files.length - lastIndex + index + 1];
152         System.arraycopy(files,0,newFiles,0,index + 1);
153         System.arraycopy(files,lastIndex,newFiles,index + 1,
154             files.length - lastIndex);
155
156         files = newFiles;
157
158         /* fireTableRowsUpdated(index,index);
159         fireTableRowsDeleted(index + 1,lastIndex); */

160
161         fireTableStructureChanged();
162     } //}}}
163

164     //{{{ getColumnCount() method
165
public int getColumnCount()
166     {
167         return 1 + extAttrs.size();
168     } //}}}
169

170     //{{{ getRowCount() method
171
public int getRowCount()
172     {
173         if(files == null)
174             return 0;
175         else
176             return files.length;
177     } //}}}
178

179     //{{{ getColumnName() method
180
public String JavaDoc getColumnName(int col)
181     {
182         if(col == 0)
183             return jEdit.getProperty("vfs.browser.name");
184         else
185             return jEdit.getProperty("vfs.browser." + getExtendedAttribute(col));
186     } //}}}
187

188     //{{{ getColumnClass() method
189
public Class JavaDoc getColumnClass(int col)
190     {
191         return Entry.class;
192     } //}}}
193

194     //{{{ getValueAt() method
195
public Object JavaDoc getValueAt(int row, int col)
196     {
197         if(files == null)
198             return null;
199         else
200             return files[row];
201     } //}}}
202

203     //{{{ getAscending() method
204
public boolean getAscending()
205     {
206         return ascending;
207     } //}}}
208

209     //{{{ getSortColumn() method
210
public int getSortColumn()
211     {
212         return sortColumn;
213     } //}}}
214

215     //{{{ getSortAttribute() method
216
public String JavaDoc getSortAttribute(int column)
217     {
218         return (column == 0) ? "name" : getExtendedAttribute(column);
219     } //}}}
220

221     //{{{ sortByColumn() method
222
public boolean sortByColumn(int column)
223     {
224         // toggle ascending/descending if column was clicked again
225
ascending = (sortColumn == column) ? !ascending : true;
226
227         // we don't sort by some attributes
228
String JavaDoc sortBy = getSortAttribute(column);
229         if(sortBy == VFS.EA_STATUS)
230             return false;
231
232         Arrays.sort(files, new EntryCompare(sortBy, ascending));
233
234         // remember column
235
sortColumn = column;
236         fireTableStructureChanged();
237
238         return true;
239     } //}}}
240

241     //{{{ getExtendedAttribute() method
242
public String JavaDoc getExtendedAttribute(int index)
243     {
244         return extAttrs.get(index - 1).name;
245     } //}}}
246

247     //{{{ getColumnWidth() method
248
/**
249      * @param i The column index
250      * @return A saved column width
251      * @since jEdit 4.3pre2
252      */

253     public int getColumnWidth(int i)
254     {
255         String JavaDoc extAttr = getExtendedAttribute(i);
256         return jEdit.getIntegerProperty("vfs.browser."
257             + extAttr + ".width",100);
258     } //}}}
259

260     //{{{ setColumnWidth() method
261
/**
262      * @param i The column index
263      * @param w The column width
264      * @since jEdit 4.3pre2
265      */

266     public void setColumnWidth(int i, int w)
267     {
268         String JavaDoc extAttr = getExtendedAttribute(i);
269         jEdit.setIntegerProperty("vfs.browser."
270             + extAttr + ".width",w);
271     } //}}}
272

273     //{{{ getFiles() method
274
public VFSFile[] getFiles()
275     {
276         VFSFile[] f = new VFSFile[files.length];
277         for(int i = 0; i < f.length; i++)
278             f[i] = files[i].dirEntry;
279         return f;
280     } //}}}
281

282     //{{{ Package-private members
283
Entry[] files;
284     //}}}
285

286     //{{{ Private members
287
private List<ExtendedAttribute> extAttrs;
288     private int sortColumn;
289     private boolean ascending;
290
291     //{{{ addExtendedAttributes() method
292
private void addExtendedAttributes(VFS vfs)
293     {
294         String JavaDoc[] attrs = vfs.getExtendedAttributes();
295 vfs_attr_loop: for(int i = 0; i < attrs.length; i++)
296         {
297             for (ExtendedAttribute attr : extAttrs)
298             {
299                 if (attrs[i].equals(attr.name))
300                 {
301                     attr.ref++;
302                     continue vfs_attr_loop;
303                 }
304             }
305
306             // this vfs has an extended attribute which is not
307
// in the list. add it to the end with a ref count
308
// of 1
309
extAttrs.add(new ExtendedAttribute(attrs[i]));
310         }
311     } //}}}
312

313     //{{{ removeExtendedAttributes() method
314
private void removeExtendedAttributes(VFS vfs)
315     {
316         String JavaDoc[] attrs = vfs.getExtendedAttributes();
317 vfs_attr_loop: for(int i = 0; i < attrs.length; i++)
318         {
319             Iterator<ExtendedAttribute> iter = extAttrs.iterator();
320             while(iter.hasNext())
321             {
322                 ExtendedAttribute attr = iter.next();
323                 if(attrs[i].equals(attr.name))
324                 {
325                     if(--attr.ref == 0)
326                     {
327                         // we no longer have any
328
// dirs using this extended
329
// attribute
330
iter.remove();
331                     }
332
333                     continue vfs_attr_loop;
334                 }
335             }
336
337             // this vfs has an extended attribute which is not
338
// in the list ???
339
Log.log(Log.WARNING,this,"We forgot about " + attrs[i]);
340         }
341     } //}}}
342

343     //}}}
344

345     //{{{ Entry class
346
static class Entry
347     {
348         VFSFile dirEntry;
349         // is this branch an expanded dir?
350
boolean expanded;
351         // how deeply we are nested
352
int level;
353         // parent entry
354
Entry parent;
355         // file extension
356
String JavaDoc extension;
357
358         Entry(VFSFile dirEntry, int level, Entry parent)
359         {
360             this(dirEntry,level);
361             this.parent = parent;
362         }
363
364         Entry(VFSFile dirEntry, int level)
365         {
366             this.dirEntry = dirEntry;
367             this.level = level;
368             this.extension = MiscUtilities.getFileExtension(dirEntry.getName());
369         }
370     } //}}}
371

372     //{{{ ExtendedAttribute class
373
static class ExtendedAttribute
374     {
375         /* reference counter allows us to remove a column from
376          * the table when no directory using this column is
377          * visible */

378         int ref;
379
380         String JavaDoc name;
381
382         ExtendedAttribute(String JavaDoc name)
383         {
384             this.name = name;
385             ref = 1;
386         }
387     } //}}}
388

389     //{{{ EntryCompare class
390
/**
391      * Implementation of {@link Comparator}
392      * interface that compares {@link VFSDirectoryEntryTableModel.Entry} instances.
393      * For sorting columns in the VFS Browser.
394      * @since jEdit 4.3pre7
395      */

396     static class EntryCompare implements Comparator
397     {
398         private boolean sortIgnoreCase, sortMixFilesAndDirs, sortAscending;
399         private String JavaDoc sortAttribute;
400         /**
401          * Creates a new <code>EntryCompare</code>
402          * Expanded branches are sorted, too, but keep with their parent entries
403          * @param sortBy The extended attribute by which to sort the entries.
404          * @param ascending If false, sort order is reversed.
405          */

406         EntryCompare(String JavaDoc sortBy, boolean ascending)
407         {
408             this.sortMixFilesAndDirs = jEdit.getBooleanProperty(
409                 "vfs.browser.sortMixFilesAndDirs");
410             this.sortIgnoreCase = jEdit.getBooleanProperty(
411                 "vfs.browser.sortIgnoreCase");
412             this.sortAscending = ascending;
413             this.sortAttribute = sortBy;
414         }
415
416         public int compare(Object JavaDoc obj1, Object JavaDoc obj2)
417         {
418             Entry entry1 = (Entry)obj1;
419             Entry entry2 = (Entry)obj2;
420
421             // we want to compare sibling ancestors of the entries
422
if(entry1.level < entry2.level)
423                 return compare(entry1, entry2.parent);
424             if(entry1.level > entry2.level)
425                 return compare(entry1.parent, entry2);
426
427             // here we have entries of the same level
428
if(entry1.parent != entry2.parent)
429                 return compare(entry1.parent, entry2.parent);
430
431             // here we have siblings with the same parents
432
// let's do the real comparison
433

434             VFSFile file1 = entry1.dirEntry;
435             VFSFile file2 = entry2.dirEntry;
436
437             if(!sortMixFilesAndDirs)
438             {
439                 if(file1.getType() != file2.getType())
440                     return file2.getType() - file1.getType();
441             }
442
443             int result;
444
445             // if the modified attribute is present, then we have a LocalFile
446
if(sortAttribute == VFS.EA_MODIFIED)
447                 result = (
448                     (Long JavaDoc)((FileVFS.LocalFile)file1).getModified())
449                     .compareTo(
450                     (Long JavaDoc)((FileVFS.LocalFile)file2).getModified());
451             // sort by size
452
else if(sortAttribute == VFS.EA_SIZE)
453                 result = (
454                     (Long JavaDoc)file1.getLength())
455                     .compareTo(
456                     (Long JavaDoc)file2.getLength());
457             // sort by type (= extension)
458
else if(sortAttribute == VFS.EA_TYPE)
459                 result = StandardUtilities.compareStrings(
460                     entry1.extension,
461                     entry2.extension,
462                     sortIgnoreCase);
463             // default: sort by name
464
else
465                 result = StandardUtilities.compareStrings(
466                     file1.getName(),
467                     file2.getName(),
468                     sortIgnoreCase);
469             return (sortAscending) ? result : -result;
470         }
471     } //}}}
472

473 }
474
Popular Tags