diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..2bc5437
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,24 @@
+# Change Log
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).
+
+## [Unreleased]
+
+## [1.4.9] - 2016-11-13
+
+### Added
+
+- Better menubar integration on MacOS
+- Validation of number of lines improved (negative numbers are rejected)
+- Better menubar integration on Mac OS X
+
+### Changed
+
+- URLs pointing to SourceForge updated to point to Github
+
+### Fixed
+
+- Broken unit test
+
diff --git a/pom.xml b/pom.xml
index 4157776..1c3fdeb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0
com.santiagolizardo.neocommander
NeoCommander
- 1.4.8
+ 1.4.9
jar
NeoCommander
https://github.com/santiagolizardo/neocommander
diff --git a/src/main/java/com/santiagolizardo/madcommander/AppConstants.java b/src/main/java/com/santiagolizardo/madcommander/AppConstants.java
new file mode 100644
index 0000000..85b8ce1
--- /dev/null
+++ b/src/main/java/com/santiagolizardo/madcommander/AppConstants.java
@@ -0,0 +1,30 @@
+/**
+ * This file is part of MadCommander, a file manager with two panels.
+ *
+ * MadCommander 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.
+ *
+ * MadCommander 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 MadCommander. If not, see .
+ */
+package com.santiagolizardo.madcommander;
+
+public final class AppConstants {
+
+ private AppConstants() {
+
+ }
+
+ public final static String APP_NAME = "NeoCommander";
+ public final static String APP_VERSION = "1.4.9";
+ public final static String APP_URL = "https://github.com/santiagolizardo/neocommander";
+ public final static String DOWNLOAD_URL = "https://github.com/santiagolizardo/neocommander/releases";
+
+}
diff --git a/src/main/java/com/santiagolizardo/madcommander/Main.java b/src/main/java/com/santiagolizardo/madcommander/Main.java
index 6345c53..16f94dc 100644
--- a/src/main/java/com/santiagolizardo/madcommander/Main.java
+++ b/src/main/java/com/santiagolizardo/madcommander/Main.java
@@ -22,6 +22,8 @@
import com.santiagolizardo.madcommander.config.ConfigHandler;
import com.santiagolizardo.madcommander.resources.languages.Translator;
import com.santiagolizardo.madcommander.services.LoggingServices;
+import com.santiagolizardo.madcommander.util.Os;
+import com.santiagolizardo.madcommander.util.OsDetector;
import com.santiagolizardo.madcommander.util.gui.SwingUtil;
import java.io.IOException;
@@ -42,15 +44,24 @@ public static void main(String[] args) {
final ConfigData configData = configHandler.read();
Translator.start(configData.getLanguage());
-
+
// LockManager.check();
+
+ try {
+ if (OsDetector.get().equals(Os.Osx)) {
+ System.setProperty("apple.laf.useScreenMenuBar", "true");
+ System.setProperty("com.apple.mrj.application.apple.menu.about.name", AppConstants.APP_NAME);
+ }
+ } catch(Exception e) {
+ System.err.println(e.getMessage());
+ }
/*
* We put the main frame in the event-dispatching thread
*/
SwingUtilities.invokeLater(() -> {
SwingUtil.setSystemLookAndFeel();
-
+
MainWindow app = new MainWindow();
app.setConfigData(configData);
app.init();
diff --git a/src/main/java/com/santiagolizardo/madcommander/MainWindow.java b/src/main/java/com/santiagolizardo/madcommander/MainWindow.java
index fa22674..f7d46f7 100644
--- a/src/main/java/com/santiagolizardo/madcommander/MainWindow.java
+++ b/src/main/java/com/santiagolizardo/madcommander/MainWindow.java
@@ -45,10 +45,6 @@
@SuppressWarnings("serial")
public class MainWindow extends JFrame {
- public final static String APP_NAME = "NeoCommander";
- public final static String APP_VERSION = "1.4.8";
- public final static String APP_URL = "https://github.com/santiagolizardo/neocommander";
-
private static final Logger LOGGER = Logger.getLogger(MainWindow.class
.getName());
@@ -75,7 +71,7 @@ public class MainWindow extends JFrame {
public MainWindow() {
super();
- setTitle(APP_NAME + " " + APP_VERSION);
+ setTitle(AppConstants.APP_NAME + " " + AppConstants.APP_VERSION);
setIconImage(IconFactory.newIcon("icon.png").getImage());
currentPanel = Position.Left;
diff --git a/src/main/java/com/santiagolizardo/madcommander/dialogs/AboutDialog.java b/src/main/java/com/santiagolizardo/madcommander/dialogs/AboutDialog.java
index 67870e9..d254630 100644
--- a/src/main/java/com/santiagolizardo/madcommander/dialogs/AboutDialog.java
+++ b/src/main/java/com/santiagolizardo/madcommander/dialogs/AboutDialog.java
@@ -16,6 +16,7 @@
*/
package com.santiagolizardo.madcommander.dialogs;
+import com.santiagolizardo.madcommander.AppConstants;
import javax.swing.JLabel;
import com.santiagolizardo.madcommander.MainWindow;
@@ -61,10 +62,10 @@ private void defineLayout() {
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
String headlineText = String.format("
%s v%s
",
- MainWindow.APP_NAME, MainWindow.APP_VERSION);
+ AppConstants.APP_NAME, AppConstants.APP_VERSION);
String infoText = String.format("%s
", String.format(
Translator.tr("More info about the project at %s."),
- MainWindow.APP_URL, MainWindow.APP_URL));
+ AppConstants.APP_URL, AppConstants.APP_URL));
String creditsText = ResourcesLoader.readResource(AboutDialog.class,
"credits.html");
diff --git a/src/main/java/com/santiagolizardo/madcommander/dialogs/progressive/AbstractProgressDialog.java b/src/main/java/com/santiagolizardo/madcommander/dialogs/progressive/AbstractProgressDialog.java
index 9e0d9b1..4951862 100644
--- a/src/main/java/com/santiagolizardo/madcommander/dialogs/progressive/AbstractProgressDialog.java
+++ b/src/main/java/com/santiagolizardo/madcommander/dialogs/progressive/AbstractProgressDialog.java
@@ -16,6 +16,7 @@
*/
package com.santiagolizardo.madcommander.dialogs.progressive;
+import com.santiagolizardo.madcommander.AppConstants;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
@@ -68,7 +69,7 @@ public AbstractProgressDialog(MainWindow mainWindow) {
this.mainWindow = mainWindow;
- setTitle(MainWindow.APP_NAME);
+ setTitle(AppConstants.APP_NAME);
setModal(true);
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
setResizable(false);
diff --git a/src/main/java/com/santiagolizardo/madcommander/menu/HelpMenu.java b/src/main/java/com/santiagolizardo/madcommander/menu/HelpMenu.java
index 8de8aad..60e8803 100644
--- a/src/main/java/com/santiagolizardo/madcommander/menu/HelpMenu.java
+++ b/src/main/java/com/santiagolizardo/madcommander/menu/HelpMenu.java
@@ -16,6 +16,7 @@
*/
package com.santiagolizardo.madcommander.menu;
+import com.santiagolizardo.madcommander.AppConstants;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
@@ -69,7 +70,7 @@ public void actionPerformed(ActionEvent ev) {
Object source = ev.getSource();
if (source == visitJavaCommanderWebSite) {
- SystemUtil.browse(this, MainWindow.APP_URL);
+ SystemUtil.browse(this, AppConstants.APP_URL);
} else if (source == checkForUpdate) {
UpdateManager.checkForUpdate();
} else if (source == aboutJavaCommander) {
diff --git a/src/main/java/com/santiagolizardo/madcommander/util/LockManager.java b/src/main/java/com/santiagolizardo/madcommander/util/LockManager.java
index b589833..a7974d9 100644
--- a/src/main/java/com/santiagolizardo/madcommander/util/LockManager.java
+++ b/src/main/java/com/santiagolizardo/madcommander/util/LockManager.java
@@ -16,6 +16,7 @@
*/
package com.santiagolizardo.madcommander.util;
+import com.santiagolizardo.madcommander.AppConstants;
import java.io.File;
import java.io.IOException;
import java.util.logging.Logger;
@@ -25,9 +26,9 @@
/**
* Controls if the application can run multiple instances at the same time.
- *
+ *
* @author Santiago Lizardo
- *
+ *
*/
public final class LockManager {
@@ -43,7 +44,7 @@ public static void check() throws IOException {
if (!allowInstances) {
String tempDir = System.getProperty("java.io.tmpdir");
String lockPath = tempDir.concat(File.separator)
- .concat(MainWindow.APP_NAME).concat(".lock");
+ .concat(AppConstants.APP_NAME).concat(".lock");
LOGGER.info(lockPath);
File lock = new File(lockPath);
diff --git a/src/main/java/com/santiagolizardo/madcommander/util/OsDetector.java b/src/main/java/com/santiagolizardo/madcommander/util/OsDetector.java
new file mode 100644
index 0000000..fd99b77
--- /dev/null
+++ b/src/main/java/com/santiagolizardo/madcommander/util/OsDetector.java
@@ -0,0 +1,44 @@
+/**
+ * This file is part of MadCommander, a file manager with two panels.
+ *
+ * MadCommander 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.
+ *
+ * MadCommander 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 MadCommander. If not, see .
+ */
+package com.santiagolizardo.madcommander.util;
+
+public class OsDetector {
+
+ private static Os currentOs = null;
+
+ public static void reset() {
+ currentOs = null;
+ }
+
+ public static Os get() throws Exception {
+ if (null != currentOs) {
+ return currentOs;
+ }
+ final String osName = System.getProperty("os.name").toLowerCase();
+ if (osName.contains("windows")) {
+ currentOs = Os.Windows;
+ } else if (osName.contains("linux")) {
+ currentOs = Os.Linux;
+ } else if (osName.contains("osx") || osName.contains("os x")) {
+ currentOs = Os.Osx;
+ }
+ if (currentOs == null) {
+ throw new Exception("Unable to recognize OS with name: " + osName);
+ }
+ return currentOs;
+ }
+}
diff --git a/src/main/java/com/santiagolizardo/madcommander/util/SystemUtil.java b/src/main/java/com/santiagolizardo/madcommander/util/SystemUtil.java
index 415cde2..28c46f2 100644
--- a/src/main/java/com/santiagolizardo/madcommander/util/SystemUtil.java
+++ b/src/main/java/com/santiagolizardo/madcommander/util/SystemUtil.java
@@ -24,44 +24,29 @@
import java.io.IOException;
import java.net.URISyntaxException;
-
public class SystemUtil {
-
- public static Os getOs() {
- String osName = System.getProperty("os.name").toLowerCase();
- if(osName.contains("windows")) {
- return Os.Windows;
- }
- if(osName.contains("linux")) {
- return Os.Linux;
- }
- if(osName.contains("osx")) {
- return Os.Osx;
- }
- return null;
- }
-
- public static void execute(Component component, String command) {
- Runtime runtime = Runtime.getRuntime();
- String[] args = new String[3];
- args[0] = "cmd.exe";
- args[1] = "/C";
- args[2] = command;
- try {
- runtime.exec(args);
- } catch (IOException e) {
- DialogFactory.showErrorMessage(component, e.getMessage());
- }
- }
+ public static void execute(Component component, String command) {
+ Runtime runtime = Runtime.getRuntime();
+ String[] args = new String[3];
+ args[0] = "cmd.exe";
+ args[1] = "/C";
+ args[2] = command;
+
+ try {
+ runtime.exec(args);
+ } catch (IOException e) {
+ DialogFactory.showErrorMessage(component, e.getMessage());
+ }
+ }
- public static void browse(Component component, String address) {
- Desktop desktop = Desktop.getDesktop();
+ public static void browse(Component component, String address) {
+ Desktop desktop = Desktop.getDesktop();
- try {
- desktop.browse(new URI(address));
- } catch (URISyntaxException | IOException e) {
- System.err.println(e.getMessage());
- }
- }
+ try {
+ desktop.browse(new URI(address));
+ } catch (URISyntaxException | IOException e) {
+ System.err.println(e.getMessage());
+ }
+ }
}
diff --git a/src/main/java/com/santiagolizardo/madcommander/util/UpdateManager.java b/src/main/java/com/santiagolizardo/madcommander/util/UpdateManager.java
index 0e0912b..2b9cf0b 100644
--- a/src/main/java/com/santiagolizardo/madcommander/util/UpdateManager.java
+++ b/src/main/java/com/santiagolizardo/madcommander/util/UpdateManager.java
@@ -16,18 +16,16 @@
*/
package com.santiagolizardo.madcommander.util;
+import com.santiagolizardo.madcommander.AppConstants;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
-import com.santiagolizardo.madcommander.MainWindow;
import com.santiagolizardo.madcommander.util.gui.DialogFactory;
import java.io.IOException;
public final class UpdateManager extends Thread {
-
- public final static String DOWNLOAD_URL = "http://sourceforge.net/projects/madcommander/files/";
public static void checkForUpdate() {
UpdateManager updateManager = new UpdateManager();
@@ -38,18 +36,17 @@ private UpdateManager() {
}
+ @Override
public void run() {
try {
URL url = new URL("http://madcommander.sourceforge.net/version.html");
- InputStreamReader reader = new InputStreamReader(url.openStream());
- BufferedReader buffer = new BufferedReader(reader);
- String version = buffer.readLine();
- buffer.close();
- reader.close();
- int serverVersion = Integer.valueOf(version.replaceAll("\\.", ""))
- .intValue();
- int currentVersion = Integer.valueOf(
- MainWindow.APP_VERSION.replaceAll("\\.", "")).intValue();
+ String version;
+ try (InputStreamReader reader = new InputStreamReader(url.openStream()); BufferedReader buffer = new BufferedReader(reader)) {
+ version = buffer.readLine();
+ }
+ int serverVersion = Integer
+ .parseInt(version.replaceAll("\\.", ""));
+ int currentVersion = Integer.parseInt(AppConstants.APP_VERSION.replaceAll("\\.", ""));
if (serverVersion > currentVersion) {
StringBuilder text = new StringBuilder();
text.append("New version \"");
@@ -57,7 +54,7 @@ public void run() {
text
.append("\" available.\n\nDo you want to go to the download site?\n");
if (DialogFactory.showQuestionDialog(null, text.toString())) {
- SystemUtil.browse(null, DOWNLOAD_URL);
+ SystemUtil.browse(null, AppConstants.DOWNLOAD_URL);
}
} else if (serverVersion <= currentVersion) {
DialogFactory.showInformationMessage(null,
diff --git a/src/main/java/com/santiagolizardo/madcommander/util/gui/DialogFactory.java b/src/main/java/com/santiagolizardo/madcommander/util/gui/DialogFactory.java
index 3111df3..2c77704 100644
--- a/src/main/java/com/santiagolizardo/madcommander/util/gui/DialogFactory.java
+++ b/src/main/java/com/santiagolizardo/madcommander/util/gui/DialogFactory.java
@@ -16,32 +16,30 @@
*/
package com.santiagolizardo.madcommander.util.gui;
+import com.santiagolizardo.madcommander.AppConstants;
import java.awt.Component;
import javax.swing.JOptionPane;
-import com.santiagolizardo.madcommander.MainWindow;
-
-
public class DialogFactory {
public static void showInformationMessage(Component parent, String message) {
- JOptionPane.showMessageDialog(parent, message, MainWindow.APP_NAME,
+ JOptionPane.showMessageDialog(parent, message, AppConstants.APP_NAME,
JOptionPane.INFORMATION_MESSAGE);
}
public static void showErrorMessage(Component parent, String message) {
- JOptionPane.showMessageDialog(parent, message, MainWindow.APP_NAME,
+ JOptionPane.showMessageDialog(parent, message, AppConstants.APP_NAME,
JOptionPane.ERROR_MESSAGE);
}
public static boolean showQuestionDialog(Component parent, String message) {
return (JOptionPane.showConfirmDialog(parent, message,
- MainWindow.APP_NAME, JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION);
+ AppConstants.APP_NAME, JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION);
}
public static String showInputDialog(Component parent, String message) {
return JOptionPane.showInputDialog(parent, message,
- MainWindow.APP_NAME, JOptionPane.OK_CANCEL_OPTION);
+ AppConstants.APP_NAME, JOptionPane.OK_CANCEL_OPTION);
}
}
diff --git a/src/main/java/com/santiagolizardo/madcommander/util/io/FileUtil.java b/src/main/java/com/santiagolizardo/madcommander/util/io/FileUtil.java
index d4dc0cc..a7410f3 100644
--- a/src/main/java/com/santiagolizardo/madcommander/util/io/FileUtil.java
+++ b/src/main/java/com/santiagolizardo/madcommander/util/io/FileUtil.java
@@ -16,7 +16,8 @@
*/
package com.santiagolizardo.madcommander.util.io;
-import com.santiagolizardo.madcommander.util.SystemUtil;
+import com.santiagolizardo.madcommander.util.OsDetector;
+import com.santiagolizardo.madcommander.util.Os;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
@@ -76,7 +77,14 @@ public static String extractFilePart(File file) {
* @return
*/
public static String getHumanizedAttributes(File file) {
- switch (SystemUtil.getOs()) {
+ Os os = null;
+ try {
+ os = OsDetector.get();
+ } catch(Exception e) {
+ logger.warning(e.getMessage());
+ return "";
+ }
+ switch (os) {
case Osx:
case Linux:
return getPosixHumanizedAttributes(file);
diff --git a/src/main/resources/com/santiagolizardo/madcommander/dialogs/credits.html b/src/main/resources/com/santiagolizardo/madcommander/dialogs/credits.html
index aafff82..1071b55 100644
--- a/src/main/resources/com/santiagolizardo/madcommander/dialogs/credits.html
+++ b/src/main/resources/com/santiagolizardo/madcommander/dialogs/credits.html
@@ -4,8 +4,7 @@
Contributors:
-
- Santiago Lizardo (Developer; Translator: en, ca, es)
- http://www.santiagolizardo.com
+ Santiago Lizardo (Developer; Translator: en, ca, es)
-
Carlos SS (Developer)
diff --git a/src/test/java/com/santiagolizardo/madcommander/util/ListUtilsTest.java b/src/test/java/com/santiagolizardo/madcommander/util/ListUtilsTest.java
index c3cb265..9a9fe8c 100644
--- a/src/test/java/com/santiagolizardo/madcommander/util/ListUtilsTest.java
+++ b/src/test/java/com/santiagolizardo/madcommander/util/ListUtilsTest.java
@@ -38,6 +38,7 @@ public void testExplode() {
Assert.assertEquals(4, names.size());
names = ListsUtils.explode(",", "");
- Assert.assertTrue(names.isEmpty());
+ Assert.assertEquals(1, names.size());
+ Assert.assertEquals("", names.get(0));
}
}
diff --git a/src/test/java/com/santiagolizardo/madcommander/util/OsDetectorTest.java b/src/test/java/com/santiagolizardo/madcommander/util/OsDetectorTest.java
new file mode 100644
index 0000000..42883aa
--- /dev/null
+++ b/src/test/java/com/santiagolizardo/madcommander/util/OsDetectorTest.java
@@ -0,0 +1,56 @@
+/**
+ * This file is part of MadCommander, a file manager with two panels.
+ *
+ * MadCommander 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.
+ *
+ * MadCommander 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 MadCommander. If not, see .
+ */
+package com.santiagolizardo.madcommander.util;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class OsDetectorTest {
+
+ private String originalOsName;
+
+ @Before
+ public void setUp() {
+ this.originalOsName = System.getProperty("os.name");
+ }
+
+ @After
+ public void tearDown() {
+ System.setProperty("os.name", originalOsName);
+ OsDetector.reset();
+ }
+
+ @Test
+ public void testWindowsIsDetected() throws Exception {
+ System.setProperty("os.name", "Windows 95");
+ Assert.assertEquals(Os.Windows, OsDetector.get());
+ }
+
+ @Test
+ public void testMacOsIsDetected() throws Exception {
+ System.setProperty("os.name", "Mac OS X");
+ Assert.assertEquals(Os.Osx, OsDetector.get());
+ }
+
+ @Test(expected = Exception.class)
+ public void testUnknownOsThrowsException() throws Exception {
+ System.setProperty("os.name", "Foo Bar OS");
+ OsDetector.get();
+ }
+}