* Fix #2010 * Improve behaviour * Add License
This commit is contained in:
@@ -42,8 +42,14 @@ import org.jackhuang.hmcl.ui.construct.PageCloseEvent;
|
||||
import org.jackhuang.hmcl.ui.decorator.DecoratorPage;
|
||||
import org.jackhuang.hmcl.util.Pair;
|
||||
import org.jackhuang.hmcl.util.TaskCancellationAction;
|
||||
import org.jackhuang.hmcl.util.io.CSVTable;
|
||||
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -100,6 +106,9 @@ public class ModUpdatesPage extends BorderPane implements DecoratorPage {
|
||||
actions.setPadding(new Insets(8));
|
||||
actions.setAlignment(Pos.CENTER_RIGHT);
|
||||
|
||||
JFXButton exportListButton = FXUtils.newRaisedButton(i18n("button.export"));
|
||||
exportListButton.setOnAction(e -> exportList());
|
||||
|
||||
JFXButton nextButton = FXUtils.newRaisedButton(i18n("mods.check_updates.update"));
|
||||
nextButton.setOnAction(e -> updateMods());
|
||||
|
||||
@@ -107,7 +116,7 @@ public class ModUpdatesPage extends BorderPane implements DecoratorPage {
|
||||
cancelButton.setOnAction(e -> fireEvent(new PageCloseEvent()));
|
||||
onEscPressed(this, cancelButton::fire);
|
||||
|
||||
actions.getChildren().setAll(nextButton, cancelButton);
|
||||
actions.getChildren().setAll(exportListButton, nextButton, cancelButton);
|
||||
setBottom(actions);
|
||||
}
|
||||
|
||||
@@ -140,6 +149,36 @@ public class ModUpdatesPage extends BorderPane implements DecoratorPage {
|
||||
TaskCancellationAction.NORMAL);
|
||||
}
|
||||
|
||||
private void exportList() {
|
||||
Path path = Paths.get("hmcl-mod-update-list-" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH-mm-ss")) + ".csv").toAbsolutePath();
|
||||
|
||||
Controllers.taskDialog(Task.runAsync(() -> {
|
||||
CSVTable csvTable = CSVTable.createEmpty();
|
||||
|
||||
csvTable.set(0, 0, "Source File Name");
|
||||
csvTable.set(1, 0, "Current Version");
|
||||
csvTable.set(2, 0, "Target Version");
|
||||
csvTable.set(3, 0, "Update Source");
|
||||
|
||||
for (int i = 0; i < objects.size(); i++) {
|
||||
csvTable.set(0, i + 1, objects.get(i).fileName.get());
|
||||
csvTable.set(1, i + 1, objects.get(i).currentVersion.get());
|
||||
csvTable.set(2, i + 1, objects.get(i).targetVersion.get());
|
||||
csvTable.set(3, i + 1, objects.get(i).source.get());
|
||||
}
|
||||
|
||||
csvTable.write(Files.newOutputStream(path));
|
||||
|
||||
FXUtils.showFileInExplorer(path);
|
||||
}).whenComplete(exception -> {
|
||||
if (exception == null) {
|
||||
Controllers.dialog(path.toString(), i18n("message.success"));
|
||||
} else {
|
||||
Controllers.dialog("", i18n("message.error"), MessageDialogPane.MessageType.ERROR);
|
||||
}
|
||||
}), i18n("button.export"), TaskCancellationAction.NORMAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadOnlyObjectWrapper<State> stateProperty() {
|
||||
return state;
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher
|
||||
* Copyright (C) 2020 huangyuhui <huanghongxun2008@126.com> and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.jackhuang.hmcl.util;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
public final class InfiniteSizeList<T> extends ArrayList<T> {
|
||||
private int actualSize;
|
||||
|
||||
public InfiniteSizeList(int initialCapacity) {
|
||||
super(initialCapacity);
|
||||
|
||||
this.actualSize = 0;
|
||||
}
|
||||
|
||||
public InfiniteSizeList() {
|
||||
this.actualSize = 0;
|
||||
}
|
||||
|
||||
public InfiniteSizeList(@NotNull Collection<? extends T> c) {
|
||||
super(c);
|
||||
|
||||
this.actualSize = 0;
|
||||
for (int i = super.size() - 1; i >= 0; i--) {
|
||||
if (super.get(i) != null) {
|
||||
actualSize = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get(int index) {
|
||||
if (index >= super.size()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return super.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T set(int index, T element) {
|
||||
if (element == null) { // The element is null.
|
||||
if (index >= super.size()) {
|
||||
return null; // The element (actually null) is out of the allocated size.
|
||||
}
|
||||
|
||||
T previous = super.get(index);
|
||||
if (previous != null) { // !null -> null
|
||||
super.set(index, null);
|
||||
|
||||
if (index == this.actualSize - 1) { // Recalculate the actualSize.
|
||||
this.actualSize = 0;
|
||||
|
||||
for (int i = index - 1; i >= 0; i--) {
|
||||
if (super.get(i) != null) {
|
||||
this.actualSize = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return previous;
|
||||
} else { // null -> null
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
// The element isn't null.
|
||||
|
||||
if (index >= super.size()) {
|
||||
allocate0(index);
|
||||
}
|
||||
|
||||
T previous = super.get(index);
|
||||
if (previous != null) { // !null -> !null
|
||||
super.set(index, element);
|
||||
return previous;
|
||||
} else { // null -> !null
|
||||
super.set(index, element);
|
||||
if (index >= this.actualSize) {
|
||||
this.actualSize = index + 1;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void allocate0(int index) {
|
||||
super.ensureCapacity(index + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return actualSize;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher
|
||||
* Copyright (C) 2020 huangyuhui <huanghongxun2008@126.com> and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.jackhuang.hmcl.util.io;
|
||||
|
||||
import org.jackhuang.hmcl.util.InfiniteSizeList;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
|
||||
public final class CSVTable {
|
||||
private final List<List<String>> table = new InfiniteSizeList<>();
|
||||
|
||||
private CSVTable() {
|
||||
}
|
||||
|
||||
public static CSVTable createEmpty() {
|
||||
return new CSVTable();
|
||||
}
|
||||
|
||||
public String get(int x, int y) {
|
||||
List<String> row = table.get(y);
|
||||
if (row == null) {
|
||||
return null;
|
||||
}
|
||||
return row.get(x);
|
||||
}
|
||||
|
||||
public void set(int x, int y, String txt) {
|
||||
List<String> row = table.get(y);
|
||||
if (row == null) {
|
||||
row = new InfiniteSizeList<>(x);
|
||||
table.set(y, row);
|
||||
}
|
||||
row.set(x, txt);
|
||||
}
|
||||
|
||||
public void write(OutputStream outputStream) throws IOException {
|
||||
try (PrintWriter printWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
|
||||
outputStream, StandardCharsets.UTF_8)), false
|
||||
)) {
|
||||
for (List<String> row : this.table) {
|
||||
if (row != null) {
|
||||
for (int j = 0; j < row.size(); j++) {
|
||||
String txt = row.get(j);
|
||||
if (txt != null) {
|
||||
printWriter.write(this.escape(txt));
|
||||
}
|
||||
|
||||
if (j != row.size() - 1) {
|
||||
printWriter.write(',');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printWriter.write('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String escape(String txt) {
|
||||
if (!txt.contains("\"") && !txt.contains(",")) {
|
||||
return txt;
|
||||
} else {
|
||||
return "\"" + txt.replace("\"", "\"\"") + "\"";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user