From 20d49eec2ba81d5e100dc9f189249a8309c554a4 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Fri, 21 Jun 2024 10:42:43 -0300 Subject: [PATCH 01/32] first commit --- .../java/iped/app/ui/BookmarksManager.java | 123 +++++++++++++++++- 1 file changed, 119 insertions(+), 4 deletions(-) diff --git a/iped-app/src/main/java/iped/app/ui/BookmarksManager.java b/iped-app/src/main/java/iped/app/ui/BookmarksManager.java index 8fb2569acb..4f1d009a81 100644 --- a/iped-app/src/main/java/iped/app/ui/BookmarksManager.java +++ b/iped-app/src/main/java/iped/app/ui/BookmarksManager.java @@ -104,6 +104,8 @@ public class BookmarksManager implements ActionListener, ListSelectionListener, JRadioButton checked = new JRadioButton(); ButtonGroup group = new ButtonGroup(); JCheckBox duplicates = new JCheckBox(); + JCheckBox parentItems = new JCheckBox(); + JCheckBox subItems = new JCheckBox(); JButton butAdd = new JButton(Messages.getString("BookmarksManager.Add")); //$NON-NLS-1$ JButton butRemove = new JButton(Messages.getString("BookmarksManager.Remove")); //$NON-NLS-1$ JButton butEdit = new JButton(Messages.getString("BookmarksManager.Edit")); //$NON-NLS-1$ @@ -148,6 +150,10 @@ private BookmarksManager() { group.add(highlighted); group.add(checked); highlighted.setSelected(true); + subItems.setText("Include Subitems"); //$NON-NLS-1$ + subItems.setSelected(false); + parentItems.setText("Include Parent Item"); //$NON-NLS-1$ + parentItems.setSelected(false); duplicates.setText(Messages.getString("BookmarksManager.AddDuplicates")); //$NON-NLS-1$ duplicates.setSelected(false); @@ -163,11 +169,13 @@ private BookmarksManager() { butDelete.setToolTipText(Messages.getString("BookmarksManager.Delete.Tip")); //$NON-NLS-1$ butEdit.setToolTipText(Messages.getString("BookmarksManager.Edit.Tip")); //$NON-NLS-1$ - JPanel top = new JPanel(new GridLayout(3, 2, 0, 5)); + JPanel top = new JPanel(new GridLayout(4, 2, 0, 5)); top.add(msg); top.add(new JLabel()); top.add(highlighted); top.add(checked); + top.add(subItems); + top.add(parentItems); top.add(duplicates); butAdd.setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE)); @@ -530,19 +538,67 @@ public void actionPerformed(final ActionEvent evt) { private ArrayList getUniqueSelectedIds() { final ArrayList uniqueSelectedIds = new ArrayList(); final App app = App.get(); + IPEDMultiSource ipedCase = app.appCase; if (checked.isSelected()) { int sourceId = 0; - for (IPEDSource source : app.appCase.getAtomicSources()) { + for (IPEDSource source : ipedCase.getAtomicSources()) { BitSet ids = new BitSet(); + BitSet idps = new BitSet(); // we must add items in index order final int finalSourceId = sourceId; source.getLuceneIdStream().forEach(luceneId -> { int id = source.getId(luceneId); if (source.getBookmarks().isChecked(id) && !ids.get(id)) { - uniqueSelectedIds.add(new ItemId(finalSourceId, id)); + ItemId itemId = new ItemId(finalSourceId, id); + uniqueSelectedIds.add(itemId); ids.set(id); + if(parentItems.isSelected()){ + int idp = source.getParentId(id); + idps.set(idp); + } } }); + + try{ + String textQuery = ""; + if(subItems.isSelected()){ + textQuery = ids.toString(); + if (textQuery.compareTo("{}")!=0){ + textQuery = "parentId:" + textQuery.replace("{","(").replace("}",")").replace(",","").trim(); + MultiSearchResult result = new IPEDSearcher(ipedCase, textQuery).multiSearch(); + if (result != null){ + for (IItemId item : result.getIterator()) { + int id2 = item.getId(); + if (!ids.get(id2)){ + ItemId itemId2 = new ItemId(finalSourceId,id2); + uniqueSelectedIds.add(itemId2); + ids.set(id2); + } + } + } + } + } + if(parentItems.isSelected()){ + textQuery = idps.toString(); + if (textQuery.compareTo("{}")!=0){ + textQuery = "id:" + textQuery.replace("{","(").replace("}",")").replace(",","").trim(); + MultiSearchResult result = new IPEDSearcher(ipedCase, textQuery).multiSearch(); + if (result != null){ + for (IItemId item : result.getIterator()) { + int id2 = item.getId(); + if (!ids.get(id2)){ + ItemId itemId2 = new ItemId(finalSourceId,id2); + uniqueSelectedIds.add(itemId2); + ids.set(id2); + } + } + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + sourceId++; } } else if (highlighted.isSelected()) { @@ -552,7 +608,66 @@ private ArrayList getUniqueSelectedIds() { bitSet.set(rowModel); } // we must add items in index order - bitSet.stream().forEach(rowModel -> uniqueSelectedIds.add(app.ipedResult.getItem(rowModel))); + BitSet ids = new BitSet(); + BitSet idps = new BitSet(); + bitSet.stream().forEach(rowModel -> { + IItemId itemId = app.ipedResult.getItem(rowModel); + uniqueSelectedIds.add(itemId); + int id = itemId.getId(); + ids.set(id); + if(parentItems.isSelected()){ + try { + int luceneId = ipedCase.getLuceneId(itemId); + String parentId = ipedCase.getSearcher().doc(luceneId).get(IndexItem.PARENTID); + if (parentId != null && !parentId.isEmpty()){ + int idp = Integer.parseInt(parentId); + idps.set(idp); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + + try{ + String textQuery = ""; + if(subItems.isSelected()){ + textQuery = ids.toString(); + if (textQuery.compareTo("{}")!=0){ + textQuery = "parentId:" + textQuery.replace("{","(").replace("}",")").replace(",","").trim(); + MultiSearchResult result = new IPEDSearcher(ipedCase, textQuery).multiSearch(); + if (result != null){ + for (IItemId item : result.getIterator()) { + int id2 = item.getId(); + if (!ids.get(id2)){ + ItemId itemId2 = new ItemId(item.getSourceId(),id2); + uniqueSelectedIds.add(itemId2); + ids.set(id2); + } + } + } + } + } + if(parentItems.isSelected()){ + textQuery = idps.toString(); + if (textQuery.compareTo("{}")!=0){ + textQuery = "id:" + textQuery.replace("{","(").replace("}",")").replace(",","").trim(); + MultiSearchResult result = new IPEDSearcher(ipedCase, textQuery).multiSearch(); + if (result != null){ + for (IItemId item : result.getIterator()) { + int id2 = item.getId(); + if (!ids.get(id2)){ + ItemId itemId2 = new ItemId(item.getSourceId(),id2 ); + uniqueSelectedIds.add(itemId2); + ids.set(id2); + } + } + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } } return uniqueSelectedIds; From 045e119f23ebdf3a9188b408ca647d9d7d0b30f2 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Fri, 21 Jun 2024 17:05:28 -0300 Subject: [PATCH 02/32] fix mismatch map in multicases --- .../java/iped/app/ui/BookmarksManager.java | 193 ++++++++++++------ 1 file changed, 133 insertions(+), 60 deletions(-) diff --git a/iped-app/src/main/java/iped/app/ui/BookmarksManager.java b/iped-app/src/main/java/iped/app/ui/BookmarksManager.java index 4f1d009a81..b8aefbccc1 100644 --- a/iped-app/src/main/java/iped/app/ui/BookmarksManager.java +++ b/iped-app/src/main/java/iped/app/ui/BookmarksManager.java @@ -89,6 +89,7 @@ import iped.properties.BasicProps; import iped.utils.LocalizedFormat; import iped.viewers.util.ProgressDialog; +import java.util.*; public class BookmarksManager implements ActionListener, ListSelectionListener, KeyListener { @@ -540,21 +541,27 @@ private ArrayList getUniqueSelectedIds() { final App app = App.get(); IPEDMultiSource ipedCase = app.appCase; if (checked.isSelected()) { - int sourceId = 0; for (IPEDSource source : ipedCase.getAtomicSources()) { - BitSet ids = new BitSet(); - BitSet idps = new BitSet(); + BitSetSource idsBSS = new BitSetSource(); + BitSetSource idpsBSS = new BitSetSource(); // we must add items in index order - final int finalSourceId = sourceId; + int sourceId = source.getSourceId(); source.getLuceneIdStream().forEach(luceneId -> { int id = source.getId(luceneId); - if (source.getBookmarks().isChecked(id) && !ids.get(id)) { - ItemId itemId = new ItemId(finalSourceId, id); - uniqueSelectedIds.add(itemId); - ids.set(id); + if (source.getBookmarks().isChecked(id)) { + BitSet ids = idsBSS.getBitSet(sourceId); + if (ids == null){ + ItemId itemId = new ItemId(sourceId, id); + idsBSS.setBitSet(sourceId,id); + uniqueSelectedIds.add(itemId); + }else if (!ids.get(id)){ + ItemId itemId = new ItemId(sourceId, id); + idsBSS.setBitSet(sourceId,id); + uniqueSelectedIds.add(itemId); + } if(parentItems.isSelected()){ int idp = source.getParentId(id); - idps.set(idp); + idpsBSS.setBitSet(sourceId,idp); } } }); @@ -562,34 +569,51 @@ private ArrayList getUniqueSelectedIds() { try{ String textQuery = ""; if(subItems.isSelected()){ - textQuery = ids.toString(); - if (textQuery.compareTo("{}")!=0){ - textQuery = "parentId:" + textQuery.replace("{","(").replace("}",")").replace(",","").trim(); - MultiSearchResult result = new IPEDSearcher(ipedCase, textQuery).multiSearch(); - if (result != null){ - for (IItemId item : result.getIterator()) { - int id2 = item.getId(); - if (!ids.get(id2)){ - ItemId itemId2 = new ItemId(finalSourceId,id2); - uniqueSelectedIds.add(itemId2); - ids.set(id2); + List keys = idsBSS.getBitSetKeys(); + if (keys != null){ + for (int k : keys) { + BitSet ids = idsBSS.getBitSet(k); + if(ids != null){ + textQuery = ids.toString(); + if (textQuery.compareTo("{}")!=0){ + textQuery = "parentId:" + textQuery.replace("{","(").replace("}",")").replace(",","").trim(); + MultiSearchResult result = new IPEDSearcher(ipedCase, textQuery).multiSearch(); + if (result != null){ + for (IItemId item : result.getIterator()) { + int id2 = item.getId(); + if (!ids.get(id2) && k==item.getSourceId()){ + ItemId itemId2 = new ItemId(item.getSourceId(),id2); + uniqueSelectedIds.add(itemId2); + ids.set(id2); + } + } + } } } } } } if(parentItems.isSelected()){ - textQuery = idps.toString(); - if (textQuery.compareTo("{}")!=0){ - textQuery = "id:" + textQuery.replace("{","(").replace("}",")").replace(",","").trim(); - MultiSearchResult result = new IPEDSearcher(ipedCase, textQuery).multiSearch(); - if (result != null){ - for (IItemId item : result.getIterator()) { - int id2 = item.getId(); - if (!ids.get(id2)){ - ItemId itemId2 = new ItemId(finalSourceId,id2); - uniqueSelectedIds.add(itemId2); - ids.set(id2); + List keys = idpsBSS.getBitSetKeys(); + if (keys != null){ + for (int k : keys) { + BitSet idps = idpsBSS.getBitSet(k); + if(idps != null){ + textQuery = idps.toString(); + if (textQuery.compareTo("{}")!=0){ + textQuery = "id:" + textQuery.replace("{","(").replace("}",")").replace(",","").trim(); + MultiSearchResult result = new IPEDSearcher(ipedCase, textQuery).multiSearch(); + if (result != null){ + for (IItemId item : result.getIterator()) { + int id2 = item.getId(); + BitSet ids = idsBSS.getBitSet(k); + if (ids!=null && !ids.get(id2) && k==item.getSourceId()){ + ItemId itemId2 = new ItemId(item.getSourceId(),id2); + uniqueSelectedIds.add(itemId2); + ids.set(id2); + } + } + } } } } @@ -597,9 +621,7 @@ private ArrayList getUniqueSelectedIds() { } } catch (Exception e) { e.printStackTrace(); - } - - sourceId++; + } } } else if (highlighted.isSelected()) { BitSet bitSet = new BitSet(); @@ -608,20 +630,20 @@ private ArrayList getUniqueSelectedIds() { bitSet.set(rowModel); } // we must add items in index order - BitSet ids = new BitSet(); - BitSet idps = new BitSet(); + BitSetSource idsBSS = new BitSetSource(); + BitSetSource idpsBSS = new BitSetSource(); bitSet.stream().forEach(rowModel -> { IItemId itemId = app.ipedResult.getItem(rowModel); uniqueSelectedIds.add(itemId); int id = itemId.getId(); - ids.set(id); + idsBSS.setBitSet(itemId.getSourceId(),id); if(parentItems.isSelected()){ try { int luceneId = ipedCase.getLuceneId(itemId); String parentId = ipedCase.getSearcher().doc(luceneId).get(IndexItem.PARENTID); if (parentId != null && !parentId.isEmpty()){ int idp = Integer.parseInt(parentId); - idps.set(idp); + idpsBSS.setBitSet(itemId.getSourceId(),idp); } } catch (Exception e) { e.printStackTrace(); @@ -632,34 +654,51 @@ private ArrayList getUniqueSelectedIds() { try{ String textQuery = ""; if(subItems.isSelected()){ - textQuery = ids.toString(); - if (textQuery.compareTo("{}")!=0){ - textQuery = "parentId:" + textQuery.replace("{","(").replace("}",")").replace(",","").trim(); - MultiSearchResult result = new IPEDSearcher(ipedCase, textQuery).multiSearch(); - if (result != null){ - for (IItemId item : result.getIterator()) { - int id2 = item.getId(); - if (!ids.get(id2)){ - ItemId itemId2 = new ItemId(item.getSourceId(),id2); - uniqueSelectedIds.add(itemId2); - ids.set(id2); + List keys = idsBSS.getBitSetKeys(); + if (keys != null){ + for (int k : keys) { + BitSet ids = idsBSS.getBitSet(k); + if(ids != null){ + textQuery = ids.toString(); + if (textQuery.compareTo("{}")!=0){ + textQuery = "parentId:" + textQuery.replace("{","(").replace("}",")").replace(",","").trim(); + MultiSearchResult result = new IPEDSearcher(ipedCase, textQuery).multiSearch(); + if (result != null){ + for (IItemId item : result.getIterator()) { + int id2 = item.getId(); + if (!ids.get(id2) && k==item.getSourceId()){ + ItemId itemId2 = new ItemId(item.getSourceId(),id2); + uniqueSelectedIds.add(itemId2); + ids.set(id2); + } + } + } } } } } } if(parentItems.isSelected()){ - textQuery = idps.toString(); - if (textQuery.compareTo("{}")!=0){ - textQuery = "id:" + textQuery.replace("{","(").replace("}",")").replace(",","").trim(); - MultiSearchResult result = new IPEDSearcher(ipedCase, textQuery).multiSearch(); - if (result != null){ - for (IItemId item : result.getIterator()) { - int id2 = item.getId(); - if (!ids.get(id2)){ - ItemId itemId2 = new ItemId(item.getSourceId(),id2 ); - uniqueSelectedIds.add(itemId2); - ids.set(id2); + List keys = idpsBSS.getBitSetKeys(); + if (keys != null){ + for (int k : keys) { + BitSet idps = idpsBSS.getBitSet(k); + if(idps != null){ + textQuery = idps.toString(); + if (textQuery.compareTo("{}")!=0){ + textQuery = "id:" + textQuery.replace("{","(").replace("}",")").replace(",","").trim(); + MultiSearchResult result = new IPEDSearcher(ipedCase, textQuery).multiSearch(); + if (result != null){ + for (IItemId item : result.getIterator()) { + int id2 = item.getId(); + BitSet ids = idsBSS.getBitSet(k); + if (ids!=null && !ids.get(id2) && k==item.getSourceId()){ + ItemId itemId2 = new ItemId(item.getSourceId(),id2); + uniqueSelectedIds.add(itemId2); + ids.set(id2); + } + } + } } } } @@ -843,3 +882,37 @@ public boolean hasSingleKeyShortcut() { return false; } } + +class BitSetSource { + + private Map bitSetMap = null; + + public BitSetSource(){ + this.bitSetMap = new HashMap(); + } + + public void setBitSet(int source, int bit){ + BitSet bs = this.bitSetMap.get(source); + if (bs == null){ + BitSet nbs = new BitSet(); + nbs.set(bit); + this.bitSetMap.put(source,nbs); + }else{ + bs.set(bit); + } + } + + public BitSet getBitSet(int source){ + return this.bitSetMap.get(source); + } + + public List getBitSetKeys(){ + + if (this.bitSetMap != null) + return new ArrayList(this.bitSetMap.keySet()); + else + return null; + + } + +} From b228297ebad0c4e1ed1ab4947489dd474890ee80 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Fri, 2 Aug 2024 12:51:17 -0300 Subject: [PATCH 03/32] add sqlitewalmode config parameter --- iped-app/resources/config/conf/AudioTranscriptConfig.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/iped-app/resources/config/conf/AudioTranscriptConfig.txt b/iped-app/resources/config/conf/AudioTranscriptConfig.txt index 7814aa1331..00e5330e44 100644 --- a/iped-app/resources/config/conf/AudioTranscriptConfig.txt +++ b/iped-app/resources/config/conf/AudioTranscriptConfig.txt @@ -65,6 +65,9 @@ minTimeout = 180 # Number of seconds to wait for each audio second transcription. 'minTimeout' param above is added to this. timeoutPerSec = 3 +# Enable SQLite's WAL mode to mitigate connection errors when the output directory is on a network share +SQLiteWalMode = false + ######################################### # VoskTranscriptTask options ######################################### From 4fa12b8ae0322f71aae085f822f24b097073a3de Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Fri, 2 Aug 2024 12:51:41 -0300 Subject: [PATCH 04/32] add sqlitewalmode config parameter and get method --- .../java/iped/engine/config/AudioTranscriptConfig.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/iped-engine/src/main/java/iped/engine/config/AudioTranscriptConfig.java b/iped-engine/src/main/java/iped/engine/config/AudioTranscriptConfig.java index 7e118e70d4..0ad5256a0b 100644 --- a/iped-engine/src/main/java/iped/engine/config/AudioTranscriptConfig.java +++ b/iped-engine/src/main/java/iped/engine/config/AudioTranscriptConfig.java @@ -35,6 +35,7 @@ public class AudioTranscriptConfig extends AbstractTaskPropertiesConfig { private static final String SKIP_KNOWN_FILES = "skipKnownFiles"; private static final String PRECISION = "precision"; private static final String BATCH_SIZE = "batchSize"; + private static final String SQLITE_WAL_MODE = "SQLiteWalMode"; private List languages = new ArrayList<>(); private List mimesToProcess = new ArrayList<>(); @@ -51,6 +52,7 @@ public class AudioTranscriptConfig extends AbstractTaskPropertiesConfig { private String remoteService; private String googleModel; private boolean skipKnownFiles = true; + private boolean sqliteWalMode = false; private String precision = "int8"; private int batchSize = 1; @@ -62,6 +64,10 @@ public int getBatchSize() { return batchSize; } + public boolean getSqliteWalMode() { + return this.sqliteWalMode; + } + public boolean getSkipKnownFiles() { return this.skipKnownFiles; } @@ -200,6 +206,10 @@ public void processProperties(UTF8Properties properties) { if (value != null) { batchSize = Integer.parseInt(value.trim()); } + value = properties.getProperty(SQLITE_WAL_MODE); + if (value != null) { + this.sqliteWalMode = Boolean.valueOf(value.trim()); + } } /** From 9ce99d86f8cb0d78b67be3e4f1b8477f82df8d08 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Fri, 2 Aug 2024 12:52:28 -0300 Subject: [PATCH 05/32] enable wal mode if the parameter is set to true --- .../iped/engine/task/transcript/AbstractTranscriptTask.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/iped-engine/src/main/java/iped/engine/task/transcript/AbstractTranscriptTask.java b/iped-engine/src/main/java/iped/engine/task/transcript/AbstractTranscriptTask.java index 8c66a3c569..ef4eb5e5a7 100644 --- a/iped-engine/src/main/java/iped/engine/task/transcript/AbstractTranscriptTask.java +++ b/iped-engine/src/main/java/iped/engine/task/transcript/AbstractTranscriptTask.java @@ -31,6 +31,7 @@ import org.slf4j.LoggerFactory; import org.sqlite.SQLiteConfig; import org.sqlite.SQLiteConfig.SynchronousMode; +import org.sqlite.SQLiteConfig.JournalMode; import iped.configuration.Configurable; import iped.configuration.IConfigurationDirectory; @@ -120,6 +121,11 @@ private Connection createConnection(File output) { SQLiteConfig config = new SQLiteConfig(); config.setSynchronous(SynchronousMode.OFF); config.setBusyTimeout(3600000); + + if (transcriptConfig.getSqliteWalMode()){ + config.setJournalMode( JournalMode.WAL ); + } + Connection conn = config.createConnection("jdbc:sqlite:" + db.getAbsolutePath()); try (Statement stmt = conn.createStatement()) { From 8b5a59fb9d7a27189417029a64453ec83cc0efbe Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 30 Dec 2024 13:17:47 -0300 Subject: [PATCH 06/32] Export Case module. All logic to copy files to destination --- .../src/main/java/iped/app/ui/ExportCase.java | 455 ++++++++++++++++++ 1 file changed, 455 insertions(+) create mode 100644 iped-app/src/main/java/iped/app/ui/ExportCase.java diff --git a/iped-app/src/main/java/iped/app/ui/ExportCase.java b/iped-app/src/main/java/iped/app/ui/ExportCase.java new file mode 100644 index 0000000000..afb8217f13 --- /dev/null +++ b/iped-app/src/main/java/iped/app/ui/ExportCase.java @@ -0,0 +1,455 @@ +package iped.app.ui; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.attribute.BasicFileAttributes; +import java.text.DecimalFormat; +import java.util.concurrent.atomic.AtomicLong; +import javax.swing.JOptionPane; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import iped.engine.data.IPEDSource; +import iped.utils.UTF8Properties; +import iped.viewers.api.CancelableWorker; +import iped.viewers.util.ProgressDialog; + +import java.util.*; + +import java.nio.file.*; +import javax.swing.JDialog; + +public class ExportCase extends CancelableWorker { + + ArrayList srcPaths; + ArrayList otherPaths; + String dstPath; + boolean copyImages; + boolean estimateSizeOnly; + Map> imgPaths; + + private static Logger LOGGER = LoggerFactory.getLogger(ExportCase.class); + + protected ProgressDialog progressMonitor; + + boolean success = false; + + Values values = new Values(); + + long free = 0; + + DecimalFormat decimal; + + JDialog dialog; + + public ExportCase(JDialog dialog, ArrayList srcPaths, String dstPath, Map> imgPaths, ArrayList otherPaths,boolean copyImages, boolean estimateSizeOnly){ + + this.srcPaths = srcPaths; + this.otherPaths = otherPaths; + this.dstPath = dstPath; + this.copyImages = copyImages; + this.imgPaths = imgPaths; + this.estimateSizeOnly = estimateSizeOnly; + this.dialog = dialog; + + decimal = new DecimalFormat( "###.##"); + + progressMonitor = new ProgressDialog(this.dialog, this,2); + progressMonitor.setIndeterminate(true); + + free = (new File(dstPath)).getUsableSpace(); + + + } + + @Override + public void done() { + if(progressMonitor != null){ + progressMonitor.close(); + + if (estimateSizeOnly){ + if(success){ + JOptionPane.showMessageDialog(this.dialog, "Estimated Size: "+getEstimateSize(), "Export Case", JOptionPane.INFORMATION_MESSAGE); + dialog.setVisible(true); + } + } + else{ + if(success){ + String msg = copyImages?"with":"without"; + LOGGER.info("Exported Case {} evidences on folder '{}' - Size: {}",msg, dstPath, getEstimateSize()); + JOptionPane.showMessageDialog(this.dialog, "Case successfully exported to:\n"+dstPath, "Export Case", JOptionPane.INFORMATION_MESSAGE); + } + } + } + } + + public long size(Path path) { + + final AtomicLong size = new AtomicLong(0); + + try { + Files.walkFileTree(path, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { + + size.addAndGet(attrs.size()); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(Path file, IOException exc) { + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) { + return FileVisitResult.CONTINUE; + } + }); + } catch (IOException e) { + throw new AssertionError("walkFileTree will not throw IOException if the FileVisitor does not"); + } + + return size.get(); + } + + protected void copyFiles(File src, File target) throws IOException { + + InputStream in = null; + BufferedOutputStream out = null; + + if (progressMonitor.isCanceled()) { + return; + } + + if (src.isDirectory()){ + + if (!target.exists()){ + target.mkdirs(); + } + + String files[] = src.list(); + + for (String file : files){ + File srcFile = new File(src, file); + File destFile = new File(target, file); + + if (progressMonitor.isCanceled()) { + return; + } + copyFiles(srcFile, destFile); + } + } else{ + + try { + + in = new FileInputStream(src); + out = null; + + if(target.isDirectory()) + out = new BufferedOutputStream(new FileOutputStream(new File(target, src.getName()))); + else + out = new BufferedOutputStream(new FileOutputStream(target)); + + byte[] buf = new byte[8*1024]; + int len; + + while ((len = in.read(buf)) >= 0 && !Thread.currentThread().isInterrupted()) { + out.write(buf, 0, len); + values.megas += len; + } + + + in.close(); + out.close(); + + } catch (Exception e1) { + System.out.println("Error on export:"+src); + e1.printStackTrace(); + } finally { + if (in != null) + in.close(); + if (out != null) + out.close(); + } + + } + } + + + protected String getEstimateSize(){ + return formatBytes(values.totalMega); + } + + protected boolean estimateSize(){ + + long size = 0; + + try{ + + for (String path : this.srcPaths) { + size += size(Paths.get(path)); + } + if (copyImages){ + + for (String path2 : this.otherPaths) { + size += size(Paths.get(path2)); + } + + } + + Thread.sleep(1000); + + } catch (Exception e) { + e.printStackTrace(); + } + + values.totalMega = size; + + return true; + + } + + + + + @Override + protected String doInBackground() { + + progressMonitor.setNote("Estimating total size"); + File target = null; + File src = null; + String folderName = "evidences"; + String root = "."+File.separator+folderName+File.separator; + + + + try { + + if (estimateSize()){ + + if (estimateSizeOnly){ + success = true; + return null; + } + + progressMonitor.setIndeterminate(false); + progressMonitor.reset(); + progressMonitor.setMaximum(values.totalMega); + + + ArrayList dstPaths = new ArrayList(); + + Timer timer = new Timer(); + timer.schedule(new RefreshProgress(progressMonitor, values), 0, 1000); + + target = new File(dstPath); + if (target != null){ + for (String path : this.srcPaths) { + + src = new File (path); + + if (src != null && src.exists()){ + copyFiles(src, target); + } + + } + } + + if(copyImages){ + + target = new File(dstPath,folderName); + if (!target.exists()){ + target.mkdirs(); + } + + IPEDSource iCase = new IPEDSource(new File(dstPath)); + for (Long idSleuthCase : imgPaths.keySet()) { + List pathsImage = imgPaths.get(idSleuthCase); + dstPaths.clear(); + for(String path : pathsImage){ + File temp = new File(path); + dstPaths.add(root+temp.getName()); + } + if (iCase!=null){ + iCase.getSleuthCase().setImagePaths(idSleuthCase,dstPaths); + } + } + + for (String path : this.otherPaths) { + + src = new File (path); + + if (src != null && src.exists()){ + if (src.isDirectory()){ + target = new File(dstPath,root+src.getName()); + }else{ + target = new File(dstPath,root); + } + + copyFiles(src, target); + } + + + File newPath = new File(folderName,src.getName()); + File oldPath; + + if (src.isAbsolute()) + oldPath = src; + else + oldPath = new File(dstPath,src.getPath()); + + saveDataSourcePath(new File(dstPath,"iped"),oldPath, newPath); + + } + + + } + + + + timer.cancel(); + + + success = true; + } + }catch (Exception ex) { + ex.printStackTrace(); + System.out.println(ex.getMessage()); + if (progressMonitor != null) + JOptionPane.showMessageDialog(this.dialog, "Export Error! Verify aplication logs.", "Export Case", JOptionPane.ERROR_MESSAGE); + } + + return null; + } + + private static void saveDataSourcePath(File caseModuleDir, File oldPath, File newPath) throws IOException { + String NEW_DATASOURCE_PATH_FILE = "data/newDataSourceLocations.txt"; + File file = new File(caseModuleDir, NEW_DATASOURCE_PATH_FILE); + UTF8Properties props = new UTF8Properties(); + if (file.exists()) + props.load(file); + props.setProperty(oldPath.getPath(), newPath.getPath()); + try { + props.store(file); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public String formatBytes(long soma){ + + String resultado = "0 Bytes"; + + try { + + if (soma >= 1125899906842624.0){ + resultado = decimal.format((soma/1125899906842624.0)) + " PB"; + } else if (soma >= 1099511627776.0){ + resultado = decimal.format((soma/1099511627776.0)) + " TB"; + } else if (soma >= 1073741824.0){ + resultado = decimal.format((soma/1073741824.0)) + " GB"; + } else if (soma >= 1048576.0) { + resultado = decimal.format((soma/1048576.0)) + " MB"; + } else if (soma >= 1024.0) { + resultado = decimal.format((soma/1024.0)) + " KB"; + } else if (soma >= 0.0) { + resultado = decimal.format((soma)) + " B"; + } + } + catch (Exception ex){ + ; + } + + return resultado; + + } + + +} + +class Values { + + public long megas = 0; + public long totalMega = 0; + +} + + +class RefreshProgress extends TimerTask { + + DecimalFormat decimal; + long num = 0; + Values valores = null; + ProgressDialog progressMonitor = null; + + public RefreshProgress(ProgressDialog progressMonitor, Values valores){ + super(); + this.progressMonitor = progressMonitor; + this.valores = valores; + decimal = new DecimalFormat( "###.##"); + } + + public void run() { + + long timeLeft = 0; + this.num++; + + if (progressMonitor.isCanceled()) { + this.cancel(); + return; + } + + if (this.valores.megas <= 0) + timeLeft = 359999; + else + timeLeft = (long)(((double)this.valores.totalMega - (double)this.valores.megas)/((double)this.valores.megas/(double)this.num)); + + String timeLeftString = "Time left: "+formatTime(timeLeft); + + progressMonitor.setProgress(this.valores.megas); + progressMonitor.setNote(""+"Copying " + formatBytes(this.valores.megas) + " of " + formatBytes(this.valores.totalMega)+"
"+timeLeftString+""); + } + public String formatTime(long tempo){ + + long t1 = tempo/3600; + long t2 = ((tempo % 3600) / 60); + long t3 = tempo%60; + String s1 = (t1<10)?("0"+t1):t1+""; + String s2 = (t2<10)?("0"+t2):t2+""; + String s3 = (t3<10)?("0"+t3):t3+""; + return s1+":"+s2+":"+s3; + + } + public String formatBytes(long soma){ + + String resultado = "0 Bytes"; + + try { + + if (soma >= 1125899906842624.0){ + resultado = decimal.format((soma/1125899906842624.0)) + " PB"; + } else if (soma >= 1099511627776.0){ + resultado = decimal.format((soma/1099511627776.0)) + " TB"; + } else if (soma >= 1073741824.0){ + resultado = decimal.format((soma/1073741824.0)) + " GB"; + } else if (soma >= 1048576.0) { + resultado = decimal.format((soma/1048576.0)) + " MB"; + } else if (soma >= 1024.0) { + resultado = decimal.format((soma/1024.0)) + " KB"; + } else if (soma >= 0.0) { + resultado = decimal.format((soma)) + " B"; + } + } + catch (Exception ex){ + ; + } + + return resultado; + + } + +} \ No newline at end of file From d877da87e61c646f0dfcfbda1529bde7a1006786 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 30 Dec 2024 13:17:57 -0300 Subject: [PATCH 07/32] Export case dialog. Create java file. User interface --- .../java/iped/app/ui/ExportCaseDialog.java | 308 ++++++++++++++++++ 1 file changed, 308 insertions(+) create mode 100644 iped-app/src/main/java/iped/app/ui/ExportCaseDialog.java diff --git a/iped-app/src/main/java/iped/app/ui/ExportCaseDialog.java b/iped-app/src/main/java/iped/app/ui/ExportCaseDialog.java new file mode 100644 index 0000000000..810efaa4fe --- /dev/null +++ b/iped-app/src/main/java/iped/app/ui/ExportCaseDialog.java @@ -0,0 +1,308 @@ +package iped.app.ui; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.io.IOException; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JDialog; +import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JTextField; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import iped.properties.BasicProps; +import iped.engine.data.IPEDSource; +import iped.engine.search.IPEDSearcher; +import iped.engine.search.LuceneSearchResult; +import iped.engine.search.MultiSearchResult; +import iped.engine.sleuthkit.SleuthkitInputStreamFactory; +import iped.engine.task.index.IndexItem; + +import org.apache.lucene.document.Document; + +import org.sleuthkit.datamodel.SleuthkitCase; + +import iped.data.IItem; +import iped.data.IItemId; + +import java.util.*; +import iped.engine.task.ExportFileTask.SQLiteInputStreamFactory; + +import java.nio.file.DirectoryStream; +import java.nio.file.Paths; +import java.nio.file.Path; +import java.nio.file.Files; + +public class ExportCaseDialog implements ActionListener { + + private static Logger logger = LoggerFactory.getLogger(ReportDialog.class); + + JDialog dialog = new JDialog(App.get()); + + JTextField newPath = null; + JCheckBox chkCopyImages = new JCheckBox("Export Evidences",true); + JButton btnExport = new JButton("Export"); + JButton btnClose = new JButton("Close"); + JButton btnOpen = new JButton("Open"); + JButton btnSize = new JButton("Estimate Size"); + + + + File casePath = App.get().casesPathFile; + String srcPath = casePath.getAbsolutePath(); + String caseName = casePath.getName(); + ArrayList srcPaths = new ArrayList(); + Map> imgPaths = new HashMap>(); + ArrayList otherPaths = new ArrayList(); + + + HashSet noContent = new HashSet<>(); + + public ExportCaseDialog() { + + + + dialog.setTitle("Export Case"); + dialog.setBounds(0, 0, 800, 250); + dialog.setModal(true); + dialog.setLocationRelativeTo(null); + + + JLabel msg = new JLabel("Export Folder:"); + newPath = new JTextField(); + newPath.setText(""); + + + msg.setBounds(15, 20, 600, 30); + newPath.setBounds(15, 60, 600, 30); + chkCopyImages.setBounds(15, 110, 150, 30); + btnOpen.setBounds(650, 60, 80, 30); + btnExport.setBounds(150, 150, 80, 30); + btnSize.setBounds(270, 150, 130, 30); + btnClose.setBounds(440, 150, 80, 30); + + dialog.getContentPane().add(msg); + dialog.getContentPane().add(newPath); + dialog.getContentPane().add(chkCopyImages); + dialog.getContentPane().add(btnOpen); + dialog.getContentPane().add(btnExport); + dialog.getContentPane().add(btnSize); + dialog.getContentPane().add(btnClose); + dialog.getContentPane().add(new JLabel()); + + btnOpen.addActionListener(this); + btnExport.addActionListener(this); + btnClose.addActionListener(this); + btnSize.addActionListener(this); + + initPaths(); + + } + + public void setVisible() { + dialog.setVisible(true); + } + + public void initPaths(){ + + try{ + + ArrayList doNotIncludeInOthers = new ArrayList(); + doNotIncludeInOthers.add(SleuthkitInputStreamFactory.class.getName()); + doNotIncludeInOthers.add(SQLiteInputStreamFactory.class.getName()); + + srcPaths.add(srcPath); + + for(IPEDSource iCase: App.get().appCase.getAtomicSources()){ + SleuthkitCase sleuthCase = iCase.getSleuthCase(); + if (sleuthCase != null){ + Map> tmp = sleuthCase.getImagePaths(); + tmp.forEach(imgPaths::putIfAbsent); + for (List listPaths : tmp.values()){ + for(String paths: listPaths){ + if (!otherPaths.contains(paths)){ + otherPaths.add(paths); + } + } + } + } + } + + IPEDSearcher task = new IPEDSearcher(App.get().appCase, IndexItem.ISROOT + ":true"); + task.setTreeQuery(true); + LuceneSearchResult rs = MultiSearchResult.get(task.multiSearch(), App.get().appCase); + + boolean shouldAdd = true; + + for (int docID : rs.getLuceneIds()) { + + + Document doc = App.get().appCase.getReader().document(docID); + String dtPath = doc.get(IndexItem.SOURCE_PATH); + String dtDecoder = doc.get(IndexItem.SOURCE_DECODER); + + //workaround for empty datasource path + if (dtPath == null || dtPath.isEmpty()){ + + IItemId item = App.get().appCase.getItemId(docID); + IItem e = App.get().appCase.getItemByItemId(item); + + String query = BasicProps.EVIDENCE_UUID + ":" + e.getDataSource().getUUID(); + IPEDSearcher task2 = new IPEDSearcher(App.get().appCase, query); + LuceneSearchResult rs2 = MultiSearchResult.get(task2.multiSearch(), App.get().appCase); + + for (int docID2 : rs2.getLuceneIds()) { + + Document doc2 = App.get().appCase.getReader().document(docID2); + String dtPath2 = doc2.get(IndexItem.SOURCE_PATH); + String dtDecorder2 = doc2.get(IndexItem.SOURCE_DECODER); + + if (dtPath2 != null && !dtPath2.isEmpty() && dtDecorder2 != null && !dtDecorder2.isEmpty()){ + + + shouldAdd = true; + for (String decoder: doNotIncludeInOthers){ + if(decoder.contains(dtDecorder2)){ + shouldAdd = false; + break; + } + } + + if (shouldAdd){ + dtPath = dtPath2; + dtDecoder = dtDecorder2; + break; + } + } + + } + + } + + shouldAdd = true; + for (String decoder: doNotIncludeInOthers){ + if(decoder.contains(dtDecoder)){ + shouldAdd = false; + break; + } + } + if (dtPath != null && !dtPath.isEmpty()){ + if (shouldAdd){ + otherPaths.add(dtPath); + } + } + + } + + + }catch (Exception ex){ + ex.printStackTrace(); + } + + + } + + @Override + public void actionPerformed(ActionEvent e) { + + + if (e.getSource() == btnClose) { + dialog.setVisible(false); + } + if (e.getSource() == btnOpen) { + JFileChooser c = new JFileChooser(); + c.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + c.setMultiSelectionEnabled(false); + c.setDialogTitle("Open Export Folder"); + int rVal = c.showOpenDialog(dialog); + if (rVal == JFileChooser.APPROVE_OPTION) { + String arquivoAberto = c.getSelectedFile().getAbsolutePath(); + newPath.setText(arquivoAberto); + } + if (rVal == JFileChooser.CANCEL_OPTION) { + ; + } + c = null; + } + if (e.getSource() == btnSize) { + dialog.setVisible(false); + (new ExportCase(this.dialog, srcPaths, "", imgPaths, otherPaths,chkCopyImages.isSelected(), true)).execute(); + } + if (e.getSource() == btnExport) { + + try{ + + String dstPath = newPath.getText(); + + File file = new File(dstPath); + if(!file.exists()){ + JOptionPane.showMessageDialog(dialog, "Invalid Export Folder!","Export Case",JOptionPane.ERROR_MESSAGE); + return; + } + + //dstPath cannot be in same folder as srcPath, consequence -> infinite loop + if(isSubDirectory(casePath,file)){ + JOptionPane.showMessageDialog(dialog, "Export directory cannot be inside case folder!","Export Case",JOptionPane.ERROR_MESSAGE); + return; + } + + + if (dstPath.substring(dstPath.length() - 1).compareTo(File.separator)==0 ) + dstPath += caseName; + else + dstPath += File.separator+caseName; + + File tmpDst = new File (dstPath); + if (tmpDst.exists()){ + if (!isDirEmpty(Paths.get(dstPath))){ + JOptionPane.showMessageDialog(dialog, "Export Folder is not empty!\n"+dstPath,"Export Case",JOptionPane.ERROR_MESSAGE); + return; + } + } + + + dialog.setVisible(false); + (new ExportCase(this.dialog, srcPaths, dstPath, imgPaths, otherPaths,chkCopyImages.isSelected(), false)).execute(); + + }catch (Exception ex){ + ex.printStackTrace(); + } + + } + + + } + + private boolean isDirEmpty(final Path directory){ + try(DirectoryStream dirStream = Files.newDirectoryStream(directory)) { + return !dirStream.iterator().hasNext(); + } + catch (Exception ex){ + return false; + } + } + + + private boolean isSubDirectory(File base, File child) throws IOException { + base = base.getCanonicalFile(); + child = child.getCanonicalFile(); + + File parentFile = child; + while (parentFile != null) { + if (base.equals(parentFile)) { + return true; + } + parentFile = parentFile.getParentFile(); + } + return false; + } + + + + +} \ No newline at end of file From 0449bb099ac98c90da5662d7dadaa3d47331472b Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 30 Dec 2024 13:18:06 -0300 Subject: [PATCH 08/32] Create Menu Item 'Export Case' --- .../src/main/java/iped/app/ui/MenuClass.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/iped-app/src/main/java/iped/app/ui/MenuClass.java b/iped-app/src/main/java/iped/app/ui/MenuClass.java index 1d3810f977..12933168ed 100644 --- a/iped-app/src/main/java/iped/app/ui/MenuClass.java +++ b/iped-app/src/main/java/iped/app/ui/MenuClass.java @@ -35,6 +35,7 @@ import iped.data.IItem; import iped.engine.config.ConfigurationManager; import iped.engine.config.IndexTaskConfig; +import iped.engine.data.IPEDSource; import iped.engine.search.SimilarFacesSearch; import iped.engine.task.similarity.ImageSimilarityTask; import iped.parsers.vcard.VCardParser; @@ -49,7 +50,7 @@ public class MenuClass extends JPopupMenu { checkHighlightedAndSubItems, uncheckHighlightedAndSubItems, checkHighlightedAndParent, uncheckHighlightedAndParent, checkHighlightedAndReferences, uncheckHighlightedAndReferences, checkHighlightedAndReferencedBy, uncheckHighlightedAndReferencedBy, changeGalleryColCount, defaultLayout, changeLayout, previewScreenshot, manageBookmarks, clearSearchHistory, importKeywords, navigateToParent, exportTerms, manageFilters, manageColumns, exportCheckedToZip, exportCheckedTreeToZip, exportTree, exportTreeChecked, similarDocs, openViewfile, createReport, resetColLayout, lastColLayout, saveColLayout, addToGraph, navigateToParentChat, pinFirstColumns, similarImagesCurrent, similarImagesExternal, - similarFacesCurrent, similarFacesExternal, toggleTimelineView, uiZoom, catIconSize, savePanelsLayout, loadPanelsLayout; + similarFacesCurrent, similarFacesExternal, toggleTimelineView, uiZoom, catIconSize, savePanelsLayout, loadPanelsLayout, exportCase; MenuListener menuListener = new MenuListener(this); boolean isTreeMenu; @@ -338,6 +339,21 @@ public void actionPerformed(ActionEvent e) { createReport.addActionListener(menuListener); this.add(createReport); + boolean isReport = false; + for (IPEDSource source : App.get().appCase.getAtomicSources()) { + if (source.isReport()){ + isReport = true; + break; + } + } + + if (!isReport && !App.get().isMultiCase){ + this.addSeparator(); + exportCase = new JMenuItem("Export Case"); //$NON-NLS-1$ + exportCase.addActionListener(menuListener); + this.add(exportCase); + } + } public void addExportTreeMenuItems(JComponent menu) { From 88f7ca30def45a6d11df04240ab41da6f4618891 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 30 Dec 2024 13:18:14 -0300 Subject: [PATCH 09/32] Update menuListner actionperformed calling ExportCase --- iped-app/src/main/java/iped/app/ui/MenuListener.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iped-app/src/main/java/iped/app/ui/MenuListener.java b/iped-app/src/main/java/iped/app/ui/MenuListener.java index d5348a5f19..a13a57341e 100644 --- a/iped-app/src/main/java/iped/app/ui/MenuListener.java +++ b/iped-app/src/main/java/iped/app/ui/MenuListener.java @@ -418,6 +418,8 @@ public void actionPerformed(ActionEvent e) { } else if (e.getSource() == menu.createReport) { new ReportDialog().setVisible(); + } else if (e.getSource() == menu.exportCase) { + new ExportCaseDialog().setVisible(); } else if (e.getSource() == menu.lastColLayout) { ColumnsManager.getInstance().resetToLastLayout(); From 760d78b071e3c01f14e6c001979150342dcf466f Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 30 Dec 2024 13:18:23 -0300 Subject: [PATCH 10/32] Create a way to reset progressDialog initial value --- .../src/main/java/iped/viewers/util/ProgressDialog.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/iped-viewers/iped-viewers-impl/src/main/java/iped/viewers/util/ProgressDialog.java b/iped-viewers/iped-viewers-impl/src/main/java/iped/viewers/util/ProgressDialog.java index 1274ce9d6e..32ed7809fb 100644 --- a/iped-viewers/iped-viewers-impl/src/main/java/iped/viewers/util/ProgressDialog.java +++ b/iped-viewers/iped-viewers-impl/src/main/java/iped/viewers/util/ProgressDialog.java @@ -169,6 +169,10 @@ public void run() { }); } + public void reset(){ + progressBar.setValue(0); + } + public void setMaximum(final long max) { scale = 100f / max; } From 96e4e1aa3e1433e5e93a7ac638416b4ac44d24a9 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Fri, 3 Jan 2025 11:32:51 -0300 Subject: [PATCH 11/32] add localization messages --- .../iped-desktop-messages.properties | 19 +++++++++++++++++++ .../iped-desktop-messages_de_DE.properties | 19 +++++++++++++++++++ .../iped-desktop-messages_es_AR.properties | 19 +++++++++++++++++++ .../iped-desktop-messages_fr_FR.properties | 19 +++++++++++++++++++ .../iped-desktop-messages_it_IT.properties | 19 +++++++++++++++++++ .../iped-desktop-messages_pt_BR.properties | 19 +++++++++++++++++++ 6 files changed, 114 insertions(+) diff --git a/iped-app/resources/localization/iped-desktop-messages.properties b/iped-app/resources/localization/iped-desktop-messages.properties index 0590d6e4de..afcf3aa0d1 100644 --- a/iped-app/resources/localization/iped-desktop-messages.properties +++ b/iped-app/resources/localization/iped-desktop-messages.properties @@ -107,6 +107,24 @@ CopyProperties.CSVDateFormat=MM/dd/yyyy HH:mm:ss z CopyProperties.CSVDelimiter=, CopyProperties.from=\ of DuplicatesTableModel.Duplicates=\ Duplicates +ExportCase.Title=Export Case +ExportCase.ExportEvidence=Export Evidences +ExportCase.ExportFolder=Export Folder +ExportCase.Export=Export +ExportCase.Close=Close +ExportCase.Open=Open +ExportCase.EstimateSize=Estimate Size +ExportCase.OpenExportFolder=Open Export Folder +ExportCase.InvalidExportFolder=Invalid Export Folder! +ExportCase.ExportDirectoryInside=Export directory cannot be inside case folder! +ExportCase.ExportFolderEmpty=Export Folder is not empty! +ExportCase.EstimatedSize=Estimated Size +ExportCase.EstimatingSize=Estimating total size +ExportCase.CaseExported=Case successfully exported to +ExportCase.ExportError=Export Error! Verify aplication logs +ExportCase.of=of +ExportCase.timeLeft=Time left +ExportCase.Copying=Copying ExportFiles.Copying=Copying ExportFiles.of=\ of ExportFilesToZip.Copying=Copying @@ -262,6 +280,7 @@ MenuClass.UncheckHighlightedAndSubItems=Uncheck highlighted items and subitems MenuClass.UncheckHighlightedAndParent=Uncheck highlighted and parent items MenuClass.UncheckHighlightedAndReferences=Uncheck highlighted and reference items MenuClass.UncheckHighlightedAndReferencedBy=Uncheck highlighted and "referenced by" items +MenuClass.ExportCase=Export Case MenuListener.ChatNotFound=Parent chat not found MenuListener.Cols=Columns: MenuListener.ExportTree.Warn=Highlight 01 (one) tree node as export reference\! diff --git a/iped-app/resources/localization/iped-desktop-messages_de_DE.properties b/iped-app/resources/localization/iped-desktop-messages_de_DE.properties index 0b665596d6..d8154dfe25 100644 --- a/iped-app/resources/localization/iped-desktop-messages_de_DE.properties +++ b/iped-app/resources/localization/iped-desktop-messages_de_DE.properties @@ -107,6 +107,24 @@ CopyProperties.CSVDateFormat=dd/MM/yyyy HH:mm:ss z CopyProperties.CSVDelimiter=; CopyProperties.from=\ von DuplicatesTableModel.Duplicates=\ Duplikate +ExportCase.Title=Export Case[TBT] +ExportCase.ExportEvidence=Export Evidences[TBT] +ExportCase.ExportFolder=Export Folder[TBT] +ExportCase.Export=Export[TBT] +ExportCase.Close=Close[TBT] +ExportCase.Open=Open[TBT] +ExportCase.EstimateSize=Estimate Size[TBT] +ExportCase.OpenExportFolder=Open Export Folder[TBT] +ExportCase.InvalidExportFolder=Invalid Export Folder![TBT] +ExportCase.ExportDirectoryInside=Export directory cannot be inside case folder![TBT] +ExportCase.ExportFolderEmpty=Export Folder is not empty![TBT] +ExportCase.EstimatedSize=Estimated Size[TBT] +ExportCase.EstimatingSize=Estimating total size[TBT] +ExportCase.CaseExported=Case successfully exported to[TBT] +ExportCase.ExportError=Export Error! Verify aplication logs[TBT] +ExportCase.of=of[TBT] +ExportCase.timeLeft=Time left[TBT] +ExportCase.Copying=Copying[TBT] ExportFiles.Copying=Kopiere ExportFiles.of=\ von ExportFilesToZip.Copying=Kopiere @@ -262,6 +280,7 @@ MenuClass.UncheckHighlightedAndSubItems=markierte Elemente und Unterelemente abw MenuClass.UncheckHighlightedAndParent=Uncheck highlighted and parent items [TBT] MenuClass.UncheckHighlightedAndReferences=Uncheck highlighted and reference items [TBT] MenuClass.UncheckHighlightedAndReferencedBy=Uncheck highlighted and "referenced by" items [TBT] +MenuClass.ExportCase=Export Case [TBT] MenuListener.ChatNotFound=übergeordneten Chat nicht gefunden MenuListener.Cols=Spalten: MenuListener.ExportTree.Warn=Markiere 01 (einen) Baumknoten als Exportreferenz\! diff --git a/iped-app/resources/localization/iped-desktop-messages_es_AR.properties b/iped-app/resources/localization/iped-desktop-messages_es_AR.properties index 0ae32a0990..2dc4b42635 100644 --- a/iped-app/resources/localization/iped-desktop-messages_es_AR.properties +++ b/iped-app/resources/localization/iped-desktop-messages_es_AR.properties @@ -107,6 +107,24 @@ CopyProperties.CSVDateFormat=dd/MM/yyyy HH:mm:ss z CopyProperties.CSVDelimiter=, CopyProperties.from=\ de DuplicatesTableModel.Duplicates=\ Duplicados +ExportCase.Title=Export Case[TBT] +ExportCase.ExportEvidence=Export Evidences[TBT] +ExportCase.ExportFolder=Export Folder[TBT] +ExportCase.Export=Export[TBT] +ExportCase.Close=Close[TBT] +ExportCase.Open=Open[TBT] +ExportCase.EstimateSize=Estimate Size[TBT] +ExportCase.OpenExportFolder=Open Export Folder[TBT] +ExportCase.InvalidExportFolder=Invalid Export Folder![TBT] +ExportCase.ExportDirectoryInside=Export directory cannot be inside case folder![TBT] +ExportCase.ExportFolderEmpty=Export Folder is not empty![TBT] +ExportCase.EstimatedSize=Estimated Size[TBT] +ExportCase.EstimatingSize=Estimating total size[TBT] +ExportCase.CaseExported=Case successfully exported to[TBT] +ExportCase.ExportError=Export Error! Verify aplication logs[TBT] +ExportCase.of=of[TBT] +ExportCase.timeLeft=Time left[TBT] +ExportCase.Copying=Copying[TBT] ExportFiles.Copying=Copiando ExportFiles.of=\ de ExportFilesToZip.Copying=Copiando @@ -262,6 +280,7 @@ MenuClass.UncheckHighlightedAndSubItems=Desmarcar elementos y subelementos resal MenuClass.UncheckHighlightedAndParent=Uncheck highlighted and parent items [TBT] MenuClass.UncheckHighlightedAndReferences=Uncheck highlighted and reference items [TBT] MenuClass.UncheckHighlightedAndReferencedBy=Uncheck highlighted and "referenced by" items [TBT] +MenuClass.ExportCase=Export Case [TBT] MenuListener.ChatNotFound=Chat principal no encontrado MenuListener.Cols=Columnas: MenuListener.ExportTree.Warn=¡Resalte 01 (un) nodo del árbol como referencia de exportación\! diff --git a/iped-app/resources/localization/iped-desktop-messages_fr_FR.properties b/iped-app/resources/localization/iped-desktop-messages_fr_FR.properties index b5fd73cc6d..40e2d7d7f3 100644 --- a/iped-app/resources/localization/iped-desktop-messages_fr_FR.properties +++ b/iped-app/resources/localization/iped-desktop-messages_fr_FR.properties @@ -107,6 +107,24 @@ CopyProperties.CSVDateFormat=dd/MM/yyyy HH:mm:ss z CopyProperties.CSVDelimiter=; CopyProperties.from=\ de DuplicatesTableModel.Duplicates=\ Doublons +ExportCase.Title=Export Case[TBT] +ExportCase.ExportEvidence=Export Evidences[TBT] +ExportCase.ExportFolder=Export Folder[TBT] +ExportCase.Export=Export[TBT] +ExportCase.Close=Close[TBT] +ExportCase.Open=Open[TBT] +ExportCase.EstimateSize=Estimate Size[TBT] +ExportCase.OpenExportFolder=Open Export Folder[TBT] +ExportCase.InvalidExportFolder=Invalid Export Folder![TBT] +ExportCase.ExportDirectoryInside=Export directory cannot be inside case folder![TBT] +ExportCase.ExportFolderEmpty=Export Folder is not empty![TBT] +ExportCase.EstimatedSize=Estimated Size[TBT] +ExportCase.EstimatingSize=Estimating total size[TBT] +ExportCase.CaseExported=Case successfully exported to[TBT] +ExportCase.ExportError=Export Error! Verify aplication logs[TBT] +ExportCase.of=of[TBT] +ExportCase.timeLeft=Time left[TBT] +ExportCase.Copying=Copying[TBT] ExportFiles.Copying=Copier ExportFiles.of=\ de ExportFilesToZip.Copying=Copier @@ -262,6 +280,7 @@ MenuClass.UncheckHighlightedAndSubItems=Décocher les éléments et sous-éléme MenuClass.UncheckHighlightedAndParent=Uncheck highlighted and parent items [TBT] MenuClass.UncheckHighlightedAndReferences=Uncheck highlighted and reference items [TBT] MenuClass.UncheckHighlightedAndReferencedBy=Uncheck highlighted and "referenced by" items [TBT] +MenuClass.ExportCase=Export Case [TBT] MenuListener.ChatNotFound=Origine du chat non trouvé MenuListener.Cols=Colonnes : MenuListener.ExportTree.Warn=Selectionner 01 (un) nœud de l''arborescence comme référence d''export \! diff --git a/iped-app/resources/localization/iped-desktop-messages_it_IT.properties b/iped-app/resources/localization/iped-desktop-messages_it_IT.properties index 933a9b1ace..09d508bc40 100644 --- a/iped-app/resources/localization/iped-desktop-messages_it_IT.properties +++ b/iped-app/resources/localization/iped-desktop-messages_it_IT.properties @@ -107,6 +107,24 @@ CopyProperties.CSVDateFormat=dd/MM/yyyy HH:mm:ss z CopyProperties.CSVDelimiter=, CopyProperties.from=\ di DuplicatesTableModel.Duplicates=\ Duplicati +ExportCase.Title=Export Case[TBT] +ExportCase.ExportEvidence=Export Evidences[TBT] +ExportCase.ExportFolder=Export Folder[TBT] +ExportCase.Export=Export[TBT] +ExportCase.Close=Close[TBT] +ExportCase.Open=Open[TBT] +ExportCase.EstimateSize=Estimate Size[TBT] +ExportCase.OpenExportFolder=Open Export Folder[TBT] +ExportCase.InvalidExportFolder=Invalid Export Folder![TBT] +ExportCase.ExportDirectoryInside=Export directory cannot be inside case folder![TBT] +ExportCase.ExportFolderEmpty=Export Folder is not empty![TBT] +ExportCase.EstimatedSize=Estimated Size[TBT] +ExportCase.EstimatingSize=Estimating total size[TBT] +ExportCase.CaseExported=Case successfully exported to[TBT] +ExportCase.ExportError=Export Error! Verify aplication logs[TBT] +ExportCase.of=of[TBT] +ExportCase.timeLeft=Time left[TBT] +ExportCase.Copying=Copying[TBT] ExportFiles.Copying=Copia ExportFiles.of=\ di ExportFilesToZip.Copying=Copia @@ -262,6 +280,7 @@ MenuClass.UncheckHighlightedAndSubItems=Deseleziona gli elementi evidenziati e i MenuClass.UncheckHighlightedAndParent=Uncheck highlighted and parent items [TBT] MenuClass.UncheckHighlightedAndReferences=Uncheck highlighted and reference items [TBT] MenuClass.UncheckHighlightedAndReferencedBy=Uncheck highlighted and "referenced by" items [TBT] +MenuClass.ExportCase=Export Case [TBT] MenuListener.ChatNotFound=Chat d''origine non trovata MenuListener.Cols=Colonne: MenuListener.ExportTree.Warn=Evidenzia 01 (un) nodo dell''albero come riferimento all''esportazione\! diff --git a/iped-app/resources/localization/iped-desktop-messages_pt_BR.properties b/iped-app/resources/localization/iped-desktop-messages_pt_BR.properties index 538f7e80ad..47f3dfdb2a 100644 --- a/iped-app/resources/localization/iped-desktop-messages_pt_BR.properties +++ b/iped-app/resources/localization/iped-desktop-messages_pt_BR.properties @@ -107,6 +107,24 @@ CopyProperties.CSVDateFormat=dd/MM/yyyy HH:mm:ss z CopyProperties.CSVDelimiter=; CopyProperties.from=\ de DuplicatesTableModel.Duplicates=\ Duplicatas +ExportCase.Title=Exportar Caso +ExportCase.ExportEvidence=Exportar Evidências +ExportCase.ExportFolder=Diretório de Exportação +ExportCase.Export=Exportar +ExportCase.Close=Fechar +ExportCase.Open=Abrir +ExportCase.EstimateSize=Estimar Tamanho +ExportCase.OpenExportFolder=Abrir Diretório de Exportação +ExportCase.InvalidExportFolder=Diretório de Exportação Inválido! +ExportCase.ExportDirectoryInside=Diretório de Exportação não pode estar dentro do da pasta do caso! +ExportCase.ExportFolderEmpty=Diretório de Exportação não está vazio! +ExportCase.EstimatedSize=Tamanho estimado +ExportCase.EstimatingSize=Estimando tamanho total +ExportCase.CaseExported=Caso exportado com sucesso para +ExportCase.ExportError=Erro na exportação! Verificar logs da aplicação +ExportCase.of=de +ExportCase.timeLeft=Tempo restante +ExportCase.Copying=Copiando ExportFiles.Copying=Copiando ExportFiles.of=\ de ExportFilesToZip.Copying=Copiando @@ -262,6 +280,7 @@ MenuClass.UncheckHighlightedAndSubItems=Desmarcar itens destacados e subitens MenuClass.UncheckHighlightedAndParent=Desmarcar itens destacados e item pai MenuClass.UncheckHighlightedAndReferences=Desmarcar itens destacados e referências MenuClass.UncheckHighlightedAndReferencedBy=Desmarcar itens destacados e "referenciado por" +MenuClass.ExportCase=Exportar Caso MenuListener.ChatNotFound=Chat pai não encontrado MenuListener.Cols=Colunas: MenuListener.ExportTree.Warn=Selecione 01 (um) nó na árvore de diretórios como base de exportação\! From 50cff76b0ddefe948bec8620ff5c861ce9ee6aec Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Fri, 3 Jan 2025 11:33:07 -0300 Subject: [PATCH 12/32] add localization messages --- .../src/main/java/iped/app/ui/ExportCase.java | 12 +++++----- .../java/iped/app/ui/ExportCaseDialog.java | 22 +++++++++---------- .../src/main/java/iped/app/ui/MenuClass.java | 2 +- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/iped-app/src/main/java/iped/app/ui/ExportCase.java b/iped-app/src/main/java/iped/app/ui/ExportCase.java index afb8217f13..aa6fb6d5b6 100644 --- a/iped-app/src/main/java/iped/app/ui/ExportCase.java +++ b/iped-app/src/main/java/iped/app/ui/ExportCase.java @@ -72,7 +72,7 @@ public void done() { if (estimateSizeOnly){ if(success){ - JOptionPane.showMessageDialog(this.dialog, "Estimated Size: "+getEstimateSize(), "Export Case", JOptionPane.INFORMATION_MESSAGE); + JOptionPane.showMessageDialog(this.dialog, Messages.getString("ExportCase.EstimatedSize")+": "+getEstimateSize(), Messages.getString("ExportCase.Title"), JOptionPane.INFORMATION_MESSAGE); dialog.setVisible(true); } } @@ -80,7 +80,7 @@ public void done() { if(success){ String msg = copyImages?"with":"without"; LOGGER.info("Exported Case {} evidences on folder '{}' - Size: {}",msg, dstPath, getEstimateSize()); - JOptionPane.showMessageDialog(this.dialog, "Case successfully exported to:\n"+dstPath, "Export Case", JOptionPane.INFORMATION_MESSAGE); + JOptionPane.showMessageDialog(this.dialog, Messages.getString("ExportCase.CaseExported")+":\n"+dstPath, Messages.getString("ExportCase.Title"), JOptionPane.INFORMATION_MESSAGE); } } } @@ -219,7 +219,7 @@ protected boolean estimateSize(){ @Override protected String doInBackground() { - progressMonitor.setNote("Estimating total size"); + progressMonitor.setNote(Messages.getString("ExportCase.EstimatingSize")); File target = null; File src = null; String folderName = "evidences"; @@ -320,7 +320,7 @@ protected String doInBackground() { ex.printStackTrace(); System.out.println(ex.getMessage()); if (progressMonitor != null) - JOptionPane.showMessageDialog(this.dialog, "Export Error! Verify aplication logs.", "Export Case", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(this.dialog, Messages.getString("ExportCase.ExportError"), Messages.getString("ExportCase.Title"), JOptionPane.ERROR_MESSAGE); } return null; @@ -408,10 +408,10 @@ public void run() { else timeLeft = (long)(((double)this.valores.totalMega - (double)this.valores.megas)/((double)this.valores.megas/(double)this.num)); - String timeLeftString = "Time left: "+formatTime(timeLeft); + String timeLeftString = Messages.getString("ExportCase.timeLeft")+": "+formatTime(timeLeft); progressMonitor.setProgress(this.valores.megas); - progressMonitor.setNote(""+"Copying " + formatBytes(this.valores.megas) + " of " + formatBytes(this.valores.totalMega)+"
"+timeLeftString+""); + progressMonitor.setNote(""+Messages.getString("ExportCase.Copying")+" " + formatBytes(this.valores.megas) +" "+ Messages.getString("ExportCase.of") +" "+formatBytes(this.valores.totalMega)+"
"+timeLeftString+""); } public String formatTime(long tempo){ diff --git a/iped-app/src/main/java/iped/app/ui/ExportCaseDialog.java b/iped-app/src/main/java/iped/app/ui/ExportCaseDialog.java index 810efaa4fe..bba6f09cb2 100644 --- a/iped-app/src/main/java/iped/app/ui/ExportCaseDialog.java +++ b/iped-app/src/main/java/iped/app/ui/ExportCaseDialog.java @@ -45,11 +45,11 @@ public class ExportCaseDialog implements ActionListener { JDialog dialog = new JDialog(App.get()); JTextField newPath = null; - JCheckBox chkCopyImages = new JCheckBox("Export Evidences",true); - JButton btnExport = new JButton("Export"); - JButton btnClose = new JButton("Close"); - JButton btnOpen = new JButton("Open"); - JButton btnSize = new JButton("Estimate Size"); + JCheckBox chkCopyImages = new JCheckBox(Messages.getString("ExportCase.ExportEvidence"),true); + JButton btnExport = new JButton(Messages.getString("ExportCase.Export")); + JButton btnClose = new JButton(Messages.getString("ExportCase.Close")); + JButton btnOpen = new JButton(Messages.getString("ExportCase.Open")); + JButton btnSize = new JButton(Messages.getString("ExportCase.EstimateSize")); @@ -67,13 +67,13 @@ public ExportCaseDialog() { - dialog.setTitle("Export Case"); + dialog.setTitle(Messages.getString("ExportCase.Title")); dialog.setBounds(0, 0, 800, 250); dialog.setModal(true); dialog.setLocationRelativeTo(null); - JLabel msg = new JLabel("Export Folder:"); + JLabel msg = new JLabel(Messages.getString("ExportCase.ExportFolder")); newPath = new JTextField(); newPath.setText(""); @@ -218,7 +218,7 @@ public void actionPerformed(ActionEvent e) { JFileChooser c = new JFileChooser(); c.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); c.setMultiSelectionEnabled(false); - c.setDialogTitle("Open Export Folder"); + c.setDialogTitle(Messages.getString("ExportCase.OpenExportFolder")); int rVal = c.showOpenDialog(dialog); if (rVal == JFileChooser.APPROVE_OPTION) { String arquivoAberto = c.getSelectedFile().getAbsolutePath(); @@ -241,13 +241,13 @@ public void actionPerformed(ActionEvent e) { File file = new File(dstPath); if(!file.exists()){ - JOptionPane.showMessageDialog(dialog, "Invalid Export Folder!","Export Case",JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(dialog, Messages.getString("ExportCase.InvalidExportFolder"), Messages.getString("ExportCase.Title"),JOptionPane.ERROR_MESSAGE); return; } //dstPath cannot be in same folder as srcPath, consequence -> infinite loop if(isSubDirectory(casePath,file)){ - JOptionPane.showMessageDialog(dialog, "Export directory cannot be inside case folder!","Export Case",JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(dialog, Messages.getString("ExportCase.ExportDirectoryInside"),Messages.getString("ExportCase.Title"),JOptionPane.ERROR_MESSAGE); return; } @@ -260,7 +260,7 @@ public void actionPerformed(ActionEvent e) { File tmpDst = new File (dstPath); if (tmpDst.exists()){ if (!isDirEmpty(Paths.get(dstPath))){ - JOptionPane.showMessageDialog(dialog, "Export Folder is not empty!\n"+dstPath,"Export Case",JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(dialog, Messages.getString("ExportCase.ExportFolderEmpty")+"\n"+dstPath,Messages.getString("ExportCase.Title"),JOptionPane.ERROR_MESSAGE); return; } } diff --git a/iped-app/src/main/java/iped/app/ui/MenuClass.java b/iped-app/src/main/java/iped/app/ui/MenuClass.java index 12933168ed..cfa741417f 100644 --- a/iped-app/src/main/java/iped/app/ui/MenuClass.java +++ b/iped-app/src/main/java/iped/app/ui/MenuClass.java @@ -349,7 +349,7 @@ public void actionPerformed(ActionEvent e) { if (!isReport && !App.get().isMultiCase){ this.addSeparator(); - exportCase = new JMenuItem("Export Case"); //$NON-NLS-1$ + exportCase = new JMenuItem(Messages.getString("MenuClass.ExportCase")); //$NON-NLS-1$ exportCase.addActionListener(menuListener); this.add(exportCase); } From 20a9e5ed872746052666bfc42472bf9cac71817a Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Fri, 3 Jan 2025 13:01:33 -0300 Subject: [PATCH 13/32] add localization --- .../resources/localization/iped-desktop-messages.properties | 2 ++ .../localization/iped-desktop-messages_de_DE.properties | 2 ++ .../localization/iped-desktop-messages_es_AR.properties | 2 ++ .../localization/iped-desktop-messages_fr_FR.properties | 2 ++ .../localization/iped-desktop-messages_it_IT.properties | 2 ++ .../localization/iped-desktop-messages_pt_BR.properties | 2 ++ iped-app/src/main/java/iped/app/ui/BookmarksManager.java | 4 ++-- 7 files changed, 14 insertions(+), 2 deletions(-) diff --git a/iped-app/resources/localization/iped-desktop-messages.properties b/iped-app/resources/localization/iped-desktop-messages.properties index 0590d6e4de..8de9ce780c 100644 --- a/iped-app/resources/localization/iped-desktop-messages.properties +++ b/iped-app/resources/localization/iped-desktop-messages.properties @@ -75,6 +75,8 @@ BookmarksManager.CommentsTooltip=Bookmark comments BookmarksManager.Update=Update BookmarksManager.UpdateTooltip=Update comments BookmarksManager.AlreadyExists=Bookmark name already exists! +BookmarksManager.IncludeSubitems=Include Subitems +BookmarksManager.IncludeParentItem=Include Parent Item BookmarksTreeModel.NoBookmarks=[No Bookmarks] BookmarksTreeModel.RootName=Bookmarks CategoryTreeModel.RootName=Categories diff --git a/iped-app/resources/localization/iped-desktop-messages_de_DE.properties b/iped-app/resources/localization/iped-desktop-messages_de_DE.properties index 0b665596d6..d14ef55813 100644 --- a/iped-app/resources/localization/iped-desktop-messages_de_DE.properties +++ b/iped-app/resources/localization/iped-desktop-messages_de_DE.properties @@ -75,6 +75,8 @@ BookmarksManager.CommentsTooltip=Kommentare zu Lesezeichen BookmarksManager.Update=Update BookmarksManager.UpdateTooltip=Kommentare zu Updates BookmarksManager.AlreadyExists=Lesezeichen ist bereits vorhanden! +BookmarksManager.IncludeSubitems=Include Subitems[TBT] +BookmarksManager.IncludeParentItem=Include Parent Item[TBT] BookmarksTreeModel.NoBookmarks=[Keine Lesezeichen] BookmarksTreeModel.RootName=Lesezeichen CategoryTreeModel.RootName=Kategorien diff --git a/iped-app/resources/localization/iped-desktop-messages_es_AR.properties b/iped-app/resources/localization/iped-desktop-messages_es_AR.properties index 0ae32a0990..bb52dcb395 100644 --- a/iped-app/resources/localization/iped-desktop-messages_es_AR.properties +++ b/iped-app/resources/localization/iped-desktop-messages_es_AR.properties @@ -75,6 +75,8 @@ BookmarksManager.CommentsTooltip=Marcar comentarios BookmarksManager.Update=Actualizar BookmarksManager.UpdateTooltip=Actualizar comentarios BookmarksManager.AlreadyExists=¡El nombre del marcador ya existe! +BookmarksManager.IncludeSubitems=Include Subitems[TBT] +BookmarksManager.IncludeParentItem=Include Parent Item[TBT] BookmarksTreeModel.NoBookmarks=[Sin marcadores] BookmarksTreeModel.RootName=Marcadores CategoryTreeModel.RootName=Categorías diff --git a/iped-app/resources/localization/iped-desktop-messages_fr_FR.properties b/iped-app/resources/localization/iped-desktop-messages_fr_FR.properties index b5fd73cc6d..f42edaa4f0 100644 --- a/iped-app/resources/localization/iped-desktop-messages_fr_FR.properties +++ b/iped-app/resources/localization/iped-desktop-messages_fr_FR.properties @@ -75,6 +75,8 @@ BookmarksManager.CommentsTooltip=Commentaires du favori BookmarksManager.Update=Mise à jour BookmarksManager.UpdateTooltip=Mettre à jour les commentaires BookmarksManager.AlreadyExists=Nom du favori existe déjà \! +BookmarksManager.IncludeSubitems=Include Subitems[TBT] +BookmarksManager.IncludeParentItem=Include Parent Item[TBT] BookmarksTreeModel.NoBookmarks=[Aucun favori] BookmarksTreeModel.RootName=Favoris CategoryTreeModel.RootName=Catégories diff --git a/iped-app/resources/localization/iped-desktop-messages_it_IT.properties b/iped-app/resources/localization/iped-desktop-messages_it_IT.properties index 933a9b1ace..fdf22e31ba 100644 --- a/iped-app/resources/localization/iped-desktop-messages_it_IT.properties +++ b/iped-app/resources/localization/iped-desktop-messages_it_IT.properties @@ -75,6 +75,8 @@ BookmarksManager.CommentsTooltip=Commenti ai segnalibri BookmarksManager.Update=Aggiorna BookmarksManager.UpdateTooltip=Aggiorna commento BookmarksManager.AlreadyExists=Il nome del segnalibro esiste già! +BookmarksManager.IncludeSubitems=Include Subitems[TBT] +BookmarksManager.IncludeParentItem=Include Parent Item[TBT] BookmarksTreeModel.NoBookmarks=[Nessun segnalibro] BookmarksTreeModel.RootName=Segnalibri CategoryTreeModel.RootName=Categorie diff --git a/iped-app/resources/localization/iped-desktop-messages_pt_BR.properties b/iped-app/resources/localization/iped-desktop-messages_pt_BR.properties index 538f7e80ad..87c6739371 100644 --- a/iped-app/resources/localization/iped-desktop-messages_pt_BR.properties +++ b/iped-app/resources/localization/iped-desktop-messages_pt_BR.properties @@ -75,6 +75,8 @@ BookmarksManager.CommentsTooltip=Comentários do marcador BookmarksManager.Update=Atualizar BookmarksManager.UpdateTooltip=Atualizar comentários BookmarksManager.AlreadyExists=Nome de marcador já existente! +BookmarksManager.IncludeSubitems=Incluir Subitens +BookmarksManager.IncludeParentItem=Incluir Itens de Origem BookmarksTreeModel.NoBookmarks=[Sem Marcadores] BookmarksTreeModel.RootName=Marcadores CategoryTreeModel.RootName=Categorias diff --git a/iped-app/src/main/java/iped/app/ui/BookmarksManager.java b/iped-app/src/main/java/iped/app/ui/BookmarksManager.java index 945d132c46..d0a546e667 100644 --- a/iped-app/src/main/java/iped/app/ui/BookmarksManager.java +++ b/iped-app/src/main/java/iped/app/ui/BookmarksManager.java @@ -151,9 +151,9 @@ private BookmarksManager() { group.add(highlighted); group.add(checked); highlighted.setSelected(true); - subItems.setText("Include Subitems"); //$NON-NLS-1$ + subItems.setText(Messages.getString("BookmarksManager.IncludeSubitems")); //$NON-NLS-1$ subItems.setSelected(false); - parentItems.setText("Include Parent Item"); //$NON-NLS-1$ + parentItems.setText(Messages.getString("BookmarksManager.IncludeParentItem")); //$NON-NLS-1$ parentItems.setSelected(false); duplicates.setText(Messages.getString("BookmarksManager.AddDuplicates")); //$NON-NLS-1$ duplicates.setSelected(false); From b15704d2fad2ded7a4473cd3504da2c1e107ebbb Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 6 Jan 2025 16:44:33 -0300 Subject: [PATCH 14/32] turn on whisper, walmode, change model path-name --- iped-app/resources/config/conf/AudioTranscriptConfig.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iped-app/resources/config/conf/AudioTranscriptConfig.txt b/iped-app/resources/config/conf/AudioTranscriptConfig.txt index 3acb7352ba..cf9c564b8f 100644 --- a/iped-app/resources/config/conf/AudioTranscriptConfig.txt +++ b/iped-app/resources/config/conf/AudioTranscriptConfig.txt @@ -7,7 +7,7 @@ # Default implementation uses Vosk transcription on local CPU (slow and medium quality). # We include small portable models for 'en' and 'pt-BR', if you want to use a different language model # you should download it from https://alphacephei.com/vosk/models and put in 'models/vosk/[lang]' folder. -implementationClass = iped.engine.task.transcript.VoskTranscriptTask +#implementationClass = iped.engine.task.transcript.VoskTranscriptTask # Uses a local wav2vec2 implementation for transcription. Accuracy is much better than most Vosk models. # This is up to 10x slower than Vosk on high end CPUs. Using a good GPU is highly recommended! @@ -19,7 +19,7 @@ implementationClass = iped.engine.task.transcript.VoskTranscriptTask # This is up to 4x slower than wav2vec2 depending on compared models. Using a high end GPU is strongly recommended! # Please check the installation steps: https://github.com/sepinf-inc/IPED/wiki/User-Manual#whisper # If you enable this, you must set 'whisperModel' param below. -#implementationClass = iped.engine.task.transcript.WhisperTranscriptTask +implementationClass = iped.engine.task.transcript.WhisperTranscriptTask # Uses a remote service for transcription. # The remote service is useful if you have a central server/cluster with many GPUs to be shared among processing nodes. @@ -66,7 +66,7 @@ minTimeout = 180 timeoutPerSec = 3 # Enable SQLite's WAL mode to mitigate connection errors when the output directory is on a network share -SQLiteWalMode = false +SQLiteWalMode = true ######################################### # VoskTranscriptTask options @@ -111,7 +111,7 @@ minWordScore = 0.5 # If you know the language you want to transcribe, please set the 'language' option above. # 'language = auto' uses the 'locale' set on LocalConfig.txt # 'language = detect' uses auto detection, but it can cause mistakes -whisperModel = medium +whisperModel = ./models/whisper # Compute type precision. This affects accuracy, speed and memory usage. # Possible values: float32 (better), float16 (recommended for GPU), int8 (faster) From 1b65260abdbf57135e789b538a71672733f0cb99 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 6 Jan 2025 16:45:20 -0300 Subject: [PATCH 15/32] turn on addunallocated as default --- iped-app/resources/config/conf/FileSystemConfig.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iped-app/resources/config/conf/FileSystemConfig.txt b/iped-app/resources/config/conf/FileSystemConfig.txt index e5a063e933..bef03aa3e2 100644 --- a/iped-app/resources/config/conf/FileSystemConfig.txt +++ b/iped-app/resources/config/conf/FileSystemConfig.txt @@ -9,7 +9,7 @@ robustImageReading = true numImageReaders = auto # Add and process unallocated areas of images. -addUnallocated = false +addUnallocated = true # Add and process file slacks. addFileSlacks = false From 9d7c789c89b2c442e945e9660546f62dcca4ddbf Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 6 Jan 2025 16:45:37 -0300 Subject: [PATCH 16/32] turn on indexunallocated as default --- iped-app/resources/config/conf/IndexTaskConfig.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iped-app/resources/config/conf/IndexTaskConfig.txt b/iped-app/resources/config/conf/IndexTaskConfig.txt index df58abfba0..d492460fbf 100644 --- a/iped-app/resources/config/conf/IndexTaskConfig.txt +++ b/iped-app/resources/config/conf/IndexTaskConfig.txt @@ -1,5 +1,5 @@ # Added unallocated space will be indexed. "addUnallocated" (FileSystemConfig.txt) and "parseUnknownFiles" (ParsingTaskConfig.txt) must be enabled. -indexUnallocated = false +indexUnallocated = true # Converts text to lowercase before indexing, making the search case-insensitive. # Disable only in exceptional cases to generate better dictionaries to use in case-sensitive password breaking. From 23a4deca19fbc388583af65a66a43bc0ebdf8b5d Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 6 Jan 2025 16:45:48 -0300 Subject: [PATCH 17/32] add danfe regexp --- iped-app/resources/config/conf/RegexConfig.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iped-app/resources/config/conf/RegexConfig.txt b/iped-app/resources/config/conf/RegexConfig.txt index e9c3d914d6..47af4d6062 100644 --- a/iped-app/resources/config/conf/RegexConfig.txt +++ b/iped-app/resources/config/conf/RegexConfig.txt @@ -91,3 +91,5 @@ BR_BOLETO = \b[0-9]{5}(\s|\.)?[0-9]{5}(\s|\.)?[0-9]{5}(\s|\.)?[0-9]{6}(\s|\.)?[0 BR_BANK_ACCOUNT = (ag|agen|ag[eê]ncia)(\s|\.|:){0,10}[0-9]{4}(\-?[0-9xX])?.{0,10}(cc|conta|conta[ \-]corrente)(\s|\.|:){0,10}[0-9]{5,11}(\-?[0-9xX])? BR_CAR_PLATE = \b((([A-Z]{3})(()|-)([0-9]{4}))|(Placas?( |:|: )([A-Za-z]{3})( )([0-9]{4})))\b + +BR_CHAVE_DANFE = \b(11|12|13|14|15|16|17|21|22|23|24|25|26|27|28|29|31|32|33|35|41|42|43|50|51|52|53)[1-2]{1}[0-9]{1}[0-1]{1}[0-9]{1}[0-9]{14}(55|65)[0-9]{22}\b From 11f41fbff8d946e2da5ec3f87f56e8264a76a844 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 6 Jan 2025 16:46:06 -0300 Subject: [PATCH 18/32] enable ocr, audiotranscript and carving --- iped-app/resources/config/IPEDConfig.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iped-app/resources/config/IPEDConfig.txt b/iped-app/resources/config/IPEDConfig.txt index 5962493875..39fdda8d81 100644 --- a/iped-app/resources/config/IPEDConfig.txt +++ b/iped-app/resources/config/IPEDConfig.txt @@ -94,7 +94,7 @@ enableMinIO = false # Enables OCR on images and scanned PDF files. It can increase processing time a lot. # OCR language dictionary and other advanced configurations can be found in conf/OCRConfig.txt. -enableOCR = false +enableOCR = true # Enable audio transcription. # Default implementation uses VOSK transcription on local CPU (faster but bad accuracy). @@ -103,12 +103,12 @@ enableOCR = false # - Whisper algorithm (much slower but better accuracy) # - Google Cloud (about $1.00 per hour cost) # - Microsoft Azure (about $1.00 per hour cost) -enableAudioTranscription = false +enableAudioTranscription = true # Enables carving. "addUnallocated" must be enabled to scan unallocated space. # By default, our carving module scans many places in the evidence for deleted or embedded files. # Places to scan and file types to recover can be configured in "conf/CarverConfig.xml" -enableCarving = false +enableCarving = true # Enables carving that retrieves known files from the LED base, based on the beginning (64K) of the file. # It's necessary to enable "addUnallocated" and to configure "hashesDB" (with LED hashes data imported). From 48c284b68c0d0fff13ed460d0d6d2fcca5173aa3 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 6 Jan 2025 16:46:34 -0300 Subject: [PATCH 19/32] enable locale pt-BR and indexTempOnSSD --- iped-app/resources/config/LocalConfig.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iped-app/resources/config/LocalConfig.txt b/iped-app/resources/config/LocalConfig.txt index e131f9d5b9..db44c8c474 100644 --- a/iped-app/resources/config/LocalConfig.txt +++ b/iped-app/resources/config/LocalConfig.txt @@ -3,7 +3,7 @@ ######################################################################## # Defines program localization/language. Currently there are localizations for 'en', 'pt-BR', 'it-IT', 'de-DE', 'es-AR' and 'fr-FR'. -locale = en +locale = pt-BR # Temporary directory for processing: "default" uses the system temporary folder. # Configure it on a folder free of antivirus, system indexing or restoring. Using a SSD disk is highly recommended. @@ -11,7 +11,7 @@ indexTemp = default # Enable if indexTemp is on a SSD disk. Optimizations are made that can improve processing speed up to 2x. # Do not enable it if indexTemp is NOT on SSD or you will have performance problems. -indexTempOnSSD = false +indexTempOnSSD = true # Enable if output/case folder is on SSD. If enabled, index is created directly in case folder, # not in indexTemp, so you will need less free space in temp folder. From d7fee28b4dba1183696869e638a8d9c3cd7c2d10 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 6 Jan 2025 16:46:54 -0300 Subject: [PATCH 20/32] change report dialog SEF custom --- .../iped-desktop-messages_pt_BR.properties | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/iped-app/resources/localization/iped-desktop-messages_pt_BR.properties b/iped-app/resources/localization/iped-desktop-messages_pt_BR.properties index 273339fdde..495f67203f 100644 --- a/iped-app/resources/localization/iped-desktop-messages_pt_BR.properties +++ b/iped-app/resources/localization/iped-desktop-messages_pt_BR.properties @@ -326,9 +326,9 @@ ReportDialog.ChooseLabel=Escolha os marcadores para inserir no relatório: ReportDialog.Create=Gerar ReportDialog.ErrorTitle=Erro ReportDialog.Evidences=Materiais -ReportDialog.Examiner=Examinador +ReportDialog.Examiner=Observações ReportDialog.FillInfo=Preencher -ReportDialog.Investigation=Número da Investigação +ReportDialog.Investigation=Hash ReportDialog.KeywordsFile=Arquivo de palavras-chave (opcional): ReportDialog.LoadButton=Abrir ReportDialog.LoadInfo=Carregar informações do caso de arquivo .json ou .asap: @@ -338,11 +338,11 @@ ReportDialog.Output=Pasta do relatório: ReportDialog.OutputRequired=Necessário especificar pasta de saída\! ReportDialog.Record=Registro/Protocolo ReportDialog.RecordDate=Data do Registro -ReportDialog.ReportDate=Data do Laudo +ReportDialog.ReportDate=Nome do Caso ReportDialog.ReportError=Erro ao gerar Relatório, verifique o log\! ReportDialog.ReportFinished=Geração de Relatório finalizada\! -ReportDialog.ReportNum=Número do Laudo -ReportDialog.ReportTitle=Título do Laudo +ReportDialog.ReportNum=Nome do Investigador +ReportDialog.ReportTitle=Nome da Operação ReportDialog.Request=Número da Solicitação ReportDialog.RequestDate=Data da Solicitação ReportDialog.Requester=Requisitante From 5fdacfbdfb2b29ff54d987b8ab8a6319ee49f3e2 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 6 Jan 2025 16:47:05 -0300 Subject: [PATCH 21/32] change help SEF custom --- .../resources/root/htmlreport/pt-BR/ajuda.htm | 41 ++++--------------- 1 file changed, 7 insertions(+), 34 deletions(-) diff --git a/iped-app/resources/root/htmlreport/pt-BR/ajuda.htm b/iped-app/resources/root/htmlreport/pt-BR/ajuda.htm index 5cf9bd0bb7..af3ccc08ec 100644 --- a/iped-app/resources/root/htmlreport/pt-BR/ajuda.htm +++ b/iped-app/resources/root/htmlreport/pt-BR/ajuda.htm @@ -44,46 +44,19 @@


- O Algoritmo SHA-256
+ O Algoritmo SHA-1

    -
  • O SHA-256 (Secure Hash Algorithm de 256 bits) é um algoritmo que, a partir de uma mensagem de entrada de qualquer tamanho, gera uma saída de tamanho fixo de 256 bits (conhecido como código de integridade, resumo ou hash), calculada a partir do conteúdo dessa mensagem. A segurança do procedimento consiste no fato de não ser conhecido método computacionalmente viável para produzir o mesmo código de integridade a partir de duas mensagens distintas ou, a partir do código de integridade, obter a mensagem de entrada.
    -
  • -
  • Cada arquivo contido nesta mídia ótica é tratado como se fosse uma mensagem que passa individualmente pelo processamento do algoritmo. Ao final, obtém-se a relação dos nomes dos arquivos precedidos por seus respectivos códigos de integridade em formato hexadecimal.
    -
  • -
  • Esta mídia ótica apresenta um arquivo denominado "hashes.txt" que contém a relação supracitada (listagem dos nomes dos arquivos precedidos do respectivo código de integridade). Por sua vez, o código de integridade do arquivo "hashes.txt" encontra-se no laudo impresso.
    -
  • -
  • O acréscimo, alteração ou remoção de um único caractere em um arquivo é condição suficiente para que o código de integridade gerado seja diferente, tornando detectável a alteração do conteúdo desta mídia ótica.
    -
  • +
  • O SHA-1 (Secure Hash Algorithm de 160 bits) é um algoritmo que, a partir de uma mensagem de entrada de qualquer tamanho, gera uma saída de tamanho fixo de 160 bits (conhecido como código de integridade, resumo ou hash), calculada a partir do conteúdo dessa mensagem. A segurança do procedimento consiste no fato de não ser conhecido método computacionalmente viável para produzir o mesmo código de integridade a partir de duas mensagens distintas ou, a partir do código de integridade, obter a mensagem de entrada.
    +
  • +
  • Cada arquivo contido nesta mídia ótica é tratado como se fosse uma mensagem que passa individualmente pelo processamento do algoritmo. Ao final, obtém-se a relação dos nomes dos arquivos precedidos por seus respectivos códigos de integridade em formato hexadecimal.
    +
  • +
  • O acréscimo, alteração ou remoção de um único caractere em um arquivo é condição suficiente para que o código de integridade gerado seja diferente, tornando detectável a alteração do conteúdo desta mídia ótica.
    +



- Verificação da integridade da mídia ótica
-
-
    -
  • Para verificar a integridade das mídias óticas, qualquer programa que suporte o algoritmo SHA-256 pode ser utilizado. O processo de verificação envolve duas etapas que devem ser executadas para cada mídia: -
    1. cálculo da integridade do arquivo “hashes.txt” e comparação com o resultado presente no laudo impresso;
    2. -
    3. cálculo da integridade dos arquivos contidos nesta mídia e comparação com os valores registrados no arquivo “hashes.txt”.
    -
  • -
  • Um dos programas que pode ser utilizado para realizar essa verificação é o FSUM, disponível gratuitamente na Internet no endereço http://www.slavasoft.com.
    -
  • -
  • Assumindo que o sistema operacional utilizado para a verificação seja da família Windows, que o programa FSUM esteja armazenado na pasta "c:\fsum\" e que esta mídia ótica esteja no drive "d:\", as seguintes etapas devem ser executadas:
    -
    -
      -
    1. Na janela do prompt de comando (normalmente em Iniciar - Programas - Acessórios - Prompt de comando) verificar o código de integridade do arquivo "hashes.txt", digitando:
      - c:\fsum\fsum -d"d:" -sha256 d:\hashes.txt
      -
    2. -
    3. Nesta mesma janela, verificar os códigos de integridade dos arquivos contidos nesta mídia ótica, digitando:
      - c:\fsum\fsum -jf -d"d:" -c d:\hashes.txt
      -
    4. -
    -
  • -
  • O resultado da etapa (1) será um código de integridade apresentado na tela, que deve ser comparado com aquele presente no laudo impresso. Ambos devem ser idênticos, indicando que não houve alteração nesta mídia ótica.
    -
  • -
  • O resultado esperado da etapa (2) é a correta verificação de todos os arquivos, ou seja, o programa não deve acusar nenhuma falha, indicando que todos os arquivos presentes nesta mídia ótica estão íntegros conforme os códigos de integridade calculados durante a produção do laudo.
    -
  • -
From 771e42ed10dd26733fc6901003c66c4fbfbb469f Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 6 Jan 2025 16:47:14 -0300 Subject: [PATCH 22/32] change report dialog SEF custom --- .../root/htmlreport/pt-BR/caseinformation.htm | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/iped-app/resources/root/htmlreport/pt-BR/caseinformation.htm b/iped-app/resources/root/htmlreport/pt-BR/caseinformation.htm index 13826a3743..81e4d2214d 100644 --- a/iped-app/resources/root/htmlreport/pt-BR/caseinformation.htm +++ b/iped-app/resources/root/htmlreport/pt-BR/caseinformation.htm @@ -12,7 +12,16 @@
%HEADER% - Laudo%REPORT% de %REPORT_DATE% +Versão%VERSAO% +Relatório Criado%DATA% +Nome do Investigador%REPORT% +Nome do Caso%REPORT_DATE% +Nome da Operação%TITLE% +Observações%EXAMINERS% +Hash%INVESTIGATION% + + + From 6871ad0c63dc3dff115d66c6d0beceb422114d4a Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 6 Jan 2025 16:47:44 -0300 Subject: [PATCH 23/32] change report style --- iped-app/resources/root/htmlreport/pt-BR/contents.htm | 2 +- iped-app/resources/root/htmlreport/pt-BR/report.htm | 2 +- .../resources/root/htmlreport/pt-BR/res/common.css | 2 +- .../resources/root/htmlreport/pt-BR/res/contents.css | 10 +++++----- .../resources/root/htmlreport/pt-BR/res/estilo.css | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/iped-app/resources/root/htmlreport/pt-BR/contents.htm b/iped-app/resources/root/htmlreport/pt-BR/contents.htm index aac6810bec..738322e400 100644 --- a/iped-app/resources/root/htmlreport/pt-BR/contents.htm +++ b/iped-app/resources/root/htmlreport/pt-BR/contents.htm @@ -9,7 +9,7 @@