/** * jdotxt * * Copyright (C) 2013-2015 Christian M. Schmid * * jdotxt 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 <http://www.gnu.org/licenses/>. */ package com.chschmid.jdotxt; import java.awt.EventQueue; import java.io.File; import java.io.IOException; import java.util.prefs.Preferences; import com.chschmid.jdotxt.gui.JdotxtGUI; import com.chschmid.jdotxt.gui.JdotxtWelcomeDialog; import com.chschmid.jdotxt.util.FileModifiedListener; import com.chschmid.jdotxt.util.FileModifiedWatcher; import com.sun.jna.Function; import com.sun.jna.NativeLibrary; import com.sun.jna.NativeLong; import com.sun.jna.WString; import com.todotxt.todotxttouch.task.LocalFileTaskRepository; import com.todotxt.todotxttouch.task.TaskBag; import com.todotxt.todotxttouch.task.TaskBagFactory; public class Jdotxt { public static final String VERSION = "0.4.8"; public static final String APPID = "chschmid.jdotxt"; public static final int AUTOSAVE_DELAY = 3000; public static TaskBag taskBag; public static Preferences userPrefs; public static final String DEFAULT_DIR = System.getProperty("user.home") + File.separator + "jdotxt"; private static FileModifiedWatcher fileModifiedWatcher; private static native NativeLong SetCurrentProcessExplicitAppUserModelID(WString appID); // Lock object for file operations private static Object fileLock = new Object(); public static void main( String[] args ) { loadPreferences(); // For detecting file changes to todo.txt, start thread, file will be specified later try { fileModifiedWatcher = new FileModifiedWatcher(); fileModifiedWatcher.startProcessingEvents(); } catch (IOException e) { } JdotxtGUI.loadLookAndFeel(userPrefs.get("lang", "English")); // Windows taskbar fix if (isWindows()) onWindows(); // Mac OS X fixes if (isMacOSX()) onMacOSX(); // Start GUI Runnable viewGUI = new Runnable() { @Override public void run() { File todoFileDir; boolean showDialog = true; while (showDialog) { // Show settings on first run or show path selection if file path is not found if (userPrefs.getBoolean("firstRun", true)) { userPrefs.putBoolean("firstRun", false); JdotxtWelcomeDialog welcomeDialog = new JdotxtWelcomeDialog(JdotxtWelcomeDialog.P_WELCOME); welcomeDialog.setVisible(true); } else { todoFileDir = new File(userPrefs.get("dataDir", DEFAULT_DIR)); if (!todoFileDir.exists()) { JdotxtWelcomeDialog welcomeDialog = new JdotxtWelcomeDialog(JdotxtWelcomeDialog.P_PATH_NOT_FOUND); welcomeDialog.setVisible(true); } } // Try to create path todoFileDir = new File(userPrefs.get("dataDir", DEFAULT_DIR)); todoFileDir.mkdirs(); showDialog = !todoFileDir.exists(); } // Main window JdotxtGUI mainGUI = new JdotxtGUI(); //JdotxtGUItest mainGUI = new JdotxtGUItest(); mainGUI.setVisible(true); } }; EventQueue.invokeLater(viewGUI); } public static void loadPreferences() { userPrefs = Preferences.userNodeForPackage(Jdotxt.class); } public static void loadTodos() { String dataDir = userPrefs.get("dataDir", DEFAULT_DIR); File todoFileDir = new File(dataDir); if (!todoFileDir.exists()) dataDir = DEFAULT_DIR; String todoFile = dataDir + File.separator + "todo.txt"; String doneFile = dataDir + File.separator + "done.txt"; LocalFileTaskRepository.TODO_TXT_FILE = new File(todoFile); LocalFileTaskRepository.DONE_TXT_FILE = new File(doneFile); LocalFileTaskRepository.initFiles(); taskBag = TaskBagFactory.getTaskBag(); synchronized(fileLock){ if (fileModifiedWatcher != null) { // Unregister first, in case path has been changed fileModifiedWatcher.unRegisterFile(); try { fileModifiedWatcher.registerFile(LocalFileTaskRepository.TODO_TXT_FILE); } catch (IOException e) { } } taskBag.reload(); } } public static void addFileModifiedListener(FileModifiedListener fileModifiedListener) { fileModifiedWatcher.addFileModifiedListener(fileModifiedListener); } public static void removeFileModifiedListener(FileModifiedListener fileModifiedListener) { fileModifiedWatcher.removeFileModifiedListener(fileModifiedListener); } public static void archiveTodos() { synchronized(fileLock){ fileModifiedWatcher.unRegisterFile(); taskBag.archive(); try { fileModifiedWatcher.registerFile(LocalFileTaskRepository.TODO_TXT_FILE); } catch (IOException e) { } } } public static void storeTodos() { synchronized(fileLock){ fileModifiedWatcher.unRegisterFile(); taskBag.store(); try { fileModifiedWatcher.registerFile(LocalFileTaskRepository.TODO_TXT_FILE); } catch (IOException e) { } } } // Detect OS public static boolean isWindows() { return System.getProperty("os.name").startsWith("Windows"); } public static boolean isMacOSX() { return System.getProperty("os.name").startsWith("Mac OS X"); } public static void onWindows() { // Windows taskbar fix: provideAppUserModelID try { NativeLibrary lib = NativeLibrary.getInstance("shell32"); Function function = lib.getFunction("SetCurrentProcessExplicitAppUserModelID"); Object[] args = {new WString(APPID)}; function.invokeInt(args); } catch (Error e) { return; } catch (Exception x) { return; } } public static void onMacOSX() { // Nothing so far } public static String insertReplaceString(String original, String replace, int offset) { String a = original.substring(0, Math.min(offset, original.length())); String b; if (original.length() > (offset + replace.length())) b = original.substring(offset + replace.length(), original.length()); else b = ""; return a + replace + b; } }