From 757da3ae624e53fabdbd2a91f6f701a851c69d9f Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dgrove" Date: Fri, 8 Dec 2017 16:14:54 -0500 Subject: [PATCH] Implemented feature to remove logo. --- .../corecomponents/AutopsyOptionsPanel.form | 94 ++++++----- .../corecomponents/AutopsyOptionsPanel.java | 154 +++++++++++++----- .../autopsy/corecomponents/Bundle.properties | 3 +- 3 files changed, 168 insertions(+), 83 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form index 00881c2ca7..789438198a 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.form @@ -2,9 +2,11 @@
- + - + + + @@ -22,10 +24,7 @@ - - - - + @@ -69,7 +68,7 @@ - + @@ -92,15 +91,14 @@ - - - - - - - + + + + + + @@ -109,42 +107,32 @@ - - - - - - - - - - - + + + + + + + - + + + + + - - - - - - - - - - @@ -179,6 +167,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -276,7 +290,7 @@ - + @@ -292,7 +306,7 @@ - + @@ -369,7 +383,7 @@ - + @@ -382,7 +396,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java index a62ae4400c..bd88015ce8 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/AutopsyOptionsPanel.java @@ -76,9 +76,12 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { private static final long ONE_BILLION = 1000000000L; //used to roughly convert system memory from bytes to gigabytes private static final long MEGA_IN_GIGA = 1024; //used to convert memory settings saved as megabytes to gigabytes private static final int MIN_MEMORY_IN_GB = 2; //the enforced minimum memory in gigabytes - private static final Logger logger = Logger.getLogger(AutopsyOptionsPanel.class.getName()); + private static final Logger LOGGER = Logger.getLogger(AutopsyOptionsPanel.class.getName()); private String initialMemValue = Long.toString(Runtime.getRuntime().maxMemory() / ONE_BILLION); + /** + * Instantiate the Autopsy options panel. + */ AutopsyOptionsPanel() { initComponents(); fc = new JFileChooser(); @@ -86,7 +89,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { fc.setMultiSelectionEnabled(false); fc.setAcceptAllFileFilterUsed(false); fc.setFileFilter(new GeneralFilter(GeneralFilter.GRAPHIC_IMAGE_EXTS, GeneralFilter.GRAPHIC_IMG_DECR)); - if (!PlatformUtil.is64BitJVM() || Version.getBuildType() == Version.Type.DEVELOPMENT) { + if (!PlatformUtil.is64BitJVM() || Version.getBuildType() == Version.Type.DEVELOPMENT) { //32 bit JVM has a max heap size of 1.4 gb to 4 gb depending on OS //So disabling the setting of heap size when the JVM is not 64 bit //Is the safest course of action @@ -247,7 +250,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { try { lines = Files.readAllLines(filePath, charset); } catch (IOException e) { - logger.log(Level.SEVERE, "Error reading config file contents. {}", configFile.getAbsolutePath()); + LOGGER.log(Level.SEVERE, "Error reading config file contents. {}", configFile.getAbsolutePath()); } } return lines; @@ -273,6 +276,9 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { return new String[]{}; } + /** + * Load the saved user preferences. + */ void load() { boolean keepPreferredViewer = UserPreferences.keepPreferredContentViewer(); keepCurrentViewerRB.setSelected(keepPreferredViewer); @@ -286,15 +292,20 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { useGMTTimeRB.setSelected(!useLocalTime); String path = ModuleSettings.getConfigSetting(ReportBranding.MODULE_NAME, ReportBranding.AGENCY_LOGO_PATH_PROP); try { + boolean useDefault = (path == null || path.isEmpty()); + defaultLogoRB.setSelected(useDefault); + specifyLogoRB.setSelected(!useDefault); + agencyLogoPathField.setEnabled(!useDefault); + browseLogosButton.setEnabled(!useDefault); updateAgencyLogo(path); } catch (IOException ex) { - logger.log(Level.WARNING, "Error loading image from previously saved agency logo path", ex); + LOGGER.log(Level.WARNING, "Error loading image from previously saved agency logo path", ex); } if (memField.isEnabled()) { try { initialMemValue = Long.toString(getCurrentJvmMaxMemoryInGB()); } catch (IOException ex) { - logger.log(Level.SEVERE, "Can't read current Jvm max memory setting from file", ex); + LOGGER.log(Level.SEVERE, "Can't read current Jvm max memory setting from file", ex); memField.setEnabled(false); } memField.setText(initialMemValue); @@ -302,6 +313,13 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { isMemFieldValid(); //ensure the error message is up to date } + /** + * Update the agency logo with the image specified by the path. + * + * @param path The path to the image. + * + * @throws IOException Thrown when there is a problem reading the file. + */ private void updateAgencyLogo(String path) throws IOException { agencyLogoPathField.setText(path); ImageIcon agencyLogoIcon = new ImageIcon(); @@ -321,6 +339,9 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { agencyLogoPreview.repaint(); } + /** + * Store the current user preferences. + */ void store() { UserPreferences.setKeepPreferredContentViewer(keepCurrentViewerRB.isSelected()); UserPreferences.setHideKnownFilesInDataSourcesTree(dataSourcesHideKnownCB.isSelected()); @@ -333,16 +354,23 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { if (file.exists()) { ModuleSettings.setConfigSetting(ReportBranding.MODULE_NAME, ReportBranding.AGENCY_LOGO_PATH_PROP, agencyLogoPathField.getText()); } + } else { + ModuleSettings.setConfigSetting(ReportBranding.MODULE_NAME, ReportBranding.AGENCY_LOGO_PATH_PROP, ""); } if (memField.isEnabled()) { //if the field could of been changed we need to try and save it try { writeEtcConfFile(); } catch (IOException ex) { - logger.log(Level.WARNING, "Unable to save config file to " + PlatformUtil.getUserDirectory() + "\\" + ETC_FOLDER_NAME, ex); + LOGGER.log(Level.WARNING, "Unable to save config file to " + PlatformUtil.getUserDirectory() + "\\" + ETC_FOLDER_NAME, ex); } } } + /** + * Checks to see if the memory field value is valid. + * + * @return True if valid; false otherwise. + */ boolean valid() { return isMemFieldValid(); } @@ -355,15 +383,17 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { // //GEN-BEGIN:initComponents private void initComponents() { - buttonGroup1 = new javax.swing.ButtonGroup(); - buttonGroup3 = new javax.swing.ButtonGroup(); + fileSelectionButtonGroup = new javax.swing.ButtonGroup(); + displayTimesButtonGroup = new javax.swing.ButtonGroup(); + logoSourceButtonGroup = new javax.swing.ButtonGroup(); jScrollPane1 = new javax.swing.JScrollPane(); jPanel1 = new javax.swing.JPanel(); logoPanel = new javax.swing.JPanel(); - agencyLogoImageLabel = new javax.swing.JLabel(); agencyLogoPathField = new javax.swing.JTextField(); browseLogosButton = new javax.swing.JButton(); agencyLogoPreview = new javax.swing.JLabel(); + defaultLogoRB = new javax.swing.JRadioButton(); + specifyLogoRB = new javax.swing.JRadioButton(); viewPanel = new javax.swing.JPanel(); jLabelSelectFile = new javax.swing.JLabel(); useBestViewerRB = new javax.swing.JRadioButton(); @@ -391,13 +421,8 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { logoPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.logoPanel.border.title"))); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(agencyLogoImageLabel, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.agencyLogoImageLabel.text")); // NOI18N - - agencyLogoPathField.setEditable(false); agencyLogoPathField.setBackground(new java.awt.Color(255, 255, 255)); agencyLogoPathField.setText(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.agencyLogoPathField.text")); // NOI18N - agencyLogoPathField.setFocusable(false); - agencyLogoPathField.setRequestFocusEnabled(false); org.openide.awt.Mnemonics.setLocalizedText(browseLogosButton, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.browseLogosButton.text")); // NOI18N browseLogosButton.addActionListener(new java.awt.event.ActionListener() { @@ -413,6 +438,22 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { agencyLogoPreview.setMinimumSize(new java.awt.Dimension(64, 64)); agencyLogoPreview.setPreferredSize(new java.awt.Dimension(64, 64)); + logoSourceButtonGroup.add(defaultLogoRB); + org.openide.awt.Mnemonics.setLocalizedText(defaultLogoRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.defaultLogoRB.text")); // NOI18N + defaultLogoRB.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + defaultLogoRBActionPerformed(evt); + } + }); + + logoSourceButtonGroup.add(specifyLogoRB); + org.openide.awt.Mnemonics.setLocalizedText(specifyLogoRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.specifyLogoRB.text")); // NOI18N + specifyLogoRB.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + specifyLogoRBActionPerformed(evt); + } + }); + javax.swing.GroupLayout logoPanelLayout = new javax.swing.GroupLayout(logoPanel); logoPanel.setLayout(logoPanelLayout); logoPanelLayout.setHorizontalGroup( @@ -420,12 +461,12 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, logoPanelLayout.createSequentialGroup() .addContainerGap() .addGroup(logoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(agencyLogoImageLabel) - .addGroup(logoPanelLayout.createSequentialGroup() - .addGap(10, 10, 10) - .addComponent(agencyLogoPathField, javax.swing.GroupLayout.PREFERRED_SIZE, 259, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(browseLogosButton))) + .addComponent(specifyLogoRB) + .addComponent(defaultLogoRB)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(agencyLogoPathField, javax.swing.GroupLayout.PREFERRED_SIZE, 259, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(browseLogosButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(agencyLogoPreview, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) @@ -433,23 +474,24 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { logoPanelLayout.setVerticalGroup( logoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(logoPanelLayout.createSequentialGroup() - .addGroup(logoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(agencyLogoPreview, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGroup(logoPanelLayout.createSequentialGroup() - .addContainerGap() - .addComponent(agencyLogoImageLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(logoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(agencyLogoPathField) - .addComponent(browseLogosButton)))) - .addGap(0, 0, 0)) + .addGap(6, 6, 6) + .addComponent(defaultLogoRB) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(logoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(specifyLogoRB) + .addComponent(agencyLogoPathField) + .addComponent(browseLogosButton)) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, logoPanelLayout.createSequentialGroup() + .addComponent(agencyLogoPreview, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE)) ); viewPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.viewPanel.border.title"))); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(jLabelSelectFile, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.jLabelSelectFile.text")); // NOI18N - buttonGroup1.add(useBestViewerRB); + fileSelectionButtonGroup.add(useBestViewerRB); org.openide.awt.Mnemonics.setLocalizedText(useBestViewerRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.useBestViewerRB.text")); // NOI18N useBestViewerRB.setToolTipText(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.useBestViewerRB.toolTipText")); // NOI18N useBestViewerRB.addActionListener(new java.awt.event.ActionListener() { @@ -458,7 +500,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { } }); - buttonGroup1.add(keepCurrentViewerRB); + fileSelectionButtonGroup.add(keepCurrentViewerRB); org.openide.awt.Mnemonics.setLocalizedText(keepCurrentViewerRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.keepCurrentViewerRB.text")); // NOI18N keepCurrentViewerRB.setToolTipText(org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.keepCurrentViewerRB.toolTipText")); // NOI18N keepCurrentViewerRB.addActionListener(new java.awt.event.ActionListener() { @@ -501,7 +543,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { org.openide.awt.Mnemonics.setLocalizedText(jLabelTimeDisplay, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.jLabelTimeDisplay.text")); // NOI18N - buttonGroup3.add(useLocalTimeRB); + displayTimesButtonGroup.add(useLocalTimeRB); org.openide.awt.Mnemonics.setLocalizedText(useLocalTimeRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.useLocalTimeRB.text")); // NOI18N useLocalTimeRB.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -509,7 +551,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { } }); - buttonGroup3.add(useGMTTimeRB); + displayTimesButtonGroup.add(useGMTTimeRB); org.openide.awt.Mnemonics.setLocalizedText(useGMTTimeRB, org.openide.util.NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.useGMTTimeRB.text")); // NOI18N useGMTTimeRB.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -665,7 +707,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { .addComponent(runtimePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(logoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, 0)) + .addContainerGap()) ); jScrollPane1.setViewportView(jPanel1); @@ -674,9 +716,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(jScrollPane1) - .addGap(0, 0, 0)) + .addComponent(jScrollPane1) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -733,7 +773,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { try { updateAgencyLogo(oldLogoPath); //restore previous setting if new one is invalid } catch (IOException ex1) { - logger.log(Level.WARNING, "Error loading image from previously saved agency logo path", ex1); + LOGGER.log(Level.WARNING, "Error loading image from previously saved agency logo path", ex1); } } } @@ -748,6 +788,34 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); }//GEN-LAST:event_memFieldKeyReleased + private void defaultLogoRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_defaultLogoRBActionPerformed + agencyLogoPathField.setEnabled(false); + browseLogosButton.setEnabled(false); + try { + updateAgencyLogo(""); + } catch (IOException ex) { + // This should never happen since we're not reading from a file. + LOGGER.log(Level.SEVERE, "Unexpected error occurred while updating the agency logo.", ex); + } + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + }//GEN-LAST:event_defaultLogoRBActionPerformed + + private void specifyLogoRBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_specifyLogoRBActionPerformed + agencyLogoPathField.setEnabled(true); + browseLogosButton.setEnabled(true); + try { + if (agencyLogoPathField.getText().isEmpty()) { + String path = ModuleSettings.getConfigSetting(ReportBranding.MODULE_NAME, ReportBranding.AGENCY_LOGO_PATH_PROP); + if (path != null && !path.isEmpty()) { + updateAgencyLogo(path); + } + } + } catch (IOException ex) { + LOGGER.log(Level.WARNING, "Error loading image from previously saved agency logo path.", ex); + } + firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); + }//GEN-LAST:event_specifyLogoRBActionPerformed + /** * Checks that if the mem field is enabled it has a valid value. * @@ -786,14 +854,14 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { return true; } // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JLabel agencyLogoImageLabel; private javax.swing.JTextField agencyLogoPathField; private javax.swing.JLabel agencyLogoPreview; private javax.swing.JButton browseLogosButton; - private javax.swing.ButtonGroup buttonGroup1; - private javax.swing.ButtonGroup buttonGroup3; private javax.swing.JCheckBox dataSourcesHideKnownCB; private javax.swing.JCheckBox dataSourcesHideSlackCB; + private javax.swing.JRadioButton defaultLogoRB; + private javax.swing.ButtonGroup displayTimesButtonGroup; + private javax.swing.ButtonGroup fileSelectionButtonGroup; private javax.swing.JLabel invalidReasonLabel; private javax.swing.JLabel jLabelHideKnownFiles; private javax.swing.JLabel jLabelHideSlackFiles; @@ -803,12 +871,14 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel { private javax.swing.JScrollPane jScrollPane1; private javax.swing.JRadioButton keepCurrentViewerRB; private javax.swing.JPanel logoPanel; + private javax.swing.ButtonGroup logoSourceButtonGroup; private javax.swing.JLabel maxMemoryLabel; private javax.swing.JLabel maxMemoryUnitsLabel; private javax.swing.JLabel maxMemoryUnitsLabel1; private javax.swing.JTextField memField; private javax.swing.JLabel restartNecessaryWarning; private javax.swing.JPanel runtimePanel; + private javax.swing.JRadioButton specifyLogoRB; private javax.swing.JLabel systemMemoryTotal; private javax.swing.JLabel totalMemoryLabel; private javax.swing.JRadioButton useBestViewerRB; diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties index 26a2cc03e0..78a3853231 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties @@ -192,7 +192,6 @@ AutopsyOptionsPanel.jLabelHideSlackFiles.text=Hide slack files in the: AutopsyOptionsPanel.dataSourcesHideSlackCB.text=Data Sources area (the directory hierarchy) AutopsyOptionsPanel.viewsHideSlackCB.text=Views area AutopsyOptionsPanel.agencyLogoImageLabel.toolTipText= -AutopsyOptionsPanel.agencyLogoImageLabel.text=Image to use as the agency logo for HTML reports: AutopsyOptionsPanel.browseLogosButton.text=Browse AutopsyOptionsPanel.agencyLogoPathField.text= SortChooserDialog.label=remove @@ -201,3 +200,5 @@ DataResultViewerThumbnail.sortButton.text=Sort CriterionChooser.ascendingRadio.text=\u25b2 Ascending\n CriterionChooser.removeButton.text=Remove CriterionChooser.descendingRadio.text=\u25bc Descending +AutopsyOptionsPanel.defaultLogoRB.text=Use default +AutopsyOptionsPanel.specifyLogoRB.text=Specify a logo