From 81c9b92f277c70cdf00cd3acf8ae746f05d79fc7 Mon Sep 17 00:00:00 2001 From: Dick Fickling Date: Wed, 22 Feb 2012 17:18:12 -0500 Subject: [PATCH 1/6] Make file content viewable from blackboard entry --- .../autopsy/datamodel/BlackboardArtifactNode.java | 15 ++++++++++++++- .../autopsy/directorytree/ViewContextAction.java | 6 ++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 939a12542a..de447a5b71 100644 --- a/DataModel/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -26,6 +26,7 @@ import java.util.logging.Logger; import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; import org.openide.nodes.Sheet; +import org.openide.util.Lookup; import org.openide.util.lookup.Lookups; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; @@ -44,7 +45,8 @@ public class BlackboardArtifactNode extends AbstractNode implements DisplayableI static final Logger logger = Logger.getLogger(BlackboardArtifactNode.class.getName()); public BlackboardArtifactNode(BlackboardArtifact artifact) { - super(Children.LEAF, Lookups.singleton(new ArtifactStringContent(artifact))); + super(Children.LEAF, Lookups.singleton(getAssociatedFile(artifact))); + //super(Children.LEAF, Lookups.singleton(new ArtifactStringContent(artifact))); this.artifact = artifact; this.setName(Long.toString(artifact.getArtifactID())); this.setDisplayName(artifact.getDisplayName()); @@ -129,6 +131,17 @@ public class BlackboardArtifactNode extends AbstractNode implements DisplayableI throw new IllegalArgumentException("Couldn't get file from database"); } + public static File getAssociatedFile(BlackboardArtifact artifact){ + try { + return artifact.getSleuthkitCase().getFileById(artifact.getObjectID()); + } catch (SQLException ex) { + logger.log(Level.WARNING, "SQL query threw exception", ex); + } catch (TskException ex) { + logger.log(Level.WARNING, "Getting file failed", ex); + } + throw new IllegalArgumentException("Couldn't get file from database"); + } + public Directory getParentDirectory(){ try{ return getAssociatedFile().getParentDirectory(); diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java index c65a11b027..40e5eaa012 100644 --- a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java +++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/ViewContextAction.java @@ -69,10 +69,11 @@ class ViewContextAction extends AbstractAction { ReverseHierarchyVisitor vtor = new ReverseHierarchyVisitor(); List hierarchy = node.getAssociatedFile().accept(vtor); Collections.reverse(hierarchy); - Node generated = new AbstractNode(new RootContentChildren(hierarchy)); + Node generated = new DirectoryTreeFilterNode(new AbstractNode(new RootContentChildren(hierarchy))); Children genChilds = generated.getChildren(); final DirectoryTreeTopComponent directoryTree = DirectoryTreeTopComponent.findInstance(); + TreeView tree = directoryTree.getTree(); ExplorerManager man = directoryTree.getExplorerManager(); Node dirRoot = man.getRootContext(); Children dirChilds = dirRoot.getChildren(); @@ -85,6 +86,7 @@ class ViewContextAction extends AbstractAction { Node currentDirectoryTreeNode = dirChilds.getNodeAt(j); if (currentGeneratedNode.getDisplayName().equals(currentDirectoryTreeNode.getDisplayName())) { dirExplored = currentDirectoryTreeNode; + tree.expandNode(dirExplored); dirChilds = currentDirectoryTreeNode.getChildren(); break; } @@ -93,7 +95,6 @@ class ViewContextAction extends AbstractAction { try { if (dirExplored != null) { - TreeView tree = directoryTree.getTree(); tree.expandNode(dirExplored); man.setExploredContextAndSelection(dirExplored, new Node[]{dirExplored}); } @@ -114,6 +115,7 @@ class ViewContextAction extends AbstractAction { for (int i = 0; i < resultChilds.getNodesCount(); i++) { Node current = resultChilds.getNodeAt(i); if (generated.getName().equals(current.getName())) { + dataResult.requestActive(); dataResult.setSelectedNodes(new Node[]{current}); break; } From d3f5b054ec37fdd6f29ba125c94e32a7babcdeab Mon Sep 17 00:00:00 2001 From: Dick Fickling Date: Wed, 22 Feb 2012 17:19:18 -0500 Subject: [PATCH 2/6] Ingest Service now keeps track of current Keyword Lists --- .../KeywordSearchIngestService.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java index f8b3c86a63..4f815b8c7e 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java @@ -64,6 +64,7 @@ public final class KeywordSearchIngestService implements IngestServiceFsContent private volatile boolean commitIndex = false; //whether to commit index next time private volatile boolean runTimer = false; private List keywords; //keywords to search + private List keywordLists; // lists currently being searched //private final Object lock = new Object(); private Thread timer; private Indexer indexer; @@ -188,6 +189,7 @@ public final class KeywordSearchIngestService implements IngestServiceFsContent reportedHits = new HashMap>(); keywords = new ArrayList(); + keywordLists = new ArrayList(); updateKeywords(); @@ -277,17 +279,32 @@ public final class KeywordSearchIngestService implements IngestServiceFsContent } } + /** + * Retrieve the updated keyword search lists from the XML loader + */ private void updateKeywords() { KeywordSearchListsXML loader = KeywordSearchListsXML.getCurrent(); keywords.clear(); + keywordLists.clear(); for(KeywordSearchList list : loader.getListsL()){ if(list.getUseForIngest()) + keywordLists.add(list); keywords.addAll(list.getKeywords()); } logger.info(keywords.size()+""); } + + List getKeywordLists() { + List ret = new ArrayList(); + if(keywordLists == null) + return ret; + for(KeywordSearchList list : keywordLists) { + ret.add(list.getName()); + } + return ret; + } //CommitTimer wakes up every interval ms //and sets a flag for indexer to commit after indexing next file From 290528d4696f3273ea53cc911418b3006ab0ec36 Mon Sep 17 00:00:00 2001 From: Dick Fickling Date: Thu, 23 Feb 2012 09:48:06 -0500 Subject: [PATCH 3/6] Hide known files from search filters --- .../autopsy/datamodel/FileSearchFilterChildren.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/FileSearchFilterChildren.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/FileSearchFilterChildren.java index 669e76b9ce..4ed4ece677 100644 --- a/DataModel/src/org/sleuthkit/autopsy/datamodel/FileSearchFilterChildren.java +++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/FileSearchFilterChildren.java @@ -44,6 +44,7 @@ class FileSearchFilterChildren extends ChildFactory { SleuthkitCase skCase; FileSearchFilter filter; + Logger logger = Logger.getLogger(FileSearchFilterChildren.class.getName()); public FileSearchFilterChildren(FileSearchFilter filter, SleuthkitCase skCase) { this.filter = filter; @@ -57,10 +58,11 @@ class FileSearchFilterChildren extends ChildFactory { } private String createQuery(){ - String query = "select * from tsk_files where 0"; + String query = "select * from tsk_files where known <> 1 and (0"; for(String s : filter.getFilter()){ query += " or name like '%" + s + "'"; } + query += ')'; return query; } @@ -78,8 +80,7 @@ class FileSearchFilterChildren extends ChildFactory { if (s != null) s.close(); } catch (SQLException ex) { - Logger.getLogger(FileSearchFilterChildren.class.getName()) - .log(Level.INFO, "Couldn't get search results", ex); + logger.log(Level.INFO, "Couldn't get search results", ex); } return list; From 608337d3b77fba414587c1e4e998764ea9fce90d Mon Sep 17 00:00:00 2001 From: Dick Fickling Date: Thu, 23 Feb 2012 15:38:38 -0500 Subject: [PATCH 4/6] Disable unsupported Data Content Viewers --- .../DataContentViewerArtifact.java | 22 ++++++++++++-- .../corecomponents/DataContentViewerHex.java | 7 +++++ .../DataContentViewerPicture.java | 30 +++++++++---------- .../DataContentViewerString.java | 7 +++++ .../datamodel/ArtifactStringContent.java | 17 ++++++++++- .../DirectoryTreeTopComponent.java | 9 ++++-- 6 files changed, 71 insertions(+), 21 deletions(-) diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java index 4c2c74b80e..5d55dab6ae 100644 --- a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java +++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java @@ -277,12 +277,30 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat @Override public boolean isSupported(Node node) { - return true; + if (node == null) { + return false; + } + + ArtifactStringContent artifact = node.getLookup().lookup(ArtifactStringContent.class); + Content content = node.getLookup().lookup(Content.class); + + if(artifact != null) { + return true; + } + if(content != null) { + try { + int size = content.getAllArtifacts().size(); + return size > 0; + } catch (TskException ex) { + logger.log(Level.WARNING, "Couldn't get All blackboard Artifacts", ex); + } + } + return false; } @Override public boolean isPreferred(Node node, boolean isSupported) { - return false; + return node.getLookup().lookup(ArtifactStringContent.class) != null; } private void customizeComponents(){ diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.java b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.java index ce7a5ecc28..6dc35b4a7e 100644 --- a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.java +++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.java @@ -31,6 +31,7 @@ import org.openide.util.lookup.ServiceProvider; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.datamodel.DataConversion; import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.File; import org.sleuthkit.datamodel.TskException; /** @@ -370,6 +371,12 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont @Override public boolean isSupported(Node node) { + if(node == null) { + return false; + } + File file = node.getLookup().lookup(File.class); + if(file != null && file.getSize() == 0) + return false; return true; } diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerPicture.java b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerPicture.java index 59e2edfec7..ebed25f32b 100644 --- a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerPicture.java +++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerPicture.java @@ -150,22 +150,22 @@ public class DataContentViewerPicture extends javax.swing.JPanel implements Data || //node.getDisplayName().toLowerCase().endsWith(".tif") || //node.getDisplayName().toLowerCase().endsWith(".tiff") || //node.getDisplayName().toLowerCase().endsWith(".tga") || - node.getDisplayName().toLowerCase().endsWith(".png");*/ + node.getDisplayName().toLowerCase().endsWith(".png");*/ File file = node.getLookup().lookup(File.class); - - if(file != null){ - return file.getName().toLowerCase().endsWith(".jpg") - || file.getName().toLowerCase().endsWith(".jpeg") - || file.getName().toLowerCase().endsWith(".jpe") - || file.getName().toLowerCase().endsWith(".jfif") - || file.getName().toLowerCase().endsWith(".gif") - || file.getName().toLowerCase().endsWith(".bmp") - || //node.getName().toLowerCase().endsWith(".tif") || - //node.getName().toLowerCase().endsWith(".tiff") || - //node.getName().toLowerCase().endsWith(".tga") || - file.getName().toLowerCase().endsWith(".png"); - } - else{ + + if (file != null) { + return file.getSize() > 0 + && (file.getName().toLowerCase().endsWith(".jpg") + || file.getName().toLowerCase().endsWith(".jpeg") + || file.getName().toLowerCase().endsWith(".jpe") + || file.getName().toLowerCase().endsWith(".jfif") + || file.getName().toLowerCase().endsWith(".gif") + || file.getName().toLowerCase().endsWith(".bmp") + || //node.getName().toLowerCase().endsWith(".tif") || + //node.getName().toLowerCase().endsWith(".tiff") || + //node.getName().toLowerCase().endsWith(".tga") || + file.getName().toLowerCase().endsWith(".png")); + } else { return false; } } else { diff --git a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerString.java b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerString.java index c603169363..ad0396f8c0 100644 --- a/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerString.java +++ b/CoreComponents/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerString.java @@ -32,6 +32,7 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.datamodel.DataConversion; import org.sleuthkit.autopsy.datamodel.StringContent; import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.File; import org.sleuthkit.datamodel.TskException; /** @@ -360,6 +361,12 @@ public class DataContentViewerString extends javax.swing.JPanel implements DataC @Override public boolean isSupported(Node node) { + if(node == null) { + return false; + } + File file = node.getLookup().lookup(File.class); + if(file != null && file.getSize() == 0) + return false; return true; } diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/ArtifactStringContent.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/ArtifactStringContent.java index c055a9b30a..a8b32e54a7 100644 --- a/DataModel/src/org/sleuthkit/autopsy/datamodel/ArtifactStringContent.java +++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/ArtifactStringContent.java @@ -18,10 +18,13 @@ */ package org.sleuthkit.autopsy.datamodel; +import java.sql.SQLException; import java.util.Arrays; -import org.openide.util.Exceptions; +import java.util.logging.Level; +import java.util.logging.Logger; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; +import org.sleuthkit.datamodel.File; import org.sleuthkit.datamodel.TskException; /** @@ -31,6 +34,7 @@ import org.sleuthkit.datamodel.TskException; */ public class ArtifactStringContent implements StringContent{ BlackboardArtifact wrapped; + static final Logger logger = Logger.getLogger(ArtifactStringContent.class.getName()); public ArtifactStringContent(BlackboardArtifact art){ wrapped = art; @@ -74,4 +78,15 @@ public class ArtifactStringContent implements StringContent{ } } + public static File getAssociatedFile(BlackboardArtifact artifact){ + try { + return artifact.getSleuthkitCase().getFileById(artifact.getObjectID()); + } catch (SQLException ex) { + logger.log(Level.WARNING, "SQL query threw exception", ex); + } catch (TskException ex) { + logger.log(Level.WARNING, "Getting file failed", ex); + } + throw new IllegalArgumentException("Couldn't get file from database"); + } + } diff --git a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java index 6cbcd597aa..e6c5892311 100644 --- a/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java +++ b/DirectoryTree/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java @@ -579,8 +579,11 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat Node treeNode = DirectoryTreeTopComponent.this.getSelectedNode(); if (treeNode != null) { - Node originNode = treeNode.getLookup().lookup(DirectoryTreeFilterNode.OriginalNode.class).getNode(); - + OriginalNode origin = treeNode.getLookup().lookup(DirectoryTreeFilterNode.OriginalNode.class); + if(origin == null) + return; + Node originNode = origin.getNode(); + //int count = originNode.getChildren().getNodesCount(true); //if (count > 1000) { // DirectoryTreeTopComponent.this.setCursor(null); @@ -723,10 +726,10 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat @Override public void run() { - Children resultChilds = dataResult.getRootNode().getChildren(); Node select = resultChilds.findChild(Long.toString(art.getArtifactID())); if (select != null) { + dataResult.requestActive(); dataResult.setSelectedNodes(new Node[]{select}); } } From 056867d61a8f6119fd6eb429dae9988c20cb73a7 Mon Sep 17 00:00:00 2001 From: Dick Fickling Date: Thu, 23 Feb 2012 15:41:17 -0500 Subject: [PATCH 5/6] Recent Files and File Types adjustments in Directory Tree --- .../datamodel/RecentFilesChildren.java | 42 ++++++++++++++++++- .../datamodel/RecentFilesFilterChildren.java | 37 ++-------------- .../datamodel/RecentFilesFilterNode.java | 13 +++++- .../autopsy/datamodel/SearchFilters.java | 13 ++++-- .../autopsy/datamodel/SearchFiltersNode.java | 4 +- 5 files changed, 66 insertions(+), 43 deletions(-) diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/RecentFilesChildren.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/RecentFilesChildren.java index f865ccccb6..7f1245fef2 100644 --- a/DataModel/src/org/sleuthkit/autopsy/datamodel/RecentFilesChildren.java +++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/RecentFilesChildren.java @@ -18,8 +18,13 @@ */ package org.sleuthkit.autopsy.datamodel; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; import java.util.Arrays; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; import org.openide.nodes.ChildFactory; import org.openide.nodes.Node; import org.sleuthkit.datamodel.SleuthkitCase; @@ -31,6 +36,8 @@ import org.sleuthkit.datamodel.SleuthkitCase; public class RecentFilesChildren extends ChildFactory{ SleuthkitCase skCase; + long latestUpdateTime; + private final static Logger logger = Logger.getLogger(RecentFilesChildren.class.getName()); public RecentFilesChildren(SleuthkitCase skCase) { this.skCase = skCase; @@ -39,12 +46,45 @@ public class RecentFilesChildren extends ChildFactory list) { list.addAll(Arrays.asList(RecentFiles.RecentFilesFilter.values())); + latestUpdateTime = getLastTime(); return true; } @Override protected Node createNodeForKey(RecentFiles.RecentFilesFilter key){ - return new RecentFilesFilterNode(skCase, key); + return new RecentFilesFilterNode(skCase, key, latestUpdateTime); + } + + private long getLastTime() { + String query = createMaxQuery("crtime"); + long maxcr = runTimeQuery(query); + query = createMaxQuery("ctime"); + long maxc = runTimeQuery(query); + query = createMaxQuery("mtime"); + long maxm = runTimeQuery(query); + query = createMaxQuery("atime"); + long maxa = runTimeQuery(query); + return Math.max(maxcr, Math.max(maxc, Math.max(maxm, maxa))); + } + + private String createMaxQuery(String attr){ + return "select max(" + attr + ") from tsk_files where " + attr + " < " + System.currentTimeMillis()/1000; + } + + private long runTimeQuery(String query) { + long result = 0; + try { + ResultSet rs = skCase.runQuery(query); + result = rs.getLong(1); + Statement s = rs.getStatement(); + rs.close(); + if (s != null) + s.close(); + } catch (SQLException ex) { + Logger.getLogger(RecentFilesFilterChildren.class.getName()) + .log(Level.INFO, "Couldn't get search results", ex); + } + return result; } } diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/RecentFilesFilterChildren.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/RecentFilesFilterChildren.java index b94a62f539..36ad641afa 100644 --- a/DataModel/src/org/sleuthkit/autopsy/datamodel/RecentFilesFilterChildren.java +++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/RecentFilesFilterChildren.java @@ -44,11 +44,13 @@ public class RecentFilesFilterChildren extends ChildFactory{ SleuthkitCase skCase; RecentFilesFilter filter; + long latestUpdate; private final static Logger logger = Logger.getLogger(RecentFilesFilterChildren.class.getName()); - RecentFilesFilterChildren(RecentFilesFilter filter, SleuthkitCase skCase) { + RecentFilesFilterChildren(RecentFilesFilter filter, SleuthkitCase skCase, long latestUpdate) { this.skCase = skCase; this.filter = filter; + this.latestUpdate = latestUpdate; } @Override @@ -59,7 +61,6 @@ public class RecentFilesFilterChildren extends ChildFactory{ private String createQuery(){ String query = "select * from tsk_files where "; - long latestUpdate = getLastTime(); long threshold = latestUpdate-filter.getDurationSeconds(); query += "(crtime between " + threshold + " and " + latestUpdate + ") or "; query += "(ctime between " + threshold + " and " + latestUpdate + ") or "; @@ -109,36 +110,4 @@ public class RecentFilesFilterChildren extends ChildFactory{ }); } - - private long getLastTime() { - String query = createMaxQuery("crtime"); - long maxcr = runTimeQuery(query); - query = createMaxQuery("ctime"); - long maxc = runTimeQuery(query); - query = createMaxQuery("mtime"); - long maxm = runTimeQuery(query); - query = createMaxQuery("atime"); - long maxa = runTimeQuery(query); - return Math.max(maxcr, Math.max(maxc, Math.max(maxm, maxa))); - } - - private String createMaxQuery(String attr){ - return "select max(" + attr + ") from tsk_files where " + attr + " < " + System.currentTimeMillis()/1000; - } - - private long runTimeQuery(String query) { - long result = 0; - try { - ResultSet rs = skCase.runQuery(query); - result = rs.getLong(1); - Statement s = rs.getStatement(); - rs.close(); - if (s != null) - s.close(); - } catch (SQLException ex) { - Logger.getLogger(RecentFilesFilterChildren.class.getName()) - .log(Level.INFO, "Couldn't get search results", ex); - } - return result; - } } diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/RecentFilesFilterNode.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/RecentFilesFilterNode.java index 953e8b7568..a32e229890 100644 --- a/DataModel/src/org/sleuthkit/autopsy/datamodel/RecentFilesFilterNode.java +++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/RecentFilesFilterNode.java @@ -18,6 +18,12 @@ */ package org.sleuthkit.autopsy.datamodel; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Date; +import java.util.logging.Level; +import java.util.logging.Logger; import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; import org.openide.nodes.Sheet; @@ -34,12 +40,15 @@ public class RecentFilesFilterNode extends AbstractNode implements DisplayableIt SleuthkitCase skCase; RecentFilesFilter filter; - RecentFilesFilterNode(SleuthkitCase skCase, RecentFilesFilter filter) { - super(Children.create(new RecentFilesFilterChildren(filter, skCase), true), Lookups.singleton(filter)); + RecentFilesFilterNode(SleuthkitCase skCase, RecentFilesFilter filter, long latestUpdate) { + super(Children.create(new RecentFilesFilterChildren(filter, skCase, latestUpdate), true), Lookups.singleton(filter)); super.setName(filter.getName()); super.setDisplayName(filter.getDisplayName()); this.skCase = skCase; this.filter = filter; + String tooltip = "Between " + new Date((latestUpdate-filter.getDurationSeconds())*1000).toString(); + tooltip += "\n and " + new Date(latestUpdate*1000).toString(); + this.setShortDescription(tooltip); this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/recent-icon.png"); } diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/SearchFilters.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/SearchFilters.java index 2d9e8378c2..4491ee3dd8 100644 --- a/DataModel/src/org/sleuthkit/autopsy/datamodel/SearchFilters.java +++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/SearchFilters.java @@ -30,10 +30,15 @@ public class SearchFilters implements AutopsyVisitableItem{ SleuthkitCase skCase; public enum FileSearchFilter implements AutopsyVisitableItem { - TSK_IMAGE_FILTER(0, "TSK_IMAGE_FILTER", "Images", Arrays.asList(".jpg", ".jpeg", ".png", ".psd", ".nef")), - TSK_VIDEO_FILTER(1, "TSK_VIDEO_FILTER", "Videos", Arrays.asList(".mov", ".avi", ".m4v")), - TSK_AUDIO_FILTER(2, "TSK_AUDIO_FILTER", "Audio", Arrays.asList(".mp3", ".aac", ".wav", ".ogg", ".wma", ".m4a")), - TSK_DOCUMENT_FILTER(3, "TSK_DOCUMENT_FILTER", "Documents", Arrays.asList(".doc", ".docx", ".pdf", ".xls")); + TSK_IMAGE_FILTER(0, "TSK_IMAGE_FILTER", "Images", Arrays.asList(".jpg", ".jpeg", ".png", ".psd", ".nef", ".tiff")), + TSK_VIDEO_FILTER(1, "TSK_VIDEO_FILTER", "Videos", + Arrays.asList(".aaf", ".3gp", ".asf", ".avi", ".m1v", ".m2v", ".m4v", + ".mov", ".mpeg", ".mpg", ".mpe", ".mp4", ".rm", ".wmv", ".mpv")), + TSK_AUDIO_FILTER(2, "TSK_AUDIO_FILTER", "Audio", + Arrays.asList(".aiff", ".aif", ".flac", ".wav", ".m4a", ".ape", ".wma", ".mp2", + ".mp1", ".mp3", ".aac", ".mp4", ".m4p", ".m1a", ".m2a", ".m4r", ".mpa", + ".m3u", ".mid", ".midi", ".ogg")), + TSK_DOCUMENT_FILTER(3, "TSK_DOCUMENT_FILTER", "Documents", Arrays.asList(".doc", ".docx", ".pdf", ".xls", ".rtf", ".txt")); int id; String name; diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/SearchFiltersNode.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/SearchFiltersNode.java index dc9aa1b42a..d285aea416 100644 --- a/DataModel/src/org/sleuthkit/autopsy/datamodel/SearchFiltersNode.java +++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/SearchFiltersNode.java @@ -32,8 +32,8 @@ public class SearchFiltersNode extends AbstractNode implements DisplayableItemNo SearchFiltersNode(SleuthkitCase skCase) { super(Children.create(new SearchFiltersChildren(skCase), true)); - super.setName("Search Filters"); - super.setDisplayName("Search Filters"); + super.setName("File Types"); + super.setDisplayName("File Types"); this.skCase = skCase; this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/filter-icon.png"); } From 3fc87577f52ad75953248a9f4006bd3bc3c8d745 Mon Sep 17 00:00:00 2001 From: Dick Fickling Date: Thu, 23 Feb 2012 15:44:10 -0500 Subject: [PATCH 6/6] Keyword search panel improvements --- .../autopsy/keywordsearch/Bundle.properties | 1 + .../KeywordSearchConfigurationDialog.java | 21 +++- .../KeywordSearchEditListPanel.java | 70 +++++++++++-- .../KeywordSearchIngestService.java | 41 +++++--- .../KeywordSearchListsManagementPanel.java | 23 +---- .../KeywordSearchListsViewerPanel.form | 32 +++--- .../KeywordSearchListsViewerPanel.java | 98 +++++++++++-------- 7 files changed, 184 insertions(+), 102 deletions(-) diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties index 3c7f21cd04..af9866b682 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties @@ -82,3 +82,4 @@ KeywordSearchPanel.settingsLabel.text= KeywordSearchPanel.listsButton.text=Watch Lists KeywordSearchListsViewerPanel.searchAddButton.text=Search KeywordSearchListsViewerPanel.manageListsButton.text=Manage Lists +KeywordSearchListsViewerPanel.ingestLabel.text=Lists added during ingest will be enqueued until index is ready for searching diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchConfigurationDialog.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchConfigurationDialog.java index 71d1d3a8bd..ffe33d2d67 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchConfigurationDialog.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchConfigurationDialog.java @@ -26,16 +26,19 @@ package org.sleuthkit.autopsy.keywordsearch; import java.awt.Dimension; import java.awt.Toolkit; +import java.util.logging.Logger; import javax.swing.JFrame; +import org.sleuthkit.autopsy.ingest.IngestManager; /** * * @author dfickling */ public class KeywordSearchConfigurationDialog extends javax.swing.JDialog { - + KeywordSearchListsManagementPanel listsManagementPanel; KeywordSearchEditListPanel editListPanel; + private final static Logger logger = Logger.getLogger(KeywordSearchConfigurationDialog.class.getName()); /** Creates new form KeywordSearchConfigurationDialog */ public KeywordSearchConfigurationDialog(String title) { @@ -44,17 +47,17 @@ public class KeywordSearchConfigurationDialog extends javax.swing.JDialog { initComponents(); customizeComponents(); } - + private void customizeComponents() { listsManagementPanel = KeywordSearchListsManagementPanel.getDefault(); editListPanel = KeywordSearchEditListPanel.getDefault(); - + listsManagementPanel.addListSelectionListener(KeywordSearchEditListPanel.getDefault()); mainSplitPane.setLeftComponent(listsManagementPanel); mainSplitPane.setRightComponent(editListPanel); mainSplitPane.revalidate(); mainSplitPane.repaint(); - + Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize(); // set the popUp window / JFrame @@ -113,9 +116,17 @@ public class KeywordSearchConfigurationDialog extends javax.swing.JDialog { private void applyButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_applyButtonActionPerformed editListPanel.save(); + KeywordSearchListsXML loader = KeywordSearchListsXML.getCurrent(); + KeywordSearchIngestService service = KeywordSearchIngestService.getDefault(); + if (IngestManager.getDefault().isServiceRunning(service)) { + for (KeywordSearchList list : loader.getListsL()) { + if (list.getUseForIngest()) { + service.addToKeywordLists(list.getName()); + } + } + } this.dispose(); }//GEN-LAST:event_applyButtonActionPerformed - // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton applyButton; private javax.swing.JSplitPane mainSplitPane; diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchEditListPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchEditListPanel.java index fa724f96e4..94951b277b 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchEditListPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchEditListPanel.java @@ -27,6 +27,8 @@ package org.sleuthkit.autopsy.keywordsearch; import java.awt.Component; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import java.io.File; import java.util.ArrayList; import java.util.Iterator; @@ -48,16 +50,18 @@ import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableColumn; +import org.sleuthkit.autopsy.ingest.IngestManager; /** * * @author dfickling */ -public class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelectionListener{ +class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelectionListener{ private static Logger logger = Logger.getLogger(KeywordSearchEditListPanel.class.getName()); private KeywordTableModel tableModel; private String currentKeywordList; + private boolean ingestRunning; private static KeywordSearchEditListPanel instance = null; @@ -137,19 +141,69 @@ public class KeywordSearchEditListPanel extends javax.swing.JPanel implements Li copyMenuItem.addActionListener(actList); pasteMenuItem.addActionListener(actList); selectAllMenuItem.addActionListener(actList); + + + + if(IngestManager.getDefault().isServiceRunning(KeywordSearchIngestService.getDefault())) + initIngest(0); + else + initIngest(1); + + IngestManager.addPropertyChangeListener(new PropertyChangeListener() { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + String changed = evt.getPropertyName(); + Object oldValue = evt.getOldValue(); + if(changed.equals(IngestManager.SERVICE_COMPLETED_EVT) && + ((String) oldValue).equals(KeywordSearchIngestService.MODULE_NAME)) + initIngest(1); + else if(changed.equals(IngestManager.SERVICE_STARTED_EVT) && + ((String) oldValue).equals(KeywordSearchIngestService.MODULE_NAME)) + initIngest(0); + else if(changed.equals(IngestManager.SERVICE_STOPPED_EVT) && + ((String) oldValue).equals(KeywordSearchIngestService.MODULE_NAME)) + initIngest(1); + } + + }); + + } + + /** + * Initialize this panel depending on whether ingest is running + * @param running + * case 0: ingest running + * case 1: ingest not running + */ + private void initIngest(int running) { + switch (running) { + case 0: + ingestRunning = true; + break; + case 1: + ingestRunning = false; + break; + } + initButtons(); } - private void initButtons() { + void initButtons() { //initialize buttons boolean listSet = (currentKeywordList != null); - addWordButton.setEnabled(listSet); - addWordField.setEnabled(listSet); - chRegex.setEnabled(listSet); - useForIngestCheckbox.setEnabled(listSet); + List locked = new ArrayList(); + if (ingestRunning) { + locked = KeywordSearchIngestService.getDefault().getKeywordLists(); + } + boolean currentUnlocked = !locked.contains(currentKeywordList); + addWordButton.setEnabled(listSet && currentUnlocked); + addWordField.setEnabled(listSet && currentUnlocked); + chRegex.setEnabled(listSet && currentUnlocked); + useForIngestCheckbox.setEnabled(listSet && currentUnlocked); saveListButton.setEnabled(listSet); exportButton.setEnabled(listSet); - deleteListButton.setEnabled(listSet); - deleteWordButton.setEnabled(listSet); + deleteListButton.setEnabled(listSet && currentUnlocked); + deleteWordButton.setEnabled(listSet && currentUnlocked); if (getAllKeywords().isEmpty()) { saveListButton.setEnabled(false); diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java index 131df14fa7..6c10599b43 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java @@ -64,7 +64,7 @@ public final class KeywordSearchIngestService implements IngestServiceFsContent private volatile boolean commitIndex = false; //whether to commit index next time private volatile boolean runTimer = false; private List keywords; //keywords to search - private List keywordLists; // lists currently being searched + private List keywordLists; // lists currently being searched //private final Object lock = new Object(); private Thread timer; private Indexer indexer; @@ -189,9 +189,9 @@ public final class KeywordSearchIngestService implements IngestServiceFsContent reportedHits = new HashMap>(); keywords = new ArrayList(); - keywordLists = new ArrayList(); + keywordLists = new ArrayList(); - updateKeywords(); + initKeywords(); if (keywords.isEmpty()) { managerProxy.postMessage(IngestMessage.createErrorMessage(++messageID, instance, "No keywords in keyword list. Will index and skip search.")); @@ -291,9 +291,9 @@ public final class KeywordSearchIngestService implements IngestServiceFsContent } /** - * Retrieve the updated keyword search lists from the XML loader + * Initialize the keyword search lists from the XML loader */ - private void updateKeywords() { + private void initKeywords() { KeywordSearchListsXML loader = KeywordSearchListsXML.getCurrent(); keywords.clear(); @@ -301,20 +301,31 @@ public final class KeywordSearchIngestService implements IngestServiceFsContent for(KeywordSearchList list : loader.getListsL()){ if(list.getUseForIngest()) - keywordLists.add(list); + keywordLists.add(list.getName()); keywords.addAll(list.getKeywords()); } - logger.info(keywords.size()+""); + } + + /** + * Retrieve the updated keyword search lists from the XML loader + */ + private void updateKeywords() { + KeywordSearchListsXML loader = KeywordSearchListsXML.getCurrent(); + + keywords.clear(); + + for(String name : keywordLists) { + keywords.addAll(loader.getList(name).getKeywords()); + } } List getKeywordLists() { - List ret = new ArrayList(); - if(keywordLists == null) - return ret; - for(KeywordSearchList list : keywordLists) { - ret.add(list.getName()); - } - return ret; + return keywordLists == null ? new ArrayList() : keywordLists; + } + + void addToKeywordLists(String name) { + if(!keywordLists.contains(name)) + keywordLists.add(name); } //CommitTimer wakes up every interval ms @@ -571,6 +582,8 @@ public final class KeywordSearchIngestService implements IngestServiceFsContent //logger.log(Level.INFO, "Finished search"); if (finalRun) { + keywords.clear(); + keywordLists.clear(); managerProxy.postMessage(IngestMessage.createMessage(++messageID, MessageType.INFO, KeywordSearchIngestService.instance, "Completed")); } } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsManagementPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsManagementPanel.java index b2b3ea7461..4f7c3321b3 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsManagementPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsManagementPanel.java @@ -46,7 +46,7 @@ import javax.swing.table.DefaultTableCellRenderer; * * @author dfickling */ -public class KeywordSearchListsManagementPanel extends javax.swing.JPanel { +class KeywordSearchListsManagementPanel extends javax.swing.JPanel { private Logger logger = Logger.getLogger(KeywordSearchListsManagementPanel.class.getName()); private KeywordListTableModel tableModel; @@ -411,27 +411,6 @@ public class KeywordSearchListsManagementPanel extends javax.swing.JPanel { } } } - - /** - * tooltips that show text - */ - private static class CellTooltipRenderer extends DefaultTableCellRenderer { - - @Override - public Component getTableCellRendererComponent( - JTable table, Object value, - boolean isSelected, boolean hasFocus, - int row, int column) { - - if (column < 3) { - String val = (String) table.getModel().getValueAt(row, column); - setToolTipText(val); - setText(val); - } - - return this; - } - } void addListSelectionListener(ListSelectionListener l) { listsTable.getSelectionModel().addListSelectionListener(l); diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsViewerPanel.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsViewerPanel.form index 6441ac718f..b12ede9a65 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsViewerPanel.form +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsViewerPanel.form @@ -24,13 +24,20 @@ + + + + + - + + + @@ -42,19 +49,11 @@ - - - - - - - - @@ -85,11 +84,6 @@ - - - - - @@ -131,5 +125,15 @@ + + + + + + + + + + diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsViewerPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsViewerPanel.java index 8ec7242539..a4d0056b12 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsViewerPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsViewerPanel.java @@ -24,6 +24,7 @@ */ package org.sleuthkit.autopsy.keywordsearch; +import java.awt.Component; import java.awt.Cursor; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -35,10 +36,15 @@ import java.util.List; import java.util.Set; import java.util.TreeSet; import java.util.logging.Logger; +import javax.swing.JCheckBox; +import javax.swing.JTable; import javax.swing.ListSelectionModel; +import javax.swing.border.Border; +import javax.swing.border.EmptyBorder; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import org.openide.util.actions.SystemAction; import org.sleuthkit.autopsy.ingest.IngestManager; @@ -47,7 +53,7 @@ import org.sleuthkit.autopsy.ingest.IngestManager; * * @author dfickling */ -public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerformer { +class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerformer { private static final Logger logger = Logger.getLogger(KeywordSearchListsViewerPanel.class.getName()); private static KeywordSearchListsViewerPanel instance; @@ -74,9 +80,9 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme } private void customizeComponents() { - listsTableModel.resync(); - + ingestLabel.setVisible(false); listsTable.setTableHeader(null); + listsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); //customize column witdhs final int leftWidth = leftPane.getPreferredSize().width; TableColumn column = null; @@ -84,6 +90,7 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme column = listsTable.getColumnModel().getColumn(i); if (i == 0) { column.setPreferredWidth(((int) (leftWidth * 0.10))); + column.setCellRenderer(new CheckBoxRenderer()); } else { column.setPreferredWidth(((int) (leftWidth * 0.89))); } @@ -116,6 +123,7 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme else listsTable.getSelectionModel().clearSelection(); } else if (changed.equals(KeywordSearchListsXML.ListsEvt.LIST_UPDATED.toString())) { + //keywordsTableModel.resync(loader.getList((String) newValue)); listsTableModel.resync(); } } @@ -147,7 +155,7 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme } }; - if(IngestManager.getDefault().isFileIngestRunning()) + if(IngestManager.getDefault().isServiceRunning(KeywordSearchIngestService.getDefault())) initIngest(0); else initIngest(1); @@ -164,6 +172,9 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme else if(changed.equals(IngestManager.SERVICE_STARTED_EVT) && ((String) oldValue).equals(KeywordSearchIngestService.MODULE_NAME)) initIngest(0); + else if(changed.equals(IngestManager.SERVICE_STOPPED_EVT) && + ((String) oldValue).equals(KeywordSearchIngestService.MODULE_NAME)) + initIngest(1); } }); @@ -174,8 +185,6 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme * @param running * case 0: ingest running * case 1: ingest not running - * case 2: ingest completed - * case 3: ingest started */ private void initIngest(int running) { ActionListener[] current = searchAddButton.getActionListeners(); @@ -189,12 +198,14 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme searchAddButton.setText("Add to Ingest"); searchAddButton.addActionListener(ingestListener); listsTableModel.resync(); + ingestLabel.setVisible(true); break; case 1: ingestRunning = false; searchAddButton.setText("Search"); searchAddButton.addActionListener(searchListener); listsTableModel.resync(); + ingestLabel.setVisible(false); break; } } @@ -215,10 +226,8 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme keywordsTable = new javax.swing.JTable(); manageListsButton = new javax.swing.JButton(); searchAddButton = new javax.swing.JButton(); + ingestLabel = new javax.swing.JLabel(); - jSplitPane1.setPreferredSize(new java.awt.Dimension(406, 404)); - - leftPane.setBackground(new java.awt.Color(204, 204, 204)); leftPane.setMinimumSize(new java.awt.Dimension(150, 23)); listsTable.setBackground(new java.awt.Color(240, 240, 240)); @@ -230,8 +239,6 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme jSplitPane1.setLeftComponent(leftPane); - rightPane.setBackground(new java.awt.Color(204, 204, 204)); - keywordsTable.setBackground(new java.awt.Color(240, 240, 240)); keywordsTable.setModel(keywordsTableModel); keywordsTable.setShowHorizontalLines(false); @@ -249,6 +256,9 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme searchAddButton.setText(org.openide.util.NbBundle.getMessage(KeywordSearchListsViewerPanel.class, "KeywordSearchListsViewerPanel.searchAddButton.text")); // NOI18N + ingestLabel.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N + ingestLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchListsViewerPanel.class, "KeywordSearchListsViewerPanel.ingestLabel.text")); // NOI18N + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( @@ -260,12 +270,18 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 220, Short.MAX_VALUE) .addComponent(manageListsButton) .addContainerGap()) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(ingestLabel) + .addContainerGap(51, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 268, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 8, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 7, Short.MAX_VALUE) + .addComponent(ingestLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(manageListsButton) .addComponent(searchAddButton)) @@ -278,6 +294,7 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme }//GEN-LAST:event_manageListsButtonActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel ingestLabel; private javax.swing.JSplitPane jSplitPane1; private javax.swing.JTable keywordsTable; private javax.swing.JScrollPane leftPane; @@ -302,7 +319,9 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme } private void addToIngestAction(ActionEvent e) { - //TODO: something + for(KeywordSearchList list : listsTableModel.getSelectedListsL()){ + KeywordSearchIngestService.getDefault().addToKeywordLists(list.getName()); + } } @Override @@ -393,7 +412,8 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme @Override public boolean isCellEditable(int rowIndex, int columnIndex) { - return columnIndex == 0; + List locked = KeywordSearchIngestService.getDefault().getKeywordLists(); + return (columnIndex == 0 && (!ingestRunning || !locked.contains((String)getValueAt(rowIndex, 1)))); } @Override @@ -407,7 +427,7 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme if(entry != null) { entry.selected = (Boolean) aValue; if(ingestRunning) { - updateUseForIngest(getListAt(rowIndex), (Boolean) aValue); + //updateUseForIngest(getListAt(rowIndex), (Boolean) aValue); } } @@ -420,6 +440,7 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme } private void updateUseForIngest(KeywordSearchList list, boolean selected) { + // This causes an event to be fired which resyncs the list and makes user lose selection listsHandle.addList(list.getName(), list.getKeywords(), selected); } @@ -464,29 +485,6 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme fireTableDataChanged(); } - //resync single model entry from handle, then update table - void resync(String listName) { - ListTableEntry found = null; - for (ListTableEntry e : listData) { - if (e.name.equals(listName)) { - found = e; - break; - } - } - if (found != null) { - listData.remove(found); - addList(listsHandle.getList(listName)); - } - fireTableDataChanged(); - } - - //add list to the model - private void addList(KeywordSearchList list) { - if (!listExists(list.getName())) { - listData.add(new ListTableEntry(list, ingestRunning)); - } - } - //add lists to the model private void addLists(List lists) { for (KeywordSearchList list : lists) { @@ -614,5 +612,27 @@ public class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerforme } } - + private static class CheckBoxRenderer extends JCheckBox implements TableCellRenderer{ + + private static final Border noFocusBorder = new EmptyBorder(3, 6, 3, 3); + + @Override + public Component getTableCellRendererComponent( + JTable table, Object value, + boolean isSelected, boolean hasFocus, + int row, int column) { + + setBorder(noFocusBorder); + + if (column == 0) { + String name = (String) table.getModel().getValueAt(row, 1); + Boolean selected = (Boolean) table.getModel().getValueAt(row, 0); + List locked = KeywordSearchIngestService.getDefault().getKeywordLists(); + setEnabled(!locked.contains(name)); + setSelected(selected); + } + + return this; + } + } }