diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/Bundle.properties b/Core/src/com/basistech/df/cybertriage/autopsy/Bundle.properties
new file mode 100644
index 0000000000..4d7a376395
--- /dev/null
+++ b/Core/src/com/basistech/df/cybertriage/autopsy/Bundle.properties
@@ -0,0 +1,10 @@
+
+# Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
+# Click nbfs://nbhost/SystemFileSystem/Templates/Other/properties.properties to edit this template
+
+
+CTIntegrationMissingDialog.title=Cyber Triage Importer Module Required
+CTIntegrationMissingDialog.descriptionLabel.text=
The Cyber Triage Importer Module is required to open this case.
To open this case:
- Extract the module from the Integrations tab in the Cyber Triage options panel.
- Select the 'Plugins' option from the 'Tools' menu, and go to the 'Downloaded' tab.
- Click 'Add Plugins...' and select the path of the plugin.
- Press 'Install' to finish the installation.
+CTIntegrationMissingDialog.link.text=http://docs.cybertriage.com
+CTIntegrationMissingDialog.docsLabel.text=For more information, refer to the Cyber Triage Users Guide
+CTIntegrationMissingDialog.okButton.text=OK
diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/Bundle.properties-MERGED b/Core/src/com/basistech/df/cybertriage/autopsy/Bundle.properties-MERGED
new file mode 100644
index 0000000000..a9a4571ed2
--- /dev/null
+++ b/Core/src/com/basistech/df/cybertriage/autopsy/Bundle.properties-MERGED
@@ -0,0 +1,7 @@
+
+# Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
+# Click nbfs://nbhost/SystemFileSystem/Templates/Other/properties.properties to edit this template
+
+
+CTIntegrationMissingDialog.title=Cyber Triage Importer Module Required
+CTIntegrationMissingDialog.descriptionLabel.text=jLabel1
diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/CTIntegrationMissingDialog.form b/Core/src/com/basistech/df/cybertriage/autopsy/CTIntegrationMissingDialog.form
new file mode 100644
index 0000000000..6005c35acc
--- /dev/null
+++ b/Core/src/com/basistech/df/cybertriage/autopsy/CTIntegrationMissingDialog.form
@@ -0,0 +1,144 @@
+
+
+
diff --git a/Core/src/com/basistech/df/cybertriage/autopsy/CTIntegrationMissingDialog.java b/Core/src/com/basistech/df/cybertriage/autopsy/CTIntegrationMissingDialog.java
new file mode 100644
index 0000000000..dbac6f9f55
--- /dev/null
+++ b/Core/src/com/basistech/df/cybertriage/autopsy/CTIntegrationMissingDialog.java
@@ -0,0 +1,165 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2023 Basis Technology Corp.
+ * Contact: carrier sleuthkit org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.basistech.df.cybertriage.autopsy;
+
+import java.awt.Desktop;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.logging.Level;
+import javax.swing.JComponent;
+import org.sleuthkit.autopsy.coreutils.Logger;
+
+/**
+ * Provides directions with how to enable CT integration with Autopsy when
+ * trying to open a CT exported case.
+ */
+public class CTIntegrationMissingDialog extends javax.swing.JDialog {
+
+ private static final String DOCS_PAGE_URL = "http://docs.cybertriage.com";
+
+ private static final Logger LOGGER = Logger.getLogger(CTIntegrationMissingDialog.class.getName());
+
+ /**
+ * Creates new form CTIntegrationMissingDialog
+ */
+ public CTIntegrationMissingDialog(java.awt.Frame parent, boolean modal) {
+ super(parent, modal);
+ initComponents();
+ }
+
+ /**
+ * This method is called from within the constructor to initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is always
+ * regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+ java.awt.GridBagConstraints gridBagConstraints;
+
+ javax.swing.JLabel descriptionLabel = new javax.swing.JLabel();
+ javax.swing.JLabel docsLabel = new javax.swing.JLabel();
+ javax.swing.JLabel link = new javax.swing.JLabel();
+ javax.swing.JPanel paddingPanel = new javax.swing.JPanel();
+ javax.swing.JButton okButton = new javax.swing.JButton();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+ setTitle(org.openide.util.NbBundle.getMessage(CTIntegrationMissingDialog.class, "CTIntegrationMissingDialog.title")); // NOI18N
+ setAlwaysOnTop(true);
+ setMaximumSize(new java.awt.Dimension(500, 190));
+ setMinimumSize(new java.awt.Dimension(500, 190));
+ setPreferredSize(new java.awt.Dimension(500, 190));
+ setResizable(false);
+ setSize(new java.awt.Dimension(500, 190));
+ getContentPane().setLayout(new java.awt.GridBagLayout());
+
+ org.openide.awt.Mnemonics.setLocalizedText(descriptionLabel, org.openide.util.NbBundle.getMessage(CTIntegrationMissingDialog.class, "CTIntegrationMissingDialog.descriptionLabel.text")); // NOI18N
+ descriptionLabel.setMinimumSize(new java.awt.Dimension(123, 116));
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 0;
+ gridBagConstraints.gridwidth = 2;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
+ getContentPane().add(descriptionLabel, gridBagConstraints);
+
+ org.openide.awt.Mnemonics.setLocalizedText(docsLabel, org.openide.util.NbBundle.getMessage(CTIntegrationMissingDialog.class, "CTIntegrationMissingDialog.docsLabel.text")); // NOI18N
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 0);
+ getContentPane().add(docsLabel, gridBagConstraints);
+
+ org.openide.awt.Mnemonics.setLocalizedText(link, org.openide.util.NbBundle.getMessage(CTIntegrationMissingDialog.class, "CTIntegrationMissingDialog.link.text")); // NOI18N
+ link.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
+ link.addMouseListener(new java.awt.event.MouseAdapter() {
+ public void mouseClicked(java.awt.event.MouseEvent evt) {
+ linkMouseClicked(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5);
+ getContentPane().add(link, gridBagConstraints);
+
+ javax.swing.GroupLayout paddingPanelLayout = new javax.swing.GroupLayout(paddingPanel);
+ paddingPanel.setLayout(paddingPanelLayout);
+ paddingPanelLayout.setHorizontalGroup(
+ paddingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 0, Short.MAX_VALUE)
+ );
+ paddingPanelLayout.setVerticalGroup(
+ paddingPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 0, Short.MAX_VALUE)
+ );
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 2;
+ gridBagConstraints.gridwidth = 2;
+ gridBagConstraints.weighty = 1.0;
+ getContentPane().add(paddingPanel, gridBagConstraints);
+
+ org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(CTIntegrationMissingDialog.class, "CTIntegrationMissingDialog.okButton.text")); // NOI18N
+ okButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ okButtonActionPerformed(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 1;
+ gridBagConstraints.gridy = 2;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
+ gridBagConstraints.insets = new java.awt.Insets(10, 5, 5, 5);
+ getContentPane().add(okButton, gridBagConstraints);
+
+ pack();
+ }// //GEN-END:initComponents
+
+ private void linkMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_linkMouseClicked
+ if (Desktop.isDesktopSupported()) {
+ try {
+ Desktop.getDesktop().browse(new URI(DOCS_PAGE_URL));
+ } catch (IOException | URISyntaxException e) {
+ LOGGER.log(Level.SEVERE, "Error opening link to: " + DOCS_PAGE_URL, e);
+ }
+ } else {
+ LOGGER.log(Level.WARNING, "Desktop API is not supported. Link cannot be opened.");
+ }
+ }//GEN-LAST:event_linkMouseClicked
+
+ private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
+ dispose();
+ }//GEN-LAST:event_okButtonActionPerformed
+
+ public void showDialog(JComponent parentComp) {
+ setLocationRelativeTo(parentComp);
+ setVisible(true);
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ // End of variables declaration//GEN-END:variables
+}