<commit_before>package org.waterforpeople.mapping.portal.client.widgets.component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.waterforpeople.mapping.app.gwt.client.survey.OptionContainerDto;
import org.waterforpeople.mapping.app.gwt.client.survey.QuestionDependencyDto;
import org.waterforpeople.mapping.app.gwt.client.survey.QuestionDto;
import org.waterforpeople.mapping.app.gwt.client.survey.QuestionGroupDto;
import org.waterforpeople.mapping.app.gwt.client.survey.QuestionOptionDto;
import org.waterforpeople.mapping.app.gwt.client.survey.SurveyService;
import org.waterforpeople.mapping.app.gwt.client.survey.SurveyServiceAsync;
import org.waterforpeople.mapping.app.gwt.client.survey.TranslationDto;
import org.waterforpeople.mapping.app.gwt.client.survey.QuestionDto.QuestionType;

import com.gallatinsystems.framework.gwt.util.client.CompletionListener;
import com.gallatinsystems.framework.gwt.util.client.MessageDialog;
import com.gallatinsystems.framework.gwt.util.client.ViewUtil;
import com.gallatinsystems.framework.gwt.wizard.client.ContextAware;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CaptionPanel;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HTMLTable.Cell;

/**
 * Widget for creating and editing a Survey Question.
 * 
 * @author <NAME>
 * 
 */
public class QuestionEditWidget extends Composite implements ContextAware,
		ChangeHandler, ClickHandler, TranslationChangeListener,
		CompletionListener {

	private static final String REORDER_BUTTON_CSS = "reorder-button";
	private static final String DEFAULT_BOX_WIDTH = "300px";
	private static final String SELECT_TXT = "Select...";
	private static final String EDIT_TRANS_OP = "Edit Translation";
	private static final String EDIT_HELP_OP = "Edit Help";
	private VerticalPanel panel;
	private CaptionPanel basePanel;
	private TextArea questionTextArea;
	private ListBox questionTypeSelector;
	private TextArea tooltipArea;
	private TextBox validationRuleBox;
	private CheckBox mandatoryBox;
	private CheckBox dependentBox;
	private ListBox dependentQuestionSelector;
	private ListBox dependentAnswerSelector;
	private CaptionPanel dependencyPanel;
	private Grid dependencyGrid;

	private CheckBox allowOtherBox;
	private CheckBox allowMultipleBox;
	private Button addOptionButton;
	private CaptionPanel optionPanel;
	private VerticalPanel optionContent;
	private FlexTable optionTable;
	private SurveyServiceAsync surveyService;
	private Map<String, Object> bundle;
	private QuestionDto currentQuestion;
	private Map<Long, List<QuestionDto>> optionQuestions;
	private Button editTranslationButton;
	private Button editHelpButton;

	private QuestionGroupDto questionGroup;
	private String operation;

	public QuestionEditWidget() {
		surveyService = GWT.create(SurveyService.class);
		optionQuestions = new HashMap<Long, List<QuestionDto>>();
		installWidgets();
		initWidget(panel);
	}

	/**
	 * installs all the UI elements in their respective panels (even invisible
	 * items).
	 */
	private void installWidgets() {
		panel = new VerticalPanel();
		questionTextArea = new TextArea();
		questionTextArea.setWidth(DEFAULT_BOX_WIDTH);
		tooltipArea = new TextArea();
		tooltipArea.setWidth(DEFAULT_BOX_WIDTH);
		validationRuleBox = new TextBox();
		mandatoryBox = new CheckBox();
		dependentBox = new CheckBox();
		dependentBox.addClickHandler(this);
		questionTypeSelector = new ListBox();
		questionTypeSelector.addItem("Free Text",
				QuestionDto.QuestionType.FREE_TEXT.toString());
		questionTypeSelector.addItem("Option", QuestionDto.QuestionType.OPTION
				.toString());
		questionTypeSelector.addItem("Number", QuestionDto.QuestionType.NUMBER
				.toString());
		questionTypeSelector.addItem("Geo", QuestionDto.QuestionType.GEO
				.toString());
		questionTypeSelector.addItem("Photo", QuestionDto.QuestionType.PHOTO
				.toString());
		questionTypeSelector.addItem("Video", QuestionDto.QuestionType.VIDEO
				.toString());
		questionTypeSelector.addItem("Strength",
				QuestionDto.QuestionType.STRENGTH.toString());
		questionTypeSelector.addChangeHandler(this);
		basePanel = new CaptionPanel("Question Basics:");

		Grid grid = new Grid(7, 2);
		basePanel.add(grid);

		ViewUtil.installGridRow("Question Text", questionTextArea, grid, 0);
		ViewUtil.installGridRow("Question Type", questionTypeSelector, grid, 1);
		ViewUtil.installGridRow("Tooltip", tooltipArea, grid, 2);
		ViewUtil.installGridRow("Validation Rule", validationRuleBox, grid, 3);
		ViewUtil.installGridRow("Mandatory", mandatoryBox, grid, 4);
		ViewUtil.installGridRow("Dependent", dependentBox, grid, 5);

		dependencyPanel = new CaptionPanel("Dependency Details:");
		dependentQuestionSelector = new ListBox();
		dependentQuestionSelector.setWidth(DEFAULT_BOX_WIDTH);
		dependentQuestionSelector.addChangeHandler(this);
		dependentQuestionSelector.addItem(SELECT_TXT);

		dependentAnswerSelector = new ListBox();
		dependentAnswerSelector.addItem(SELECT_TXT);
		dependentAnswerSelector.setWidth(DEFAULT_BOX_WIDTH);

		dependencyGrid = new Grid(2, 2);
		dependencyPanel.add(dependencyGrid);
		ViewUtil.installGridRow(null, dependencyPanel, grid, 6, 1, null);
		dependencyPanel.setVisible(false);
		ViewUtil.installGridRow("Question", dependentQuestionSelector,
				dependencyGrid, 0);
		ViewUtil.installGridRow("Response", dependentAnswerSelector,
				dependencyGrid, 1);

		panel.add(basePanel);

		allowMultipleBox = new CheckBox();
		allowOtherBox = new CheckBox();
		addOptionButton = new Button("Add Option");
		addOptionButton.addClickHandler(this);
		optionPanel = new CaptionPanel("Option Details:");
		optionContent = new VerticalPanel();
		optionPanel.add(optionContent);
		optionTable = new FlexTable();
		Grid optGrid = new Grid(2, 4);
		ViewUtil.installGridRow("Allow Multiple", allowMultipleBox, optGrid, 0,
				0, null);
		ViewUtil.installGridRow("Allow 'Other'", allowOtherBox, optGrid, 0, 2,
				null);

		optionContent.add(optGrid);
		optionContent.add(optionTable);
		optionContent.add(addOptionButton);
		optionPanel.setVisible(false);
		panel.add(optionPanel);

		HorizontalPanel tempPanel = new HorizontalPanel();
		editTranslationButton = new Button("Edit Translations");
		editTranslationButton.addClickHandler(this);
		tempPanel.add(editTranslationButton);

		editHelpButton = new Button("Edit Help");
		editHelpButton.addClickHandler(this);
		tempPanel.add(editHelpButton);
		panel.add(tempPanel);
	}

	/**
	 * populates the UI based on the values in the loaded QuestionDto
	 */
	private void populateFields() {
		questionTextArea.setText(currentQuestion.getText());
		if (currentQuestion.getTip() != null
				&& currentQuestion.getTip().trim().length() > 0
				&& !"null".equals(currentQuestion.getTip())) {
			tooltipArea.setText(currentQuestion.getTip());
		}
		if (currentQuestion.getType() != null) {
			for (int i = 0; i < questionTypeSelector.getItemCount(); i++) {
				if (currentQuestion.getType().toString().equals(
						questionTypeSelector.getValue(i))) {
					questionTypeSelector.setSelectedIndex(i);
					break;
				}
			}
		}
		if (currentQuestion.getMandatoryFlag() != null) {
			mandatoryBox.setValue(currentQuestion.getMandatoryFlag());
		}
		if (currentQuestion.getQuestionDependency() != null && currentQuestion.getQuestionDependency().getQuestionId() != null) {
			dependentBox.setValue(true);
			loadDependencyList();
		}
		if (QuestionDto.QuestionType.OPTION == currentQuestion.getType()) {
			loadOptions();
		}
	}

	/**
	 * fetches the QuestionOptions from the server if they haven't already been
	 * retrieved
	 */
	private void loadOptions() {
		if (QuestionDto.QuestionType.OPTION == currentQuestion.getType()
				&& (currentQuestion.getOptionContainerDto() == null || currentQuestion
						.getOptionContainerDto().getOptionsList() == null)) {
			optionPanel.setVisible(true);
			showLoading(optionPanel, "Loading options...");
			surveyService.loadQuestionDetails(currentQuestion.getKeyId(),
					new AsyncCallback<QuestionDto>() {

						@Override
						public void onFailure(Throwable caught) {
							showContent(optionPanel, new Label("Error"));
						}

						@Override
						public void onSuccess(QuestionDto result) {
							showContent(optionPanel, optionContent);
							currentQuestion = result;
							populateOptions(currentQuestion
									.getOptionContainerDto());
						}
					});
		} else {
			populateOptions(currentQuestion.getOptionContainerDto());
		}
	}

	/**
	 * populates the UI with data from all the QuestionOptionDto objects in the
	 * question.
	 * 
	 * @param optionContainer
	 */
	private void populateOptions(OptionContainerDto optionContainer) {
		if (optionContainer != null) {
			optionPanel.setVisible(true);
			// wipe out any old values
			optionTable.clear(true);
			allowMultipleBox.setValue(optionContainer.getAllowMultipleFlag());
			allowOtherBox.setValue(optionContainer.getAllowOtherFlag());
			if (optionContainer != null
					&& optionContainer.getOptionsList() != null) {
				for (QuestionOptionDto opt : optionContainer.getOptionsList()) {
					installOptionRow(opt);
				}
			}
		}
	}

	/**
	 * adds a row representing a Question Option to the UI. The rows support
	 * deletion as well as reordering.
	 * 
	 * @param opt
	 */
	private void installOptionRow(QuestionOptionDto opt) {
		int row = optionTable.getRowCount();
		optionTable.insertRow(row);
		TextBox optText = new TextBox();
		optionTable.setWidget(row, 0, optText);
		HorizontalPanel bp = new HorizontalPanel();
		final Image moveUp = new Image("/images/greenuparrow.png");
		final Image moveDown = new Image("/images/greendownarrow.png");
		final Button deleteButton = new Button("Remove");

		ClickHandler optionClickHandler = new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				ArrayList<QuestionOptionDto> optList = currentQuestion
						.getOptionContainerDto().getOptionsList();
				Cell cell = optionTable.getCellForEvent(event);
				if (event.getSource() == deleteButton) {
					optionTable.removeRow(cell.getRowIndex());
					optList.remove(cell.getRowIndex());
				} else {
					int increment = 0;
					if (event.getSource() == moveUp && cell.getRowIndex() > 0) {
						increment = -1;
					} else if (event.getSource() == moveDown
							&& cell.getRowIndex() < optList.size() - 1) {
						increment = 1;
					}
					if (increment != 0) {
						QuestionOptionDto targetOpt = optList.get(cell
								.getRowIndex()
								+ increment);
						QuestionOptionDto movingOpt = optList.get(cell
								.getRowIndex());<commit_msg>added ability to re-sort options prior to saving question<commit_after>package org.waterforpeople.mapping.portal.client.widgets.component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.waterforpeople.mapping.app.gwt.client.survey.OptionContainerDto;
import org.waterforpeople.mapping.app.gwt.client.survey.QuestionDependencyDto;
import org.waterforpeople.mapping.app.gwt.client.survey.QuestionDto;
import org.waterforpeople.mapping.app.gwt.client.survey.QuestionGroupDto;
import org.waterforpeople.mapping.app.gwt.client.survey.QuestionOptionDto;
import org.waterforpeople.mapping.app.gwt.client.survey.SurveyService;
import org.waterforpeople.mapping.app.gwt.client.survey.SurveyServiceAsync;
import org.waterforpeople.mapping.app.gwt.client.survey.TranslationDto;
import org.waterforpeople.mapping.app.gwt.client.survey.QuestionDto.QuestionType;

import com.gallatinsystems.framework.gwt.util.client.CompletionListener;
import com.gallatinsystems.framework.gwt.util.client.MessageDialog;
import com.gallatinsystems.framework.gwt.util.client.ViewUtil;
import com.gallatinsystems.framework.gwt.wizard.client.ContextAware;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CaptionPanel;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HTMLTable.Cell;

/**
 * Widget for creating and editing a Survey Question.
 * 
 * @author <NAME>
 * 
 */
public class QuestionEditWidget extends Composite implements ContextAware,
		ChangeHandler, ClickHandler, TranslationChangeListener,
		CompletionListener {

	private static final String REORDER_BUTTON_CSS = "reorder-button";
	private static final String DEFAULT_BOX_WIDTH = "300px";
	private static final String SELECT_TXT = "Select...";
	private static final String EDIT_TRANS_OP = "Edit Translation";
	private static final String EDIT_HELP_OP = "Edit Help";
	private VerticalPanel panel;
	private CaptionPanel basePanel;
	private TextArea questionTextArea;
	private ListBox questionTypeSelector;
	private TextArea tooltipArea;
	private TextBox validationRuleBox;
	private CheckBox mandatoryBox;
	private CheckBox dependentBox;
	private ListBox dependentQuestionSelector;
	private ListBox dependentAnswerSelector;
	private CaptionPanel dependencyPanel;
	private Grid dependencyGrid;

	private CheckBox allowOtherBox;
	private CheckBox allowMultipleBox;
	private Button addOptionButton;
	private CaptionPanel optionPanel;
	private VerticalPanel optionContent;
	private FlexTable optionTable;
	private SurveyServiceAsync surveyService;
	private Map<String, Object> bundle;
	private QuestionDto currentQuestion;
	private Map<Long, List<QuestionDto>> optionQuestions;
	private Button editTranslationButton;
	private Button editHelpButton;

	private QuestionGroupDto questionGroup;
	private String operation;

	public QuestionEditWidget() {
		surveyService = GWT.create(SurveyService.class);
		optionQuestions = new HashMap<Long, List<QuestionDto>>();
		installWidgets();
		initWidget(panel);
	}

	/**
	 * installs all the UI elements in their respective panels (even invisible
	 * items).
	 */
	private void installWidgets() {
		panel = new VerticalPanel();
		questionTextArea = new TextArea();
		questionTextArea.setWidth(DEFAULT_BOX_WIDTH);
		tooltipArea = new TextArea();
		tooltipArea.setWidth(DEFAULT_BOX_WIDTH);
		validationRuleBox = new TextBox();
		mandatoryBox = new CheckBox();
		dependentBox = new CheckBox();
		dependentBox.addClickHandler(this);
		questionTypeSelector = new ListBox();
		questionTypeSelector.addItem("Free Text",
				QuestionDto.QuestionType.FREE_TEXT.toString());
		questionTypeSelector.addItem("Option", QuestionDto.QuestionType.OPTION
				.toString());
		questionTypeSelector.addItem("Number", QuestionDto.QuestionType.NUMBER
				.toString());
		questionTypeSelector.addItem("Geo", QuestionDto.QuestionType.GEO
				.toString());
		questionTypeSelector.addItem("Photo", QuestionDto.QuestionType.PHOTO
				.toString());
		questionTypeSelector.addItem("Video", QuestionDto.QuestionType.VIDEO
				.toString());
		questionTypeSelector.addItem("Strength",
				QuestionDto.QuestionType.STRENGTH.toString());
		questionTypeSelector.addChangeHandler(this);
		basePanel = new CaptionPanel("Question Basics:");

		Grid grid = new Grid(7, 2);
		basePanel.add(grid);

		ViewUtil.installGridRow("Question Text", questionTextArea, grid, 0);
		ViewUtil.installGridRow("Question Type", questionTypeSelector, grid, 1);
		ViewUtil.installGridRow("Tooltip", tooltipArea, grid, 2);
		ViewUtil.installGridRow("Validation Rule", validationRuleBox, grid, 3);
		ViewUtil.installGridRow("Mandatory", mandatoryBox, grid, 4);
		ViewUtil.installGridRow("Dependent", dependentBox, grid, 5);

		dependencyPanel = new CaptionPanel("Dependency Details:");
		dependentQuestionSelector = new ListBox();
		dependentQuestionSelector.setWidth(DEFAULT_BOX_WIDTH);
		dependentQuestionSelector.addChangeHandler(this);
		dependentQuestionSelector.addItem(SELECT_TXT);

		dependentAnswerSelector = new ListBox();
		dependentAnswerSelector.addItem(SELECT_TXT);
		dependentAnswerSelector.setWidth(DEFAULT_BOX_WIDTH);

		dependencyGrid = new Grid(2, 2);
		dependencyPanel.add(dependencyGrid);
		ViewUtil.installGridRow(null, dependencyPanel, grid, 6, 1, null);
		dependencyPanel.setVisible(false);
		ViewUtil.installGridRow("Question", dependentQuestionSelector,
				dependencyGrid, 0);
		ViewUtil.installGridRow("Response", dependentAnswerSelector,
				dependencyGrid, 1);

		panel.add(basePanel);

		allowMultipleBox = new CheckBox();
		allowOtherBox = new CheckBox();
		addOptionButton = new Button("Add Option");
		addOptionButton.addClickHandler(this);
		optionPanel = new CaptionPanel("Option Details:");
		optionContent = new VerticalPanel();
		optionPanel.add(optionContent);
		optionTable = new FlexTable();
		Grid optGrid = new Grid(2, 4);
		ViewUtil.installGridRow("Allow Multiple", allowMultipleBox, optGrid, 0,
				0, null);
		ViewUtil.installGridRow("Allow 'Other'", allowOtherBox, optGrid, 0, 2,
				null);

		optionContent.add(optGrid);
		optionContent.add(optionTable);
		optionContent.add(addOptionButton);
		optionPanel.setVisible(false);
		panel.add(optionPanel);

		HorizontalPanel tempPanel = new HorizontalPanel();
		editTranslationButton = new Button("Edit Translations");
		editTranslationButton.addClickHandler(this);
		tempPanel.add(editTranslationButton);

		editHelpButton = new Button("Edit Help");
		editHelpButton.addClickHandler(this);
		tempPanel.add(editHelpButton);
		panel.add(tempPanel);
	}

	/**
	 * populates the UI based on the values in the loaded QuestionDto
	 */
	private void populateFields() {
		questionTextArea.setText(currentQuestion.getText());
		if (currentQuestion.getTip() != null
				&& currentQuestion.getTip().trim().length() > 0
				&& !"null".equals(currentQuestion.getTip())) {
			tooltipArea.setText(currentQuestion.getTip());
		}
		if (currentQuestion.getType() != null) {
			for (int i = 0; i < questionTypeSelector.getItemCount(); i++) {
				if (currentQuestion.getType().toString().equals(
						questionTypeSelector.getValue(i))) {
					questionTypeSelector.setSelectedIndex(i);
					break;
				}
			}
		}
		if (currentQuestion.getMandatoryFlag() != null) {
			mandatoryBox.setValue(currentQuestion.getMandatoryFlag());
		}
		if (currentQuestion.getQuestionDependency() != null && currentQuestion.getQuestionDependency().getQuestionId() != null) {
			dependentBox.setValue(true);
			loadDependencyList();
		}
		if (QuestionDto.QuestionType.OPTION == currentQuestion.getType()) {
			loadOptions();
		}
	}

	/**
	 * fetches the QuestionOptions from the server if they haven't already been
	 * retrieved
	 */
	private void loadOptions() {
		if (QuestionDto.QuestionType.OPTION == currentQuestion.getType()
				&& (currentQuestion.getOptionContainerDto() == null || currentQuestion
						.getOptionContainerDto().getOptionsList() == null)) {
			optionPanel.setVisible(true);
			showLoading(optionPanel, "Loading options...");
			surveyService.loadQuestionDetails(currentQuestion.getKeyId(),
					new AsyncCallback<QuestionDto>() {

						@Override
						public void onFailure(Throwable caught) {
							showContent(optionPanel, new Label("Error"));
						}

						@Override
						public void onSuccess(QuestionDto result) {
							showContent(optionPanel, optionContent);
							currentQuestion = result;
							populateOptions(currentQuestion
									.getOptionContainerDto());
						}
					});
		} else {
			populateOptions(currentQuestion.getOptionContainerDto());
		}
	}

	/**
	 * populates the UI with data from all the QuestionOptionDto objects in the
	 * question.
	 * 
	 * @param optionContainer
	 */
	private void populateOptions(OptionContainerDto optionContainer) {
		if (optionContainer != null) {
			optionPanel.setVisible(true);
			// wipe out any old values
			optionTable.clear(true);
			allowMultipleBox.setValue(optionContainer.getAllowMultipleFlag());
			allowOtherBox.setValue(optionContainer.getAllowOtherFlag());
			if (optionContainer != null
					&& optionContainer.getOptionsList() != null) {
				for (QuestionOptionDto opt : optionContainer.getOptionsList()) {
					installOptionRow(opt);
				}
			}
		}
	}

	/**
	 * adds a row representing a Question Option to the UI. The rows support
	 * deletion as well as reordering.
	 * 
	 * @param opt
	 */
	private void installOptionRow(QuestionOptionDto opt) {
		int row = optionTable.getRowCount();
		optionTable.insertRow(row);
		TextBox optText = new TextBox();
		optionTable.setWidget(row, 0, optText);
		HorizontalPanel bp = new HorizontalPanel();
		final Image moveUp = new Image("/images/greenuparrow.png");
		final Image moveDown = new Image("/images/greendownarrow.png");
		final Button deleteButton = new Button("Remove");

		ClickHandler optionClickHandler = new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				updateCurrentQuestion();
				ArrayList<QuestionOptionDto> optList = currentQuestion
						.getOptionContainerDto().getOptionsList();
				Cell cell = optionTable.getCellForEvent(event);
				if (event.getSource() == deleteButton) {
					optionTable.removeRow(cell.getRowIndex());
					optList.remove(cell.getRowIndex());
				} else {
					int increment = 0;
					if (event.getSource() == moveUp && cell.getRowIndex() > 0) {
						increment = -1;
					} else if (event.getSource() == moveDown
							&& cell.getRowIndex() < optList.size() - 1) {
						increment = 1;
					}
					if (increment != 0) {
						QuestionOptionDto targetOpt = optList.get(cell
								.getRowIndex()
								+ increment);
						QuestionOptionDto movingOpt = optList.get(cell
								.getRowIndex());
{'fraction_non_alphanumeric': 0.11238858028678465, 'fraction_numerical': 0.0027558885587564055, 'mean_word_length': 5.052645295804013, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, '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': '3877468', 'n_tokens_mistral': 7628, 'n_tokens_neox': 6742, 'n_words': 1356}