summaryrefslogtreecommitdiff
path: root/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/StatsDialog.java
blob: 0398093b0991840f0c2c50273ea497290574ff59 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package cuchaz.enigma.gui.dialog;

import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.*;
import java.util.stream.Collectors;

import javax.swing.*;

import cuchaz.enigma.gui.Gui;
import cuchaz.enigma.gui.config.UiConfig;
import cuchaz.enigma.gui.stats.StatsGenerator;
import cuchaz.enigma.gui.stats.StatsMember;
import cuchaz.enigma.gui.stats.StatsResult;
import cuchaz.enigma.gui.util.GridBagConstraintsBuilder;
import cuchaz.enigma.gui.util.ScaleUtil;
import cuchaz.enigma.utils.I18n;

public class StatsDialog {

	public static void show(Gui gui) {
		ProgressDialog.runOffThread(gui.getFrame(), listener -> {
			final StatsGenerator statsGenerator = new StatsGenerator(gui.getController().project);
			final Map<StatsMember, StatsResult> results = new HashMap<>();
			for (StatsMember member : StatsMember.values()) {
				results.put(member, statsGenerator.generate(listener, Collections.singleton(member), "", false));
			}
			SwingUtilities.invokeLater(() -> show(gui, results));
		});
	}

	public static void show(Gui gui, Map<StatsMember, StatsResult> results) {
		// init frame
		JDialog dialog = new JDialog(gui.getFrame(), I18n.translate("menu.file.stats.title"), true);
		Container contentPane = dialog.getContentPane();
		contentPane.setLayout(new GridBagLayout());

		GridBagConstraintsBuilder cb = GridBagConstraintsBuilder.create().insets(2);

		Map<StatsMember, JCheckBox> checkboxes = new HashMap<>();

		int[] i = {0};
		results.entrySet().stream().sorted(Map.Entry.comparingByKey()).forEach(e -> {
			StatsMember m = e.getKey();
			StatsResult result = e.getValue();

			JCheckBox checkBox = new JCheckBox(I18n.translate("type." + m.name().toLowerCase(Locale.ROOT)));
			checkboxes.put(m, checkBox);
			contentPane.add(checkBox, cb.pos(0, i[0]).weightX(1.0).anchor(GridBagConstraints.WEST).build());

			GridBagConstraintsBuilder labels = cb.anchor(GridBagConstraints.EAST);

			contentPane.add(new JLabel(Integer.toString(result.getMapped())), labels.pos(1, i[0]).build());
			contentPane.add(new JLabel("/"), labels.pos(2, i[0]).build());
			contentPane.add(new JLabel(Integer.toString(result.getTotal())), labels.pos(3, i[0]).build());
			contentPane.add(new JLabel(String.format("%.2f%%", result.getPercentage())), labels.pos(4, i[0]).build());

			i[0]++;
		});

		GridBagConstraintsBuilder cb1 = cb.pos(0, 0).width(5).weightX(1.0).anchor(GridBagConstraints.WEST);

		// show top-level package option
		JLabel topLevelPackageOption = new JLabel(I18n.translate("menu.file.stats.top_level_package"));
		contentPane.add(topLevelPackageOption, cb1.pos(0, results.size() + 1).build());

		JTextField topLevelPackage = new JTextField();
		topLevelPackage.setText(UiConfig.getLastTopLevelPackage());
		contentPane.add(topLevelPackage, cb1.pos(0, results.size() + 2).fill(GridBagConstraints.HORIZONTAL).build());

		// show synthetic members option
		JCheckBox syntheticParametersOption = new JCheckBox(I18n.translate("menu.file.stats.synthetic_parameters"));
		syntheticParametersOption.setSelected(UiConfig.shouldIncludeSyntheticParameters());
		contentPane.add(syntheticParametersOption, cb1.pos(0, results.size() + 3).build());

		// show generate button
		JButton button = new JButton(I18n.translate("menu.file.stats.generate"));
		button.setEnabled(false);
		button.addActionListener(action -> {
			dialog.dispose();

			UiConfig.setLastTopLevelPackage(topLevelPackage.getText());
			UiConfig.setIncludeSyntheticParameters(syntheticParametersOption.isSelected());
			UiConfig.save();

			generateStats(gui, checkboxes, topLevelPackage.getText(), syntheticParametersOption.isSelected());
		});

		contentPane.add(button, cb1.pos(0, results.size() + 4).weightY(1.0).anchor(GridBagConstraints.SOUTHEAST).build());

		// add action listener to each checkbox
		checkboxes.forEach((key, value) -> value.addActionListener(action -> {
			if (!button.isEnabled()) {
				button.setEnabled(true);
			} else if (checkboxes.entrySet().stream().noneMatch(entry -> entry.getValue().isSelected())) {
				button.setEnabled(false);
			}
		}));

		// show the frame
		dialog.pack();
		Dimension size = dialog.getSize();
		dialog.setMinimumSize(size);
		size.width = ScaleUtil.scale(350);
		dialog.setSize(size);
		dialog.setLocationRelativeTo(gui.getFrame());
		dialog.setVisible(true);
	}

	private static void generateStats(Gui gui, Map<StatsMember, JCheckBox> checkboxes, String topLevelPackage, boolean includeSynthetic) {
		// get members from selected checkboxes
		Set<StatsMember> includedMembers = checkboxes
				.entrySet()
				.stream()
				.filter(entry -> entry.getValue().isSelected())
				.map(Map.Entry::getKey)
				.collect(Collectors.toSet());

		// checks if a project is open
		if (gui.getController().project != null) {
			gui.getController().openStats(includedMembers, topLevelPackage, includeSynthetic);
		}
	}
}