19 package org.sleuthkit.autopsy.texttranslation.ui;
21 import com.google.common.collect.Lists;
22 import com.google.common.util.concurrent.ThreadFactoryBuilder;
23 import java.awt.Component;
24 import java.awt.ComponentOrientation;
26 import java.awt.event.ActionEvent;
27 import java.awt.event.ActionListener;
28 import java.io.IOException;
29 import java.io.Reader;
30 import java.util.Arrays;
31 import java.util.concurrent.ExecutorService;
32 import java.util.concurrent.Executors;
33 import java.util.concurrent.ThreadFactory;
34 import org.openide.nodes.Node;
35 import org.openide.util.lookup.ServiceProvider;
38 import org.openide.util.Lookup;
39 import org.openide.util.NbBundle;
40 import org.openide.util.lookup.Lookups;
46 import java.util.List;
47 import java.util.logging.Level;
48 import javax.swing.SwingUtilities;
57 @ServiceProvider(service =
TextViewer.class, position = 4)
62 private static final int MAX_EXTRACT_SIZE_BYTES = 25600;
66 private volatile Node
node;
68 private final ThreadFactory translationThreadFactory
69 =
new ThreadFactoryBuilder().setNameFormat(
"translation-content-viewer-%d").build();
70 private final ExecutorService executorService = Executors.newSingleThreadExecutor(translationThreadFactory);
73 "TranslatedTextViewer.maxPayloadSize=Up to the first %dKB of text will be translated"
79 panel.addDisplayTextActionListener(displayDropDownListener);
82 panel.addLanguagePackNames(INSTALLED_LANGUAGE_PACKS);
87 panel.setWarningLabelMsg(String.format(Bundle.TranslatedTextViewer_maxPayloadSize(), payloadMaxInKB));
93 @NbBundle.Messages({
"TranslatedTextViewer.title=Translation"})
96 return Bundle.TranslatedTextViewer_title();
99 @NbBundle.Messages({
"TranslatedTextViewer.toolTip=Displays translated file text."})
102 return Bundle.TranslatedTextViewer_toolTip();
119 if (backgroundTask != null) {
120 backgroundTask.cancel(
true);
122 backgroundTask = null;
135 AbstractFile file = node.getLookup().lookup(AbstractFile.class);
151 private final AbstractFile
file;
154 super(translateText, String.format(
"%s (objId=%d)", file.getName(), file.getId()));
166 "TranslatedContentViewer.extractingText=Extracting text, please wait...",
167 "# {0} - exception message",
"TranslatedContentViewer.errorExtractingText=An error occurred while extracting the text ({0}).",
169 protected String
retrieveText()
throws IOException, InterruptedException, IllegalStateException {
170 SwingUtilities.invokeLater(() -> {
171 onProgressDisplay(Bundle.TranslatedContentViewer_extractingText(), ComponentOrientation.LEFT_TO_RIGHT, Font.ITALIC);
175 return getFileText(file);
177 logger.log(Level.WARNING, String.format(
"Error extracting text for file %s (objId=%d)", file.getName(), file.getId()), ex);
179 throw new IllegalStateException(Bundle.TranslatedContentViewer_errorExtractingText(ex.getMessage()), ex);
197 "TranslatedContentViewer.ocrNotEnabled=OCR is not enabled. To change, go to Tools->Options->Machine Translation",
200 final boolean isImage = file.getMIMEType().toLowerCase().startsWith(
"image/");
202 return Bundle.TranslatedContentViewer_ocrNotEnabled();
208 byte[] resultInUTF8Bytes = result.getBytes(
"UTF8");
209 byte[] trimToArraySize = Arrays.copyOfRange(resultInUTF8Bytes, 0,
210 Math.min(resultInUTF8Bytes.length, MAX_EXTRACT_SIZE_BYTES));
211 return new String(trimToArraySize,
"UTF-8");
228 Reader textExtractor = getTextExtractor(source, ocrEnabled);
230 char[] cbuf =
new char[8096];
231 StringBuilder textBuilder =
new StringBuilder();
238 while ((read = textExtractor.read(cbuf)) != -1) {
239 if (this.isCancelled()) {
240 throw new InterruptedException();
245 int bytesLeft = MAX_EXTRACT_SIZE_BYTES - bytesRead;
247 if (bytesLeft < read) {
248 textBuilder.append(cbuf, 0, bytesLeft);
249 return textBuilder.toString();
252 textBuilder.append(cbuf, 0, read);
256 return textBuilder.toString();
274 Lookup context = null;
280 String ocrSelection = panel.getSelectedOcrLanguagePack();
281 if (!ocrSelection.isEmpty()) {
288 context = Lookups.fixed(imageConfig, terminator);
301 protected void onTextDisplay(String text, ComponentOrientation orientation,
int font) {
302 panel.
display(text, orientation, font);
315 abstract String getSelection();
319 String selection = getSelection();
320 if (!selection.equals(currentSelection)) {
321 currentSelection = selection;
323 if (backgroundTask != null && !backgroundTask.isDone()) {
324 backgroundTask.cancel(
true);
327 AbstractFile file = node.getLookup().lookup(AbstractFile.class);
328 String textDisplaySelection = panel.getDisplayDropDownSelection();
329 boolean translateText = !textDisplaySelection.equals(DisplayDropdownOptions.ORIGINAL_TEXT.toString());
334 executorService.execute(backgroundTask);
345 String getSelection() {
346 return panel.getDisplayDropDownSelection();
356 String getSelection() {
357 return panel.getSelectedOcrLanguagePack();
void setNode(final Node node)
volatile ExtractAndTranslateTextTask backgroundTask
synchronized int getMaxTextChars()
static boolean getUseOcrInTranslation()
void onTextDisplay(String text, ComponentOrientation orientation, int font)
String extractText(AbstractFile source, boolean ocrEnabled)
String getFileText(AbstractFile file)
void display(String text, ComponentOrientation direction, int font)
ExtractAndTranslateTextTask(AbstractFile file, boolean translateText)
Reader getTextExtractor(AbstractFile file, boolean ocrEnabled)
boolean isSupported(Node node)
final void actionPerformed(ActionEvent e)
static TextTranslationService getInstance()
synchronized boolean hasProvider()
synchronized static Logger getLogger(String name)
TextViewer createInstance()
int isPreferred(Node node)