" +
+ "
" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.enable.description") + "
" +
+ "
" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.enable.description2") + "
" +
+ "
" +
+ "",
+ NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.enable.title"),
+ JOptionPane.YES_NO_OPTION)) {
+
+ // setup database for CR
+ CentralRepoDbUtil.setUseCentralRepo(true);
+ CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.POSTGRESQL_MULTIUSER);
+ handleDbChange(parent);
+ }
+ });
+ }
+ // moving from selected to not selected && 'PostgreSQL using multi-user settings' is selected
+ else if (muPreviouslySelected && !muCurrentlySelected && crEnabled && crMultiUser) {
+ SwingUtilities.invokeLater(() -> {
+ askForCentralRepoDbChoice(parent);
+ });
+ }
+ // changing multi-user settings connection && 'PostgreSQL using multi-user settings' is selected &&
+ // central repo either enabled or was disabled due to error
+ else if (muPreviouslySelected && muCurrentlySelected && crMultiUser && (crEnabled || crDisabledDueToFailure)) {
+ // test databse for CR change
+ CentralRepoDbUtil.setUseCentralRepo(true);
+ handleDbChange(parent);
+ }
+ }
- if (CentralRepoPlatforms.getSelectedPlatform().equals(DISABLED)) {
+
+ /**
+ * This method is called when a user must select a new database other than using database from multi user settings.
+ * @param parent The parent component to use for displaying dialogs in reference.
+ */
+ @NbBundle.Messages({
+ "GlobalSettingsPanel.onMultiUserChange.disabledMu.title=Central Repository Change Necessary",
+ "GlobalSettingsPanel.onMultiUserChange.disabledMu.description=The Central Repository will be reconfigured to use a local SQLite database.",
+ "GlobalSettingsPanel.onMultiUserChange.disabledMu.description2=Press Configure PostgreSQL to change to a PostgreSQL database."
+ })
+ private static void askForCentralRepoDbChoice(Component parent) {
+ // disable central repository until user makes choice
+ CentralRepoDbUtil.setUseCentralRepo(false);
+ CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.DISABLED, false);
+
+ Object[] options = {
+ "Use SQLite",
+ "Configure PostgreSQL",
+ "Disable Central Repository"
+ };
+
+ int result = JOptionPane.showOptionDialog(
+ parent,
+ "" +
+ "" +
+ "
" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.description") + "
" +
+ "
" + NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.description2") + "
" +
+ "
" +
+ "",
+ NbBundle.getMessage(GlobalSettingsPanel.class, "GlobalSettingsPanel.onMultiUserChange.disabledMu.title"),
+ JOptionPane.YES_NO_CANCEL_OPTION,
+ JOptionPane.PLAIN_MESSAGE,
+ null,
+ options,
+ options[0]
+ );
+
+ if (JOptionPane.YES_OPTION == result) {
+ invokeCrChoice(parent, CentralRepoDbChoice.SQLITE);
+ }
+ else if (JOptionPane.NO_OPTION == result) {
+ invokeCrChoice(parent, CentralRepoDbChoice.POSTGRESQL_CUSTOM);
+ }
+ }
+
+
+ private static void handleDbChange(Component parent) {
+ SwingUtilities.invokeLater(() -> {
+ boolean successful = EamDbSettingsDialog.testStatusAndCreate(parent, new CentralRepoDbManager());
+ if (successful) {
+ updateDatabase(parent);
+ }
+ else {
+ // disable central repository due to error
+ CentralRepoDbManager.disableDueToFailure();
+ }
+ });
+ }
+
+
+ @Messages({"GlobalSettingsPanel.updateFailed.title=Central repository disabled"})
+ private static void updateDatabase(Component parent) {
+ if (CentralRepoDbChoice.DISABLED.equals(CentralRepoDbManager.getSavedDbChoice())) {
return;
}
- setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+ parent.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
try {
CentralRepoDbManager.upgradeDatabase();
- setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
} catch (CentralRepoException ex) {
- setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
- JOptionPane.showMessageDialog(this,
+ parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ JOptionPane.showMessageDialog(parent,
ex.getUserMessage(),
- NbBundle.getMessage(this.getClass(),
+ NbBundle.getMessage(GlobalSettingsPanel.class,
"GlobalSettingsPanel.updateFailed.title"),
JOptionPane.WARNING_MESSAGE);
} finally {
- setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}
@@ -425,9 +569,8 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
private void bnDbConfigureActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnDbConfigureActionPerformed
store();
- EamDbSettingsDialog dialog = new EamDbSettingsDialog();
- if (dialog.wasConfigurationChanged()) {
- updateDatabase();
+ boolean changed = invokeCrChoice(this, null);
+ if (changed) {
load(); // reload db settings content and update buttons
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
}
@@ -446,6 +589,16 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
private void cbUseCentralRepoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbUseCentralRepoActionPerformed
//if saved setting is disabled checkbox should be disabled already
store();
+
+ // if moving to using CR, multi-user mode is disabled and selection is multiuser settings, set to disabled
+ if (cbUseCentralRepo.isSelected() &&
+ !CentralRepoDbManager.isPostgresMultiuserAllowed() &&
+ CentralRepoDbManager.getSavedDbChoice() == CentralRepoDbChoice.POSTGRESQL_MULTIUSER) {
+
+ CentralRepoDbManager.saveDbChoice(CentralRepoDbChoice.DISABLED);
+ }
+
+
updateDatabase();
load();
this.ingestStateUpdated(Case.isCaseOpen());
@@ -457,31 +610,35 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
public void load() {
tbOops.setText("");
enableButtonSubComponents(false);
- CentralRepoPlatforms selectedPlatform = CentralRepoPlatforms.getSelectedPlatform();
+ CentralRepoDbChoice selectedChoice = CentralRepoDbManager.getSavedDbChoice();
cbUseCentralRepo.setSelected(CentralRepoDbUtil.allowUseOfCentralRepository()); // NON-NLS
- switch (selectedPlatform) {
- case POSTGRESQL:
- PostgresCentralRepoSettings dbSettingsPg = new PostgresCentralRepoSettings();
- lbDbPlatformValue.setText(CentralRepoPlatforms.POSTGRESQL.toString());
- lbDbNameValue.setText(dbSettingsPg.getDbName());
- lbDbLocationValue.setText(dbSettingsPg.getHost());
- enableButtonSubComponents(cbUseCentralRepo.isSelected());
- break;
- case SQLITE:
+
+ lbDbPlatformValue.setText(selectedChoice.getTitle());
+ CentralRepoPlatforms selectedDb = selectedChoice.getDbPlatform();
+
+ if (selectedChoice == null || selectedDb == CentralRepoPlatforms.DISABLED) {
+ lbDbNameValue.setText("");
+ lbDbLocationValue.setText("");
+ tbOops.setText(Bundle.GlobalSettingsPanel_validationerrMsg_mustConfigure());
+ }
+ else {
+ enableButtonSubComponents(cbUseCentralRepo.isSelected());
+ if (selectedDb == CentralRepoPlatforms.POSTGRESQL) {
+ try {
+ PostgresCentralRepoSettings dbSettingsPg = new PostgresCentralRepoSettings();
+ lbDbNameValue.setText(dbSettingsPg.getDbName());
+ lbDbLocationValue.setText(dbSettingsPg.getHost());
+ }
+ catch (CentralRepoException e) {
+ logger.log(Level.WARNING, "Unable to load settings into global panel for postgres settings", e);
+ }
+ }
+ else if (selectedDb == CentralRepoPlatforms.SQLITE) {
SqliteCentralRepoSettings dbSettingsSqlite = new SqliteCentralRepoSettings();
- lbDbPlatformValue.setText(CentralRepoPlatforms.SQLITE.toString());
lbDbNameValue.setText(dbSettingsSqlite.getDbName());
lbDbLocationValue.setText(dbSettingsSqlite.getDbDirectory());
- enableButtonSubComponents(cbUseCentralRepo.isSelected());
- break;
- default:
- lbDbPlatformValue.setText(CentralRepoPlatforms.DISABLED.toString());
- lbDbNameValue.setText("");
- lbDbLocationValue.setText("");
- tbOops.setText(Bundle.GlobalSettingsPanel_validationerrMsg_mustConfigure());
- break;
+ }
}
-
}
@Override
@@ -490,12 +647,12 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
}
/**
- * Validates that the dialog/panel is filled out correctly for our usage.
+ * This method validates that the dialog/panel is filled out correctly for our usage.
*
- * @return true if it's okay, false otherwise.
+ * @return True if it is okay, false otherwise.
*/
public boolean valid() {
- return !cbUseCentralRepo.isSelected() || !lbDbPlatformValue.getText().equals(DISABLED.toString());
+ return !cbUseCentralRepo.isSelected() || !lbDbPlatformValue.getText().equals(CentralRepoDbChoice.DISABLED.toString());
}
@Override
@@ -574,9 +731,9 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i
enableButtonSubComponents(cbUseCentralRepo.isSelected());
} else {
load();
- enableDatabaseConfigureButton(cbUseCentralRepo.isSelected() && !caseIsOpen);
}
+ enableDatabaseConfigureButton(cbUseCentralRepo.isSelected() && !caseIsOpen);
}
/**
diff --git a/Core/src/org/sleuthkit/autopsy/commandlineingest/CommandLineIngestManager.java b/Core/src/org/sleuthkit/autopsy/commandlineingest/CommandLineIngestManager.java
index 3dfaf53001..f5d9a5c641 100755
--- a/Core/src/org/sleuthkit/autopsy/commandlineingest/CommandLineIngestManager.java
+++ b/Core/src/org/sleuthkit/autopsy/commandlineingest/CommandLineIngestManager.java
@@ -343,6 +343,7 @@ public class CommandLineIngestManager {
* @param baseCaseName Case name
* @param rootOutputDirectory Full path to directory in which case
* output folder will be created
+ * @param caseType Type of case being created
*
* @throws CaseActionException
*/
diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java
index 288b3efa3f..3151d75780 100755
--- a/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java
+++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java
@@ -19,6 +19,7 @@
package org.sleuthkit.autopsy.communications.relationships;
import java.util.logging.Level;
+import org.apache.commons.lang.StringUtils;
import org.openide.nodes.Sheet;
import org.sleuthkit.autopsy.communications.Utils;
import static org.sleuthkit.autopsy.communications.relationships.RelationshipsNodeUtilities.getAttributeDisplayString;
@@ -67,14 +68,6 @@ final class CallLogNode extends BlackboardArtifactNode {
return sheet;
}
- String phoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_FROM);
- if(phoneNumber == null || phoneNumber.isEmpty()) {
- phoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_TO);
- }
- if(phoneNumber == null || phoneNumber.isEmpty()) {
- phoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER);
- }
-
long duration = -1;
try{
duration = getCallDuration(artifact);
@@ -84,7 +77,7 @@ final class CallLogNode extends BlackboardArtifactNode {
sheetSet.put(createNode(TSK_DATETIME_START, artifact));
sheetSet.put(createNode(TSK_DIRECTION, artifact));
- sheetSet.put(new NodeProperty<>(TSK_PHONE_NUMBER.getLabel(), TSK_PHONE_NUMBER.getDisplayName(), "", phoneNumber));
+ sheetSet.put(new NodeProperty<>(TSK_PHONE_NUMBER.getLabel(), TSK_PHONE_NUMBER.getDisplayName(), "", getPhoneNumber(artifact)));
if(duration != -1) {
sheetSet.put(new NodeProperty<>("duration", "Duration", "", Long.toString(duration)));
}
@@ -107,6 +100,59 @@ final class CallLogNode extends BlackboardArtifactNode {
return endAttribute.getValueLong() - startAttribute.getValueLong();
}
+ /**
+ * Returns the phone number to display in the To/From column. The number is
+ * picked from one of the 3 possible phone number attributes, based on the
+ * direction of the call.
+ *
+ * @param artifact Call log artifact.
+ *
+ * @return Phone number to display.
+ */
+ private String getPhoneNumber(BlackboardArtifact artifact) {
+ String direction = getAttributeDisplayString(artifact, TSK_DIRECTION);
+
+ String phoneNumberToReturn;
+ String fromPhoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_FROM);
+ String toPhoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_TO);
+ String phoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER);
+ switch (direction.toLowerCase()) {
+ case "incoming": // NON-NLS
+ phoneNumberToReturn = getFirstNonBlank(fromPhoneNumber, phoneNumber, toPhoneNumber);
+ break;
+ case "outgoing": // NON-NLS
+ phoneNumberToReturn = getFirstNonBlank(toPhoneNumber, phoneNumber, fromPhoneNumber);
+ break;
+ default:
+ phoneNumberToReturn = getFirstNonBlank(toPhoneNumber, fromPhoneNumber, phoneNumber );
+ break;
+ }
+
+ return phoneNumberToReturn;
+ }
+
+ /**
+ * Checks the given string arguments in order and returns the first non blank string.
+ * Returns a blank string if all the input strings are blank.
+ *
+ * @param string1 First string to check
+ * @param string2 Second string to check
+ * @param string3 Third string to check
+ *
+ * @retunr first non blank string if there is one, blank string otherwise.
+ *
+ */
+ private String getFirstNonBlank(String string1, String string2, String string3 ) {
+
+ if (!StringUtils.isBlank(string1)) {
+ return string1;
+ } else if (!StringUtils.isBlank(string2)) {
+ return string2;
+ } else if (!StringUtils.isBlank(string3)) {
+ return string3;
+ }
+ return "";
+ }
/**
* Circumvent DataResultFilterNode's slightly odd delegation to
* BlackboardArtifactNode.getSourceName().
diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED
index 737b6900d4..c0a6f73aaf 100755
--- a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED
+++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED
@@ -41,6 +41,7 @@ MediaFileViewer.AccessibleContext.accessibleDescription=
MediaFileViewer.title=Media
MediaFileViewer.toolTip=Displays supported multimedia files (images, videos, audio)
MediaPlayerPanel.noSupport=File not supported.
+MediaPlayerPanel.playbackDisabled=A problem was encountered with the video and audio playback service. Video and audio playback will be disabled for the remainder of the session.
MediaPlayerPanel.timeFormat=%02d:%02d:%02d
MediaPlayerPanel.unknownTime=Unknown
MediaViewImagePanel.createTagOption=Create
@@ -168,7 +169,7 @@ MediaPlayerPanel.playBackSpeedLabel.text=Speed:
SQLiteViewer.readTable.errorText=Error getting rows for table: {0}
# {0} - tableName
SQLiteViewer.selectTable.errorText=Error getting row count for table: {0}
-TextTranslatableComponent.setPanelContent.onSetContentError=Unable to display text at this time.
-TextTranslatableComponent.setTranslated.onTranslateError=Unable to translate text at this time.
TranslatablePanel.comboBoxOption.originalText=Original Text
TranslatablePanel.comboBoxOption.translatedText=Translated Text
+# {0} - exception message
+TranslatablePanel.onSetContentError.text=There was an error displaying the text: {0}
diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaFileViewer.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaFileViewer.java
index 56dd8e9ebe..9decc79175 100644
--- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaFileViewer.java
+++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaFileViewer.java
@@ -194,6 +194,6 @@ class MediaFileViewer extends javax.swing.JPanel implements FileTypeViewer {
@Override
public boolean isSupported(AbstractFile file){
- return true;
+ return mediaPlayerPanel.isSupported(file) || imagePanel.isSupported(file);
}
}
diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form
index 0b00c43d8a..793e31830b 100755
--- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form
+++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form
@@ -63,7 +63,7 @@