Skip to content

Commit 2e890cd

Browse files
committed
Allow only one instance of app, add debug log(#4)
1 parent cc766f5 commit 2e890cd

File tree

12 files changed

+181
-15
lines changed

12 files changed

+181
-15
lines changed

.gitattributes

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Declare files that will always have CRLF line endings on checkout.
2+
gpl-3.0.txt text eol=lf
3+
gpl-3.0_windows.txt text eol=crlf
4+
libraries_used.txt text eol=lf
5+
libraries_used_windows.txt text eol=crlf

.idea/modules/blobsaver_main.iml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules/blobsaver_test.iml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ If you have an antivirus or firewall, you may need to disable some other setting
2323
Please send feedback via [Github Issue](https://github.com/airsquared/blobsaver/issues/new/choose) or [Reddit PM](https://www.reddit.com//message/compose?to=01110101_00101111&subject=Blobsaver+Feedback) if you encounter any bugs/problems or have a feature request.
2424

2525
## TODO:
26-
- Allow only one instance
27-
- Debug log/window
2826
- Use macOS menu bar
2927
- Auto-upload to Dropbox/Google Drive
3028
- Package into .app/.exe [maybe this](https://github.com/Jorl17/jar2app)
@@ -37,4 +35,3 @@ Please send feedback via [Github Issue](https://github.com/airsquared/blobsaver/
3735

3836
## License
3937
This project is licensed under GNU GPL v3.0-only - see the [LICENSE](https://github.com/airsquared/blobsaver/blob/master/LICENSE) file for details
40-

build.gradle

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,15 @@ sourceCompatibility = 1.8
99

1010
repositories {
1111
mavenCentral()
12+
maven {
13+
url "http://repo.spring.io/plugins-release/"
14+
}
1215
}
1316

1417
dependencies {
15-
// https://mvnrepository.com/artifact/org.json/json
1618
compile group: 'org.json', name: 'json', version: '20180130'
1719
compile fileTree(dir: 'libs', include: ['*.jar'])
20+
compile group: 'it.sauronsoftware', name: 'junique', version: '1.0.4'
1821
}
1922

2023
compileJava {

src/main/java/blobsaver/Background.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,6 @@ private static void deleteTempFiles(File tsschecker) {
447447
}
448448
}
449449

450-
@SuppressWarnings("unused")
451450
private static void log(String msg) {
452451
System.out.println(msg);
453452
}

src/main/java/blobsaver/Controller.java

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import com.sun.javafx.PlatformUtil;
2222
import com.sun.javafx.scene.control.skin.LabeledText;
23+
import eu.hansolo.enzo.notification.Notification;
2324
import javafx.application.Platform;
2425
import javafx.beans.value.ObservableValue;
2526
import javafx.collections.FXCollections;
@@ -374,7 +375,11 @@ private void run(String device) {
374375
deleteTempFiles(tsschecker, buildManifestPlist);
375376
return;
376377
}
377-
378+
try {
379+
proc.waitFor();
380+
} catch (InterruptedException e) {
381+
newReportableError("The tsschecker process was interrupted.", e.toString());
382+
}
378383
if (tsscheckerLog.contains("Saved shsh blobs")) {
379384
Alert alert = new Alert(Alert.AlertType.INFORMATION, "Successfully saved blobs in\n" + pathField.getText(), ButtonType.OK);
380385
alert.setHeaderText("Success!");
@@ -430,11 +435,6 @@ private void run(String device) {
430435
} else {
431436
newReportableError("Unknown result.\n\nIf this was done to test whether the preset works in the background, please cancel that preset, fix the error, and try again.", tsscheckerLog);
432437
}
433-
try {
434-
proc.waitFor();
435-
} catch (InterruptedException e) {
436-
newReportableError("The tsschecker process was interrupted.", e.toString());
437-
}
438438

439439
deleteTempFiles(tsschecker, buildManifestPlist);
440440
}
@@ -621,7 +621,7 @@ private void savePreset(int preset) {
621621
if (doReturn) {
622622
return;
623623
}
624-
TextInputDialog textInputDialog = new TextInputDialog("Preset " + preset);
624+
TextInputDialog textInputDialog = new TextInputDialog(appPrefs.get("Name Preset" + preset, "Preset " + preset));
625625
textInputDialog.setTitle("Name Preset " + preset);
626626
textInputDialog.setHeaderText("Name Preset");
627627
textInputDialog.setContentText("Please enter a name for the preset:");
@@ -949,7 +949,12 @@ public void startBackgroundHandler() {
949949
}
950950

951951
public void forceCheckForBlobsHandler() {
952-
Background.startBackground(true);
952+
if (Background.inBackground) {
953+
Background.stopBackground(false);
954+
Background.startBackground(false);
955+
} else {
956+
Background.startBackground(true);
957+
}
953958
}
954959

955960
public void resetAppHandler() {
@@ -973,7 +978,18 @@ public void resetAppHandler() {
973978
}
974979
}
975980

976-
@SuppressWarnings("unused")
981+
public void debugLogHandler() {
982+
if (DebugWindow.isShowing()) {
983+
DebugWindow.hide();
984+
} else {
985+
DebugWindow.show();
986+
}
987+
}
988+
989+
public void throwException() {
990+
throw new EnumConstantNotPresentException(Notification.Notifier.class, "");
991+
}
992+
977993
private void log(String msg) {
978994
System.out.println(msg);
979995
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
* Copyright (c) 2018 airsquared
3+
*
4+
* This file is part of blobsaver.
5+
*
6+
* blobsaver is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, version 3 of the License.
9+
*
10+
* blobsaver is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with blobsaver. If not, see <https://www.gnu.org/licenses/>.
17+
*/
18+
19+
package blobsaver;
20+
21+
import javafx.application.Platform;
22+
import javafx.scene.Scene;
23+
import javafx.scene.control.TextArea;
24+
import javafx.scene.layout.Priority;
25+
import javafx.scene.layout.VBox;
26+
import javafx.stage.Stage;
27+
28+
import java.io.OutputStream;
29+
import java.io.PrintStream;
30+
31+
class DebugWindow {
32+
33+
private static final PrintStream sysOut = System.out;
34+
private static Stage debugStage = new Stage();
35+
private static PrintStream myPrintStream;
36+
37+
static {
38+
VBox vBox = new VBox();
39+
vBox.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
40+
TextArea textArea = new TextArea();
41+
VBox.setVgrow(textArea, Priority.ALWAYS);
42+
textArea.setEditable(false);
43+
textArea.setWrapText(true);
44+
textArea.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
45+
vBox.getChildren().add(textArea);
46+
debugStage.setTitle("Debug Log");
47+
debugStage.setScene(new Scene(vBox));
48+
debugStage.setOnCloseRequest((event) -> {
49+
hide();
50+
event.consume();
51+
});
52+
53+
myPrintStream = new PrintStream(new OutputStream() {
54+
void appendText(String valueOf) {
55+
if (Platform.isFxApplicationThread()) {
56+
textArea.appendText(valueOf);
57+
} else {
58+
Platform.runLater(() -> textArea.appendText(valueOf));
59+
}
60+
}
61+
62+
@Override
63+
public void write(int b) {
64+
sysOut.write(b);
65+
appendText(String.valueOf((char) b));
66+
}
67+
});
68+
}
69+
70+
static void show() {
71+
debugStage.show();
72+
System.setOut(myPrintStream);
73+
System.setErr(myPrintStream);
74+
}
75+
76+
static void hide() {
77+
debugStage.hide();
78+
System.setOut(sysOut);
79+
System.setErr(sysOut);
80+
}
81+
82+
static boolean isShowing() {
83+
return debugStage.isShowing();
84+
}
85+
86+
}

src/main/java/blobsaver/Main.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
import com.sun.javafx.PlatformUtil;
2222
import com.sun.javafx.application.PlatformImpl;
23+
import it.sauronsoftware.junique.AlreadyLockedException;
24+
import it.sauronsoftware.junique.JUnique;
2325
import javafx.application.Application;
2426
import javafx.application.Platform;
2527
import javafx.fxml.FXMLLoader;
@@ -35,9 +37,16 @@ public class Main {
3537

3638
static final String appVersion = "v2.1-beta";
3739
static final Preferences appPrefs = Preferences.userRoot().node("airsquared/blobsaver/prefs");
40+
private static final String appID = "com.airsquared.blobsaver";
3841
static Stage primaryStage;
3942

4043
public static void main(String[] args) {
44+
try {
45+
JUnique.acquireLock(appID);
46+
} catch (AlreadyLockedException e) {
47+
javax.swing.JOptionPane.showMessageDialog(null, "blobsaver already running, exiting");
48+
System.exit(-1);
49+
}
4150
try {
4251
Class.forName("javafx.application.Application");
4352
if (PlatformUtil.isMac() || PlatformUtil.isWindows() || PlatformUtil.isLinux()) {

src/main/resources/blobsaver/blobsaver.fxml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
<VBox maxHeight="Infinity" maxWidth="-Infinity" minHeight="580.0" prefWidth="500.0">
2525
<MenuBar>
2626
<Menu mnemonicParsing="false" text="Options">
27+
<MenuItem mnemonicParsing="false" onAction="#debugLogHandler"
28+
text="Debug log"/>
29+
<MenuItem mnemonicParsing="false" onAction="#throwException"
30+
text="Throw exception"/>
2731
<MenuItem mnemonicParsing="false" onAction="#checkBlobs"
2832
text="Check for valid blobs..."/>
2933
<MenuItem mnemonicParsing="false" onAction="#checkForUpdatesHandler"

0 commit comments

Comments
 (0)