From: yuki Date: Mon, 11 Nov 2013 08:58:54 +0000 (+0900) Subject: Merge branch 'master' of http://git.code.sf.net/p/nevernote/code into develop X-Git-Tag: version0.4~1^2~1 X-Git-Url: http://git.sourceforge.jp/view?p=neighbornote%2FNeighborNote.git;a=commitdiff_plain;h=ea94dfeb4e955c79616af64448be1a8fd09c23d3 Merge branch 'master' of git.code.sf.net/p/nevernote/code into develop Conflicts: src/cx/fbn/nevernote/Global.java src/cx/fbn/nevernote/oauth/OAuthWindow.java src/cx/fbn/nevernote/threads/SyncRunner.java --- ea94dfeb4e955c79616af64448be1a8fd09c23d3 diff --cc src/cx/fbn/nevernote/Global.java index fd74338,767a978..149c60a --- a/src/cx/fbn/nevernote/Global.java +++ b/src/cx/fbn/nevernote/Global.java @@@ -1,2625 -1,2033 +1,2625 @@@ -/* - * This file is part of NixNote - * Copyright 2009 Randy Baumgarte - * - * This file may be licensed under the terms of of the - * GNU General Public License Version 2 (the ``GPL''). - * - * Software distributed under the License is distributed - * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either - * express or implied. See the GPL for the specific language - * governing rights and limitations. - * - * You should have received a copy of the GPL along with this - * program. If not, go to http://www.gnu.org/licenses/gpl.html - * or write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * -*/ - -package cx.fbn.nevernote; - - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.HashMap; -import java.util.List; - -import org.apache.commons.lang3.StringEscapeUtils; - -import com.evernote.edam.type.Accounting; -import com.evernote.edam.type.PrivilegeLevel; -import com.evernote.edam.type.User; -import com.evernote.edam.type.UserAttributes; -import com.swabunga.spell.engine.Configuration; -import com.trolltech.qt.core.QByteArray; -import com.trolltech.qt.core.QSettings; -import com.trolltech.qt.core.QSize; -import com.trolltech.qt.gui.QPalette; -import com.trolltech.qt.gui.QSystemTrayIcon; - -import cx.fbn.nevernote.config.FileManager; -import cx.fbn.nevernote.config.InitializationException; -import cx.fbn.nevernote.config.StartupConfig; -import cx.fbn.nevernote.gui.ContainsAttributeFilterTable; -import cx.fbn.nevernote.gui.DateAttributeFilterTable; -import cx.fbn.nevernote.gui.ShortcutKeys; -import cx.fbn.nevernote.utilities.ApplicationLogger; -import cx.fbn.nevernote.utilities.Pair; - - -//***************************************************** -//***************************************************** -//* Global constants & static functions used by -//* multiple threads. -//***************************************************** -//***************************************************** - -public class Global { - // Set current version and the known versions. - public static String version = "1.6"; - public static String[] validVersions = {"1.6", "1.5", "1.4", "1.3", "1.2", "1.1", "1.0", "0.99", "0.98", "0.97", "0.96"}; - public static String username = ""; - //public static String password = ""; - - - // Each thread has an ID. This is used primarily to check the status - // of running threads. - public static final int mainThreadId=0; - public static final int syncThreadId=1; - public static final int tagCounterThreadId=2; - public static final int trashCounterThreadId=3; // This should always be the highest thread ID - public static final int indexThreadId=4; // Thread for indexing words - public static final int saveThreadId=5; // Thread used for processing data to saving content - public static final int notebookCounterThreadId=6; // Notebook Thread - public static final int indexThread03Id=7; // unused - public static final int indexThread04Id=8; // unused - public static final int dbThreadId=9; // This should always be the highest thread ID - public static final int threadCount = 10; - - - // These variables deal with where the list of notes appears - // They will either be vertical (View_List_Narrow) or will be - // on top of the note (View_List_Wide). It also has the size of - // thumbnails displayed in each view - public static int View_List_Wide = 1; - public static int View_List_Narrow = 2; - public static QSize smallThumbnailSize = new QSize(100,75); - public static QSize largeThumbnailSize = new QSize(300,225); - - // This is used to keep a running list of passwords that the user - // wants us to remember. - public static HashMap> passwordSafe = new HashMap>(); - public static List> passwordRemember = new ArrayList>(); - - - //public static String currentNotebookGuid; - - // These deal with Evernote user settings - public static User user; - public static long authTimeRemaining; - public static long authRefreshTime; - public static long failedRefreshes = 0; - public static String userStoreUrl; - public static String noteStoreUrl; - public static String noteStoreUrlBase; - - // When we want to shut down we set this to true to short - // circut other threads - public static boolean keepRunning; - - // In the note list, these are the column numbers - // so I don't need to hard code numbers. - public static int noteTableCreationPosition = 0; - public static int noteTableTitlePosition = 1; - public static int noteTableTagPosition = 2; - public static int noteTableNotebookPosition = 3; - public static int noteTableChangedPosition = 4; - public static int noteTableGuidPosition = 5; - public static int noteTableAuthorPosition = 6; - public static int noteTableSourceUrlPosition = 7; - public static int noteTableSubjectDatePosition = 8; - public static int noteTableSynchronizedPosition = 9; - public static int noteTableThumbnailPosition = 10; - public static int noteTablePinnedPosition = 11; - public static int noteTableColumnCount = 12; - public static Integer cryptCounter = 0; - - //public static int minimumWordCount = 2; - - // Regular expression to parse text with when indexing - private static String wordRegex; - - // Experimental fixes. Set via Edit/Preferences/Debugging - public static boolean enableCarriageReturnFix = false; - public static boolean enableHTMLEntitiesFix = false; - - // Used to set & retrieve ini & Windows registry settings - public static QSettings settings; // Set & get ini settings - public static boolean isConnected; // Are we connected to Evernote - public static boolean showDeleted = false; // Show deleted notes? - public static boolean disableUploads = false; // Should we disable uploads (used in testing features) - public static int messageLevel; // The level of messages to write to the log files - public static String tagDelimeter = ","; // This is used to separate out tag names when entering above note - public static String attachmentNameDelimeter = "------"; // Used to separate out attachment names in the res directory - - - //* Database fields - public static String databaseName = new String("NeverNote"); // database name. used for multiple databases to separate settings. - public static String indexDatabaseName = new String("Index"); // searchable words database - public static String resourceDatabaseName = new String("Resources"); // attachments database - public static DateAttributeFilterTable createdSinceFilter; - public static DateAttributeFilterTable createdBeforeFilter; - public static DateAttributeFilterTable changedSinceFilter; - public static DateAttributeFilterTable changedBeforeFilter; - public static ContainsAttributeFilterTable containsFilter; - - // Log file used for debugging - public static ApplicationLogger logger; - //PrintStream stdoutStream; - - // Application key shortcuts & appearance - public static QPalette originalPalette; - public static ShortcutKeys shortcutKeys; - - public static boolean disableViewing; // used to disable the editor - - // When saving a note, this is a list of things we strip out because Evernote hates them - public static List invalidElements = new ArrayList(); - public static HashMap> invalidAttributes = new HashMap>(); - - public static boolean mimicEvernoteInterface; // Try to mimic Evernote or allow multiple notebook selection - public static HashMap resourceMap; // List of attachments for a note. - public static String cipherPassword = ""; // If the database is encrypted, this stores the password - public static String databaseCache = "16384"; // Default DB cache size - - // These are used for performance testing - static Calendar startTraceTime; - static Calendar intervalTraceTime; - - static boolean syncOnly; - - private static FileManager fileManager; // Used to access files & directories - - // Do initial setup - public static void setup(StartupConfig startupConfig) throws InitializationException { - settings = new QSettings("fbn.cx", startupConfig.getName()); - disableViewing = startupConfig.getDisableViewing(); - syncOnly = startupConfig.isSyncOnly(); - - fileManager = new FileManager(startupConfig.getHomeDirPath(), startupConfig.getProgramDirPath()); - - - getServer(); // Setup URL to connect to - - // Get regular expressions used to parse out words - settings.beginGroup("General"); - String regex = (String) settings.value("regex", "[,\\s]+"); - setWordRegex(regex); - settings.endGroup(); - - //Setup debugging information - settings.beginGroup("Debug"); - String msglevel = (String) settings.value("messageLevel", "Low"); - settings.endGroup(); - - - //messageLevel = 1; - setMessageLevel(msglevel); - keepRunning = true; // Make sure child threads stay running - disableUploads = disableUploads(); // Should we upload anything? Normally false. - //disableUploads = true; //***** DELETE THIS LINE ******* - enableCarriageReturnFix = enableCarriageReturnFix(); // Enable test fix? - enableHTMLEntitiesFix = enableHtmlEntitiesFix(); // Enable test fix? - - logger = new ApplicationLogger("global.log"); // Setup log for this class - shortcutKeys = new ShortcutKeys(); // Setup keyboard shortcuts. - mimicEvernoteInterface = getMimicEvernoteInterface(); // Should we mimic Evernote's notebook behavior - resourceMap = new HashMap(); // Setup resource map used to store attachments when editing - - databaseCache = getDatabaseCacheSize(); // Set database cache size - - Global.username = getUserInformation().getUsername(); - } - - // Get/Set word parsing regular expression - public static String getWordRegex() { - return wordRegex; - } - public static void setWordRegex(String r) { - wordRegex = r; - } - - // Set the debug message level - public static void setMessageLevel(String msglevel) { - if (msglevel.equalsIgnoreCase("low")) - messageLevel = 1; - if (msglevel.equalsIgnoreCase("medium")) - messageLevel = 2; - if (msglevel.equalsIgnoreCase("high")) - messageLevel = 3; - if (msglevel.equalsIgnoreCase("extreme")) - messageLevel = 4; - settings.beginGroup("Debug"); - settings.setValue("messageLevel", msglevel); - settings.endGroup(); - } - - //**************************************************** - //**************************************************** - //** Save user account information from Evernote - //**************************************************** - //**************************************************** - public static void saveUserInformation(User user) { - settings.beginGroup("User"); - settings.setValue("id", user.getId()); - settings.setValue("username", user.getUsername()); - settings.setValue("email", user.getEmail()); - settings.setValue("name", user.getName()); - settings.setValue("timezone", user.getTimezone()); - settings.setValue("privilege", user.getPrivilege().getValue()); - settings.setValue("created", user.getCreated()); - settings.setValue("updated", user.getUpdated()); - settings.setValue("deleted", user.getDeleted()); - settings.setValue("shard", user.getShardId()); - settings.endGroup(); - isPremium(); - if (user.getAttributes()!=null) - saveUserAttributes(user.getAttributes()); - if (user.getAccounting()!=null) - saveUserAccounting(user.getAccounting()); - - } - public static User getUserInformation() { - User user = new User(); - settings.beginGroup("User"); - try { - user.setId((Integer)settings.value("id", 0)); - } catch (java.lang.ClassCastException e) { - user.setId(new Integer((String)settings.value("id", "0"))); - } - String username = (String)settings.value("username", ""); - String email = (String)settings.value("email", ""); - String name = (String)settings.value("name", ""); - String timezone = (String)settings.value("timezone", ""); - Integer privilege = 0; - try { - privilege = new Integer((String)settings.value("privilege", "0")); - } catch (java.lang.ClassCastException e) { - privilege = (Integer)settings.value("privilege", 0); - } - - try { - String date = (String)settings.value("created", "0"); - user.setCreated(new Long(date)); - date = (String)settings.value("updated", "0"); - user.setUpdated(new Long(date)); - date = (String)settings.value("deleted", "0"); - user.setDeleted(new Long(date)); - } catch (java.lang.ClassCastException e) { - Long date = (Long)settings.value("created", 0); - user.setCreated(date); - date = (Long)settings.value("updated", 0); - user.setUpdated(date); - date = (Long)settings.value("deleted", 0); - user.setDeleted(date); - } - - String shard = (String)settings.value("shard", ""); - settings.endGroup(); - - user.setUsername(username); - user.setEmail(email); - user.setName(name); - user.setTimezone(timezone); - PrivilegeLevel userLevel = PrivilegeLevel.findByValue(privilege); - user.setPrivilege(userLevel); - user.setShardId(shard); - return user; - } - - public static void saveUserAttributes(UserAttributes attrib) { - settings.beginGroup("UserAttributes"); - settings.setValue("defaultLocationName", attrib.getDefaultLocationName()); - settings.setValue("defaultLatitude", attrib.getDefaultLocationName()); - settings.setValue("defaultLongitude", attrib.getDefaultLocationName()); - settings.setValue("incomingEmailAddress", attrib.getIncomingEmailAddress()); - settings.endGroup(); - } - public static UserAttributes getUserAttributes() { - settings.beginGroup("UserAttributes"); - UserAttributes attrib = new UserAttributes(); - attrib.setDefaultLocationName((String)settings.value("defaultLocationName","")); - attrib.setDefaultLatitudeIsSet(false); - attrib.setDefaultLongitudeIsSet(false); - attrib.setIncomingEmailAddress((String)settings.value("incomingEmailAddress", "")); - settings.endGroup(); - return attrib; - } - public static void saveUserAccounting(Accounting acc) { - settings.beginGroup("UserAccounting"); - settings.setValue("uploadLimit", acc.getUploadLimit()); - settings.setValue("uploadLimitEnd", acc.getUploadLimitEnd()); - settings.setValue("uploadLimitNextMonth", acc.getUploadLimitNextMonth()); - settings.setValue("premiumServiceStart", acc.getPremiumServiceStart()); - settings.setValue("nextPaymentDue", acc.getNextPaymentDue()); - settings.setValue("uploadAmount", acc.getUpdated()); - settings.endGroup(); - } - public static long getUploadLimitEnd() { - Long limit; - settings.beginGroup("UserAccounting"); - - // Upload limit - try { - String val = (String)settings.value("uploadLimitEnd", "0"); - limit = new Long(val.trim()); - } catch (Exception e) { - try { - limit = (Long)settings.value("uploadLimitEnd", 0); - } catch (Exception e1) { - limit = new Long(0); - } - } - - // return value - settings.endGroup(); - return limit; - } - public static void saveUploadAmount(long amount) { - settings.beginGroup("UserAccounting"); - settings.setValue("uploadAmount", amount); - settings.endGroup(); - } - public static long getUploadAmount() { - long amt=0; - settings.beginGroup("UserAccounting"); - try { - String num = (String)settings.value("uploadAmount", "0"); - amt = new Long(num.trim()); - } catch (Exception e) { - try { - amt = (Integer)settings.value("uploadAmount", 0); - } catch (Exception e1) { - amt = 0; - } - } - settings.endGroup(); - return amt; - } - public static void saveEvernoteUpdateCount(long amount) { - settings.beginGroup("UserAccounting"); - settings.setValue("updateCount", amount); - settings.endGroup(); - } - public static long getEvernoteUpdateCount() { - long amt; - settings.beginGroup("UserAccounting"); - try { - String num = (String)settings.value("updateCount", new Long(0).toString()); - amt = new Long(num.trim()); - } catch (java.lang.ClassCastException e) { - amt = 0; - } - settings.endGroup(); - return amt; - } - public static boolean isPremium() { - int level; - settings.beginGroup("User"); - try { - String num = (String)settings.value("privilege", "1"); - level = new Integer(num.trim()); - } catch (java.lang.ClassCastException e) { - try { - level = (Integer)settings.value("privilege", 1); - } catch (Exception e1) { - level = 1; - } - } - settings.endGroup(); - PrivilegeLevel userLevel = PrivilegeLevel.findByValue(level); - if (userLevel == PrivilegeLevel.NORMAL) - return false; - return true; - - } - public static long getUploadLimit() { - settings.beginGroup("UserAccounting"); - long limit; - try { - String num = (String)settings.value("uploadLimit", new Long(0).toString()); - limit = new Long(num.trim()); - } catch (java.lang.ClassCastException e) { - limit = 0; - } - settings.endGroup(); - return limit; - } - - - - //**************************************************** - //**************************************************** - //** View settings. Used to restore settings - //** when starting and to control how the program - //** behaves. - //**************************************************** - //**************************************************** - - //* Get/Set if we should show a tray icon - public static boolean showTrayIcon() { - settings.beginGroup("General"); - try { - String max = (String) settings.value("showTrayIcon", "false"); - settings.endGroup(); - if (!max.equalsIgnoreCase("true") || !QSystemTrayIcon.isSystemTrayAvailable()) - return false; - else - return true; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("showTrayIcon", false); - settings.endGroup(); - return value; - } - } - public static void setShowTrayIcon(boolean val) { - settings.beginGroup("General"); - if (val) - settings.setValue("showTrayIcon", "true"); - else - settings.setValue("showTrayIcon", "false"); - settings.endGroup(); - } - - // Get/Set window maximized when closed last - public static boolean wasWindowMaximized() { - try { - settings.beginGroup("General"); - String max = (String) settings.value("isMaximized", "true"); - settings.endGroup(); - if (!max.equalsIgnoreCase("true")) - return false; - return true; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("isMaximized", true); - settings.endGroup(); - return value; - } - } - public static void saveWindowMaximized(boolean isMax) { - settings.beginGroup("General"); - if (isMax) - settings.setValue("isMaximized", "true"); - else - settings.setValue("isMaximized", "false"); - settings.endGroup(); - } - - // Get/set currently viewed note Guid - public static String getLastViewedNoteGuid() { - settings.beginGroup("General"); - String guid = (String) settings.value("lastViewedNote", ""); - settings.endGroup(); - return guid; - } - public static void saveCurrentNoteGuid(String guid) { - settings.beginGroup("General"); - if (guid != null) - settings.setValue("lastViewedNote", guid); - else - settings.setValue("lastViewedNote", ""); - settings.endGroup(); - } - - // Get/Set the note column we are sorted on and the order - public static void setSortColumn(int i) { - int view = Global.getListView(); - settings.beginGroup("General"); - if (view == Global.View_List_Wide) - settings.setValue("sortColumn", i); - else - settings.setValue("sortColumn-Narrow", i); - settings.endGroup(); - } - public static int getSortColumn() {; - String key; - if (Global.getListView() == Global.View_List_Wide) - key = "sortColumn"; - else - key = "sortColumn-Narrow"; - - settings.beginGroup("General"); - int order; - try { - String val = settings.value(key, new Integer(0)).toString(); - order = new Integer(val.trim()); - } catch (Exception e) { - try { - order = (Integer)settings.value(key, 0); - } catch (Exception e1) { - order = 0; - } - } - - settings.endGroup(); - return order; - } - public static void setSortOrder(int i) { - int view = Global.getListView(); - settings.beginGroup("General"); - if (view == Global.View_List_Wide) - settings.setValue("sortOrder", i); - else - settings.setValue("sortOrder-Narrow", i); - settings.endGroup(); - } - public static int getSortOrder() { - int view = Global.getListView(); - settings.beginGroup("General"); - String key; - if (view == Global.View_List_Wide) - key = "sortOrder"; - else - key = "sortOrder-Narrow"; - - int order; - try { - String val = settings.value(key, new Integer(0)).toString(); - order = new Integer(val.trim()); - } catch (Exception e) { - try { - order = (Integer)settings.value(key, 0); - } catch (Exception e1) { - order = 0; - } - } - - settings.endGroup(); - return order; - } - - // Should we automatically log in to Evernote when starting? - public static boolean automaticLogin() { - try { - settings.beginGroup("General"); - String text = (String)settings.value("automaticLogin", "false"); - settings.endGroup(); - if (text.equalsIgnoreCase("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("automaticLogin", false); - settings.endGroup(); - return value; - } - } - public static void setAutomaticLogin(boolean val) { - settings.beginGroup("General"); - if (val) - settings.setValue("automaticLogin", "true"); - else - settings.setValue("automaticLogin", "false"); - settings.endGroup(); - } - - // Get/set the Evernote server Url. - public static void setServer(String server) { - settings.beginGroup("General"); - settings.setValue("server", server); - settings.endGroup(); - } - public static String getServer() { - settings.beginGroup("General"); - String text = (String)settings.value("server", "www.evernote.com"); - if (text.equals("www.evernote.com")) { - userStoreUrl = "https://www.evernote.com/edam/user"; - noteStoreUrlBase = "www.evernote.com/edam/note/"; - } else { - userStoreUrl = "https://sandbox.evernote.com/edam/user"; - noteStoreUrlBase = "sandbox.evernote.com/edam/note/"; - } - settings.endGroup(); -// if (isPremium()) - noteStoreUrlBase = "https://" + noteStoreUrlBase; -// else -// noteStoreUrlBase = "http://" + noteStoreUrlBase; - return text; - } - - // Get/Set if we should disable uploads to Evernote - public static boolean disableUploads() { - settings.beginGroup("General"); - try { - String text = (String)settings.value("disableUploads", "false"); - settings.endGroup(); - if (text.equalsIgnoreCase("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("disableUploads", false); - settings.endGroup(); - return value; - } - } - public static void setDisableUploads(boolean val) { - settings.beginGroup("General"); - if (val) - settings.setValue("disableUploads", "true"); - else - settings.setValue("disableUploads", "false"); - settings.endGroup(); - disableUploads = val; - } - - // Should we view PDF documents inline? - public static boolean pdfPreview() { - settings.beginGroup("General"); - try { - String text = (String)settings.value("pdfPreview", "true"); - settings.endGroup(); - if (text.equalsIgnoreCase("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("pdfPreview", true); - settings.endGroup(); - return value; - } - } - public static void setPdfPreview(boolean val) { - settings.beginGroup("General"); - if (val) - settings.setValue("pdfPreview", "true"); - else - settings.setValue("pdfPreview", "false"); - settings.endGroup(); - } - - // When creating a new note, should it inherit tags that are currently selected? - public static boolean newNoteWithSelectedTags() { - settings.beginGroup("General"); - try { - String text = (String)settings.value("newNoteWithSelectedTags", "false"); - settings.endGroup(); - if (text.equalsIgnoreCase("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("newNoteWithSelectedTags", false); - settings.endGroup(); - return value; - } - } - public static void setNewNoteWithSelectedTags(boolean val) { - settings.beginGroup("General"); - if (val) - settings.setValue("newNoteWithSelectedTags", "true"); - else - settings.setValue("newNoteWithSelectedTags", "false"); - settings.endGroup(); - } - - // Minimum weight for text OCRed from Evernote. Anything below this - // Won't be shown to the user when they search - public static void setRecognitionWeight(int len) { - settings.beginGroup("General"); - settings.setValue("recognitionWeight", len); - settings.endGroup(); - } - public static int getRecognitionWeight() { - settings.beginGroup("General"); - Integer len; - try { - len = (Integer)settings.value("recognitionWeight", 30); - } catch (Exception e) { - len = 80; - } - settings.endGroup(); - return len; - } - - // get/set current debug message level - public static String getMessageLevel() { - settings.beginGroup("Debug"); - String text = (String)settings.value("messageLevel", "Low"); - settings.endGroup(); - setMessageLevel(text); - return text; - } - public static void setDateFormat(String format) { - settings.beginGroup("General"); - settings.setValue("dateFormat", format); - settings.endGroup(); - } - - // Get/Set user date/time formats - public static String getDateFormat() { - settings.beginGroup("General"); - String text = (String)settings.value("dateFormat", "MM/dd/yyyy"); - settings.endGroup(); - return text; - } - public static void setTimeFormat(String format) { - settings.beginGroup("General"); - settings.setValue("timeFormat", format); - settings.endGroup(); - } - public static String getTimeFormat() { - settings.beginGroup("General"); - String text = (String)settings.value("timeFormat", "HH:mm:ss"); - settings.endGroup(); - return text; - } - - // How often should we sync with Evernote? - public static String getSyncInterval() { - settings.beginGroup("General"); - String text = (String)settings.value("syncInterval", "15 minutes"); - settings.endGroup(); - return text; - } - public static void setSyncInterval(String format) { - settings.beginGroup("General"); - settings.setValue("syncInterval", format); - settings.endGroup(); - } - - // Get/Set the width of columns and their position for the - // next start. - public static void setColumnWidth(String col, int width) { - if (Global.getListView() == Global.View_List_Wide) - settings.beginGroup("ColumnWidths"); - else - settings.beginGroup("ColumnWidths-Narrow"); - settings.setValue(col, width); - settings.endGroup(); - } - public static int getColumnWidth(String col) { - int view = Global.getListView(); - if (view == Global.View_List_Wide) - settings.beginGroup("ColumnWidths"); - else - settings.beginGroup("ColumnWidths-Narrow"); - Integer width; - try { - String val = (String)settings.value(col, "0"); - width = new Integer(val.trim()); - } catch (Exception e) { - try { - width = (Integer)settings.value(col, 0); - } catch (Exception e1) { - width = 0; - } - } - settings.endGroup(); - return width; - } - public static void setColumnPosition(String col, int width) { - if (Global.getListView() == Global.View_List_Wide) - settings.beginGroup("ColumnPosition"); - else - settings.beginGroup("ColumnPosition-Narrow"); - settings.setValue(col, width); - settings.endGroup(); - } - public static int getColumnPosition(String col) { - if (Global.getListView() == Global.View_List_Wide) - settings.beginGroup("ColumnPosition"); - else - settings.beginGroup("ColumnPosition-Narrow"); - Integer width; - try { - String val = (String)settings.value(col, "-1"); - width = new Integer(val.trim()); - } catch (Exception e) { - try { - width = (Integer)settings.value(col, 0); - } catch (Exception e1) { - width = 0; - } - } - settings.endGroup(); - return width; - } - - // Ping the user when they try to delete or just do it. - public static boolean verifyDelete() { - settings.beginGroup("General"); - try { - String text = (String)settings.value("verifyDelete", "true"); - settings.endGroup(); - if (text.equalsIgnoreCase("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("verifyDelete", true); - settings.endGroup(); - return value; - } - } - public static void setVerifyDelete(boolean val) { - settings.beginGroup("General"); - if (val) - settings.setValue("verifyDelete", "true"); - else - settings.setValue("verifyDelete", "false"); - settings.endGroup(); - } - - // Should it start minimized? - public static boolean startMinimized() { - settings.beginGroup("General"); - try { - String text = (String)settings.value("startMinimized", "false"); - settings.endGroup(); - if (text.equalsIgnoreCase("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("startMinimized", false); - settings.endGroup(); - return value; - } - } - public static void setStartMinimized(boolean val) { - settings.beginGroup("General"); - if (val) - settings.setValue("startMinimized", "true"); - else - settings.setValue("startMinimized", "false"); - settings.endGroup(); - } - - // Should we upload the content of any deleted notes - public static boolean synchronizeDeletedContent() { - settings.beginGroup("General"); - try { - String text = (String)settings.value("syncDeletedContent", "false"); - settings.endGroup(); - if (text.equalsIgnoreCase("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("syncDeletedContent", false); - settings.endGroup(); - return value; - } - } - public static void setSynchronizeDeletedContent(boolean val) { - settings.beginGroup("General"); - if (val) - settings.setValue("syncDeletedContent", "true"); - else - settings.setValue("syncDeletedContent", "false"); - settings.endGroup(); - } - - // Is a section of the window visible? Used to hide things people don't - // want to see. - public static boolean isWindowVisible(String window) { - settings.beginGroup("WindowsVisible"); - try { - String defaultValue = "true"; - if (window.equalsIgnoreCase("noteInformation")) - defaultValue = "false"; - String text = (String)settings.value(window, defaultValue); - settings.endGroup(); - if (text.equalsIgnoreCase("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - boolean defaultValue = true; - if (window.equalsIgnoreCase("noteInformation")) - defaultValue = false; - Boolean value = (Boolean) settings.value("showTrayIcon", defaultValue); - settings.endGroup(); - return value; - } - } - public static void saveWindowVisible(String window, boolean val) { - settings.beginGroup("WindowsVisible"); - if (val) - settings.setValue(window, "true"); - else - settings.setValue(window, "false"); - settings.endGroup(); - } - - // Is a list in the column in the note list visible? - public static boolean isColumnVisible(String window) { - String defaultValue = "true"; - int view = Global.getListView(); - if (Global.getListView() == Global.View_List_Wide) - settings.beginGroup("ColumnsVisible"); - else - settings.beginGroup("ColumnsVisible-Narrow"); - if (window.equalsIgnoreCase("thumbnail") && view == Global.View_List_Wide) - defaultValue = "false"; - if (window.equalsIgnoreCase("thumbnail")) - defaultValue = "false"; - if (window.equalsIgnoreCase("Guid")) - defaultValue = "false"; - try { - String text = (String)settings.value(window, defaultValue); - settings.endGroup(); - if (text.equalsIgnoreCase("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - boolean defBool = false; - if (window.equalsIgnoreCase("true")) - defBool = true; - else - defBool = false; - Boolean value = (Boolean) settings.value(window, defBool); - settings.endGroup(); - return value; - } - } - public static void saveColumnVisible(String column, boolean val) { - if (Global.getListView() == Global.View_List_Wide) - settings.beginGroup("ColumnsVisible"); - else - settings.beginGroup("ColumnsVisible-Narrow"); - if (val) - settings.setValue(column, "true"); - else - settings.setValue(column, "false"); - settings.endGroup(); - } - - // Is a particular editor button visible? - public static boolean isEditorButtonVisible(String window) { - settings.beginGroup("EditorButtonsVisible"); - try { - String text = (String)settings.value(window, "true"); - settings.endGroup(); - if (text.equalsIgnoreCase("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value(window, true); - settings.endGroup(); - return value; - } - } - public static void saveEditorButtonsVisible(String column, boolean val) { - settings.beginGroup("EditorButtonsVisible"); - if (val) - settings.setValue(column, "true"); - else - settings.setValue(column, "false"); - settings.endGroup(); - } - - // Should the test fixes be enabled - public static boolean enableCarriageReturnFix() { - try { - settings.beginGroup("Debug"); - String text = (String)settings.value("enableCarriageReturnFix", "false"); - settings.endGroup(); - if (text.equalsIgnoreCase("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("enableCarriageReturnFix", false); - settings.endGroup(); - return value; - } - } - public static void saveCarriageReturnFix(boolean val) { - settings.beginGroup("Debug"); - if (val) - settings.setValue("enableCarriageReturnFix", "true"); - else - settings.setValue("enableCarriageReturnFix", "false"); - settings.endGroup(); - } - public static boolean enableHtmlEntitiesFix() { - try { - settings.beginGroup("Debug"); - String text = (String)settings.value("enableHtmlEntitiesFix", "false"); - settings.endGroup(); - if (text.equalsIgnoreCase("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("enableHtmlEntitiesFix", false); - settings.endGroup(); - return value; - } - } - public static void saveHtmlEntitiesFix(boolean val) { - settings.beginGroup("Debug"); - if (val) - settings.setValue("enableHtmlEntitiesFix", "true"); - else - settings.setValue("enableHtmlEntitiesFix", "false"); - settings.endGroup(); - } - -// public static void setIndexThreads(int val) { -// settings.beginGroup("General"); -// settings.setValue("indexThreads", val); -// settings.endGroup(); -// } -// public static int getIndexThreads() { -// settings.beginGroup("General"); -// Integer threads; -// try { -// String val = (String)settings.value("indexThreads", "1"); -// threads = new Integer(val.trim()); -// } catch (Exception e) { -// try { -// threads = (Integer)settings.value("indexThreads", 1); -// } catch (Exception e1) { -// threads = 1; -// } -// } -// settings.endGroup(); -// threads = 1; -// return threads; - - // Get/Set text zoom factor -// } - public static void setZoomFactor(double val) { - settings.beginGroup("General"); - settings.setValue("zoomFactor", val); - settings.endGroup(); - } - public static double getZoomFactor() { - settings.beginGroup("General"); - Double threads; - try { - String val = (String)settings.value("zoomFactor", "1.0"); - threads = new Double(val.trim()); - } catch (Exception e) { - try { - threads = (Double)settings.value("zoomFactor", 1.0); - } catch (Exception e1) { - threads = new Double(1); - } - } - settings.endGroup(); - return threads; - } - public static void setTextSizeMultiplier(double val) { - settings.beginGroup("General"); - settings.setValue("textMultiplier", val); - settings.endGroup(); - } - public static double getTextSizeMultiplier() { - settings.beginGroup("General"); - Double threads; - try { - String val = (String)settings.value("textMultiplier", "1"); - threads = new Double(val.trim()); - } catch (Exception e) { - try { - threads = (Double)settings.value("textMultiplier", 1); - } catch (Exception e1) { - threads = new Double(1); - } - } - settings.endGroup(); - return threads; - } - - - // Should we mimic Evernote and restrict the notebooks selected? - public static boolean getMimicEvernoteInterface() { - settings.beginGroup("General"); - try { - String text = (String)settings.value("mimicEvernoteInterface", "true"); - settings.endGroup(); - if (text.equalsIgnoreCase("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("mimicEvernoteInterface", true); - settings.endGroup(); - return value; - } - } - public static void setMimicEvernoteInterface(boolean value) { - settings.beginGroup("General"); - if (value) - settings.setValue("mimicEvernoteInterface", "true"); - else - settings.setValue("mimicEvernoteInterface", "false"); - settings.endGroup(); - } - - - // Synchronize with Evernote when closing? - public static boolean synchronizeOnClose() { - settings.beginGroup("General"); - try { - String text = (String)settings.value("synchronizeOnClose", "false"); - settings.endGroup(); - if (text.equalsIgnoreCase("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("synchronizeOnClose", false); - settings.endGroup(); - return value; - } - } - public static void setSynchronizeOnClose(boolean val) { - settings.beginGroup("General"); - if (val) - settings.setValue("synchronizeOnClose", "true"); - else - settings.setValue("synchronizeOnClose", "false"); - settings.endGroup(); - } - - // Get/set the database version. Not really used any more, but kept - // for compatibility. - public static void setDatabaseVersion(String version) { - settings.beginGroup("General"); - settings.setValue("databaseVersion", version); - settings.endGroup(); - } - public static String getDatabaseVersion() { - settings.beginGroup("General"); - String val = (String)settings.value("databaseVersion", "0.70"); - settings.endGroup(); - return val; - } - - // Get the URL (full path) of the main database - public static String getDatabaseUrl() { - settings.beginGroup("General"); - String val = (String)settings.value("DatabaseURL", ""); - settings.endGroup(); - if (val.equals("")) - val = "jdbc:h2:"+Global.getFileManager().getDbDirPath(Global.databaseName); - return val; - } - - // get the url (full path) of the searchable word database - public static String getIndexDatabaseUrl() { - settings.beginGroup("General"); - String val = (String)settings.value("IndexDatabaseURL", ""); - settings.endGroup(); - if (val.equals("")) - val = "jdbc:h2:"+Global.getFileManager().getDbDirPath(Global.indexDatabaseName); - return val; - } - - // Get the url (full path) of the attachment database - public static String getResourceDatabaseUrl() { - settings.beginGroup("General"); - String val = (String)settings.value("ResourceDatabaseURL", ""); - settings.endGroup(); - if (val.equals("")) - val = "jdbc:h2:"+Global.getFileManager().getDbDirPath(Global.resourceDatabaseName); - return val; - } - public static void setDatabaseUrl(String value) { - settings.beginGroup("General"); - settings.setValue("DatabaseURL", value); - settings.endGroup(); - } - public static void setIndexDatabaseUrl(String value) { - settings.beginGroup("General"); - settings.setValue("IndexDatabaseURL", value); - settings.endGroup(); - } - public static void setResourceDatabaseUrl(String value) { - settings.beginGroup("General"); - settings.setValue("ResourceDatabaseURL", value); - settings.endGroup(); - } - public static String getDatabaseUserid() { - settings.beginGroup("General"); - String val = (String)settings.value("databaseUserid", ""); - settings.endGroup(); - return val; - } - public static String getDatabaseUserPassword() { - settings.beginGroup("General"); - String val = (String)settings.value("databaseUserPassword", ""); - settings.endGroup(); - return val; - } - - // get/Set the style sheet and the palette to control the look & feel - public static void setStyle(String style) { - settings.beginGroup("General"); - settings.setValue("style", style); - settings.endGroup(); - } - public static String getStyle() { - settings.beginGroup("General"); - String val = (String)settings.value("style", "Cleanlooks"); - settings.endGroup(); - return val; - } - public static boolean useStandardPalette() { - settings.beginGroup("General"); - try { - String text = (String)settings.value("standardPalette", "true"); - settings.endGroup(); - if (text.equalsIgnoreCase("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("standardPalette", true); - settings.endGroup(); - return value; - } - } - public static void setStandardPalette(boolean val) { - settings.beginGroup("General"); - if (val) - settings.setValue("standardPalette", "true"); - else - settings.setValue("standardPalette", "false"); - settings.endGroup(); - } - - // Set the amount of time to wait between indexing - // Get/Set interval when the index thread wakes up. - public static void setIndexThreadSleepInterval(int sleep) { - settings.beginGroup("General"); - settings.setValue("IndexThreadSleepInterval", sleep); - settings.endGroup(); - } - public static int getIndexThreadSleepInterval() { - settings.beginGroup("General"); - Integer sleep; - try { - String val = (String)settings.value("IndexThreadSleepInterval", "300"); - sleep = new Integer(val.trim()); - } catch (Exception e) { - try { - sleep = (Integer)settings.value("IndexThreadSleepInterval", 0); - } catch (Exception e1) { - sleep = 300; - } - } - settings.endGroup(); - return sleep; - } - - - // Get/Set a window state for later restoring - public static void saveState(String name, QByteArray state) { - int view = Global.getListView(); - if (view == Global.View_List_Narrow) - name = name +"Narrow"; - settings.beginGroup("SaveState"); - settings.setValue(name, state); - settings.endGroup(); - } - - public static QByteArray restoreState(String name) { - int view = Global.getListView(); - if (view == Global.View_List_Narrow) - name = name +"Narrow"; - settings.beginGroup("SaveState"); - QByteArray state = (QByteArray)settings.value(name); - settings.endGroup(); - return state; - } - public static void saveGeometry(String name, QByteArray state) { - int view = Global.getListView(); - if (view == Global.View_List_Narrow) - settings.beginGroup("SaveGeometryNarrow"); - else - settings.beginGroup("SaveGeometry"); - settings.setValue(name, state); - settings.endGroup(); - } - - public static QByteArray restoreGeometry(String name) { - int view = Global.getListView(); - if (view == Global.View_List_Narrow) - settings.beginGroup("SaveGeometryNarrow"); - else - settings.beginGroup("SaveGeometry"); - QByteArray state = (QByteArray)settings.value(name); - settings.endGroup(); - return state; - } - - - // Set how often to do an automatic save - public static void setAutoSaveInterval(int interval) { - settings.beginGroup("General"); - settings.setValue("autoSaveInterval", interval); - settings.endGroup(); - } - public static int getAutoSaveInterval() { - settings.beginGroup("General"); - Integer value; - try { - String val = (String)settings.value("autoSaveInterval", "5"); - value = new Integer(val.trim()); - } catch (Exception e) { - try { - value = (Integer)settings.value("autoSaveInterval", 5); - } catch (Exception e1) { - value = 5; - } - } - settings.endGroup(); - return value; - } - - // Add an invalid attribute & element to the database so we don't bother parsing it in the future - // These values we automatically remove from any note. - // Add invalid attributes - public static void addInvalidAttribute(String element, String attribute) { - - List attributes = invalidAttributes.get(element); - if (attributes != null) { - for (int i=0; i attributeList; - if (!invalidAttributes.containsKey(element)) { - attributeList = new ArrayList(); - attributeList.add(attribute); - invalidAttributes.put(element, attributeList); - } - else { - attributeList = invalidAttributes.get(element); - attributeList.add(attribute); - invalidAttributes.put(element,attributeList); - } - } - - // Add invalid attributes - public static void addInvalidElement(String element) { - for (int i=0; i>> 4) & 0x0F; - int two_halfs = 0; - do { - if ((0 <= halfbyte) && (halfbyte <= 9)) - buf.append((char) ('0' + halfbyte)); - else - buf.append((char) ('a' + (halfbyte - 10))); - halfbyte = element & 0x0F; - } while(two_halfs++ < 1); - } - return buf.toString(); - } - - - // Get/Set spelling settings - public static boolean getSpellSetting(String value) { - settings.beginGroup("Spell"); - String text = (String)settings.value(value, ""); - settings.endGroup(); - if (text.equalsIgnoreCase("true")) - return true; - if (text.equalsIgnoreCase("false")) - return false; - if (value.equalsIgnoreCase(Configuration.SPELL_IGNOREDIGITWORDS)) - return true; - if (value.equalsIgnoreCase(Configuration.SPELL_IGNOREINTERNETADDRESSES)) - return true; - if (value.equalsIgnoreCase(Configuration.SPELL_IGNOREUPPERCASE)) - return true; - if (value.equalsIgnoreCase(Configuration.SPELL_IGNORESENTENCECAPITALIZATION)) - return true; - return false; - } - public static void setSpellSetting(String setting, boolean val) { - settings.beginGroup("Spell"); - if (val) - settings.setValue(setting, "true"); - else - settings.setValue(setting, "false"); - settings.endGroup(); - } - - // Get/Set how we should display tags (color them, hide unused, or do nothing) - // What to do with inactive tags? - public static String tagBehavior() { - settings.beginGroup("General"); - String text = (String)settings.value("tagBehavior", "DoNothing"); - settings.endGroup(); - return text; - } - // What to do with inactive tags? - public static void setTagBehavior(String value) { - settings.beginGroup("General"); - settings.setValue("tagBehavior", value); - settings.endGroup(); - } - - - // Should the toolbar be visible? - public static boolean isToolbarButtonVisible(String window) { - settings.beginGroup("ToolbarButtonsVisible"); - try { - String text = (String)settings.value(window, "true"); - settings.endGroup(); - if (text.equalsIgnoreCase("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value(window, true); - settings.endGroup(); - return value; - } - } - public static void saveToolbarButtonsVisible(String column, boolean val) { - settings.beginGroup("ToolbarButtonsVisible"); - if (val) - settings.setValue(column, "true"); - else - settings.setValue(column, "false"); - settings.endGroup(); - } - - // Are thumbnails enabled? - - public static boolean enableThumbnails() { - settings.beginGroup("Debug"); - try { - String text = (String)settings.value("thumbnails", "true"); - settings.endGroup(); - if (text.equalsIgnoreCase("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("thumbnails", true); - settings.endGroup(); - return value; - } - } - public static void setEnableThumbnails(boolean val) { - settings.beginGroup("Debug"); - if (val) - settings.setValue("thumbnails", "true"); - else - settings.setValue("thumbnails", "false"); - settings.endGroup(); - } - - // Trace used for performance tuning. Not normally used in production. - // Print date/time. Used mainly for performance tracing - public static void trace(boolean resetInterval) { - String fmt = "MM/dd/yy HH:mm:ss.SSSSSS"; - String dateTimeFormat = new String(fmt); - SimpleDateFormat simple = new SimpleDateFormat(dateTimeFormat); - Calendar cal = Calendar.getInstance(); - if (intervalTraceTime == null) - intervalTraceTime = Calendar.getInstance(); - if (startTraceTime == null) - startTraceTime = Calendar.getInstance(); - - float interval = (cal.getTimeInMillis() - intervalTraceTime.getTimeInMillis()); - float total = (cal.getTimeInMillis() - startTraceTime.getTimeInMillis()); - -// if (interval > 00.0) { - StackTraceElement[] exceptions = Thread.currentThread().getStackTrace(); - System.out.println("------------------------------------------"); - - System.out.println("Date/Time " +simple.format(cal.getTime())); - System.out.format("Interval Time: %-10.6f%n", interval); - System.out.format("Total Time: %-10.6f%n", total); - for (int i=2; i<5 && i", "")); - zoom = 2; - if (text.length() < 500) - zoom = 2; - if (text.length() < 250) - zoom = 3; - if (text.length() < 100) - zoom = 4; - if (text.length() < 50) - zoom = 5; - if (text.length() < 10) - zoom = 6; - } - } - return zoom; - } - - //********************** - //* List View settings - //********************** - public static void setListView(int view) { - settings.beginGroup("General"); - settings.setValue("listView", view); - settings.endGroup(); - } - public static int getListView() { - settings.beginGroup("General"); - Integer value; - try { - String val = (String)settings.value("listView", View_List_Wide); - value = new Integer(val.trim()); - } catch (Exception e) { - try { - value = (Integer)settings.value("listView", View_List_Wide); - } catch (Exception e1) { - value = View_List_Wide; - } - } - settings.endGroup(); - return value; - } - - - - //******************* - // Font Settings - //******************* - public static boolean overrideDefaultFont() { - settings.beginGroup("Font"); - try { - String text = (String)settings.value("overrideFont", "false"); - settings.endGroup(); - if (text.equalsIgnoreCase("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("overrideFont", false); - settings.endGroup(); - return value; - } - - } - - //**************************************************** - // Get/Set the default font settings for a new note - //**************************************************** - public static void setOverrideDefaultFont(boolean value) { - settings.beginGroup("Font"); - settings.setValue("overrideFont", value); - settings.endGroup(); - } - public static String getDefaultFont() { - settings.beginGroup("Font"); - String val = (String)settings.value("font", ""); - settings.endGroup(); - return val; - } - public static void setDefaultFont(String value) { - settings.beginGroup("Font"); - settings.setValue("font", value); - settings.endGroup(); - } - public static String getDefaultFontSize() { - settings.beginGroup("Font"); - String val = (String)settings.value("fontSize", ""); - settings.endGroup(); - return val; - } - public static void setDefaultFontSize(String value) { - settings.beginGroup("Font"); - settings.setValue("fontSize", value); - settings.endGroup(); - } - - - //******************************************* - // Override the close & minimize instead. - //******************************************* - public static boolean minimizeOnClose() { - settings.beginGroup("General"); - try { - String text = (String)settings.value("minimizeOnClose", "false"); - settings.endGroup(); - if (text.equalsIgnoreCase("true") && QSystemTrayIcon.isSystemTrayAvailable()) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("minimizeOnClose", false); - settings.endGroup(); - return value; - } - } - public static void setMinimizeOnClose(boolean value) { - settings.beginGroup("General"); - settings.setValue("minimizeOnClose", value); - settings.endGroup(); - } - - //********************************* - // Check version information - //********************************* - public static boolean checkVersionUpgrade() { - settings.beginGroup("Upgrade"); - try { - String text = (String)settings.value("checkForUpdates", "true"); - settings.endGroup(); - if (text.equalsIgnoreCase("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("checkForUpdates", true); - settings.endGroup(); - return value; - } - } - public static void setCheckVersionUpgrade(boolean value) { - settings.beginGroup("Upgrade"); - settings.setValue("checkForUpdates", value); - settings.endGroup(); - } - public static String getUpdatesAvailableUrl() { - settings.beginGroup("Upgrade"); - String text = (String)settings.value("avialableUrl", "http://nevernote.sourceforge.net/versions.txt"); - settings.endGroup(); - return text; - } - public static String getUpdateAnnounceUrl() { - settings.beginGroup("Upgrade"); - String text = (String)settings.value("announceUrl", "http://nevernote.sourceforge.net/upgrade.html"); - settings.endGroup(); - return text; - } - - //******************* - // Index settings - //******************* - // Set/Get if we should index the text of a note - public static boolean indexNoteBody() { - settings.beginGroup("Index"); - try { - String value = (String)settings.value("indexNoteBody", "true"); - settings.endGroup(); - if (value.equals("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("indexNoteBody", true); - settings.endGroup(); - return value; - } - } - public static void setIndexNoteTitle(boolean value) { - settings.beginGroup("Index"); - settings.setValue("indexNoteTitle", value); - settings.endGroup(); - } - // Set/Get if we should index the title of a note - public static boolean indexNoteTitle() { - settings.beginGroup("Index"); - try { - String value = (String)settings.value("indexNoteTitle", "true"); - settings.endGroup(); - if (value.equals("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("indexNoteTitle", true); - settings.endGroup(); - return value; - } - } - public static void setIndexNoteBody(boolean value) { - settings.beginGroup("Index"); - settings.setValue("indexNoteBody", value); - settings.endGroup(); - } - // Set/Get if we should index any attachments - public static boolean indexAttachmentsLocally() { - settings.beginGroup("Index"); - try { - String value = (String)settings.value("indexAttachmentsLocally", "true"); - settings.endGroup(); - if (value.equals("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("indexAttachmentsLocally", true); - settings.endGroup(); - return value; - } - } - public static void setIndexImageRecognition(boolean value) { - settings.beginGroup("Index"); - settings.setValue("indexImageRecognition", value); - settings.endGroup(); - } - public static boolean indexImageRecognition() { - settings.beginGroup("Index"); - try { - String value = (String)settings.value("indexImageRecognition", "true"); - settings.endGroup(); - if (value.equals("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("indexImageRecognition", true); - settings.endGroup(); - return value; - } - } - public static void setIndexAttachmentsLocally(boolean value) { - settings.beginGroup("Index"); - settings.setValue("indexAttachmentsLocally", value); - settings.endGroup(); - } - // Get/Set characters that shouldn't be removed from a word - public static String getSpecialIndexCharacters() { - settings.beginGroup("Index"); - String text = (String)settings.value("specialCharacters", ""); - settings.endGroup(); - return text; - } - public static void setSpecialIndexCharacters(String value) { - settings.beginGroup("Index"); - settings.setValue("specialCharacters", value); - settings.endGroup(); - databaseCache = value; - } - - //***************************************************************************** - // Control how tag selection behaves (should they be "and" or "or" selections - //***************************************************************************** - public static boolean anyTagSelectionMatch() { - settings.beginGroup("General"); - try { - String value = (String)settings.value("anyTagSelectionMatch", "false"); - settings.endGroup(); - if (value.equals("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("anyTagSelectionMatch", false); - settings.endGroup(); - return value; - } - } - public static void setAnyTagSelectionMatch(boolean value) { - settings.beginGroup("General"); - settings.setValue("anyTagSelectionMatch", value); - settings.endGroup(); - } - - //***************************************************************************** - // Control if a user receives a warning when trying to create a note-to-note link - // when the DB is not synchronized. - //***************************************************************************** - public static boolean bypassSynchronizationWarning() { - settings.beginGroup("User"); - try { - String value = (String)settings.value("bypassSynchronizationWarning", "false"); - settings.endGroup(); - if (value.equals("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("bypassSynchronizationWarning", false); - settings.endGroup(); - return value; - } - } - public static void setBypassSynchronizationWarning(boolean value) { - settings.beginGroup("User"); - settings.setValue("bypassSynchronizationWarning", value); - settings.endGroup(); - } - - - //*********************** - //* Database cache size - //*********************** - public static String getDatabaseCacheSize() { - settings.beginGroup("Debug"); - String text = (String)settings.value("databaseCache", "16384"); - settings.endGroup(); - return text; - } - public static void setDatabaseCache(String value) { - settings.beginGroup("Debug"); - settings.setValue("databaseCache", value); - settings.endGroup(); - databaseCache = value; - } - - - // This is used to copy a class since Java's normal deep copy is wacked - public static Object deepCopy(Object oldObj) - { - ObjectOutputStream oos = null; - ObjectInputStream ois = null; - try - { - ByteArrayOutputStream bos = - new ByteArrayOutputStream(); // A - oos = new ObjectOutputStream(bos); // B - // serialize and pass the object - oos.writeObject(oldObj); // C - oos.flush(); // D - ByteArrayInputStream bin = - new ByteArrayInputStream(bos.toByteArray()); // E - ois = new ObjectInputStream(bin); // F - // return the new object - return ois.readObject(); // G - } - catch(Exception e) - { - Global.logger.log(logger.LOW, "Exception in ObjectCloner = " + e); - } - try { - oos.close(); - ois.close(); - } catch (IOException e) { - Global.logger.log(logger.LOW, "Exception in ObjectCloner = " + e); - e.printStackTrace(); - } - - return null; - } - - // If we should automatically select the children of any tag - public static boolean includeTagChildren() { - settings.beginGroup("General"); - try { - String value = (String)settings.value("includeTagChildren", "false"); - settings.endGroup(); - if (value.equals("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("includeTagChildren", false); - settings.endGroup(); - return value; - } - - } - public static void setIncludeTagChildren(boolean value) { - settings.beginGroup("General"); - settings.setValue("includeTagChildren", value); - settings.endGroup(); - } - - // If we should automatically wildcard searches - public static boolean automaticWildcardSearches() { - settings.beginGroup("General"); - try { - String value = (String)settings.value("automaticWildcard", "false"); - settings.endGroup(); - if (value.equals("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("automaticWildcard", false); - settings.endGroup(); - return value; - } - - } - public static void setAutomaticWildcardSearches(boolean value) { - settings.beginGroup("General"); - settings.setValue("automaticWildcard", value); - settings.endGroup(); - } - - // If we should automatically select the children of any tag - public static boolean displayRightToLeft() { - settings.beginGroup("General"); - try { - String value = (String)settings.value("displayRightToLeft", "false"); - settings.endGroup(); - if (value.equals("true")) - return true; - else - return false; - } catch (java.lang.ClassCastException e) { - Boolean value = (Boolean) settings.value("displayRightToLeft", false); - settings.endGroup(); - return value; - } - - } - public static void setDisplayRightToLeft(boolean value) { - settings.beginGroup("General"); - settings.setValue("displayRightToLeft", value); - settings.endGroup(); - } - - - //*********************** - //* Startup Notebook - //*********************** - public static String getStartupNotebook() { - settings.beginGroup("General"); - String text = (String)settings.value("startupNotebook", ""); - settings.endGroup(); - return text; - } - public static void setStartupNotebook(String value) { - settings.beginGroup("General"); - settings.setValue("startupNotebook", value); - settings.endGroup(); - databaseCache = value; - } -} - +/* + * This file is part of NixNote/NeighborNote + * Copyright 2009 Randy Baumgarte + * Copyright 2013 Yuki Takahashi + * + * This file may be licensed under the terms of of the + * GNU General Public License Version 2 (the ``GPL''). + * + * Software distributed under the License is distributed + * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the GPL for the specific language + * governing rights and limitations. + * + * You should have received a copy of the GPL along with this + * program. If not, go to http://www.gnu.org/licenses/gpl.html + * or write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * +*/ + +package cx.fbn.nevernote; + + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.HashMap; +import java.util.List; + +import org.apache.commons.lang3.StringEscapeUtils; + +import com.evernote.edam.type.Accounting; +import com.evernote.edam.type.PrivilegeLevel; +import com.evernote.edam.type.User; +import com.evernote.edam.type.UserAttributes; +import com.swabunga.spell.engine.Configuration; +import com.trolltech.qt.core.QByteArray; +import com.trolltech.qt.core.QFile; +import com.trolltech.qt.core.QSettings; +import com.trolltech.qt.core.QSize; +import com.trolltech.qt.gui.QPalette; +import com.trolltech.qt.gui.QSystemTrayIcon; + +import cx.fbn.nevernote.config.FileManager; +import cx.fbn.nevernote.config.InitializationException; +import cx.fbn.nevernote.config.StartupConfig; +import cx.fbn.nevernote.gui.ContainsAttributeFilterTable; +import cx.fbn.nevernote.gui.DateAttributeFilterTable; +import cx.fbn.nevernote.gui.ShortcutKeys; +import cx.fbn.nevernote.sql.DatabaseConnection; +import cx.fbn.nevernote.sql.driver.NSqlQuery; +import cx.fbn.nevernote.utilities.ApplicationLogger; +import cx.fbn.nevernote.utilities.Pair; + + +//***************************************************** +//***************************************************** +//* Global constants & static functions used by +//* multiple threads. +//***************************************************** +//***************************************************** + +public class Global { + // Set current version and the known versions. + public static String version = "0.3"; + public static String[] validVersions = {"0.3", "0.2", "0.1.3", "0.1.2", "0.1.1", "0.1"}; + + public static String username = ""; + //public static String password = ""; + + + // Each thread has an ID. This is used primarily to check the status + // of running threads. + public static final int mainThreadId=0; + public static final int syncThreadId=1; + public static final int tagCounterThreadId=2; + public static final int trashCounterThreadId=3; // This should always be the highest thread ID + public static final int indexThreadId=4; // Thread for indexing words + public static final int saveThreadId=5; // Thread used for processing data to saving content + public static final int notebookCounterThreadId=6; // Notebook Thread + public static final int indexThread03Id=7; // unused + public static final int indexThread04Id=8; // unused + public static final int dbThreadId=9; // This should always be the highest thread ID + public static final int threadCount = 10; + + + // These variables deal with where the list of notes appears + // They will either be vertical (View_List_Narrow) or will be + // on top of the note (View_List_Wide). It also has the size of + // thumbnails displayed in each view + public static int View_List_Wide = 1; + public static int View_List_Narrow = 2; + public static QSize smallThumbnailSize = new QSize(100,75); + public static QSize largeThumbnailSize = new QSize(300,225); + + // This is used to keep a running list of passwords that the user + // wants us to remember. + public static HashMap> passwordSafe = new HashMap>(); + public static List> passwordRemember = new ArrayList>(); + + + //public static String currentNotebookGuid; + + // These deal with Evernote user settings + public static User user; + public static long authTimeRemaining; + public static long authRefreshTime; + public static long failedRefreshes = 0; + public static String userStoreUrl; + public static String noteStoreUrl; + public static String noteStoreUrlBase; + + // When we want to shut down we set this to true to short + // circut other threads + public static boolean keepRunning; + + // In the note list, these are the column numbers + // so I don't need to hard code numbers. + public static int noteTableCreationPosition = 0; + public static int noteTableTitlePosition = 1; + public static int noteTableTagPosition = 2; + public static int noteTableNotebookPosition = 3; + public static int noteTableChangedPosition = 4; + public static int noteTableGuidPosition = 5; + public static int noteTableAuthorPosition = 6; + public static int noteTableSourceUrlPosition = 7; + public static int noteTableSubjectDatePosition = 8; + public static int noteTableSynchronizedPosition = 9; + public static int noteTableThumbnailPosition = 10; + public static int noteTablePinnedPosition = 11; + public static int noteTableColumnCount = 12; + public static Integer cryptCounter = 0; + + //public static int minimumWordCount = 2; + + // Regular expression to parse text with when indexing +// private static String wordRegex; + + // Experimental fixes. Set via Edit/Preferences/Debugging + public static boolean enableCarriageReturnFix = false; + public static boolean enableHTMLEntitiesFix = false; + + // Used to set & retrieve ini & Windows registry settings + public static QSettings settings; // Set & get ini settings + public static boolean isConnected; // Are we connected to Evernote + public static boolean showDeleted = false; // Show deleted notes? + public static boolean disableUploads = false; // Should we disable uploads (used in testing features) + public static int messageLevel; // The level of messages to write to the log files + public static String tagDelimeter = ","; // This is used to separate out tag names when entering above note + public static String attachmentNameDelimeter = "------"; // Used to separate out attachment names in the res directory + + + //* Database fields + public static String databaseName = new String("NeverNote"); // database name. used for multiple databases to separate settings. + public static String indexDatabaseName = new String("Index"); // searchable words database + public static String resourceDatabaseName = new String("Resources"); // attachments database + public static String behaviorDatabaseName = new String("Behavior"); // 操作履歴データベース + + public static DateAttributeFilterTable createdSinceFilter; + public static DateAttributeFilterTable createdBeforeFilter; + public static DateAttributeFilterTable changedSinceFilter; + public static DateAttributeFilterTable changedBeforeFilter; + public static ContainsAttributeFilterTable containsFilter; + + // Log file used for debugging + public static ApplicationLogger logger; + //PrintStream stdoutStream; + + // Application key shortcuts & appearance + public static QPalette originalPalette; + public static ShortcutKeys shortcutKeys; + + public static boolean disableViewing; // used to disable the editor + + // When saving a note, this is a list of things we strip out because Evernote hates them + public static List invalidElements = new ArrayList(); + public static HashMap> invalidAttributes = new HashMap>(); + + public static boolean mimicEvernoteInterface; // Try to mimic Evernote or allow multiple notebook selection + public static HashMap resourceMap; // List of attachments for a note. + public static String cipherPassword = ""; // If the database is encrypted, this stores the password + public static String databaseCache = "16384"; // Default DB cache size + + // These are used for performance testing + static Calendar startTraceTime; + static Calendar intervalTraceTime; + + static boolean syncOnly; + + private static FileManager fileManager; // Used to access files & directories + + // Do initial setup + public static void setup(StartupConfig startupConfig) throws InitializationException { + String settingFileName = new String("NeighborNote.ini"); + + // バージョン0.1.2以下で作成された古い設定ファイルを見つけたら、ホームディレクトリに移動させる。 + String oldSettingPath = new QSettings(settingFileName, QSettings.Format.IniFormat).fileName(); + File homeDir = new File(FileManager.toPlatformPathSeparator(startupConfig.getHomeDirPath())); + String homePath = FileManager.slashTerminatePath(homeDir.getPath()); + if (QFile.exists(oldSettingPath)) { + QFile file = new QFile(oldSettingPath); + file.copy(homePath + settingFileName); + file.remove(); + } + + settings = new QSettings(homePath + settingFileName, QSettings.Format.IniFormat); + + disableViewing = startupConfig.getDisableViewing(); + syncOnly = startupConfig.isSyncOnly(); + + fileManager = new FileManager(startupConfig.getHomeDirPath(), startupConfig.getProgramDirPath()); + + + getServer(); // Setup URL to connect to + + // Get regular expressions used to parse out words +// settings.beginGroup("General"); +// String regex = (String) settings.value("regex", "[,\\s]+"); +// setWordRegex(regex); +// settings.endGroup(); + + //Setup debugging information + settings.beginGroup("Debug"); + String msglevel = (String) settings.value("messageLevel", "Low"); + settings.endGroup(); + + + //messageLevel = 1; + setMessageLevel(msglevel); + keepRunning = true; // Make sure child threads stay running - disableUploads = disableUploads(); // Should we upload anything? Normally false. - //disableUploads = true; //***** DELETE THIS LINE ******* ++ disableUploads = disableUploads(); // Should we upload anything? Normally false. ++ //disableUploads = true; //***** DELETE THIS LINE ******* + enableCarriageReturnFix = enableCarriageReturnFix(); // Enable test fix? + enableHTMLEntitiesFix = enableHtmlEntitiesFix(); // Enable test fix? + + logger = new ApplicationLogger("global.log"); // Setup log for this class + shortcutKeys = new ShortcutKeys(); // Setup keyboard shortcuts. + mimicEvernoteInterface = getMimicEvernoteInterface(); // Should we mimic Evernote's notebook behavior + resourceMap = new HashMap(); // Setup resource map used to store attachments when editing + + databaseCache = getDatabaseCacheSize(); // Set database cache size + + Global.username = getUserInformation().getUsername(); + } + + // Get/Set word parsing regular expression +// public static String getWordRegex() { +// return wordRegex; +// } +// public static void setWordRegex(String r) { +// wordRegex = r; +// } + + // Set the debug message level + public static void setMessageLevel(String msglevel) { + if (msglevel.equalsIgnoreCase("low")) + messageLevel = 1; + if (msglevel.equalsIgnoreCase("medium")) + messageLevel = 2; + if (msglevel.equalsIgnoreCase("high")) + messageLevel = 3; + if (msglevel.equalsIgnoreCase("extreme")) + messageLevel = 4; + settings.beginGroup("Debug"); + settings.setValue("messageLevel", msglevel); + settings.endGroup(); + } + + //**************************************************** + //**************************************************** + //** Save user account information from Evernote + //**************************************************** + //**************************************************** + public static void saveUserInformation(User user) { + settings.beginGroup("User"); + settings.setValue("id", user.getId()); + settings.setValue("username", user.getUsername()); + settings.setValue("email", user.getEmail()); + settings.setValue("name", user.getName()); + settings.setValue("timezone", user.getTimezone()); + settings.setValue("privilege", user.getPrivilege().getValue()); + settings.setValue("created", user.getCreated()); + settings.setValue("updated", user.getUpdated()); + settings.setValue("deleted", user.getDeleted()); + settings.setValue("shard", user.getShardId()); + settings.endGroup(); + isPremium(); + if (user.getAttributes()!=null) + saveUserAttributes(user.getAttributes()); + if (user.getAccounting()!=null) + saveUserAccounting(user.getAccounting()); + + } + public static User getUserInformation() { + User user = new User(); + settings.beginGroup("User"); + try { + user.setId((Integer)settings.value("id", 0)); + } catch (java.lang.ClassCastException e) { + user.setId(new Integer((String)settings.value("id", "0"))); + } + String username = (String)settings.value("username", ""); + String email = (String)settings.value("email", ""); + String name = (String)settings.value("name", ""); + String timezone = (String)settings.value("timezone", ""); + Integer privilege = 0; + try { + privilege = new Integer((String)settings.value("privilege", "0")); + } catch (java.lang.ClassCastException e) { + privilege = (Integer)settings.value("privilege", 0); + } + + try { + String date = (String)settings.value("created", "0"); + user.setCreated(new Long(date)); + date = (String)settings.value("updated", "0"); + user.setUpdated(new Long(date)); + date = (String)settings.value("deleted", "0"); + user.setDeleted(new Long(date)); + } catch (java.lang.ClassCastException e) { + Long date = (Long)settings.value("created", 0); + user.setCreated(date); + date = (Long)settings.value("updated", 0); + user.setUpdated(date); + date = (Long)settings.value("deleted", 0); + user.setDeleted(date); + } + + String shard = (String)settings.value("shard", ""); + settings.endGroup(); + + user.setUsername(username); + user.setEmail(email); + user.setName(name); + user.setTimezone(timezone); + PrivilegeLevel userLevel = PrivilegeLevel.findByValue(privilege); + user.setPrivilege(userLevel); + user.setShardId(shard); + return user; + } + + public static void saveUserAttributes(UserAttributes attrib) { + settings.beginGroup("UserAttributes"); + settings.setValue("defaultLocationName", attrib.getDefaultLocationName()); + settings.setValue("defaultLatitude", attrib.getDefaultLocationName()); + settings.setValue("defaultLongitude", attrib.getDefaultLocationName()); + settings.setValue("incomingEmailAddress", attrib.getIncomingEmailAddress()); + settings.endGroup(); + } + public static UserAttributes getUserAttributes() { + settings.beginGroup("UserAttributes"); + UserAttributes attrib = new UserAttributes(); + attrib.setDefaultLocationName((String)settings.value("defaultLocationName","")); + attrib.setDefaultLatitudeIsSet(false); + attrib.setDefaultLongitudeIsSet(false); + attrib.setIncomingEmailAddress((String)settings.value("incomingEmailAddress", "")); + settings.endGroup(); + return attrib; + } + public static void saveUserAccounting(Accounting acc) { + settings.beginGroup("UserAccounting"); + settings.setValue("uploadLimit", acc.getUploadLimit()); + settings.setValue("uploadLimitEnd", acc.getUploadLimitEnd()); + settings.setValue("uploadLimitNextMonth", acc.getUploadLimitNextMonth()); + settings.setValue("premiumServiceStart", acc.getPremiumServiceStart()); + settings.setValue("nextPaymentDue", acc.getNextPaymentDue()); + settings.setValue("uploadAmount", acc.getUpdated()); + settings.endGroup(); + } + public static long getUploadLimitEnd() { + Long limit; + settings.beginGroup("UserAccounting"); + + // Upload limit + try { + String val = (String)settings.value("uploadLimitEnd", "0"); + limit = new Long(val.trim()); + } catch (Exception e) { + try { + limit = (Long)settings.value("uploadLimitEnd", 0); + } catch (Exception e1) { + limit = new Long(0); + } + } + + // return value + settings.endGroup(); + return limit; + } + public static void saveUploadAmount(long amount) { + settings.beginGroup("UserAccounting"); + settings.setValue("uploadAmount", amount); + settings.endGroup(); + } + public static long getUploadAmount() { + long amt=0; + settings.beginGroup("UserAccounting"); + try { + String num = (String)settings.value("uploadAmount", "0"); + amt = new Long(num.trim()); + } catch (Exception e) { + try { + amt = (Integer)settings.value("uploadAmount", 0); + } catch (Exception e1) { + amt = 0; + } + } + settings.endGroup(); + return amt; + } + public static void saveEvernoteUpdateCount(long amount) { + settings.beginGroup("UserAccounting"); + settings.setValue("updateCount", amount); + settings.endGroup(); + } + public static long getEvernoteUpdateCount() { + long amt; + settings.beginGroup("UserAccounting"); + try { + String num = (String)settings.value("updateCount", new Long(0).toString()); + amt = new Long(num.trim()); + } catch (java.lang.ClassCastException e) { + amt = 0; + } + settings.endGroup(); + return amt; + } + public static boolean isPremium() { + int level; + settings.beginGroup("User"); + try { + String num = (String)settings.value("privilege", "1"); + level = new Integer(num.trim()); + } catch (java.lang.ClassCastException e) { + try { + level = (Integer)settings.value("privilege", 1); + } catch (Exception e1) { + level = 1; + } + } + settings.endGroup(); + PrivilegeLevel userLevel = PrivilegeLevel.findByValue(level); + if (userLevel == PrivilegeLevel.NORMAL) + return false; + return true; + + } + public static long getUploadLimit() { + settings.beginGroup("UserAccounting"); + long limit; + try { + String num = (String)settings.value("uploadLimit", new Long(0).toString()); + limit = new Long(num.trim()); + } catch (java.lang.ClassCastException e) { + limit = 0; + } + settings.endGroup(); + return limit; + } + + + + //**************************************************** + //**************************************************** + //** View settings. Used to restore settings + //** when starting and to control how the program + //** behaves. + //**************************************************** + //**************************************************** + + //* Get/Set if we should show a tray icon + public static boolean showTrayIcon() { + settings.beginGroup("General"); + try { + String max = (String) settings.value("showTrayIcon", "false"); + settings.endGroup(); + if (!max.equalsIgnoreCase("true") || !QSystemTrayIcon.isSystemTrayAvailable()) + return false; + else + return true; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("showTrayIcon", false); + settings.endGroup(); + return value; + } + } + public static void setShowTrayIcon(boolean val) { + settings.beginGroup("General"); + if (val) + settings.setValue("showTrayIcon", "true"); + else + settings.setValue("showTrayIcon", "false"); + settings.endGroup(); + } + + // Get/Set window maximized when closed last + public static boolean wasWindowMaximized() { + try { + settings.beginGroup("General"); + String max = (String) settings.value("isMaximized", "true"); + settings.endGroup(); + if (!max.equalsIgnoreCase("true")) + return false; + return true; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("isMaximized", true); + settings.endGroup(); + return value; + } + } + public static void saveWindowMaximized(boolean isMax) { + settings.beginGroup("General"); + if (isMax) + settings.setValue("isMaximized", "true"); + else + settings.setValue("isMaximized", "false"); + settings.endGroup(); + } + + // Get/set currently viewed note Guid + public static String getLastViewedNoteGuid() { + settings.beginGroup("General"); + String guid = (String) settings.value("lastViewedNote", ""); + settings.endGroup(); + return guid; + } + public static void saveCurrentNoteGuid(String guid) { + settings.beginGroup("General"); + if (guid != null) + settings.setValue("lastViewedNote", guid); + else + settings.setValue("lastViewedNote", ""); + settings.endGroup(); + } + + // Get/Set the note column we are sorted on and the order + public static void setSortColumn(int i) { + int view = Global.getListView(); + settings.beginGroup("General"); + if (view == Global.View_List_Wide) + settings.setValue("sortColumn", i); + else + settings.setValue("sortColumn-Narrow", i); + settings.endGroup(); + } + public static int getSortColumn() {; + String key; + if (Global.getListView() == Global.View_List_Wide) + key = "sortColumn"; + else + key = "sortColumn-Narrow"; + + settings.beginGroup("General"); + int order; + try { + String val = settings.value(key, new Integer(0)).toString(); + order = new Integer(val.trim()); + } catch (Exception e) { + try { + order = (Integer)settings.value(key, 0); + } catch (Exception e1) { + order = 0; + } + } + + settings.endGroup(); + return order; + } + public static void setSortOrder(int i) { + int view = Global.getListView(); + settings.beginGroup("General"); + if (view == Global.View_List_Wide) + settings.setValue("sortOrder", i); + else + settings.setValue("sortOrder-Narrow", i); + settings.endGroup(); + } + public static int getSortOrder() { + int view = Global.getListView(); + settings.beginGroup("General"); + String key; + if (view == Global.View_List_Wide) + key = "sortOrder"; + else + key = "sortOrder-Narrow"; + + int order; + try { + String val = settings.value(key, new Integer(0)).toString(); + order = new Integer(val.trim()); + } catch (Exception e) { + try { + order = (Integer)settings.value(key, 0); + } catch (Exception e1) { + order = 0; + } + } + + settings.endGroup(); + return order; + } + + // Should we automatically log in to Evernote when starting? + public static boolean automaticLogin() { + try { + settings.beginGroup("General"); + String text = (String)settings.value("automaticLogin", "false"); + settings.endGroup(); + if (text.equalsIgnoreCase("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("automaticLogin", false); + settings.endGroup(); + return value; + } + } + public static void setAutomaticLogin(boolean val) { + settings.beginGroup("General"); + if (val) + settings.setValue("automaticLogin", "true"); + else + settings.setValue("automaticLogin", "false"); + settings.endGroup(); + } + + // Get/set the Evernote server Url. + public static void setServer(String server) { + settings.beginGroup("General"); + settings.setValue("server", server); + settings.endGroup(); + } + public static String getServer() { + settings.beginGroup("General"); + String text = (String)settings.value("server", "www.evernote.com"); + if (text.equals("www.evernote.com")) { + userStoreUrl = "https://www.evernote.com/edam/user"; + noteStoreUrlBase = "www.evernote.com/edam/note/"; + } else { + userStoreUrl = "https://sandbox.evernote.com/edam/user"; + noteStoreUrlBase = "sandbox.evernote.com/edam/note/"; + } + settings.endGroup(); +// if (isPremium()) + noteStoreUrlBase = "https://" + noteStoreUrlBase; +// else +// noteStoreUrlBase = "http://" + noteStoreUrlBase; + return text; + } + + // Get/Set if we should disable uploads to Evernote + public static boolean disableUploads() { + settings.beginGroup("General"); + try { + String text = (String)settings.value("disableUploads", "false"); + settings.endGroup(); + if (text.equalsIgnoreCase("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("disableUploads", false); + settings.endGroup(); + return value; + } + } + public static void setDisableUploads(boolean val) { + settings.beginGroup("General"); + if (val) + settings.setValue("disableUploads", "true"); + else + settings.setValue("disableUploads", "false"); + settings.endGroup(); + disableUploads = val; + } + + // Should we view PDF documents inline? + public static boolean pdfPreview() { + settings.beginGroup("General"); + try { + String text = (String)settings.value("pdfPreview", "true"); + settings.endGroup(); + if (text.equalsIgnoreCase("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("pdfPreview", true); + settings.endGroup(); + return value; + } + } + public static void setPdfPreview(boolean val) { + settings.beginGroup("General"); + if (val) + settings.setValue("pdfPreview", "true"); + else + settings.setValue("pdfPreview", "false"); + settings.endGroup(); + } + + // When creating a new note, should it inherit tags that are currently selected? + public static boolean newNoteWithSelectedTags() { + settings.beginGroup("General"); + try { + String text = (String)settings.value("newNoteWithSelectedTags", "false"); + settings.endGroup(); + if (text.equalsIgnoreCase("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("newNoteWithSelectedTags", false); + settings.endGroup(); + return value; + } + } + public static void setNewNoteWithSelectedTags(boolean val) { + settings.beginGroup("General"); + if (val) + settings.setValue("newNoteWithSelectedTags", "true"); + else + settings.setValue("newNoteWithSelectedTags", "false"); + settings.endGroup(); + } + + // Minimum weight for text OCRed from Evernote. Anything below this + // Won't be shown to the user when they search + public static void setRecognitionWeight(int len) { + settings.beginGroup("General"); + settings.setValue("recognitionWeight", len); + settings.endGroup(); + } + public static int getRecognitionWeight() { + settings.beginGroup("General"); + Integer len; + try { - len = (Integer)settings.value("recognitionWeight", 30); ++ len = (Integer)settings.value("recognitionWeight", 30); + } catch (Exception e) { - len = 80; ++ len = 80; + } + settings.endGroup(); + return len; + } + + // get/set current debug message level + public static String getMessageLevel() { + settings.beginGroup("Debug"); + String text = (String)settings.value("messageLevel", "Low"); + settings.endGroup(); + setMessageLevel(text); + return text; + } + public static void setDateFormat(String format) { + settings.beginGroup("General"); + settings.setValue("dateFormat", format); + settings.endGroup(); + } + + // Get/Set user date/time formats + public static String getDateFormat() { + settings.beginGroup("General"); + String text = (String)settings.value("dateFormat", "MM/dd/yyyy"); + settings.endGroup(); + return text; + } + public static void setTimeFormat(String format) { + settings.beginGroup("General"); + settings.setValue("timeFormat", format); + settings.endGroup(); + } + public static String getTimeFormat() { + settings.beginGroup("General"); + String text = (String)settings.value("timeFormat", "HH:mm:ss"); + settings.endGroup(); + return text; + } + + // How often should we sync with Evernote? + public static String getSyncInterval() { + settings.beginGroup("General"); + String text = (String)settings.value("syncInterval", "15 minutes"); + settings.endGroup(); + return text; + } + public static void setSyncInterval(String format) { + settings.beginGroup("General"); + settings.setValue("syncInterval", format); + settings.endGroup(); + } + + // Get/Set the width of columns and their position for the + // next start. + public static void setColumnWidth(String col, int width) { + if (Global.getListView() == Global.View_List_Wide) + settings.beginGroup("ColumnWidths"); + else + settings.beginGroup("ColumnWidths-Narrow"); + settings.setValue(col, width); + settings.endGroup(); + } + public static int getColumnWidth(String col) { + int view = Global.getListView(); + if (view == Global.View_List_Wide) + settings.beginGroup("ColumnWidths"); + else + settings.beginGroup("ColumnWidths-Narrow"); + Integer width; + try { + String val = (String)settings.value(col, "0"); + width = new Integer(val.trim()); + } catch (Exception e) { + try { + width = (Integer)settings.value(col, 0); + } catch (Exception e1) { + width = 0; + } + } + settings.endGroup(); + return width; + } + public static void setColumnPosition(String col, int width) { + if (Global.getListView() == Global.View_List_Wide) + settings.beginGroup("ColumnPosition"); + else + settings.beginGroup("ColumnPosition-Narrow"); + settings.setValue(col, width); + settings.endGroup(); + } + public static int getColumnPosition(String col) { + if (Global.getListView() == Global.View_List_Wide) + settings.beginGroup("ColumnPosition"); + else + settings.beginGroup("ColumnPosition-Narrow"); + Integer width; + try { + String val = (String)settings.value(col, "-1"); + width = new Integer(val.trim()); + } catch (Exception e) { + try { + width = (Integer)settings.value(col, 0); + } catch (Exception e1) { + width = 0; + } + } + settings.endGroup(); + return width; + } + + // Ping the user when they try to delete or just do it. + public static boolean verifyDelete() { + settings.beginGroup("General"); + try { + String text = (String)settings.value("verifyDelete", "true"); + settings.endGroup(); + if (text.equalsIgnoreCase("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("verifyDelete", true); + settings.endGroup(); + return value; + } + } + public static void setVerifyDelete(boolean val) { + settings.beginGroup("General"); + if (val) + settings.setValue("verifyDelete", "true"); + else + settings.setValue("verifyDelete", "false"); + settings.endGroup(); + } + + // Should it start minimized? + public static boolean startMinimized() { + settings.beginGroup("General"); + try { + String text = (String)settings.value("startMinimized", "false"); + settings.endGroup(); + if (text.equalsIgnoreCase("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("startMinimized", false); + settings.endGroup(); + return value; + } + } + public static void setStartMinimized(boolean val) { + settings.beginGroup("General"); + if (val) + settings.setValue("startMinimized", "true"); + else + settings.setValue("startMinimized", "false"); + settings.endGroup(); + } + + // Should we upload the content of any deleted notes + public static boolean synchronizeDeletedContent() { + settings.beginGroup("General"); + try { + String text = (String)settings.value("syncDeletedContent", "false"); + settings.endGroup(); + if (text.equalsIgnoreCase("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("syncDeletedContent", false); + settings.endGroup(); + return value; + } + } + public static void setSynchronizeDeletedContent(boolean val) { + settings.beginGroup("General"); + if (val) + settings.setValue("syncDeletedContent", "true"); + else + settings.setValue("syncDeletedContent", "false"); + settings.endGroup(); + } + + // Is a section of the window visible? Used to hide things people don't + // want to see. + public static boolean isWindowVisible(String window) { + settings.beginGroup("WindowsVisible"); + try { + String defaultValue = "true"; + if (window.equalsIgnoreCase("noteInformation")) + defaultValue = "false"; + String text = (String)settings.value(window, defaultValue); + settings.endGroup(); + if (text.equalsIgnoreCase("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + boolean defaultValue = true; + if (window.equalsIgnoreCase("noteInformation")) + defaultValue = false; + Boolean value = (Boolean) settings.value("showTrayIcon", defaultValue); + settings.endGroup(); + return value; + } + } + public static void saveWindowVisible(String window, boolean val) { + settings.beginGroup("WindowsVisible"); + if (val) + settings.setValue(window, "true"); + else + settings.setValue(window, "false"); + settings.endGroup(); + } + + // Is a list in the column in the note list visible? + public static boolean isColumnVisible(String window) { + String defaultValue = "true"; + int view = Global.getListView(); + if (Global.getListView() == Global.View_List_Wide) + settings.beginGroup("ColumnsVisible"); + else + settings.beginGroup("ColumnsVisible-Narrow"); + if (window.equalsIgnoreCase("thumbnail") && view == Global.View_List_Wide) + defaultValue = "false"; + if (window.equalsIgnoreCase("thumbnail")) + defaultValue = "false"; + if (window.equalsIgnoreCase("Guid")) + defaultValue = "false"; + try { + String text = (String)settings.value(window, defaultValue); + settings.endGroup(); + if (text.equalsIgnoreCase("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + boolean defBool = false; + if (window.equalsIgnoreCase("true")) + defBool = true; + else + defBool = false; + Boolean value = (Boolean) settings.value(window, defBool); + settings.endGroup(); + return value; + } + } + public static void saveColumnVisible(String column, boolean val) { + if (Global.getListView() == Global.View_List_Wide) + settings.beginGroup("ColumnsVisible"); + else + settings.beginGroup("ColumnsVisible-Narrow"); + if (val) + settings.setValue(column, "true"); + else + settings.setValue(column, "false"); + settings.endGroup(); + } + + // Is a particular editor button visible? + public static boolean isEditorButtonVisible(String window) { + settings.beginGroup("EditorButtonsVisible"); + try { + String text = (String)settings.value(window, "true"); + settings.endGroup(); + if (text.equalsIgnoreCase("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value(window, true); + settings.endGroup(); + return value; + } + } + public static void saveEditorButtonsVisible(String column, boolean val) { + settings.beginGroup("EditorButtonsVisible"); + if (val) + settings.setValue(column, "true"); + else + settings.setValue(column, "false"); + settings.endGroup(); + } + + // Should the test fixes be enabled + public static boolean enableCarriageReturnFix() { + try { + settings.beginGroup("Debug"); + String text = (String)settings.value("enableCarriageReturnFix", "false"); + settings.endGroup(); + if (text.equalsIgnoreCase("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("enableCarriageReturnFix", false); + settings.endGroup(); + return value; + } + } + public static void saveCarriageReturnFix(boolean val) { + settings.beginGroup("Debug"); + if (val) + settings.setValue("enableCarriageReturnFix", "true"); + else + settings.setValue("enableCarriageReturnFix", "false"); + settings.endGroup(); + } + public static boolean enableHtmlEntitiesFix() { + try { + settings.beginGroup("Debug"); + String text = (String)settings.value("enableHtmlEntitiesFix", "false"); + settings.endGroup(); + if (text.equalsIgnoreCase("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("enableHtmlEntitiesFix", false); + settings.endGroup(); + return value; + } + } + public static void saveHtmlEntitiesFix(boolean val) { + settings.beginGroup("Debug"); + if (val) + settings.setValue("enableHtmlEntitiesFix", "true"); + else + settings.setValue("enableHtmlEntitiesFix", "false"); + settings.endGroup(); + } + +// public static void setIndexThreads(int val) { +// settings.beginGroup("General"); +// settings.setValue("indexThreads", val); +// settings.endGroup(); +// } +// public static int getIndexThreads() { +// settings.beginGroup("General"); +// Integer threads; +// try { +// String val = (String)settings.value("indexThreads", "1"); +// threads = new Integer(val.trim()); +// } catch (Exception e) { +// try { +// threads = (Integer)settings.value("indexThreads", 1); +// } catch (Exception e1) { +// threads = 1; +// } +// } +// settings.endGroup(); +// threads = 1; +// return threads; + + // Get/Set text zoom factor +// } + public static void setZoomFactor(double val) { + settings.beginGroup("General"); + settings.setValue("zoomFactor", val); + settings.endGroup(); + } + public static double getZoomFactor() { + settings.beginGroup("General"); + Double threads; + try { + String val = (String)settings.value("zoomFactor", "1.0"); + threads = new Double(val.trim()); + } catch (Exception e) { + try { + threads = (Double)settings.value("zoomFactor", 1.0); + } catch (Exception e1) { + threads = new Double(1); + } + } + settings.endGroup(); + return threads; + } + public static void setTextSizeMultiplier(double val) { + settings.beginGroup("General"); + settings.setValue("textMultiplier", val); + settings.endGroup(); + } + public static double getTextSizeMultiplier() { + settings.beginGroup("General"); + Double threads; + try { + String val = (String)settings.value("textMultiplier", "1"); + threads = new Double(val.trim()); + } catch (Exception e) { + try { + threads = (Double)settings.value("textMultiplier", 1); + } catch (Exception e1) { + threads = new Double(1); + } + } + settings.endGroup(); + return threads; + } + + + // Should we mimic Evernote and restrict the notebooks selected? + public static boolean getMimicEvernoteInterface() { + settings.beginGroup("General"); + try { + String text = (String)settings.value("mimicEvernoteInterface", "true"); + settings.endGroup(); + if (text.equalsIgnoreCase("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("mimicEvernoteInterface", true); + settings.endGroup(); + return value; + } + } + public static void setMimicEvernoteInterface(boolean value) { + settings.beginGroup("General"); + if (value) + settings.setValue("mimicEvernoteInterface", "true"); + else + settings.setValue("mimicEvernoteInterface", "false"); + settings.endGroup(); + } + + + // Synchronize with Evernote when closing? + public static boolean synchronizeOnClose() { + settings.beginGroup("General"); + try { + String text = (String)settings.value("synchronizeOnClose", "false"); + settings.endGroup(); + if (text.equalsIgnoreCase("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("synchronizeOnClose", false); + settings.endGroup(); + return value; + } + } + public static void setSynchronizeOnClose(boolean val) { + settings.beginGroup("General"); + if (val) + settings.setValue("synchronizeOnClose", "true"); + else + settings.setValue("synchronizeOnClose", "false"); + settings.endGroup(); + } + + // Get/set the database version. Not really used any more, but kept + // for compatibility. + public static void setDatabaseVersion(String version) { + settings.beginGroup("General"); + settings.setValue("databaseVersion", version); + settings.endGroup(); + } + public static String getDatabaseVersion() { + settings.beginGroup("General"); + String val = (String)settings.value("databaseVersion", "0.70"); + settings.endGroup(); + return val; + } + + // Get the URL (full path) of the main database + public static String getDatabaseUrl() { + settings.beginGroup("General"); + String val = (String)settings.value("DatabaseURL", ""); + settings.endGroup(); + if (val.equals("")) + val = "jdbc:h2:"+Global.getFileManager().getDbDirPath(Global.databaseName); + return val; + } + + // get the url (full path) of the searchable word database + public static String getIndexDatabaseUrl() { + settings.beginGroup("General"); + String val = (String)settings.value("IndexDatabaseURL", ""); + settings.endGroup(); + if (val.equals("")) + val = "jdbc:h2:"+Global.getFileManager().getDbDirPath(Global.indexDatabaseName); + return val; + } + + // Get the url (full path) of the attachment database + public static String getResourceDatabaseUrl() { + settings.beginGroup("General"); + String val = (String)settings.value("ResourceDatabaseURL", ""); + settings.endGroup(); + if (val.equals("")) + val = "jdbc:h2:"+Global.getFileManager().getDbDirPath(Global.resourceDatabaseName); + return val; + } + + // 操作履歴データベースのURL(フルパス)をゲット + public static String getBehaviorDatabaseUrl() { + settings.beginGroup("General"); + String val = (String) settings.value("BehaviorDatabaseURL", ""); + settings.endGroup(); + if (val.equals("")) + val = "jdbc:h2:" + + Global.getFileManager().getDbDirPath( + Global.behaviorDatabaseName); + return val; + } + + public static void setDatabaseUrl(String value) { + settings.beginGroup("General"); + settings.setValue("DatabaseURL", value); + settings.endGroup(); + } + public static void setIndexDatabaseUrl(String value) { + settings.beginGroup("General"); + settings.setValue("IndexDatabaseURL", value); + settings.endGroup(); + } + public static void setResourceDatabaseUrl(String value) { + settings.beginGroup("General"); + settings.setValue("ResourceDatabaseURL", value); + settings.endGroup(); + } + + public static void setBehaviorDatabaseUrl(String value) { + settings.beginGroup("General"); + settings.setValue("BehaviorDatabaseURL", value); + settings.endGroup(); + } + + public static String getDatabaseUserid() { + settings.beginGroup("General"); + String val = (String)settings.value("databaseUserid", ""); + settings.endGroup(); + return val; + } + public static String getDatabaseUserPassword() { + settings.beginGroup("General"); + String val = (String)settings.value("databaseUserPassword", ""); + settings.endGroup(); + return val; + } + + // get/Set the style sheet and the palette to control the look & feel + public static void setStyle(String style) { + settings.beginGroup("General"); + settings.setValue("style", style); + settings.endGroup(); + } + public static String getStyle() { + settings.beginGroup("General"); + String val = (String)settings.value("style", "Cleanlooks"); + settings.endGroup(); + return val; + } + public static boolean useStandardPalette() { + settings.beginGroup("General"); + try { + String text = (String)settings.value("standardPalette", "true"); + settings.endGroup(); + if (text.equalsIgnoreCase("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("standardPalette", true); + settings.endGroup(); + return value; + } + } + public static void setStandardPalette(boolean val) { + settings.beginGroup("General"); + if (val) + settings.setValue("standardPalette", "true"); + else + settings.setValue("standardPalette", "false"); + settings.endGroup(); + } + + // Set the amount of time to wait between indexing + // Get/Set interval when the index thread wakes up. + public static void setIndexThreadSleepInterval(int sleep) { + settings.beginGroup("General"); + settings.setValue("IndexThreadSleepInterval", sleep); + settings.endGroup(); + } + public static int getIndexThreadSleepInterval() { + settings.beginGroup("General"); + Integer sleep; + try { + String val = (String)settings.value("IndexThreadSleepInterval", "300"); + sleep = new Integer(val.trim()); + } catch (Exception e) { + try { + sleep = (Integer)settings.value("IndexThreadSleepInterval", 0); + } catch (Exception e1) { + sleep = 300; + } + } + settings.endGroup(); + return sleep; + } + + + // Get/Set a window state for later restoring + public static void saveState(String name, QByteArray state) { + int view = Global.getListView(); + if (view == Global.View_List_Narrow) + name = name +"Narrow"; + settings.beginGroup("SaveState"); + settings.setValue(name, state); + settings.endGroup(); + } + + public static QByteArray restoreState(String name) { + int view = Global.getListView(); + if (view == Global.View_List_Narrow) + name = name +"Narrow"; + settings.beginGroup("SaveState"); + QByteArray state = (QByteArray)settings.value(name); + settings.endGroup(); + return state; + } + public static void saveGeometry(String name, QByteArray state) { + int view = Global.getListView(); + if (view == Global.View_List_Narrow) + settings.beginGroup("SaveGeometryNarrow"); + else + settings.beginGroup("SaveGeometry"); + settings.setValue(name, state); + settings.endGroup(); + } + + public static QByteArray restoreGeometry(String name) { + int view = Global.getListView(); + if (view == Global.View_List_Narrow) + settings.beginGroup("SaveGeometryNarrow"); + else + settings.beginGroup("SaveGeometry"); + QByteArray state = (QByteArray)settings.value(name); + settings.endGroup(); + return state; + } + + + // Set how often to do an automatic save + public static void setAutoSaveInterval(int interval) { + settings.beginGroup("General"); + settings.setValue("autoSaveInterval", interval); + settings.endGroup(); + } + public static int getAutoSaveInterval() { + settings.beginGroup("General"); + Integer value; + try { + String val = (String)settings.value("autoSaveInterval", "5"); + value = new Integer(val.trim()); + } catch (Exception e) { + try { + value = (Integer)settings.value("autoSaveInterval", 5); + } catch (Exception e1) { + value = 5; + } + } + settings.endGroup(); + return value; + } + + // Add an invalid attribute & element to the database so we don't bother parsing it in the future + // These values we automatically remove from any note. + // Add invalid attributes + public static void addInvalidAttribute(String element, String attribute) { + + List attributes = invalidAttributes.get(element); + if (attributes != null) { + for (int i=0; i attributeList; + if (!invalidAttributes.containsKey(element)) { + attributeList = new ArrayList(); + attributeList.add(attribute); + invalidAttributes.put(element, attributeList); + } + else { + attributeList = invalidAttributes.get(element); + attributeList.add(attribute); + invalidAttributes.put(element,attributeList); + } + } + + // Add invalid attributes + public static void addInvalidElement(String element) { + for (int i=0; i>> 4) & 0x0F; + int two_halfs = 0; + do { + if ((0 <= halfbyte) && (halfbyte <= 9)) + buf.append((char) ('0' + halfbyte)); + else + buf.append((char) ('a' + (halfbyte - 10))); + halfbyte = element & 0x0F; + } while(two_halfs++ < 1); + } + return buf.toString(); + } + + + // Get/Set spelling settings + public static boolean getSpellSetting(String value) { + settings.beginGroup("Spell"); + String text = (String)settings.value(value, ""); + settings.endGroup(); + if (text.equalsIgnoreCase("true")) + return true; + if (text.equalsIgnoreCase("false")) + return false; + if (value.equalsIgnoreCase(Configuration.SPELL_IGNOREDIGITWORDS)) + return true; + if (value.equalsIgnoreCase(Configuration.SPELL_IGNOREINTERNETADDRESSES)) + return true; + if (value.equalsIgnoreCase(Configuration.SPELL_IGNOREUPPERCASE)) + return true; + if (value.equalsIgnoreCase(Configuration.SPELL_IGNORESENTENCECAPITALIZATION)) + return true; + return false; + } + public static void setSpellSetting(String setting, boolean val) { + settings.beginGroup("Spell"); + if (val) + settings.setValue(setting, "true"); + else + settings.setValue(setting, "false"); + settings.endGroup(); + } + + // Get/Set how we should display tags (color them, hide unused, or do nothing) + // What to do with inactive tags? + public static String tagBehavior() { + settings.beginGroup("General"); + String text = (String)settings.value("tagBehavior", "DoNothing"); + settings.endGroup(); + return text; + } + // What to do with inactive tags? + public static void setTagBehavior(String value) { + settings.beginGroup("General"); + settings.setValue("tagBehavior", value); + settings.endGroup(); + } + + + // Should the toolbar be visible? + public static boolean isToolbarButtonVisible(String window, Boolean val) { + settings.beginGroup("ToolbarButtonsVisible"); + try { + String text = (String)settings.value(window, val.toString()); + settings.endGroup(); + if (text.equalsIgnoreCase("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value(window, val); + settings.endGroup(); + return value; + } + } + public static void saveToolbarButtonsVisible(String column, boolean val) { + settings.beginGroup("ToolbarButtonsVisible"); + if (val) + settings.setValue(column, "true"); + else + settings.setValue(column, "false"); + settings.endGroup(); + } + + // Are thumbnails enabled? + + public static boolean enableThumbnails() { + settings.beginGroup("Debug"); + try { + String text = (String)settings.value("thumbnails", "true"); + settings.endGroup(); + if (text.equalsIgnoreCase("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("thumbnails", true); + settings.endGroup(); + return value; + } + } + public static void setEnableThumbnails(boolean val) { + settings.beginGroup("Debug"); + if (val) + settings.setValue("thumbnails", "true"); + else + settings.setValue("thumbnails", "false"); + settings.endGroup(); + } + + // Trace used for performance tuning. Not normally used in production. + // Print date/time. Used mainly for performance tracing + public static void trace(boolean resetInterval) { + String fmt = "MM/dd/yy HH:mm:ss.SSSSSS"; + String dateTimeFormat = new String(fmt); + SimpleDateFormat simple = new SimpleDateFormat(dateTimeFormat); + Calendar cal = Calendar.getInstance(); + if (intervalTraceTime == null) + intervalTraceTime = Calendar.getInstance(); + if (startTraceTime == null) + startTraceTime = Calendar.getInstance(); + + float interval = (cal.getTimeInMillis() - intervalTraceTime.getTimeInMillis()); + float total = (cal.getTimeInMillis() - startTraceTime.getTimeInMillis()); + +// if (interval > 00.0) { + StackTraceElement[] exceptions = Thread.currentThread().getStackTrace(); + System.out.println("------------------------------------------"); + + System.out.println("Date/Time " +simple.format(cal.getTime())); + System.out.format("Interval Time: %-10.6f%n", interval); + System.out.format("Total Time: %-10.6f%n", total); + for (int i=2; i<5 && i", "")); + zoom = 2; + if (text.length() < 500) + zoom = 2; + if (text.length() < 250) + zoom = 3; + if (text.length() < 100) + zoom = 4; + if (text.length() < 50) + zoom = 5; + if (text.length() < 10) + zoom = 6; + } + } + return zoom; + } + + //********************** + //* List View settings + //********************** + public static void setListView(int view) { + settings.beginGroup("General"); + settings.setValue("listView", view); + settings.endGroup(); + } + public static int getListView() { + settings.beginGroup("General"); + Integer value; + try { + String val = (String)settings.value("listView", View_List_Wide); + value = new Integer(val.trim()); + } catch (Exception e) { + try { + value = (Integer)settings.value("listView", View_List_Wide); + } catch (Exception e1) { + value = View_List_Wide; + } + } + settings.endGroup(); + return value; + } + + + + //******************* + // Font Settings + //******************* + public static boolean overrideDefaultFont() { + settings.beginGroup("Font"); + try { + String text = (String)settings.value("overrideFont", "false"); + settings.endGroup(); + if (text.equalsIgnoreCase("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("overrideFont", false); + settings.endGroup(); + return value; + } + + } + + //**************************************************** + // Get/Set the default font settings for a new note + //**************************************************** + public static void setOverrideDefaultFont(boolean value) { + settings.beginGroup("Font"); + settings.setValue("overrideFont", value); + settings.endGroup(); + } + public static String getDefaultFont() { + settings.beginGroup("Font"); + String val = (String)settings.value("font", ""); + settings.endGroup(); + return val; + } + public static void setDefaultFont(String value) { + settings.beginGroup("Font"); + settings.setValue("font", value); + settings.endGroup(); + } + public static String getDefaultFontSize() { + settings.beginGroup("Font"); + String val = (String)settings.value("fontSize", ""); + settings.endGroup(); + return val; + } + public static void setDefaultFontSize(String value) { + settings.beginGroup("Font"); + settings.setValue("fontSize", value); + settings.endGroup(); + } + + + //******************************************* + // Override the close & minimize instead. + //******************************************* + public static boolean minimizeOnClose() { + settings.beginGroup("General"); + try { + String text = (String)settings.value("minimizeOnClose", "false"); + settings.endGroup(); + if (text.equalsIgnoreCase("true") && QSystemTrayIcon.isSystemTrayAvailable()) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("minimizeOnClose", false); + settings.endGroup(); + return value; + } + } + public static void setMinimizeOnClose(boolean value) { + settings.beginGroup("General"); + settings.setValue("minimizeOnClose", value); + settings.endGroup(); + } + + //********************************* + // Check version information + //********************************* + public static boolean checkVersionUpgrade() { + settings.beginGroup("Upgrade"); + try { + String text = (String)settings.value("checkForUpdates", "true"); + settings.endGroup(); + if (text.equalsIgnoreCase("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("checkForUpdates", true); + settings.endGroup(); + return value; + } + } + public static void setCheckVersionUpgrade(boolean value) { + settings.beginGroup("Upgrade"); + settings.setValue("checkForUpdates", value); + settings.endGroup(); + } + public static String getUpdatesAvailableUrl() { + settings.beginGroup("Upgrade"); + String text = (String)settings.value("avialableUrl", "http://puma.cis.ibaraki.ac.jp/products/neighbornote/develop/versions.txt"); + settings.endGroup(); + return text; + } + public static String getUpdateAnnounceUrl() { + settings.beginGroup("Upgrade"); + String text = (String)settings.value("announceUrl", "http://puma.cis.ibaraki.ac.jp/products/neighbornote/develop/upgrade.html"); + settings.endGroup(); + return text; + } + public static String getUpdateDownloadUrl() { + settings.beginGroup("Upgrade"); + String text = (String)settings.value("downloadUrl", "http://puma.cis.ibaraki.ac.jp/products/neighbornote/download.html"); + settings.endGroup(); + return text; + } + + //******************* + // Index settings + //******************* + // Set/Get if we should index the text of a note + public static boolean indexNoteBody() { + settings.beginGroup("Index"); + try { + String value = (String)settings.value("indexNoteBody", "true"); + settings.endGroup(); + if (value.equals("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("indexNoteBody", true); + settings.endGroup(); + return value; + } + } + public static void setIndexNoteTitle(boolean value) { + settings.beginGroup("Index"); + settings.setValue("indexNoteTitle", value); + settings.endGroup(); + } + // Set/Get if we should index the title of a note + public static boolean indexNoteTitle() { + settings.beginGroup("Index"); + try { + String value = (String)settings.value("indexNoteTitle", "true"); + settings.endGroup(); + if (value.equals("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("indexNoteTitle", true); + settings.endGroup(); + return value; + } + } + public static void setIndexNoteBody(boolean value) { + settings.beginGroup("Index"); + settings.setValue("indexNoteBody", value); + settings.endGroup(); + } + // Set/Get if we should index any attachments + public static boolean indexAttachmentsLocally() { + settings.beginGroup("Index"); + try { + String value = (String)settings.value("indexAttachmentsLocally", "true"); + settings.endGroup(); + if (value.equals("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("indexAttachmentsLocally", true); + settings.endGroup(); + return value; + } + } + public static void setIndexImageRecognition(boolean value) { + settings.beginGroup("Index"); + settings.setValue("indexImageRecognition", value); + settings.endGroup(); + } + public static boolean indexImageRecognition() { + settings.beginGroup("Index"); + try { + String value = (String)settings.value("indexImageRecognition", "true"); + settings.endGroup(); + if (value.equals("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("indexImageRecognition", true); + settings.endGroup(); + return value; + } + } + public static void setIndexAttachmentsLocally(boolean value) { + settings.beginGroup("Index"); + settings.setValue("indexAttachmentsLocally", value); + settings.endGroup(); + } + // Get/Set characters that shouldn't be removed from a word +// public static String getSpecialIndexCharacters() { +// settings.beginGroup("Index"); +// String text = (String)settings.value("specialCharacters", ""); +// settings.endGroup(); +// return text; +// } +// public static void setSpecialIndexCharacters(String value) { +// settings.beginGroup("Index"); +// settings.setValue("specialCharacters", value); +// settings.endGroup(); +// databaseCache = value; +// } + + //***************************************************************************** + // Control how tag selection behaves (should they be "and" or "or" selections + //***************************************************************************** + public static boolean anyTagSelectionMatch() { + settings.beginGroup("General"); + try { + String value = (String)settings.value("anyTagSelectionMatch", "false"); + settings.endGroup(); + if (value.equals("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("anyTagSelectionMatch", false); + settings.endGroup(); + return value; + } + } + public static void setAnyTagSelectionMatch(boolean value) { + settings.beginGroup("General"); + settings.setValue("anyTagSelectionMatch", value); + settings.endGroup(); + } + + //***************************************************************************** + // Control if a user receives a warning when trying to create a note-to-note link + // when the DB is not synchronized. + //***************************************************************************** + public static boolean bypassSynchronizationWarning() { + settings.beginGroup("User"); + try { + String value = (String)settings.value("bypassSynchronizationWarning", "false"); + settings.endGroup(); + if (value.equals("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("bypassSynchronizationWarning", false); + settings.endGroup(); + return value; + } + } + public static void setBypassSynchronizationWarning(boolean value) { + settings.beginGroup("User"); + settings.setValue("bypassSynchronizationWarning", value); + settings.endGroup(); + } + + + //*********************** + //* Database cache size + //*********************** + public static String getDatabaseCacheSize() { + settings.beginGroup("Debug"); + String text = (String)settings.value("databaseCache", "16384"); + settings.endGroup(); + return text; + } + public static void setDatabaseCache(String value) { + settings.beginGroup("Debug"); + settings.setValue("databaseCache", value); + settings.endGroup(); + databaseCache = value; + } + + + // This is used to copy a class since Java's normal deep copy is wacked + public static Object deepCopy(Object oldObj) + { + ObjectOutputStream oos = null; + ObjectInputStream ois = null; + try + { + ByteArrayOutputStream bos = + new ByteArrayOutputStream(); // A + oos = new ObjectOutputStream(bos); // B + // serialize and pass the object + oos.writeObject(oldObj); // C + oos.flush(); // D + ByteArrayInputStream bin = + new ByteArrayInputStream(bos.toByteArray()); // E + ois = new ObjectInputStream(bin); // F + // return the new object + return ois.readObject(); // G + } + catch(Exception e) + { + Global.logger.log(logger.LOW, "Exception in ObjectCloner = " + e); + } + try { + oos.close(); + ois.close(); + } catch (IOException e) { + Global.logger.log(logger.LOW, "Exception in ObjectCloner = " + e); + e.printStackTrace(); + } + + return null; + } + + // If we should automatically select the children of any tag + public static boolean includeTagChildren() { + settings.beginGroup("General"); + try { + String value = (String)settings.value("includeTagChildren", "false"); + settings.endGroup(); + if (value.equals("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("includeTagChildren", false); + settings.endGroup(); + return value; + } + + } + public static void setIncludeTagChildren(boolean value) { + settings.beginGroup("General"); + settings.setValue("includeTagChildren", value); + settings.endGroup(); + } + + // If we should automatically wildcard searches +// public static boolean automaticWildcardSearches() { +// settings.beginGroup("General"); +// try { +// String value = (String)settings.value("automaticWildcard", "false"); +// settings.endGroup(); +// if (value.equals("true")) +// return true; +// else +// return false; +// } catch (java.lang.ClassCastException e) { +// Boolean value = (Boolean) settings.value("automaticWildcard", false); +// settings.endGroup(); +// return value; +// } +// +// } +// public static void setAutomaticWildcardSearches(boolean value) { +// settings.beginGroup("General"); +// settings.setValue("automaticWildcard", value); +// settings.endGroup(); +// } + + // If we should automatically select the children of any tag + public static boolean displayRightToLeft() { + settings.beginGroup("General"); + try { + String value = (String)settings.value("displayRightToLeft", "false"); + settings.endGroup(); + if (value.equals("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("displayRightToLeft", false); + settings.endGroup(); + return value; + } + + } + public static void setDisplayRightToLeft(boolean value) { + settings.beginGroup("General"); + settings.setValue("displayRightToLeft", value); + settings.endGroup(); + } + + + //*********************** + //* Startup Notebook + //*********************** + public static String getStartupNotebook() { + settings.beginGroup("General"); + String text = (String)settings.value("startupNotebook", ""); + settings.endGroup(); + return text; + } + public static void setStartupNotebook(String value) { + settings.beginGroup("General"); + settings.setValue("startupNotebook", value); + settings.endGroup(); + databaseCache = value; + } + + // 複数ノート同時閲覧操作に対する重み付け + public static void setBrowseWeight(int weight) { + settings.beginGroup("RensoNoteList"); + settings.setValue("browseWeight", weight); + settings.endGroup(); + } + public static int getBrowseWeight() { + settings.beginGroup("RensoNoteList"); + Integer value; + try { + String val = (String)settings.value("browseWeight", 1); + value = new Integer(val.trim()); + } catch (Exception e) { + try { + value = (Integer)settings.value("browseWeight", 1); + } catch (Exception e1) { + value = 1; + } + } + settings.endGroup(); + return value; + } + + // ノート内容のコピー&ペースト操作に対する重み付け + public static void setCopyPasteWeight(int weight) { + settings.beginGroup("RensoNoteList"); + settings.setValue("copyPasteWeight", weight); + settings.endGroup(); + } + public static int getCopyPasteWeight() { + settings.beginGroup("RensoNoteList"); + Integer value; + try { + String val = (String)settings.value("copyPasteWeight", 3); + value = new Integer(val.trim()); + } catch (Exception e) { + try { + value = (Integer)settings.value("copyPasteWeight", 3); + } catch (Exception e1) { + value = 3; + } + } + settings.endGroup(); + return value; + } + + // 新規ノート追加操作に対する重み付け + public static void setAddNewNoteWeight(int weight) { + settings.beginGroup("RensoNoteList"); + settings.setValue("addNewNoteWeight", weight); + settings.endGroup(); + } + public static int getAddNewNoteWeight() { + settings.beginGroup("RensoNoteList"); + Integer value; + try { + String val = (String)settings.value("addNewNoteWeight", 3); + value = new Integer(val.trim()); + } catch (Exception e) { + try { + value = (Integer)settings.value("addNewNoteWeight", 3); + } catch (Exception e1) { + value = 1; + } + } + settings.endGroup(); + return value; + } + + // 連想ノートクリック操作に対する重み付け + public static void setRensoItemClickWeight(int weight) { + settings.beginGroup("RensoNoteList"); + settings.setValue("rensoItemClickWeight", weight); + settings.endGroup(); + } + public static int getRensoItemClickWeight() { + settings.beginGroup("RensoNoteList"); + Integer value; + try { + String val = (String)settings.value("rensoItemClickWeight", 10); + value = new Integer(val.trim()); + } catch (Exception e) { + try { + value = (Integer)settings.value("rensoItemClickWeight", 10); + } catch (Exception e1) { + value = 10; + } + } + settings.endGroup(); + return value; + } + + // タグ付け操作に対する重み付け + public static void setSameTagWeight(int weight) { + settings.beginGroup("RensoNoteList"); + settings.setValue("sameTagWeight", weight); + settings.endGroup(); + } + public static int getSameTagWeight() { + settings.beginGroup("RensoNoteList"); + Integer value; + try { + String val = (String)settings.value("sameTagWeight", 2); + value = new Integer(val.trim()); + } catch (Exception e) { + try { + value = (Integer)settings.value("sameTagWeight", 2); + } catch (Exception e1) { + value = 2; + } + } + settings.endGroup(); + return value; + } + + // ノートブック変更操作に対する重み付け + public static void setSameNotebookWeight(int weight) { + settings.beginGroup("RensoNoteList"); + settings.setValue("sameNotebookWeight", weight); + settings.endGroup(); + } + public static int getSameNotebookWeight() { + settings.beginGroup("RensoNoteList"); + Integer value; + try { + String val = (String)settings.value("sameNotebookWeight", 2); + value = new Integer(val.trim()); + } catch (Exception e) { + try { + value = (Integer)settings.value("sameNotebookWeight", 2); + } catch (Exception e1) { + value = 2; + } + } + settings.endGroup(); + return value; + } + + // Evernote関連ノート機能統合に対する重み付け + public static void setENRelatedNotesWeight(int weight) { + settings.beginGroup("RensoNoteList"); + settings.setValue("enRelatedNotesWeight", weight); + settings.endGroup(); + } + public static int getENRelatedNotesWeight() { + settings.beginGroup("RensoNoteList"); + Integer value; + try { + String val = (String)settings.value("enRelatedNotesWeight", 5); + value = new Integer(val.trim()); + } catch (Exception e) { + try { + value = (Integer)settings.value("enRelatedNotesWeight", 5); + } catch (Exception e1) { + value = 10; + } + } + settings.endGroup(); + return value; + } + + //******************* + // ノートのマージ・複製の関連ノートリストへの適用 + //******************* + public static void setMergeRensoNote(boolean value) { + settings.beginGroup("RensoNoteList"); + settings.setValue("mergeRensoNoteList", value); + settings.endGroup(); + } + + public static boolean getMergeRensoNote() { + settings.beginGroup("RensoNoteList"); + try { + String value = (String)settings.value("mergeRensoNoteList", "true"); + settings.endGroup(); + if (value.equals("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("mergeRensoNoteList", true); + settings.endGroup(); + return value; + } + } + + public static void setDuplicateRensoNote(boolean value) { + settings.beginGroup("RensoNoteList"); + settings.setValue("duplicateRensoNoteList", value); + settings.endGroup(); + } + + public static boolean getDuplicateRensoNote() { + settings.beginGroup("RensoNoteList"); + try { + String value = (String)settings.value("duplicateRensoNoteList", "true"); + settings.endGroup(); + if (value.equals("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("duplicateRensoNoteList", true); + settings.endGroup(); + return value; + } + } + + // 連想ノートリストからノートを除外するときに確認メッセージを表示するかどうか + public static boolean verifyExclude() { + settings.beginGroup("RensoNoteList"); + try { + String text = (String)settings.value("verifyExclude", "true"); + settings.endGroup(); + if (text.equalsIgnoreCase("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("verifyExclude", true); + settings.endGroup(); + return value; + } + } + + public static void setVerifyExclude(boolean val) { + settings.beginGroup("RensoNoteList"); + if (val) + settings.setValue("verifyExclude", "true"); + else + settings.setValue("verifyExclude", "false"); + settings.endGroup(); + } + + // 連想ノートリスト最大表示アイテム数 + public static void setRensoListItemMaximum(int maximum) { + settings.beginGroup("RensoNoteList"); + settings.setValue("rensoListMaximum", maximum); + settings.endGroup(); + } + public static int getRensoListItemMaximum() { + settings.beginGroup("RensoNoteList"); + Integer value; + try { + String val = (String)settings.value("rensoListMaximum", 10); + value = new Integer(val.trim()); + } catch (Exception e) { + try { + value = (Integer)settings.value("rensoListMaximum", 10); + } catch (Exception e1) { + value = 10; + } + } + settings.endGroup(); + return value; + } + + // タグを排除してプレーンテキストを抽出 + public static String extractPlainText(String sourceText) { + String plainText = sourceText.replaceAll("<.+?>", ""); // タグを除去 + plainText = plainText.replaceAll("\\s{2,}", " "); // 2個以上の空白文字を1文字の空白に変換 + String kaigyo = System.getProperty("line.separator"); + plainText = plainText.replaceAll(kaigyo, ""); // 改行を除去 +// plainText = plainText.replaceAll("<.+?>", ""); // <で始まり>で終わる文字列を除去 + + // HTML特殊文字のサニタイジングを解除 + plainText = plainText.replaceAll("'", "'"); + plainText = plainText.replaceAll(""", "\""); + plainText = plainText.replaceAll(">", ">"); + plainText = plainText.replaceAll("<", "<"); + plainText = plainText.replaceAll("&", "&"); + + plainText = plainText.replaceAll("&.+?;", ""); // その他HTML特殊文字があれば除去 + + return plainText; + } + + // 全文検索機能の対象となるテーブルとカラムを再構築 + public static boolean rebuildFullTextNoteTarget(DatabaseConnection dbConn) { + NSqlQuery nQuery = new NSqlQuery(dbConn.getConnection()); + StringBuilder noteTableTarget = new StringBuilder(); + boolean success = true; + + if (Global.indexNoteBody()) { + noteTableTarget.append("CONTENTTEXT"); + } + if (Global.indexNoteTitle()) { + if (noteTableTarget.length() > 0) { + noteTableTarget.append(", "); + } + noteTableTarget.append("TITLE"); + } + + if (noteTableTarget.length() > 0) { + nQuery.prepare("CALL FTL_CREATE_INDEX('PUBLIC', 'NOTE', :column);"); + nQuery.bindValue(":column", noteTableTarget.toString()); + if (!nQuery.exec()) { + success = false; + } + } + + return success; + } + + public static boolean rebuildFullTextResourceTarget(DatabaseConnection dbConn) { + NSqlQuery rQuery = new NSqlQuery(dbConn.getResourceConnection()); + StringBuilder resourceTableTarget = new StringBuilder(); + boolean success = true; + + if (Global.indexAttachmentsLocally()) { + resourceTableTarget.append("RESOURCETEXT"); + } + + if (resourceTableTarget.length() > 0) { + rQuery.prepare("CALL FTL_CREATE_INDEX('PUBLIC', 'NOTERESOURCES', :column);"); + rQuery.bindValue(":column", resourceTableTarget.toString()); + if (!rQuery.exec()) { + success = false; + } + } + + return success; + } + + // 操作ログを取らないモードのボタン状態 + public static boolean isHaltLogButton() { + settings.beginGroup("RensoNoteList"); + try { + String text = (String)settings.value("haltOperationLog", "false"); + settings.endGroup(); + if (text.equalsIgnoreCase("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("haltOperationLog", true); + settings.endGroup(); + return value; + } + } + public static void saveHaltLogButton(boolean val) { + settings.beginGroup("RensoNoteList"); + if (val) + settings.setValue("haltOperationLog", "true"); + else + settings.setValue("haltOperationLog", "false"); + settings.endGroup(); + } + + // 連想ノートリストの重み付けモードの状態 + public static String rensoWeightingSelect() { + settings.beginGroup("RensoNoteList"); + String text = (String)settings.value("rensoWeightingSelect", "Standard"); + settings.endGroup(); + return text; + } + public static void saveRensoWeightingSelect(String val) { + settings.beginGroup("RensoNoteList"); + settings.setValue("rensoWeightingSelect", val); + settings.endGroup(); + } + + // ordinal から指定した Enum の要素に変換する汎用関数 + public static > E fromOrdinal(Class enumClass, int ordinal) { + E[] enumArray = enumClass.getEnumConstants(); + return enumArray[ordinal]; + } + + // 連想ノートリスト重み付けモード:カスタムの設定値(同時閲覧) + public static int customBrowseWeight() { + settings.beginGroup("RensoNoteList"); + Integer value; + try { + String val = (String)settings.value("customBrowseWeight", 1); + value = new Integer(val.trim()); + } catch (Exception e) { + try { + value = (Integer)settings.value("customBrowseWeight", 1); + } catch (Exception e1) { + value = 1; + } + } + settings.endGroup(); + return value; + } + public static void saveCustomBrowseWeight(int weight) { + settings.beginGroup("RensoNoteList"); + settings.setValue("customBrowseWeight", weight); + settings.endGroup(); + } + // 連想ノートリスト重み付けモード:カスタムの設定値(コピー&ペースト) + public static int customCopyPasteWeight() { + settings.beginGroup("RensoNoteList"); + Integer value; + try { + String val = (String)settings.value("customCopyPasteWeight", 3); + value = new Integer(val.trim()); + } catch (Exception e) { + try { + value = (Integer)settings.value("customCopyPasteWeight", 3); + } catch (Exception e1) { + value = 3; + } + } + settings.endGroup(); + return value; + } + public static void saveCustomCopyPasteWeight(int weight) { + settings.beginGroup("RensoNoteList"); + settings.setValue("customCopyPasteWeight", weight); + settings.endGroup(); + } + // 連想ノートリスト重み付けモード:カスタムの設定値(新規ノート追加) + public static int customAddNewNoteWeight() { + settings.beginGroup("RensoNoteList"); + Integer value; + try { + String val = (String)settings.value("customAddNewNoteWeight", 3); + value = new Integer(val.trim()); + } catch (Exception e) { + try { + value = (Integer)settings.value("customAddNewNoteWeight", 3); + } catch (Exception e1) { + value = 3; + } + } + settings.endGroup(); + return value; + } + public static void saveCustomAddNewNoteWeight(int weight) { + settings.beginGroup("RensoNoteList"); + settings.setValue("customAddNewNoteWeight", weight); + settings.endGroup(); + } + // 連想ノートリスト重み付けモード:カスタムの設定値(連想ノートクリック) + public static int customRensoItemClickWeight() { + settings.beginGroup("RensoNoteList"); + Integer value; + try { + String val = (String)settings.value("customRensoItemClickWeight", 10); + value = new Integer(val.trim()); + } catch (Exception e) { + try { + value = (Integer)settings.value("customRensoItemClickWeight", 10); + } catch (Exception e1) { + value = 10; + } + } + settings.endGroup(); + return value; + } + public static void saveCustomRensoItemClickWeight(int weight) { + settings.beginGroup("RensoNoteList"); + settings.setValue("customRensoItemClickWeight", weight); + settings.endGroup(); + } + // 連想ノートリスト重み付けモード:カスタムの設定値(同じタグ) + public static int customSameTagWeight() { + settings.beginGroup("RensoNoteList"); + Integer value; + try { + String val = (String)settings.value("customSameTagWeight", 2); + value = new Integer(val.trim()); + } catch (Exception e) { + try { + value = (Integer)settings.value("customSameTagWeight", 2); + } catch (Exception e1) { + value = 2; + } + } + settings.endGroup(); + return value; + } + public static void saveCustomSameTagWeight(int weight) { + settings.beginGroup("RensoNoteList"); + settings.setValue("customSameTagWeight", weight); + settings.endGroup(); + } + // 連想ノートリスト重み付けモード:カスタムの設定値(同じノートブック) + public static int customSameNotebookWeight() { + settings.beginGroup("RensoNoteList"); + Integer value; + try { + String val = (String)settings.value("customSameNotebookWeight", 2); + value = new Integer(val.trim()); + } catch (Exception e) { + try { + value = (Integer)settings.value("customSameNotebookWeight", 2); + } catch (Exception e1) { + value = 2; + } + } + settings.endGroup(); + return value; + } + public static void saveCustomSameNotebookWeight(int weight) { + settings.beginGroup("RensoNoteList"); + settings.setValue("customSameNotebookWeight", weight); + settings.endGroup(); + } + // 連想ノートリスト重み付けモード:カスタムの設定値(Evernote関連ノート) + public static int customENRelatedNotesWeight() { + settings.beginGroup("RensoNoteList"); + Integer value; + try { + String val = (String)settings.value("customENRelatedNotesWeight", 5); + value = new Integer(val.trim()); + } catch (Exception e) { + try { + value = (Integer)settings.value("customENRelatedNotesWeight", 5); + } catch (Exception e1) { + value = 5; + } + } + settings.endGroup(); + return value; + } + public static void saveCustomENRelatedNotesWeight(int weight) { + settings.beginGroup("RensoNoteList"); + settings.setValue("customENRelatedNotesWeight", weight); + settings.endGroup(); + } + + // ツールバーの「新規」ボタンを押した時、新規ノートをタブで開くかどうか + public static boolean toolBarNewAction() { + settings.beginGroup("General"); + try { + String text = (String)settings.value("toolBarNewAction", "true"); + settings.endGroup(); + if (text.equalsIgnoreCase("true")) + return true; + else + return false; + } catch (java.lang.ClassCastException e) { + Boolean value = (Boolean) settings.value("toolBarNewAction", true); + settings.endGroup(); + return value; + } + } + public static void setToolBarNewAction(boolean value) { + settings.beginGroup("General"); + settings.setValue("toolBarNewAction", value); + settings.endGroup(); + } +} + diff --cc src/cx/fbn/nevernote/threads/SyncRunner.java index bff002a,81243a3..15b993c --- a/src/cx/fbn/nevernote/threads/SyncRunner.java +++ b/src/cx/fbn/nevernote/threads/SyncRunner.java @@@ -1,2217 -1,2136 +1,2217 @@@ -/* - * This file is part of NixNote - * Copyright 2009 Randy Baumgarte - * - * This file may be licensed under the terms of of the - * GNU General Public License Version 2 (the ``GPL''). - * - * Software distributed under the License is distributed - * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either - * express or implied. See the GPL for the specific language - * governing rights and limitations. - * - * You should have received a copy of the GPL along with this - * program. If not, go to http://www.gnu.org/licenses/gpl.html - * or write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * -*/ -package cx.fbn.nevernote.threads; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.HashMap; -import java.util.List; -import java.util.TreeSet; -import java.util.concurrent.LinkedBlockingQueue; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.HttpClient; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.protocol.HTTP; -import org.apache.thrift.TException; -import org.apache.thrift.protocol.TBinaryProtocol; -import org.apache.thrift.transport.THttpClient; -import org.apache.thrift.transport.TTransportException; - -import com.evernote.edam.error.EDAMNotFoundException; -import com.evernote.edam.error.EDAMSystemException; -import com.evernote.edam.error.EDAMUserException; -import com.evernote.edam.notestore.NoteStore; -import com.evernote.edam.notestore.NoteStore.Client; -import com.evernote.edam.notestore.SyncChunk; -import com.evernote.edam.notestore.SyncState; -import com.evernote.edam.type.Data; -import com.evernote.edam.type.LinkedNotebook; -import com.evernote.edam.type.Note; -import com.evernote.edam.type.Notebook; -import com.evernote.edam.type.Resource; -import com.evernote.edam.type.SavedSearch; -import com.evernote.edam.type.SharedNotebook; -import com.evernote.edam.type.Tag; -import com.evernote.edam.type.User; -import com.evernote.edam.userstore.AuthenticationResult; -import com.evernote.edam.userstore.UserStore; -import com.trolltech.qt.core.QByteArray; -import com.trolltech.qt.core.QFile; -import com.trolltech.qt.core.QIODevice.OpenModeFlag; -import com.trolltech.qt.core.QObject; -import com.trolltech.qt.core.QTextCodec; -import com.trolltech.qt.gui.QMessageBox; - -import cx.fbn.nevernote.signals.NoteIndexSignal; -import cx.fbn.nevernote.signals.NoteResourceSignal; -import cx.fbn.nevernote.signals.NoteSignal; -import cx.fbn.nevernote.signals.NotebookSignal; -import cx.fbn.nevernote.signals.SavedSearchSignal; -import cx.fbn.nevernote.signals.StatusSignal; -import cx.fbn.nevernote.signals.SyncSignal; -import cx.fbn.nevernote.signals.TagSignal; -import cx.fbn.nevernote.sql.DatabaseConnection; -import cx.fbn.nevernote.sql.DeletedItemRecord; -import cx.fbn.nevernote.utilities.ApplicationLogger; - -public class SyncRunner extends QObject implements Runnable { - - private final ApplicationLogger logger; - private DatabaseConnection conn; - private boolean idle; - public boolean error; - public volatile List errorSharedNotebooks; - public volatile HashMap errorSharedNotebooksIgnored; - public volatile boolean isConnected; - public volatile boolean keepRunning; - public volatile String authToken; - private long evernoteUpdateCount; - private final String userAgent = "NixNote/" + System.getProperty("os.name") - +"/"+System.getProperty("java.vendor") + "/" - + System.getProperty("java.version") +";"; - - public volatile NoteStore.Client localNoteStore; - private UserStore.Client userStore; - - public volatile StatusSignal status; - public volatile TagSignal tagSignal; - public volatile NotebookSignal notebookSignal; - public volatile NoteIndexSignal noteIndexSignal; - public volatile NoteSignal noteSignal; - public volatile SavedSearchSignal searchSignal; - public volatile NoteResourceSignal resourceSignal; - public volatile SyncSignal syncSignal; - public volatile boolean authRefreshNeeded; - public volatile boolean syncNeeded; - public volatile boolean disableUploads; - public volatile boolean syncDeletedContent; - private volatile List dirtyNoteGuids; - - public volatile String username = ""; - public volatile String password = ""; - public volatile String userStoreUrl; -// private final static String consumerKey = "baumgarte"; -// private final static String consumerSecret = "eb8b5740e17cb55f"; - public String noteStoreUrlBase; - private THttpClient userStoreTrans; - private TBinaryProtocol userStoreProt; - //private AuthenticationResult authResult; - private AuthenticationResult linkedAuthResult; - private User user; -// private long authTimeRemaining; - public long authRefreshTime; - public long failedRefreshes = 0; - public THttpClient noteStoreTrans; - public TBinaryProtocol noteStoreProt; - public String noteStoreUrl; - public long sequenceDate; - public int updateSequenceNumber; - private boolean refreshNeeded; - private volatile LinkedBlockingQueue workQueue; - private static int MAX_QUEUED_WAITING = 1000; - String dbuid; - String dburl; - String indexUrl; - String resourceUrl; - String dbpswd; - String dbcpswd; - private final TreeSet ignoreTags; - private final TreeSet ignoreNotebooks; - private final TreeSet ignoreLinkedNotebooks; - private HashMap badTagSync; - - - - public SyncRunner(String logname, String u, String i, String r, String uid, String pswd, String cpswd) { - logger = new ApplicationLogger(logname); - - noteSignal = new NoteSignal(); - status = new StatusSignal(); - tagSignal = new TagSignal(); - notebookSignal = new NotebookSignal(); - noteIndexSignal = new NoteIndexSignal(); - noteSignal = new NoteSignal(); - searchSignal = new SavedSearchSignal(); - syncSignal = new SyncSignal(); - resourceSignal = new NoteResourceSignal(); - resourceUrl = r; - indexUrl = i; - dbuid = uid; - dburl = u; - dbpswd = pswd; - dbcpswd = cpswd; -// this.setAutoDelete(false); - - isConnected = false; - syncNeeded = false; - authRefreshNeeded = false; - keepRunning = true; - idle = true; - disableUploads = false; - ignoreTags = new TreeSet(); - ignoreNotebooks = new TreeSet(); - ignoreLinkedNotebooks = new TreeSet(); - -// setAutoDelete(false); - workQueue=new LinkedBlockingQueue(MAX_QUEUED_WAITING); - } - @Override - public void run() { - errorSharedNotebooks = new ArrayList(); - errorSharedNotebooksIgnored = new HashMap(); - try { - logger.log(logger.EXTREME, "Starting thread"); - conn = new DatabaseConnection(logger, dburl, indexUrl, resourceUrl, dbuid, dbpswd, dbcpswd, 200); - while(keepRunning) { - logger.log(logger.EXTREME, "Blocking until work is found"); - String work = workQueue.take(); - logger.log(logger.LOW, "Dirty Notes Before Sync: " +new Integer(conn.getNoteTable().getDirtyCount()).toString()); - logger.log(logger.EXTREME, "Work found: " +work); - if (work.equalsIgnoreCase("stop")) { - idle=false; - return; - } - conn.getNoteTable().dumpDirtyNotes(); // Debugging statement - idle=false; - error=false; - if (syncNeeded) { - logger.log(logger.EXTREME, "SyncNeeded is true"); - refreshNeeded=false; - sequenceDate = conn.getSyncTable().getLastSequenceDate(); - updateSequenceNumber = conn.getSyncTable().getUpdateSequenceNumber(); - try { - logger.log(logger.EXTREME, "Beginning sync"); - evernoteSync(localNoteStore); - logger.log(logger.EXTREME, "Sync finished"); - } catch (UnknownHostException e) { - status.message.emit(e.getMessage()); - } - } - idle=true; - logger.log(logger.EXTREME, "Signaling refresh finished. refreshNeeded=" +refreshNeeded); - syncSignal.finished.emit(refreshNeeded); - if (error) { - syncSignal.errorDisconnect.emit(); - status.message.emit(tr("Error synchronizing - see log for details.")); - } - logger.log(logger.LOW, "Dirty Notes After Sync: " +new Integer(conn.getNoteTable().getDirtyCount()).toString()); - conn.getNoteTable().dumpDirtyNotes(); - logger.log(logger.LOW, "---"); - } - } - catch (InterruptedException e1) { - e1.printStackTrace(); - } - conn.dbShutdown(); - } - - - public DatabaseConnection getConnection() { - return conn; - } - - public boolean isIdle() { - return idle; - } - - - public void setConnected(boolean c) { - isConnected = c; - } - public void setKeepRunning(boolean r) { - logger.log(logger.EXTREME, "Setting keepRunning=" +r); - keepRunning = r; - } - public void setNoteStore(NoteStore.Client c) { - logger.log(logger.EXTREME, "Setting NoteStore in sync thread"); - localNoteStore = c; - } - public void setUserStore(UserStore.Client c) { - logger.log(logger.EXTREME, "Setting UserStore in sync thread"); - userStore = c; - } - - public void setEvernoteUpdateCount(long s) { - logger.log(logger.EXTREME, "Setting Update Count in sync thread"); - evernoteUpdateCount = s; - } - - //*************************************************************** - //*************************************************************** - //** These functions deal with Evernote communications - //*************************************************************** - //*************************************************************** - // Synchronize changes with Evernote - @SuppressWarnings("unused") - private void evernoteSync(Client noteStore) throws java.net.UnknownHostException { - logger.log(logger.HIGH, "Entering SyncRunner.evernoteSync"); - - // Rebuild list of tags & notebooks to ignore - ignoreNotebooks.clear(); - List ignore = conn.getSyncTable().getIgnoreRecords("NOTEBOOK"); - for (int i=0; i sequenceDate) { - logger.log(logger.EXTREME, "Full sequence date has expired"); - sequenceDate = 0; - conn.getSyncTable().setLastSequenceDate(0); - updateSequenceNumber = 0; - conn.getSyncTable().setUpdateSequenceNumber(0); - } - // Check for "special" sync instructions - String syncLinked = conn.getSyncTable().getRecord("FullLinkedNotebookSync"); - String syncShared = conn.getSyncTable().getRecord("FullSharedNotebookSync"); - String syncNotebooks = conn.getSyncTable().getRecord("FullNotebookSync"); - String syncInkNoteImages = conn.getSyncTable().getRecord("FullInkNoteImageSync"); - if (syncLinked != null) { - downloadAllLinkedNotebooks(localNoteStore); - } - if (syncShared != null) { - downloadAllSharedNotebooks(localNoteStore); - } - if (syncNotebooks != null) { - downloadAllNotebooks(localNoteStore); - } - - if (syncInkNoteImages != null) { - List guids = conn.getNoteTable().noteResourceTable.findInkNotes(); - for (int i=0; i updateSequenceNumber) { - logger.log(logger.EXTREME, "Refresh needed is true"); - refreshNeeded = true; - logger.log(logger.EXTREME, "Downloading changes"); - syncRemoteToLocal(localNoteStore); - } - - //***************************************** - //* Sync linked/shared notebooks - //***************************************** - syncLinkedNotebooks(); - //conn.getNoteTable().getDirty(); - //disableUploads = true; /// DELETE THIS LINE!!!! - if (!disableUploads) { - logger.log(logger.EXTREME, "Uploading changes"); - // Synchronize remote changes - if (!error) - syncExpunged(localNoteStore); - if (!error) - syncLocalTags(localNoteStore); - if (!error) - syncLocalNotebooks(localNoteStore); - if (!error) - syncLocalLinkedNotebooks(localNoteStore); - if (!error) - syncDeletedNotes(localNoteStore); - if (!error) - syncLocalNotes(); - if (!error) - syncLocalSavedSearches(localNoteStore); - } - - status.message.emit(tr("Cleaning up")); - List notes = conn.getNoteTable().expungeIgnoreSynchronizedNotes(conn.getSyncTable().getIgnoreRecords("NOTEBOOK"), - conn.getSyncTable().getIgnoreRecords("TAG"), conn.getSyncTable().getIgnoreRecords("LINKEDNOTEBOOK")); - if (notes.size() > 0) - syncSignal.refreshLists.emit(); - - //***************************************** - //* End of synchronization - //***************************************** - if (refreshNeeded) - syncSignal.refreshLists.emit(); - - if (!error) { - logger.log(logger.LOW, "Sync completed. Errors=" +error); - if (!disableUploads) - status.message.emit(tr("Synchronizing complete")); - else - status.message.emit(tr("Download syncronization complete. Uploads have been disabled.")); - - logger.log(logger.EXTREME, "Saving sync time"); - if (syncState.getCurrentTime() > sequenceDate) - sequenceDate = syncState.getCurrentTime(); - if (syncState.getUpdateCount() > updateSequenceNumber) - updateSequenceNumber = syncState.getUpdateCount(); - conn.getSyncTable().setLastSequenceDate(sequenceDate); - conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber); - } - } - logger.log(logger.HIGH, "Leaving SyncRunner.evernoteSync"); - } - - // Sync deleted items with Evernote - private void syncExpunged(Client noteStore) { - logger.log(logger.HIGH, "Entering SyncRunner.syncExpunged"); - - List expunged = conn.getDeletedTable().getAllDeleted(); - boolean error = false; - for (int i=0; i notes = conn.getNoteTable().getDirty(); - // Sync the local notebooks with Evernote's - for (int i=0; i 0 && (enNote.isActive() == false || enNote.getDeleted() > 0)) { - // Check that the note is valid. - if (enNote.isActive() == true || enNote.getDeleted() == 0) { - conn.getNoteTable().deleteNote(enNote.getGuid()); - enNote = conn.getNoteTable().getNote(enNote.getGuid(), false, false, false, false, false); - } - if (syncDeletedContent) { - logger.log(logger.EXTREME, "Deleted note found & synch content selected"); - Note delNote = conn.getNoteTable().getNote(enNote.getGuid(), true, true, true, true, true); - delNote = getNoteContent(delNote); - delNote = noteStore.updateNote(authToken, delNote); - enNote.setUpdateSequenceNum(delNote.getUpdateSequenceNum()); - conn.getNoteTable().updateNoteSequence(enNote.getGuid(), enNote.getUpdateSequenceNum()); - } else { - logger.log(logger.EXTREME, "Deleted note found & sync content not selected"); - int usn = noteStore.deleteNote(authToken, enNote.getGuid()); - enNote.setUpdateSequenceNum(usn); - conn.getNoteTable().updateNoteSequence(enNote.getGuid(), enNote.getUpdateSequenceNum()); - } - logger.log(logger.EXTREME, "Resetting deleted dirty flag"); - conn.getNoteTable().resetDirtyFlag(enNote.getGuid()); - updateSequenceNumber = enNote.getUpdateSequenceNum(); - logger.log(logger.EXTREME, "Saving sequence number"); - conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber); - } - } catch (EDAMUserException e) { - logger.log(logger.LOW, "*** EDAM User Excepton syncLocalNotes "+e); - //status.message.emit("Error sending local note: " +e.getParameter()); - //logger.log(logger.LOW, e.toString()); - //error = true; - } catch (EDAMSystemException e) { - logger.log(logger.LOW, "*** EDAM System Excepton syncLocalNotes "+e); - status.message.emit(tr("Error: ") +e); - logger.log(logger.LOW, e.toString()); - error = true; - } catch (EDAMNotFoundException e) { - logger.log(logger.LOW, "*** EDAM Not Found Excepton syncLocalNotes " +e); - //status.message.emit("Error deleting local note: " +e +" - Continuing"); - //logger.log(logger.LOW, e.toString()); - //error = true; - } catch (TException e) { - logger.log(logger.LOW, "*** EDAM TExcepton syncLocalNotes "+e); - status.message.emit(tr("Error sending local note: ") +e); - logger.log(logger.LOW, e.toString()); - error = true; - } - } - } - // Sync notes with Evernote - private void syncLocalNotes() { - logger.log(logger.HIGH, "Entering SyncRunner.syncNotes"); - logger.log(logger.LOW, "Dirty local notes found: " +new Integer(conn.getNoteTable().getDirtyCount()).toString()); - status.message.emit(tr("Sending local notes.")); - - List notes = conn.getNoteTable().getDirty(); - // Sync the local notebooks with Evernote's - for (int i=0; i 0) { - logger.log(logger.EXTREME, "Active dirty note found - non new - " +enNote.getGuid()); - logger.log(logger.EXTREME, "Fetching note content"); - enNote = getNoteContent(enNote); - logger.log(logger.MEDIUM, "Updating note : "+ enNote.getGuid() +" " +enNote.getTitle()+""); - enNote = noteStore.updateNote(token, enNote); - } else { - logger.log(logger.EXTREME, "Active dirty found - new note " +enNote.getGuid()); - String oldGuid = enNote.getGuid(); - logger.log(logger.MEDIUM, "Fetching note content"); - enNote = getNoteContent(enNote); - logger.log(logger.MEDIUM, "Creating note : "+ enNote.getGuid() +" " +enNote.getTitle()+""); - enNote = noteStore.createNote(token, enNote); - logger.log(logger.MEDIUM, "New note Guid : "+ enNote.getGuid() +" " +enNote.getTitle()+""); - noteSignal.guidChanged.emit(oldGuid, enNote.getGuid()); - conn.getNoteTable().updateNoteGuid(oldGuid, enNote.getGuid()); - } - updateSequenceNumber = enNote.getUpdateSequenceNum(); - logger.log(logger.EXTREME, "Saving note"); - conn.getNoteTable().updateNoteSequence(enNote.getGuid(), enNote.getUpdateSequenceNum()); - List rl = enNote.getResources(); - logger.log(logger.EXTREME, "Getting note resources"); - for (int j=0; j remoteList = new ArrayList(); - try { - logger.log(logger.EXTREME, "Getting remote notebooks to compare with local"); - remoteList = noteStore.listNotebooks(authToken); - } catch (EDAMUserException e1) { - logger.log(logger.LOW, "*** EDAM User Excepton syncLocalNotebooks getting remote Notebook List"); - status.message.emit(tr("Error: ") +e1); - logger.log(logger.LOW, e1.toString()); - error = true; - } catch (EDAMSystemException e1) { - logger.log(logger.LOW, "*** EDAM System Excepton syncLocalNotebooks getting remote Notebook List"); - status.message.emit(tr("Error: ") +e1); - logger.log(logger.LOW, e1.toString()); - error = true; - } catch (TException e1) { - logger.log(logger.LOW, "*** EDAM Transaction Excepton syncLocalNotebooks getting remote Notebook List"); - status.message.emit(tr("Error: ") +e1); - logger.log(logger.LOW, e1.toString()); - error = true; - } - logger.log(logger.EXTREME, "Getting local dirty notebooks"); - List notebooks = conn.getNotebookTable().getDirty(); - int sequence; - // Sync the local notebooks with Evernote's - for (int i=0; i 0) { - logger.log(logger.EXTREME, "Existing notebook is dirty"); - sequence = noteStore.updateNotebook(authToken, enNotebook); - } else { - logger.log(logger.EXTREME, "New dirty notebook found"); - String oldGuid = enNotebook.getGuid(); - boolean found = false; - - // Look for a notebook with the same name. If one is found, we don't need - // to create another one - logger.log(logger.EXTREME, "Looking for matching notebook name"); - for (int k=0; k remoteList = new ArrayList(); - status.message.emit(tr("Sending local tags.")); - - try { - logger.log(logger.EXTREME, "Getting remote tags to compare names with the local tags"); - remoteList = noteStore.listTags(authToken); - } catch (EDAMUserException e1) { - logger.log(logger.LOW, "*** EDAM User Excepton syncLocalTags getting remote Tag List"); - status.message.emit(tr("Error: ") +e1); - logger.log(logger.LOW, e1.toString()); - error = true; - } catch (EDAMSystemException e1) { - logger.log(logger.LOW, "*** EDAM System Excepton syncLocalTags getting remote Tag List"); - status.message.emit(tr("Error: ") +e1); - logger.log(logger.LOW, e1.toString()); - error = true; - } catch (TException e1) { - logger.log(logger.LOW, "*** EDAM Transaction Excepton syncLocalTags getting remote Tag List"); - status.message.emit(tr("Error: ") +e1); - logger.log(logger.LOW, e1.toString()); - error = true; - } - - int sequence; - - if (badTagSync == null) - badTagSync = new HashMap(); - else - badTagSync.clear(); - - Tag enTag = findNextTag(); - - // This is a hack. Sometimes this function goes flookey and goes into a - // perpetual loop. This causes NeverNote to flood Evernote's servers. - // This is a safety valve to prevent unlimited loops. - int maxCount = conn.getTagTable().getDirty().size()+10; - int loopCount = 0; - - while(enTag!=null && loopCount < maxCount) { - loopCount++; -// if (authRefreshNeeded) -// if (!refreshConnection()) -// return; - - try { - if (enTag.getUpdateSequenceNum() > 0) { - logger.log(logger.EXTREME, "Updating tag"); - sequence = noteStore.updateTag(authToken, enTag); - } else { - - // Look for a tag with the same name. If one is found, we don't need - // to create another one - logger.log(logger.EXTREME, "New tag. Comparing with remote names"); - boolean found = false; - String oldGuid = enTag.getGuid(); - for (int k=0; k list = conn.getLinkedNotebookTable().getDirtyGuids(); - for (int i=0; i remoteList = new ArrayList(); - status.message.emit(tr("Sending saved searches.")); - - logger.log(logger.EXTREME, "Getting saved searches to compare with local"); - try { - remoteList = noteStore.listSearches(authToken); - } catch (EDAMUserException e1) { - logger.log(logger.LOW, "*** EDAM User Excepton syncLocalTags getting remote saved search List"); - status.message.emit(tr("Error: ") +e1); - logger.log(logger.LOW, e1.toString()); - error = true; - } catch (EDAMSystemException e1) { - logger.log(logger.LOW, "*** EDAM System Excepton syncLocalTags getting remote saved search List"); - status.message.emit(tr("Error: ") +e1); - logger.log(logger.LOW, e1.toString()); - error = true; - } catch (TException e1) { - logger.log(logger.LOW, "*** EDAM Transaction Excepton syncLocalTags getting remote saved search List"); - status.message.emit(tr("Error: ") +e1); - logger.log(logger.LOW, e1.toString()); - error = true; - } - - List searches = conn.getSavedSearchTable().getDirty(); - int sequence; - // Sync the local notebooks with Evernote's - logger.log(logger.EXTREME, "Beginning to send saved searches"); - for (int i=0; i 0) - sequence = noteStore.updateSearch(authToken, enSearch); - else { - logger.log(logger.EXTREME, "New saved search found."); - // Look for a tag with the same name. If one is found, we don't need - // to create another one - boolean found = false; - logger.log(logger.EXTREME, "Matching remote saved search names with local"); - for (int k=0; k dirtyNotes = conn.getNoteTable().getDirty(); - dirtyNoteGuids = new ArrayList(); - for (int i=0; i 0 && keepRunning) { - logger.log(logger.EXTREME, "emitting sequence number to main thread"); - updateSequenceNumber = chunk.getChunkHighUSN(); - conn.getSyncTable().setLastSequenceDate(chunk.getCurrentTime()); - conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber); -// conn.commitTransaction(); - } - - - if (more) { - long pct = chunk.getChunkHighUSN() * 100; - conn.getSyncTable().setLastSequenceDate(chunk.getCurrentTime()); - pct = pct/evernoteUpdateCount; - status.message.emit(tr("Downloading ") +new Long(pct).toString()+tr("% complete.")); - } -// conn.commitTransaction(); - } - logger.log(logger.HIGH, "Leaving SyncRunner.syncRemoteToLocal"); - } - // Sync expunged notes - private void syncExpungedNotes(SyncChunk chunk) { - // Do the local deletes - logger.log(logger.EXTREME, "Doing local deletes"); - List guid = chunk.getExpungedNotes(); - if (guid != null) { - for (int i=0; i tags) { - logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteTags"); - if (tags != null) { - for (int i=0; i searches) { - logger.log(logger.EXTREME, "Entering SyncRunner.syncSavedSearches"); - if (searches != null) { - for (int i=0; i books) { - logger.log(logger.EXTREME, "Entering SyncRunner.syncLinkedNotebooks"); - if (books != null) { - for (int i=0; i notebooks) { - logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteNotebooks"); - if (notebooks != null) { - for (int i=0; i 0) { -// conn.getSharedNotebookTable().expungeNotebookByGuid(notebooks.get(i).getGuid(), false); -// for (int j=0; j books = noteStore.getSharedNotebookByAuth(authToken); -// } - // Sync remote Resources - private void syncRemoteResources(Client noteStore, List resource) { - logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteResources"); - if (resource != null) { - for (int i=0; i note, boolean fullSync, String token) { - - if (note != null) { - - logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteNotes"); - logger.log(logger.LOW, "Local Dirty Notes: "); - logger.log(logger.LOW, "Remote Dirty Notes:"); - for (int i=0; i books = conn.getNotebookTable().getAllLocal(); - String notebookGuid = null; - for (int i=0; i>> 4) & 0x0F; - int two_halfs = 0; - do { - if ((0 <= halfbyte) && (halfbyte <= 9)) - buf.append((char) ('0' + halfbyte)); - else - buf.append((char) ('a' + (halfbyte - 10))); - halfbyte = element & 0x0F; - } while(two_halfs++ < 1); - } - return buf.toString(); - } - - - - //******************************************************* - //* Find dirty tags, which do not have newly created parents - //******************************************************* - private Tag findNextTag() { - logger.log(logger.HIGH, "Entering SyncRunner.findNextTag"); - Tag nextTag = null; - List tags = conn.getTagTable().getDirty(); - - // Find the parent. If the parent has a sequence > 0 then it is a good - // parent. - for (int i=0; i 0) { - logger.log(logger.HIGH, "Leaving SyncRunner.findNextTag - tag found"); - return tags.get(i); - } - } - } - - logger.log(logger.HIGH, "Leaving SyncRunner.findNextTag - no tags returned"); - return nextTag; - } - - - // Connect to Evernote - public boolean enConnect() { - try { - userStoreTrans = new THttpClient(userStoreUrl); - userStoreTrans.setCustomHeader("User-Agent", userAgent); - } catch (TTransportException e) { - QMessageBox mb = new QMessageBox(QMessageBox.Icon.Critical, "Transport Excepton", e.getLocalizedMessage()); - mb.exec(); - e.printStackTrace(); - } - userStoreProt = new TBinaryProtocol(userStoreTrans); - userStore = new UserStore.Client(userStoreProt, userStoreProt); - syncSignal.saveUserStore.emit(userStore); - try { - //authResult = userStore.authenticate(username, password, consumerKey, consumerSecret); - user = userStore.getUser(authToken); - } catch (EDAMUserException e) { - QMessageBox mb = new QMessageBox(QMessageBox.Icon.Critical, "Error", "Invalid Authorization"); - mb.exec(); - isConnected = false; - return false; - } catch (EDAMSystemException e) { - QMessageBox mb = new QMessageBox(QMessageBox.Icon.Critical, "EDAM System Excepton", e.getLocalizedMessage()); - mb.exec(); - e.printStackTrace(); - isConnected = false; - } catch (TException e) { - QMessageBox mb = new QMessageBox(QMessageBox.Icon.Critical, "Transport Excepton", e.getLocalizedMessage()); - mb.exec(); - e.printStackTrace(); - isConnected = false; - } - - boolean versionOk = false; - try { - versionOk = userStore.checkVersion("NixNote", - com.evernote.edam.userstore.Constants.EDAM_VERSION_MAJOR, - com.evernote.edam.userstore.Constants.EDAM_VERSION_MINOR); - } catch (TException e) { - e.printStackTrace(); - isConnected = false; - } - if (!versionOk) { - System.err.println("Incomatible EDAM client protocol version"); - isConnected = false; - } - //if (authResult != null) { - //user = authResult.getUser(); - //authToken = authResult.getAuthenticationToken(); - if (user == null || noteStoreUrlBase == null) { - logger.log(logger.LOW, "Error retrieving user information. Aborting."); - System.err.println("Error retrieving user information."); - isConnected = false; - QMessageBox mb = new QMessageBox(QMessageBox.Icon.Critical, tr("Connection Error"), tr("Error retrieving user information. Synchronization not complete")); - mb.exec(); - return false; - - } - noteStoreUrl = noteStoreUrlBase + user.getShardId(); - syncSignal.saveAuthToken.emit(authToken); - syncSignal.saveNoteStore.emit(localNoteStore); - - - try { - noteStoreTrans = new THttpClient(noteStoreUrl); - noteStoreTrans.setCustomHeader("User-Agent", userAgent); - } catch (TTransportException e) { - QMessageBox mb = new QMessageBox(QMessageBox.Icon.Critical, "Transport Excepton", e.getLocalizedMessage()); - mb.exec(); - e.printStackTrace(); - isConnected = false; - } - noteStoreProt = new TBinaryProtocol(noteStoreTrans); - localNoteStore = - new NoteStore.Client(noteStoreProt, noteStoreProt); - isConnected = true; - //authTimeRemaining = authResult.getExpiration() - authResult.getCurrentTime(); - //authRefreshTime = authTimeRemaining / 2; - //} - - // Get user information - try { - User user = userStore.getUser(authToken); - syncSignal.saveUserInformation.emit(user); - } catch (EDAMUserException e1) { - e1.printStackTrace(); - } catch (EDAMSystemException e1) { - e1.printStackTrace(); - } catch (TException e1) { - e1.printStackTrace(); - } - - return isConnected; - } - // Disconnect from the database - public void enDisconnect() { - isConnected = false; - } - - /* - // Refresh the connection - private synchronized boolean refreshConnection() { - - logger.log(logger.EXTREME, "Entering SyncRunner.refreshConnection()"); -// Calendar cal = Calendar.getInstance(); - - // If we are not connected let's get out of here - if (!isConnected) - return false; - - // If we fail too many times, then let's give up. - if (failedRefreshes >=5) { - logger.log(logger.EXTREME, "Refresh attempts have failed. Disconnecting."); - isConnected = false; - status.message.emit(tr("Unable to synchronize - Authentication failed")); - return false; - } - - // If this is the first time through, then we need to set this -// if (authRefreshTime == 0 || cal.getTimeInMillis() > authRefreshTime) -// authRefreshTime = cal.getTimeInMillis(); - - // // Default to checking again in 5 min. This in case we fail. - // authRefreshTime = authRefreshTime +(5*60*1000); - - // Try to get a new token - AuthenticationResult newAuth = null; - logger.log(logger.EXTREME, "Beginning to try authentication refresh"); - try { - if (userStore != null && authToken != null) - newAuth = userStore.refreshAuthentication(authToken); - else - return false; - logger.log(logger.EXTREME, "UserStore.refreshAuthentication has succeeded."); - } catch (EDAMUserException e) { - e.printStackTrace(); - syncSignal.authRefreshComplete.emit(false); - failedRefreshes++; - return false; - } catch (EDAMSystemException e) { - e.printStackTrace(); - syncSignal.authRefreshComplete.emit(false); - failedRefreshes++; - return false; - } catch (TException e) { - e.printStackTrace(); - syncSignal.authRefreshComplete.emit(false); - failedRefreshes++; - return false; - } - - // If we didn't get a good auth, then we've failed - if (newAuth == null) { - failedRefreshes++; - status.message.emit(tr("Unable to synchronize - Authentication failed")); - logger.log(logger.EXTREME, "Authentication failure #" +failedRefreshes); - status.message.emit(tr("Unable to synchronize - Authentication failed")); - syncSignal.authRefreshComplete.emit(false); - return false; - } - - // We got a good token. Now we need to setup the time to renew it. - logger.log(logger.EXTREME, "Saving authentication tokens"); - authResult = newAuth; - authToken = new String(newAuth.getAuthenticationToken()); -// authTimeRemaining = authResult.getExpiration() - authResult.getCurrentTime(); -// authRefreshTime = cal.getTimeInMillis() + (authTimeRemaining/4); - failedRefreshes=0; - syncSignal.authRefreshComplete.emit(true); - authRefreshNeeded = false; - - // This should never happen, but if it does we consider this a faild attempt. -// if (authTimeRemaining <= 0) { -// failedRefreshes++; -// syncSignal.authRefreshComplete.emit(false); -// } - - return true; - } - - */ - - public synchronized boolean addWork(String request) { - if (workQueue.offer(request)) - return true; - return false; - } - - private Note getNoteContent(Note n) { - QTextCodec codec = QTextCodec.codecForLocale(); - codec = QTextCodec.codecForName("UTF-8"); - n.setContent(codec.toUnicode(new QByteArray(n.getContent()))); - return n; - } - - - - //********************************************************* - //* Special download instructions. Used for DB upgrades - //********************************************************* - private void downloadAllSharedNotebooks(Client noteStore) { - try { - List books = noteStore.listSharedNotebooks(authToken); - logger.log(logger.LOW, "Shared notebooks found = " +books.size()); - for (int i=0; i books = noteStore.listNotebooks(authToken); - logger.log(logger.LOW, "Shared notebooks found = " +books.size()); - for (int i=0; i books = noteStore.listLinkedNotebooks(authToken); - logger.log(logger.LOW, "Linked notebooks found = " +books.size()); - for (int i=0; i nvps = new ArrayList (); - nvps.add(new BasicNameValuePair("auth", authToken)); - - try { - post.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8)); - } catch (UnsupportedEncodingException e1) { - e1.printStackTrace(); - } - try { - HttpResponse response = http.execute(post); - HttpEntity resEntity = response.getEntity(); - InputStream is = resEntity.getContent(); - QByteArray data = writeToFile(is); - conn.getInkImagesTable().saveImage(guid, slice, data); - } catch (ClientProtocolException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - - slice++; - } - http.getConnectionManager().shutdown(); - noteSignal.noteChanged.emit(r.getNoteGuid(), null); // Signal to ivalidate note cache - } - - - public QByteArray writeToFile(InputStream iStream) throws IOException { - - File temp = File.createTempFile("nn-inknote-temp", ".png"); - - // Save InputStream to the file. - BufferedOutputStream fOut = null; - try { - fOut = new BufferedOutputStream(new FileOutputStream(temp)); - byte[] buffer = new byte[32 * 1024]; - int bytesRead = 0; - while ((bytesRead = iStream.read(buffer)) != -1) { - fOut.write(buffer, 0, bytesRead); - } - } - finally { - iStream.close(); - fOut.close(); - } - QFile tempFile = new QFile(temp.getAbsoluteFile().toString()); - tempFile.open(OpenModeFlag.ReadOnly); - QByteArray data = tempFile.readAll(); - tempFile.close(); - tempFile.remove(); - return data; - } - - - //****************************************** - //* Begin syncing shared notebooks - //****************************************** - private void syncLinkedNotebooks() { - logger.log(logger.MEDIUM, "Authenticating linked Notebooks"); - status.message.emit(tr("Synchronizing shared notebooks.")); - List books = conn.getLinkedNotebookTable().getAll(); - - errorSharedNotebooks.clear(); - - for (int i=0; i lastSequenceNumber) { - logger.log(logger.EXTREME, "Remote changes found"); - if (lastSyncDate < linkedSyncState.getFullSyncBefore()) { - lastSequenceNumber = 0; - } - logger.log(logger.EXTREME, "Calling syncLinkedNotebook for " +books.get(i).getShareName()); - syncLinkedNotebook(linkedNoteStore, books.get(i), - lastSequenceNumber, linkedSyncState.getUpdateCount(), authToken); - } - - // Synchronize local changes - syncLocalLinkedNoteChanges(linkedNoteStore, books.get(i)); - - } catch (EDAMUserException e) { - e.printStackTrace(); - } catch (EDAMNotFoundException e) { - status.message.emit(tr("Error synchronizing \" " + - books.get(i).getShareName()+"\". Please verify you still have access to that shared notebook.")); - errorSharedNotebooks.add(books.get(i).getGuid()); - errorSharedNotebooksIgnored.put(books.get(i).getGuid(), books.get(i).getGuid()); - logger.log(logger.LOW, "Error synchronizing shared notebook. EDAMNotFound: "+e.getMessage()); - logger.log(logger.LOW, e.getStackTrace()); - error = true; - e.printStackTrace(); - } catch (EDAMSystemException e) { - error = true; - logger.log(logger.LOW, "System error authenticating against shared notebook. "+ - "Key: "+books.get(i).getShareKey() +" Error:" +e.getMessage()); - e.printStackTrace(); - } catch (TException e) { - error = true; - e.printStackTrace(); - } - } - - // Cleanup tags - conn.getTagTable().removeUnusedLinkedTags(); - conn.getTagTable().cleanupTags(); - tagSignal.listChanged.emit(); - return; - } - - - //************************************************************** - //* Linked notebook contents (from someone else's account) - //************************************************************* - private void syncLinkedNotebook(Client linkedNoteStore, LinkedNotebook book, int usn, int highSequence, String token) { - logger.log(logger.EXTREME, "Entering syncLinkedNotebook"); - if (ignoreLinkedNotebooks.contains(book.getGuid())) - return; - List dirtyNotes = conn.getNoteTable().getDirtyLinkedNotes(); - if (dirtyNoteGuids == null) - dirtyNoteGuids = new ArrayList(); - - for (int i=0; i tags, String notebookGuid) { - logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteTags"); - if (tags != null) { - for (int i=0; i notebooks, boolean readOnly, LinkedNotebook linked) { - logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteNotebooks"); - if (notebooks != null) { - for (int i=0; i newNotes, String token) { - if (newNotes == null) - return; - for (int i=0; i notes = conn.getNoteTable().getDirtyLinked(notebookGuid); - logger.log(logger.EXTREME, "Number of changes found: " +notes.size()); - for (int i=0; i errorSharedNotebooks; + public volatile HashMap errorSharedNotebooksIgnored; + public volatile boolean isConnected; + public volatile boolean keepRunning; + public volatile String authToken; + private long evernoteUpdateCount; + private final String userAgent = "NeighborNote/" + System.getProperty("os.name") + +"/"+System.getProperty("java.vendor") + "/" + + System.getProperty("java.version") +";"; + + public volatile NoteStore.Client localNoteStore; + private UserStore.Client userStore; + + public volatile StatusSignal status; + public volatile TagSignal tagSignal; + public volatile NotebookSignal notebookSignal; + public volatile NoteIndexSignal noteIndexSignal; + public volatile NoteSignal noteSignal; + public volatile SavedSearchSignal searchSignal; + public volatile NoteResourceSignal resourceSignal; + public volatile SyncSignal syncSignal; + public volatile LimitSignal limitSignal; + public volatile boolean authRefreshNeeded; + public volatile boolean syncNeeded; + public volatile boolean disableUploads; + public volatile boolean syncDeletedContent; + private volatile List dirtyNoteGuids; + + public volatile String username = ""; + public volatile String password = ""; + public volatile String userStoreUrl; + public String noteStoreUrlBase; + private THttpClient userStoreTrans; + private TBinaryProtocol userStoreProt; + //private AuthenticationResult authResult; + private AuthenticationResult linkedAuthResult; + private User user; +// private long authTimeRemaining; + public long authRefreshTime; + public long failedRefreshes = 0; + public THttpClient noteStoreTrans; + public TBinaryProtocol noteStoreProt; + public String noteStoreUrl; + public long sequenceDate; + public int updateSequenceNumber; + private boolean refreshNeeded; + private volatile LinkedBlockingQueue workQueue; + private static int MAX_QUEUED_WAITING = 1000; + String dbuid; + String dburl; + String indexUrl; + String resourceUrl; + String behaviorUrl; + + String dbpswd; + String dbcpswd; + private final TreeSet ignoreTags; + private final TreeSet ignoreNotebooks; + private final TreeSet ignoreLinkedNotebooks; + private HashMap badTagSync; + + + public SyncRunner(String logname, String u, String i, String r, String b, String uid, String pswd, String cpswd) { + logger = new ApplicationLogger(logname); + + noteSignal = new NoteSignal(); + status = new StatusSignal(); + tagSignal = new TagSignal(); + notebookSignal = new NotebookSignal(); + noteIndexSignal = new NoteIndexSignal(); + noteSignal = new NoteSignal(); + searchSignal = new SavedSearchSignal(); + syncSignal = new SyncSignal(); + resourceSignal = new NoteResourceSignal(); + limitSignal = new LimitSignal(); + resourceUrl = r; + indexUrl = i; + behaviorUrl = b; + + dbuid = uid; + dburl = u; + dbpswd = pswd; + dbcpswd = cpswd; +// this.setAutoDelete(false); + + isConnected = false; + syncNeeded = false; + authRefreshNeeded = false; + keepRunning = true; + idle = true; + disableUploads = false; + ignoreTags = new TreeSet(); + ignoreNotebooks = new TreeSet(); + ignoreLinkedNotebooks = new TreeSet(); + +// setAutoDelete(false); + workQueue=new LinkedBlockingQueue(MAX_QUEUED_WAITING); + } + @Override + public void run() { + errorSharedNotebooks = new ArrayList(); + errorSharedNotebooksIgnored = new HashMap(); + try { + logger.log(logger.EXTREME, "Starting thread"); + conn = new DatabaseConnection(logger, dburl, indexUrl, resourceUrl, behaviorUrl, dbuid, dbpswd, dbcpswd, 200); + while(keepRunning) { + logger.log(logger.EXTREME, "Blocking until work is found"); + String work = workQueue.take(); + logger.log(logger.LOW, "Dirty Notes Before Sync: " +new Integer(conn.getNoteTable().getDirtyCount()).toString()); + logger.log(logger.EXTREME, "Work found: " +work); + if (work.equalsIgnoreCase("stop")) { + idle=false; + return; + } + conn.getNoteTable().dumpDirtyNotes(); // Debugging statement + idle=false; + error=false; + if (syncNeeded) { + logger.log(logger.EXTREME, "SyncNeeded is true"); + refreshNeeded=false; + sequenceDate = conn.getSyncTable().getLastSequenceDate(); + updateSequenceNumber = conn.getSyncTable().getUpdateSequenceNumber(); + try { + logger.log(logger.EXTREME, "Beginning sync"); + evernoteSync(localNoteStore); + logger.log(logger.EXTREME, "Sync finished"); + } catch (UnknownHostException e) { + status.message.emit(e.getMessage()); + } + } + idle=true; + logger.log(logger.EXTREME, "Signaling refresh finished. refreshNeeded=" +refreshNeeded); + syncSignal.finished.emit(refreshNeeded); + if (error) { + syncSignal.errorDisconnect.emit(); + status.message.emit(tr("Error synchronizing - see log for details.")); + } + logger.log(logger.LOW, "Dirty Notes After Sync: " +new Integer(conn.getNoteTable().getDirtyCount()).toString()); + conn.getNoteTable().dumpDirtyNotes(); + logger.log(logger.LOW, "---"); + } + } + catch (InterruptedException e1) { + e1.printStackTrace(); + } + conn.dbShutdown(); + } + + + public DatabaseConnection getConnection() { + return conn; + } + + public boolean isIdle() { + return idle; + } + + + public void setConnected(boolean c) { + isConnected = c; + } + public void setKeepRunning(boolean r) { + logger.log(logger.EXTREME, "Setting keepRunning=" +r); + keepRunning = r; + } + public void setNoteStore(NoteStore.Client c) { + logger.log(logger.EXTREME, "Setting NoteStore in sync thread"); + localNoteStore = c; + } + public void setUserStore(UserStore.Client c) { + logger.log(logger.EXTREME, "Setting UserStore in sync thread"); + userStore = c; + } + + public void setEvernoteUpdateCount(long s) { + logger.log(logger.EXTREME, "Setting Update Count in sync thread"); + evernoteUpdateCount = s; + } + + //*************************************************************** + //*************************************************************** + //** These functions deal with Evernote communications + //*************************************************************** + //*************************************************************** + // Synchronize changes with Evernote + @SuppressWarnings("unused") + private void evernoteSync(Client noteStore) throws java.net.UnknownHostException { + logger.log(logger.HIGH, "Entering SyncRunner.evernoteSync"); + + // Rebuild list of tags & notebooks to ignore + ignoreNotebooks.clear(); + List ignore = conn.getSyncTable().getIgnoreRecords("NOTEBOOK"); + for (int i=0; i sequenceDate) { + logger.log(logger.EXTREME, "Full sequence date has expired"); + sequenceDate = 0; + conn.getSyncTable().setLastSequenceDate(0); + updateSequenceNumber = 0; + conn.getSyncTable().setUpdateSequenceNumber(0); + } + // Check for "special" sync instructions + String syncLinked = conn.getSyncTable().getRecord("FullLinkedNotebookSync"); + String syncShared = conn.getSyncTable().getRecord("FullSharedNotebookSync"); + String syncNotebooks = conn.getSyncTable().getRecord("FullNotebookSync"); + String syncInkNoteImages = conn.getSyncTable().getRecord("FullInkNoteImageSync"); + if (syncLinked != null) { + downloadAllLinkedNotebooks(localNoteStore); + } + if (syncShared != null) { + downloadAllSharedNotebooks(localNoteStore); + } + if (syncNotebooks != null) { + downloadAllNotebooks(localNoteStore); + } + + if (syncInkNoteImages != null) { + List guids = conn.getNoteTable().noteResourceTable.findInkNotes(); + for (int i=0; i updateSequenceNumber) { + logger.log(logger.EXTREME, "Refresh needed is true"); + refreshNeeded = true; + logger.log(logger.EXTREME, "Downloading changes"); + syncRemoteToLocal(localNoteStore); + } + + //***************************************** + //* Sync linked/shared notebooks + //***************************************** - //syncLinkedNotebooks(); ++ syncLinkedNotebooks(); + //conn.getNoteTable().getDirty(); + //disableUploads = true; /// DELETE THIS LINE!!!! + if (!disableUploads) { + logger.log(logger.EXTREME, "Uploading changes"); + // Synchronize remote changes + if (!error) + syncExpunged(localNoteStore); + if (!error) + syncLocalTags(localNoteStore); + if (!error) + syncLocalNotebooks(localNoteStore); + if (!error) + syncLocalLinkedNotebooks(localNoteStore); + if (!error) + syncDeletedNotes(localNoteStore); + if (!error) + syncLocalNotes(); + if (!error) + syncLocalSavedSearches(localNoteStore); + } + + status.message.emit(tr("Cleaning up")); + List notes = conn.getNoteTable().expungeIgnoreSynchronizedNotes(conn.getSyncTable().getIgnoreRecords("NOTEBOOK"), + conn.getSyncTable().getIgnoreRecords("TAG"), conn.getSyncTable().getIgnoreRecords("LINKEDNOTEBOOK")); + if (notes.size() > 0) + syncSignal.refreshLists.emit(); + + //***************************************** + //* End of synchronization + //***************************************** + if (refreshNeeded) + syncSignal.refreshLists.emit(); + + if (!error) { + logger.log(logger.LOW, "Sync completed. Errors=" +error); + if (!disableUploads) + status.message.emit(tr("Synchronizing complete")); + else + status.message.emit(tr("Download syncronization complete. Uploads have been disabled.")); + + logger.log(logger.EXTREME, "Saving sync time"); + if (syncState.getCurrentTime() > sequenceDate) + sequenceDate = syncState.getCurrentTime(); + if (syncState.getUpdateCount() > updateSequenceNumber) + updateSequenceNumber = syncState.getUpdateCount(); + conn.getSyncTable().setLastSequenceDate(sequenceDate); + conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber); + } + } + logger.log(logger.HIGH, "Leaving SyncRunner.evernoteSync"); + } + + // Sync deleted items with Evernote + private void syncExpunged(Client noteStore) { + logger.log(logger.HIGH, "Entering SyncRunner.syncExpunged"); + + List expunged = conn.getDeletedTable().getAllDeleted(); + boolean error = false; + for (int i=0; i notes = conn.getNoteTable().getDirty(); + // Sync the local notebooks with Evernote's + for (int i=0; i 0 && (enNote.isActive() == false || enNote.getDeleted() > 0)) { - // Check that the note is valid. - if (enNote.isActive() == true || enNote.getDeleted() == 0) { - conn.getNoteTable().deleteNote(enNote.getGuid()); - enNote = conn.getNoteTable().getNote(enNote.getGuid(), false, false, false, false, false); - } ++ // Check that the note is valid. ++ if (enNote.isActive() == true || enNote.getDeleted() == 0) { ++ conn.getNoteTable().deleteNote(enNote.getGuid()); ++ enNote = conn.getNoteTable().getNote(enNote.getGuid(), false, false, false, false, false); ++ } + if (syncDeletedContent) { + logger.log(logger.EXTREME, "Deleted note found & synch content selected"); + Note delNote = conn.getNoteTable().getNote(enNote.getGuid(), true, true, true, true, true); + delNote = getNoteContent(delNote); + delNote = noteStore.updateNote(authToken, delNote); + enNote.setUpdateSequenceNum(delNote.getUpdateSequenceNum()); + conn.getNoteTable().updateNoteSequence(enNote.getGuid(), enNote.getUpdateSequenceNum()); + } else { + logger.log(logger.EXTREME, "Deleted note found & sync content not selected"); + int usn = noteStore.deleteNote(authToken, enNote.getGuid()); + enNote.setUpdateSequenceNum(usn); + conn.getNoteTable().updateNoteSequence(enNote.getGuid(), enNote.getUpdateSequenceNum()); + } + logger.log(logger.EXTREME, "Resetting deleted dirty flag"); + conn.getNoteTable().resetDirtyFlag(enNote.getGuid()); + updateSequenceNumber = enNote.getUpdateSequenceNum(); + logger.log(logger.EXTREME, "Saving sequence number"); + conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber); + } + } catch (EDAMUserException e) { - logger.log(logger.LOW, "*** EDAM User Excepton syncLocalNotes "+e); ++ logger.log(logger.LOW, "*** EDAM User Excepton syncLocalNotes "+e); + //status.message.emit("Error sending local note: " +e.getParameter()); + //logger.log(logger.LOW, e.toString()); + //error = true; + } catch (EDAMSystemException e) { + if (e.getErrorCode() == EDAMErrorCode.RATE_LIMIT_REACHED) { + limitSignal.rateLimitReached.emit(e.getRateLimitDuration()); + } + logger.log(logger.LOW, "*** EDAM System Excepton syncLocalNotes "+e); + status.message.emit(tr("Error: ") +e); + logger.log(logger.LOW, e.toString()); + error = true; + } catch (EDAMNotFoundException e) { - logger.log(logger.LOW, "*** EDAM Not Found Excepton syncLocalNotes " +e); ++ logger.log(logger.LOW, "*** EDAM Not Found Excepton syncLocalNotes " +e); + //status.message.emit("Error deleting local note: " +e +" - Continuing"); + //logger.log(logger.LOW, e.toString()); + //error = true; + } catch (TException e) { + logger.log(logger.LOW, "*** EDAM TExcepton syncLocalNotes "+e); + status.message.emit(tr("Error sending local note: ") +e); + logger.log(logger.LOW, e.toString()); + error = true; + } + } + } + // Sync notes with Evernote + private void syncLocalNotes() { + logger.log(logger.HIGH, "Entering SyncRunner.syncNotes"); + logger.log(logger.LOW, "Dirty local notes found: " +new Integer(conn.getNoteTable().getDirtyCount()).toString()); + status.message.emit(tr("Sending local notes.")); + + List notes = conn.getNoteTable().getDirty(); + // Sync the local notebooks with Evernote's + for (int i=0; i 0) { + logger.log(logger.EXTREME, "Active dirty note found - non new - " +enNote.getGuid()); + logger.log(logger.EXTREME, "Fetching note content"); + enNote = getNoteContent(enNote); + logger.log(logger.MEDIUM, "Updating note : "+ enNote.getGuid() +" " +enNote.getTitle()+""); + enNote = noteStore.updateNote(token, enNote); + } else { + logger.log(logger.EXTREME, "Active dirty found - new note " +enNote.getGuid()); + String oldGuid = enNote.getGuid(); + logger.log(logger.MEDIUM, "Fetching note content"); + enNote = getNoteContent(enNote); + logger.log(logger.MEDIUM, "Creating note : "+ enNote.getGuid() +" " +enNote.getTitle()+""); + enNote = noteStore.createNote(token, enNote); + logger.log(logger.MEDIUM, "New note Guid : "+ enNote.getGuid() +" " +enNote.getTitle()+""); + noteSignal.guidChanged.emit(oldGuid, enNote.getGuid()); + conn.getNoteTable().updateNoteGuid(oldGuid, enNote.getGuid()); + } + updateSequenceNumber = enNote.getUpdateSequenceNum(); + logger.log(logger.EXTREME, "Saving note"); + conn.getNoteTable().updateNoteSequence(enNote.getGuid(), enNote.getUpdateSequenceNum()); + List rl = enNote.getResources(); + logger.log(logger.EXTREME, "Getting note resources"); + for (int j=0; j remoteList = new ArrayList(); + try { + logger.log(logger.EXTREME, "Getting remote notebooks to compare with local"); + remoteList = noteStore.listNotebooks(authToken); + } catch (EDAMUserException e1) { + logger.log(logger.LOW, "*** EDAM User Excepton syncLocalNotebooks getting remote Notebook List"); + status.message.emit(tr("Error: ") +e1); + logger.log(logger.LOW, e1.toString()); + error = true; + } catch (EDAMSystemException e1) { + if (e1.getErrorCode() == EDAMErrorCode.RATE_LIMIT_REACHED) { + limitSignal.rateLimitReached.emit(e1.getRateLimitDuration()); + } + logger.log(logger.LOW, "*** EDAM System Excepton syncLocalNotebooks getting remote Notebook List"); + status.message.emit(tr("Error: ") +e1); + logger.log(logger.LOW, e1.toString()); + error = true; + } catch (TException e1) { + logger.log(logger.LOW, "*** EDAM Transaction Excepton syncLocalNotebooks getting remote Notebook List"); + status.message.emit(tr("Error: ") +e1); + logger.log(logger.LOW, e1.toString()); + error = true; + } + logger.log(logger.EXTREME, "Getting local dirty notebooks"); + List notebooks = conn.getNotebookTable().getDirty(); + int sequence; + // Sync the local notebooks with Evernote's + for (int i=0; i 0) { + logger.log(logger.EXTREME, "Existing notebook is dirty"); + sequence = noteStore.updateNotebook(authToken, enNotebook); + } else { + logger.log(logger.EXTREME, "New dirty notebook found"); + String oldGuid = enNotebook.getGuid(); + boolean found = false; + + // Look for a notebook with the same name. If one is found, we don't need + // to create another one + logger.log(logger.EXTREME, "Looking for matching notebook name"); + for (int k=0; k remoteList = new ArrayList(); + status.message.emit(tr("Sending local tags.")); + + try { + logger.log(logger.EXTREME, "Getting remote tags to compare names with the local tags"); + remoteList = noteStore.listTags(authToken); + } catch (EDAMUserException e1) { + logger.log(logger.LOW, "*** EDAM User Excepton syncLocalTags getting remote Tag List"); + status.message.emit(tr("Error: ") +e1); + logger.log(logger.LOW, e1.toString()); + error = true; + } catch (EDAMSystemException e1) { + if (e1.getErrorCode() == EDAMErrorCode.RATE_LIMIT_REACHED) { + limitSignal.rateLimitReached.emit(e1.getRateLimitDuration()); + } + logger.log(logger.LOW, "*** EDAM System Excepton syncLocalTags getting remote Tag List"); + status.message.emit(tr("Error: ") +e1); + logger.log(logger.LOW, e1.toString()); + error = true; + } catch (TException e1) { + logger.log(logger.LOW, "*** EDAM Transaction Excepton syncLocalTags getting remote Tag List"); + status.message.emit(tr("Error: ") +e1); + logger.log(logger.LOW, e1.toString()); + error = true; + } + + int sequence; + + if (badTagSync == null) + badTagSync = new HashMap(); + else + badTagSync.clear(); + + Tag enTag = findNextTag(); + + // This is a hack. Sometimes this function goes flookey and goes into a + // perpetual loop. This causes NeverNote to flood Evernote's servers. + // This is a safety valve to prevent unlimited loops. + int maxCount = conn.getTagTable().getDirty().size()+10; + int loopCount = 0; + + while(enTag!=null && loopCount < maxCount) { + loopCount++; +// if (authRefreshNeeded) +// if (!refreshConnection()) +// return; + + try { + if (enTag.getUpdateSequenceNum() > 0) { + logger.log(logger.EXTREME, "Updating tag"); + sequence = noteStore.updateTag(authToken, enTag); + } else { + + // Look for a tag with the same name. If one is found, we don't need + // to create another one + logger.log(logger.EXTREME, "New tag. Comparing with remote names"); + boolean found = false; + String oldGuid = enTag.getGuid(); + for (int k=0; k list = conn.getLinkedNotebookTable().getDirtyGuids(); + for (int i=0; i remoteList = new ArrayList(); + status.message.emit(tr("Sending saved searches.")); + + logger.log(logger.EXTREME, "Getting saved searches to compare with local"); + try { + remoteList = noteStore.listSearches(authToken); + } catch (EDAMUserException e1) { + logger.log(logger.LOW, "*** EDAM User Excepton syncLocalTags getting remote saved search List"); + status.message.emit(tr("Error: ") +e1); + logger.log(logger.LOW, e1.toString()); + error = true; + } catch (EDAMSystemException e1) { + if (e1.getErrorCode() == EDAMErrorCode.RATE_LIMIT_REACHED) { + limitSignal.rateLimitReached.emit(e1.getRateLimitDuration()); + } + logger.log(logger.LOW, "*** EDAM System Excepton syncLocalTags getting remote saved search List"); + status.message.emit(tr("Error: ") +e1); + logger.log(logger.LOW, e1.toString()); + error = true; + } catch (TException e1) { + logger.log(logger.LOW, "*** EDAM Transaction Excepton syncLocalTags getting remote saved search List"); + status.message.emit(tr("Error: ") +e1); + logger.log(logger.LOW, e1.toString()); + error = true; + } + + List searches = conn.getSavedSearchTable().getDirty(); + int sequence; + // Sync the local notebooks with Evernote's + logger.log(logger.EXTREME, "Beginning to send saved searches"); + for (int i=0; i 0) + sequence = noteStore.updateSearch(authToken, enSearch); + else { + logger.log(logger.EXTREME, "New saved search found."); + // Look for a tag with the same name. If one is found, we don't need + // to create another one + boolean found = false; + logger.log(logger.EXTREME, "Matching remote saved search names with local"); + for (int k=0; k dirtyNotes = conn.getNoteTable().getDirty(); - dirtyNoteGuids = new ArrayList(); ++ dirtyNoteGuids = new ArrayList(); + for (int i=0; i 0 && keepRunning) { + logger.log(logger.EXTREME, "emitting sequence number to main thread"); + updateSequenceNumber = chunk.getChunkHighUSN(); + conn.getSyncTable().setLastSequenceDate(chunk.getCurrentTime()); + conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber); +// conn.commitTransaction(); + } + + + if (more) { + long pct = chunk.getChunkHighUSN() * 100; + conn.getSyncTable().setLastSequenceDate(chunk.getCurrentTime()); + pct = pct/evernoteUpdateCount; + status.message.emit(tr("Downloading ") +new Long(pct).toString()+tr("% complete.")); + } +// conn.commitTransaction(); + } + logger.log(logger.HIGH, "Leaving SyncRunner.syncRemoteToLocal"); + } + // Sync expunged notes + private void syncExpungedNotes(SyncChunk chunk) { + // Do the local deletes + logger.log(logger.EXTREME, "Doing local deletes"); + List guid = chunk.getExpungedNotes(); + if (guid != null) { + for (int i=0; i tags) { + logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteTags"); + if (tags != null) { + for (int i=0; i searches) { + logger.log(logger.EXTREME, "Entering SyncRunner.syncSavedSearches"); + if (searches != null) { + for (int i=0; i books) { + logger.log(logger.EXTREME, "Entering SyncRunner.syncLinkedNotebooks"); + if (books != null) { + for (int i=0; i notebooks) { + logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteNotebooks"); + if (notebooks != null) { + for (int i=0; i 0) { +// conn.getSharedNotebookTable().expungeNotebookByGuid(notebooks.get(i).getGuid(), false); +// for (int j=0; j books = noteStore.getSharedNotebookByAuth(authToken); +// } + // Sync remote Resources + private void syncRemoteResources(Client noteStore, List resource) { + logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteResources"); + if (resource != null) { + for (int i=0; i note, boolean fullSync, String token) { - ++ + if (note != null) { - - logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteNotes"); - logger.log(logger.LOW, "Local Dirty Notes: "); - logger.log(logger.LOW, "Remote Dirty Notes:"); - for (int i=0; i books = conn.getNotebookTable().getAllLocal(); + String notebookGuid = null; + for (int i=0; i>> 4) & 0x0F; + int two_halfs = 0; + do { + if ((0 <= halfbyte) && (halfbyte <= 9)) + buf.append((char) ('0' + halfbyte)); + else + buf.append((char) ('a' + (halfbyte - 10))); + halfbyte = element & 0x0F; + } while(two_halfs++ < 1); + } + return buf.toString(); + } + + + + //******************************************************* + //* Find dirty tags, which do not have newly created parents + //******************************************************* + private Tag findNextTag() { + logger.log(logger.HIGH, "Entering SyncRunner.findNextTag"); + Tag nextTag = null; + List tags = conn.getTagTable().getDirty(); + + // Find the parent. If the parent has a sequence > 0 then it is a good + // parent. + for (int i=0; i 0) { + logger.log(logger.HIGH, "Leaving SyncRunner.findNextTag - tag found"); + return tags.get(i); + } + } + } + + logger.log(logger.HIGH, "Leaving SyncRunner.findNextTag - no tags returned"); + return nextTag; + } + + + // Connect to Evernote + public boolean enConnect() { + try { + userStoreTrans = new THttpClient(userStoreUrl); + userStoreTrans.setCustomHeader("User-Agent", userAgent); + } catch (TTransportException e) { + QMessageBox mb = new QMessageBox(QMessageBox.Icon.Critical, "Transport Excepton", e.getLocalizedMessage()); + mb.exec(); + e.printStackTrace(); + } + userStoreProt = new TBinaryProtocol(userStoreTrans); + userStore = new UserStore.Client(userStoreProt, userStoreProt); + + syncSignal.saveUserStore.emit(userStore); + try { + //authResult = userStore.authenticate(username, password, consumerKey, consumerSecret); + user = userStore.getUser(authToken); + } catch (EDAMUserException e) { + QMessageBox mb = new QMessageBox(QMessageBox.Icon.Critical, "Error", "Invalid Authorization"); + mb.exec(); + isConnected = false; + return false; + } catch (EDAMSystemException e) { + if (e.getErrorCode() == EDAMErrorCode.RATE_LIMIT_REACHED) { + limitSignal.rateLimitReached.emit(e.getRateLimitDuration()); + } + QMessageBox mb = new QMessageBox(QMessageBox.Icon.Critical, "EDAM System Excepton", e.getLocalizedMessage()); + mb.exec(); + e.printStackTrace(); + isConnected = false; + } catch (TException e) { + QMessageBox mb = new QMessageBox(QMessageBox.Icon.Critical, "Transport Excepton", e.getLocalizedMessage()); + mb.exec(); + e.printStackTrace(); + isConnected = false; + } + + boolean versionOk = false; + try { + versionOk = userStore.checkVersion("NeighborNote", + com.evernote.edam.userstore.Constants.EDAM_VERSION_MAJOR, + com.evernote.edam.userstore.Constants.EDAM_VERSION_MINOR); + } catch (TException e) { + e.printStackTrace(); + isConnected = false; + } + if (!versionOk) { + System.err.println("Incomatible EDAM client protocol version"); + isConnected = false; + } + //if (authResult != null) { + //user = authResult.getUser(); + //authToken = authResult.getAuthenticationToken(); - if (user == null || noteStoreUrlBase == null) { - logger.log(logger.LOW, "Error retrieving user information. Aborting."); - System.err.println("Error retrieving user information."); - isConnected = false; - QMessageBox mb = new QMessageBox(QMessageBox.Icon.Critical, tr("Connection Error"), tr("Error retrieving user information. Synchronization not complete")); - mb.exec(); - return false; - - } ++ if (user == null || noteStoreUrlBase == null) { ++ logger.log(logger.LOW, "Error retrieving user information. Aborting."); ++ System.err.println("Error retrieving user information."); ++ isConnected = false; ++ QMessageBox mb = new QMessageBox(QMessageBox.Icon.Critical, tr("Connection Error"), tr("Error retrieving user information. Synchronization not complete")); ++ mb.exec(); ++ return false; ++ ++ } + noteStoreUrl = noteStoreUrlBase + user.getShardId(); + syncSignal.saveAuthToken.emit(authToken); + syncSignal.saveNoteStore.emit(localNoteStore); + + + try { + noteStoreTrans = new THttpClient(noteStoreUrl); + noteStoreTrans.setCustomHeader("User-Agent", userAgent); + } catch (TTransportException e) { + QMessageBox mb = new QMessageBox(QMessageBox.Icon.Critical, "Transport Excepton", e.getLocalizedMessage()); + mb.exec(); + e.printStackTrace(); + isConnected = false; + } + noteStoreProt = new TBinaryProtocol(noteStoreTrans); + localNoteStore = + new NoteStore.Client(noteStoreProt, noteStoreProt); + isConnected = true; + //authTimeRemaining = authResult.getExpiration() - authResult.getCurrentTime(); + //authRefreshTime = authTimeRemaining / 2; + //} + + // Get user information + try { + User user = userStore.getUser(authToken); + syncSignal.saveUserInformation.emit(user); + } catch (EDAMUserException e1) { + e1.printStackTrace(); + } catch (EDAMSystemException e1) { + if (e1.getErrorCode() == EDAMErrorCode.RATE_LIMIT_REACHED) { + limitSignal.rateLimitReached.emit(e1.getRateLimitDuration()); + } + e1.printStackTrace(); + } catch (TException e1) { + e1.printStackTrace(); + } + + return isConnected; + } + // Disconnect from the database + public void enDisconnect() { + isConnected = false; + } + + /* + // Refresh the connection + private synchronized boolean refreshConnection() { + + logger.log(logger.EXTREME, "Entering SyncRunner.refreshConnection()"); +// Calendar cal = Calendar.getInstance(); + + // If we are not connected let's get out of here + if (!isConnected) + return false; + + // If we fail too many times, then let's give up. + if (failedRefreshes >=5) { + logger.log(logger.EXTREME, "Refresh attempts have failed. Disconnecting."); + isConnected = false; + status.message.emit(tr("Unable to synchronize - Authentication failed")); + return false; + } + + // If this is the first time through, then we need to set this +// if (authRefreshTime == 0 || cal.getTimeInMillis() > authRefreshTime) +// authRefreshTime = cal.getTimeInMillis(); + + // // Default to checking again in 5 min. This in case we fail. + // authRefreshTime = authRefreshTime +(5*60*1000); + + // Try to get a new token + AuthenticationResult newAuth = null; + logger.log(logger.EXTREME, "Beginning to try authentication refresh"); + try { + if (userStore != null && authToken != null) + newAuth = userStore.refreshAuthentication(authToken); + else + return false; + logger.log(logger.EXTREME, "UserStore.refreshAuthentication has succeeded."); + } catch (EDAMUserException e) { + e.printStackTrace(); + syncSignal.authRefreshComplete.emit(false); + failedRefreshes++; + return false; + } catch (EDAMSystemException e) { + e.printStackTrace(); + syncSignal.authRefreshComplete.emit(false); + failedRefreshes++; + return false; + } catch (TException e) { + e.printStackTrace(); + syncSignal.authRefreshComplete.emit(false); + failedRefreshes++; + return false; + } + + // If we didn't get a good auth, then we've failed + if (newAuth == null) { + failedRefreshes++; + status.message.emit(tr("Unable to synchronize - Authentication failed")); + logger.log(logger.EXTREME, "Authentication failure #" +failedRefreshes); + status.message.emit(tr("Unable to synchronize - Authentication failed")); + syncSignal.authRefreshComplete.emit(false); + return false; + } + + // We got a good token. Now we need to setup the time to renew it. + logger.log(logger.EXTREME, "Saving authentication tokens"); + authResult = newAuth; + authToken = new String(newAuth.getAuthenticationToken()); +// authTimeRemaining = authResult.getExpiration() - authResult.getCurrentTime(); +// authRefreshTime = cal.getTimeInMillis() + (authTimeRemaining/4); + failedRefreshes=0; + syncSignal.authRefreshComplete.emit(true); + authRefreshNeeded = false; + + // This should never happen, but if it does we consider this a faild attempt. +// if (authTimeRemaining <= 0) { +// failedRefreshes++; +// syncSignal.authRefreshComplete.emit(false); +// } + + return true; + } + + */ + + public synchronized boolean addWork(String request) { + if (workQueue.offer(request)) + return true; + return false; + } + + private Note getNoteContent(Note n) { + QTextCodec codec = QTextCodec.codecForLocale(); + codec = QTextCodec.codecForName("UTF-8"); + n.setContent(codec.toUnicode(new QByteArray(n.getContent()))); + return n; + } + + + + //********************************************************* + //* Special download instructions. Used for DB upgrades + //********************************************************* + private void downloadAllSharedNotebooks(Client noteStore) { + try { + List books = noteStore.listSharedNotebooks(authToken); + logger.log(logger.LOW, "Shared notebooks found = " +books.size()); + for (int i=0; i books = noteStore.listNotebooks(authToken); + logger.log(logger.LOW, "Shared notebooks found = " +books.size()); + for (int i=0; i books = noteStore.listLinkedNotebooks(authToken); + logger.log(logger.LOW, "Linked notebooks found = " +books.size()); + for (int i=0; i nvps = new ArrayList (); + nvps.add(new BasicNameValuePair("auth", authToken)); + + try { + post.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8)); + } catch (UnsupportedEncodingException e1) { + e1.printStackTrace(); + } + try { + HttpResponse response = http.execute(post); + HttpEntity resEntity = response.getEntity(); + InputStream is = resEntity.getContent(); + QByteArray data = writeToFile(is); + conn.getInkImagesTable().saveImage(guid, slice, data); + } catch (ClientProtocolException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + slice++; + } + http.getConnectionManager().shutdown(); + noteSignal.noteChanged.emit(r.getNoteGuid(), null); // Signal to ivalidate note cache + } + + + public QByteArray writeToFile(InputStream iStream) throws IOException { + + File temp = File.createTempFile("nn-inknote-temp", ".png"); + + // Save InputStream to the file. + BufferedOutputStream fOut = null; + try { + fOut = new BufferedOutputStream(new FileOutputStream(temp)); + byte[] buffer = new byte[32 * 1024]; + int bytesRead = 0; + while ((bytesRead = iStream.read(buffer)) != -1) { + fOut.write(buffer, 0, bytesRead); + } + } + finally { + iStream.close(); + fOut.close(); + } + QFile tempFile = new QFile(temp.getAbsoluteFile().toString()); + tempFile.open(OpenModeFlag.ReadOnly); + QByteArray data = tempFile.readAll(); + tempFile.close(); + tempFile.remove(); + return data; + } + + + //****************************************** + //* Begin syncing shared notebooks + //****************************************** + private void syncLinkedNotebooks() { + logger.log(logger.MEDIUM, "Authenticating linked Notebooks"); + status.message.emit(tr("Synchronizing shared notebooks.")); + List books = conn.getLinkedNotebookTable().getAll(); + + errorSharedNotebooks.clear(); + + for (int i=0; i lastSequenceNumber) { + logger.log(logger.EXTREME, "Remote changes found"); + if (lastSyncDate < linkedSyncState.getFullSyncBefore()) { + lastSequenceNumber = 0; + } + logger.log(logger.EXTREME, "Calling syncLinkedNotebook for " +books.get(i).getShareName()); + syncLinkedNotebook(linkedNoteStore, books.get(i), + lastSequenceNumber, linkedSyncState.getUpdateCount(), authToken); + } + + // Synchronize local changes + syncLocalLinkedNoteChanges(linkedNoteStore, books.get(i)); + + } catch (EDAMUserException e) { + e.printStackTrace(); + } catch (EDAMNotFoundException e) { + status.message.emit(tr("Error synchronizing \" " + + books.get(i).getShareName()+"\". Please verify you still have access to that shared notebook.")); + errorSharedNotebooks.add(books.get(i).getGuid()); + errorSharedNotebooksIgnored.put(books.get(i).getGuid(), books.get(i).getGuid()); + logger.log(logger.LOW, "Error synchronizing shared notebook. EDAMNotFound: "+e.getMessage()); + logger.log(logger.LOW, e.getStackTrace()); + error = true; + e.printStackTrace(); + } catch (EDAMSystemException e) { + if (e.getErrorCode() == EDAMErrorCode.RATE_LIMIT_REACHED) { + limitSignal.rateLimitReached.emit(e.getRateLimitDuration()); + } + error = true; + logger.log(logger.LOW, "System error authenticating against shared notebook. "+ + "Key: "+books.get(i).getShareKey() +" Error:" +e.getMessage()); + e.printStackTrace(); + } catch (TException e) { + error = true; + e.printStackTrace(); + } + } + + // Cleanup tags + conn.getTagTable().removeUnusedLinkedTags(); + conn.getTagTable().cleanupTags(); + tagSignal.listChanged.emit(); + return; + } + + + //************************************************************** + //* Linked notebook contents (from someone else's account) + //************************************************************* + private void syncLinkedNotebook(Client linkedNoteStore, LinkedNotebook book, int usn, int highSequence, String token) { + logger.log(logger.EXTREME, "Entering syncLinkedNotebook"); + if (ignoreLinkedNotebooks.contains(book.getGuid())) + return; + List dirtyNotes = conn.getNoteTable().getDirtyLinkedNotes(); + if (dirtyNoteGuids == null) - dirtyNoteGuids = new ArrayList(); ++ dirtyNoteGuids = new ArrayList(); + + for (int i=0; i tags, String notebookGuid) { + logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteTags"); + if (tags != null) { + for (int i=0; i notebooks, boolean readOnly, LinkedNotebook linked) { + logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteNotebooks"); + if (notebooks != null) { + for (int i=0; i newNotes, String token) { + if (newNotes == null) + return; + for (int i=0; i notes = conn.getNoteTable().getDirtyLinked(notebookGuid); + logger.log(logger.EXTREME, "Number of changes found: " +notes.size()); + for (int i=0; i