<commit_before>/*
 * Autopsy Forensic Browser
 *
 * Copyright 2013-16 Basis Technology Corp.
 * Contact: carrier <at> sleuthkit <dot> 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 org.sleuthkit.autopsy.timeline.zooming;

import java.util.function.Consumer;
import java.util.function.Function;
import javafx.application.Platform;
import javafx.beans.InvalidationListener;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.control.TitledPane;
import javafx.util.StringConverter;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
import org.sleuthkit.autopsy.timeline.TimeLineController;
import org.sleuthkit.autopsy.timeline.ViewMode;
import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel;
import org.sleuthkit.autopsy.timeline.utils.RangeDivisionInfo;

/**
 * A Panel that acts as a view for a given
 * TimeLineController/FilteredEventsModel. It has sliders to provide
 * context/control over three axes of zooming (timescale, event hierarchy level,
 * and description level of detail).
 */
public class ZoomSettingsPane extends TitledPane {

    @FXML
    private Label zoomLabel;

    @FXML
    private Label descrLODLabel;
    @FXML
    private Slider descrLODSlider;

    @FXML
    private Label typeZoomLabel;
    @FXML
    private Slider typeZoomSlider;

    @FXML
    private Label timeUnitLabel;
    @FXML
    private Slider timeUnitSlider;

    private final TimeLineController controller;
    private final FilteredEventsModel filteredEvents;

    /**
     * Constructor
     *
     * @param controller TimeLineController this panel functions as a view for.
     */
    public ZoomSettingsPane(TimeLineController controller) {
        this.controller = controller;
        this.filteredEvents = controller.getEventsModel();
        FXMLConstructor.construct(this, "ZoomSettingsPane.fxml"); // NON-NLS
    }

    @NbBundle.Messages({
        "ZoomSettingsPane.descrLODLabel.text=Description Detail:",
        "ZoomSettingsPane.typeZoomLabel.text=Event Type:",
        "ZoomSettingsPane.timeUnitLabel.text=Time Units:",
        "ZoomSettingsPane.zoomLabel.text=Zoom"})
    public void initialize() {
        zoomLabel.setText(Bundle.ZoomSettingsPane_zoomLabel_text());

        typeZoomSlider.setMin(1); //don't show ROOT_TYPE
        typeZoomSlider.setMax(EventTypeZoomLevel.values().length - 1);
        configureSliderListeners(typeZoomSlider,
                controller::pushEventTypeZoom,
                filteredEvents.eventTypeZoomProperty(),
                EventTypeZoomLevel.class,
                EventTypeZoomLevel::ordinal,
                Function.identity());
        typeZoomLabel.setText(Bundle.ZoomSettingsPane_typeZoomLabel_text());
        typeZoomSlider.disableProperty().bind(controller.viewModeProperty().isEqualTo(ViewMode.LIST));

        descrLODSlider.setMax(DescriptionLoD.values().length - 1);
        configureSliderListeners(descrLODSlider,
                controller::pushDescrLOD,
                filteredEvents.descriptionLODProperty(),
                DescriptionLoD.class,
                DescriptionLoD::ordinal,
                Function.identity());
        descrLODLabel.setText(Bundle.ZoomSettingsPane_descrLODLabel_text());
        //the description slider is only usefull in the detail view
        descrLODSlider.disableProperty().bind(controller.viewModeProperty().isNotEqualTo(ViewMode.DETAIL));

        /**
         * In order for the selected value in the time unit slider to correspond
         * to the amount of time used as units along the x-axis of the
         * visualization, and since we don't want to show "forever" as a time
         * unit, the range of the slider is restricted, and there is an offset
         * of 1 between the "real" value, and what is shown in the slider
         * labels.
         */
        timeUnitSlider.setMax(TimeUnits.values().length - 2);
        configureSliderListeners(timeUnitSlider,
                controller::pushTimeUnit,
                filteredEvents.timeRangeProperty(),
                TimeUnits.class,
                //for the purposes of this slider we want the TimeUnit one bigger than RangeDivisionInfo indicates
                modelTimeRange -> RangeDivisionInfo.getRangeDivisionInfo(modelTimeRange).getPeriodSize().ordinal() - 1,
                index -> index + 1);  //compensate for the -1 above when mapping to the Enum whose displayName will be shown at index
        timeUnitLabel.setText(Bundle.ZoomSettingsPane_timeUnitLabel_text());
        timeUnitSlider.disableProperty().bind(controller.viewModeProperty().isEqualTo(ViewMode.LIST));
    }

    /**
     * Configure the listeners that keep the given slider in sync with model
     * property changes, and that handle user input on the slider. The listener
     * attached to the slider is added and removed to avoid circular updates.
     *
     * Because Sliders work in terms of Doubles but represent ordered Enums that
     * are indexed by Integers, and because the model properties may not be of
     * the same type as the Enum(timeUnitSlider relates to an Interval in the
     * filteredEvents model, rather than the TimeUnits shown on the Slider), a
     * mapper is needed to convert between DriverType and Integer
     * indices(driverValueMapper). Another mapper is used to modifiy the mapping
     * from Integer index to Enum value displayed as the slider tick
     * label(labelIndexMapper).<commit_msg>remove  the whole zoom panel in list mode<commit_after>/*
 * Autopsy Forensic Browser
 *
 * Copyright 2013-16 Basis Technology Corp.
 * Contact: carrier <at> sleuthkit <dot> 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 org.sleuthkit.autopsy.timeline.zooming;

import java.util.function.Consumer;
import java.util.function.Function;
import javafx.application.Platform;
import javafx.beans.InvalidationListener;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.control.TitledPane;
import javafx.util.StringConverter;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.timeline.FXMLConstructor;
import org.sleuthkit.autopsy.timeline.TimeLineController;
import org.sleuthkit.autopsy.timeline.ViewMode;
import org.sleuthkit.autopsy.timeline.datamodel.FilteredEventsModel;
import org.sleuthkit.autopsy.timeline.utils.RangeDivisionInfo;

/**
 * A Panel that acts as a view for a given
 * TimeLineController/FilteredEventsModel. It has sliders to provide
 * context/control over three axes of zooming (timescale, event hierarchy level,
 * and description level of detail).
 */
public class ZoomSettingsPane extends TitledPane {

    @FXML
    private Label zoomLabel;

    @FXML
    private Label descrLODLabel;
    @FXML
    private Slider descrLODSlider;

    @FXML
    private Label typeZoomLabel;
    @FXML
    private Slider typeZoomSlider;

    @FXML
    private Label timeUnitLabel;
    @FXML
    private Slider timeUnitSlider;

    private final TimeLineController controller;
    private final FilteredEventsModel filteredEvents;

    /**
     * Constructor
     *
     * @param controller TimeLineController this panel functions as a view for.
     */
    public ZoomSettingsPane(TimeLineController controller) {
        this.controller = controller;
        this.filteredEvents = controller.getEventsModel();
        FXMLConstructor.construct(this, "ZoomSettingsPane.fxml"); // NON-NLS
    }

    @NbBundle.Messages({
        "ZoomSettingsPane.descrLODLabel.text=Description Detail:",
        "ZoomSettingsPane.typeZoomLabel.text=Event Type:",
        "ZoomSettingsPane.timeUnitLabel.text=Time Units:",
        "ZoomSettingsPane.zoomLabel.text=Zoom"})
    public void initialize() {
        zoomLabel.setText(Bundle.ZoomSettingsPane_zoomLabel_text());

        typeZoomSlider.setMin(1); //don't show ROOT_TYPE
        typeZoomSlider.setMax(EventTypeZoomLevel.values().length - 1);
        configureSliderListeners(typeZoomSlider,
                controller::pushEventTypeZoom,
                filteredEvents.eventTypeZoomProperty(),
                EventTypeZoomLevel.class,
                EventTypeZoomLevel::ordinal,
                Function.identity());
        typeZoomLabel.setText(Bundle.ZoomSettingsPane_typeZoomLabel_text());

        descrLODSlider.setMax(DescriptionLoD.values().length - 1);
        configureSliderListeners(descrLODSlider,
                controller::pushDescrLOD,
                filteredEvents.descriptionLODProperty(),
                DescriptionLoD.class,
                DescriptionLoD::ordinal,
                Function.identity());
        descrLODLabel.setText(Bundle.ZoomSettingsPane_descrLODLabel_text());
        //the description slider is only usefull in the detail view
        descrLODSlider.disableProperty().bind(controller.viewModeProperty().isEqualTo(ViewMode.COUNTS));

        /**
         * In order for the selected value in the time unit slider to correspond
         * to the amount of time used as units along the x-axis of the
         * visualization, and since we don't want to show "forever" as a time
         * unit, the range of the slider is restricted, and there is an offset
         * of 1 between the "real" value, and what is shown in the slider
         * labels.
         */
        timeUnitSlider.setMax(TimeUnits.values().length - 2);
        configureSliderListeners(timeUnitSlider,
                controller::pushTimeUnit,
                filteredEvents.timeRangeProperty(),
                TimeUnits.class,
                //for the purposes of this slider we want the TimeUnit one bigger than RangeDivisionInfo indicates
                modelTimeRange -> RangeDivisionInfo.getRangeDivisionInfo(modelTimeRange).getPeriodSize().ordinal() - 1,
                index -> index + 1);  //compensate for the -1 above when mapping to the Enum whose displayName will be shown at index
        timeUnitLabel.setText(Bundle.ZoomSettingsPane_timeUnitLabel_text());

        //hide the whole panel in list mode
        BooleanBinding notListMode = controller.viewModeProperty().isNotEqualTo(ViewMode.LIST);
        visibleProperty().bind(notListMode);
        managedProperty().bind(notListMode);

    }

    /**
     * Configure the listeners that keep the given slider in sync with model
     * property changes, and that handle user input on the slider. The listener
     * attached to the slider is added and removed to avoid circular updates.
     *
     * Because Sliders work in terms of Doubles but represent ordered Enums that
     * are indexed by Integers, and because the model properties may not be of
     * the same type as the Enum(timeUnitSlider relates to an Interval in the
     * filteredEvents model, rather than the TimeUnits shown on the Slider), a
     * mapper is needed to convert between DriverType and Integer
     * indices(driverValueMapper). Another mapper is used to modifiy the mapping
     * from Integer index to Enum value displayed as the slider tick
     * label(labelIndexMapper).
{'fraction_non_alphanumeric': 0.07464387464387465, 'fraction_numerical': 0.0029304029304029304, 'mean_word_length': 3.2248968363136177, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6000910', 'n_tokens_mistral': 3281, 'n_tokens_neox': 3189, 'n_words': 1000}