OSDN Git Service

Merge branch 'master' of http://git.code.sf.net/p/nevernote/code into develop
[neighbornote/NeighborNote.git] / src / cx / fbn / nevernote / Global.java
1 /*
2  * This file is part of NixNote/NeighborNote 
3  * Copyright 2009 Randy Baumgarte
4  * Copyright 2013 Yuki Takahashi
5  * 
6  * This file may be licensed under the terms of of the
7  * GNU General Public License Version 2 (the ``GPL'').
8  *
9  * Software distributed under the License is distributed
10  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
11  * express or implied. See the GPL for the specific language
12  * governing rights and limitations.
13  *
14  * You should have received a copy of the GPL along with this
15  * program. If not, go to http://www.gnu.org/licenses/gpl.html
16  * or write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19 */
20
21 package cx.fbn.nevernote;
22
23
24 import java.io.ByteArrayInputStream;
25 import java.io.ByteArrayOutputStream;
26 import java.io.File;
27 import java.io.IOException;
28 import java.io.ObjectInputStream;
29 import java.io.ObjectOutputStream;
30 import java.text.SimpleDateFormat;
31 import java.util.ArrayList;
32 import java.util.Calendar;
33 import java.util.HashMap;
34 import java.util.List;
35
36 import org.apache.commons.lang3.StringEscapeUtils;
37
38 import com.evernote.edam.type.Accounting;
39 import com.evernote.edam.type.PrivilegeLevel;
40 import com.evernote.edam.type.User;
41 import com.evernote.edam.type.UserAttributes;
42 import com.swabunga.spell.engine.Configuration;
43 import com.trolltech.qt.core.QByteArray;
44 import com.trolltech.qt.core.QFile;
45 import com.trolltech.qt.core.QSettings;
46 import com.trolltech.qt.core.QSize;
47 import com.trolltech.qt.gui.QPalette;
48 import com.trolltech.qt.gui.QSystemTrayIcon;
49
50 import cx.fbn.nevernote.config.FileManager;
51 import cx.fbn.nevernote.config.InitializationException;
52 import cx.fbn.nevernote.config.StartupConfig;
53 import cx.fbn.nevernote.gui.ContainsAttributeFilterTable;
54 import cx.fbn.nevernote.gui.DateAttributeFilterTable;
55 import cx.fbn.nevernote.gui.ShortcutKeys;
56 import cx.fbn.nevernote.sql.DatabaseConnection;
57 import cx.fbn.nevernote.sql.driver.NSqlQuery;
58 import cx.fbn.nevernote.utilities.ApplicationLogger;
59 import cx.fbn.nevernote.utilities.Pair;
60
61
62 //*****************************************************
63 //*****************************************************
64 //* Global constants & static functions used by 
65 //* multiple threads.
66 //*****************************************************
67 //*****************************************************
68
69 public class Global {
70         // Set current version and the known versions.
71         public static String version = "0.3";
72         public static String[] validVersions = {"0.3", "0.2", "0.1.3", "0.1.2", "0.1.1", "0.1"};
73         
74     public static String username = ""; 
75     //public static String password = "";     
76     
77
78     // Each thread has an ID.  This is used primarily to check the status
79     // of running threads.
80     public static final int mainThreadId=0;
81     public static final int syncThreadId=1;
82     public static final int tagCounterThreadId=2;
83     public static final int trashCounterThreadId=3;   // This should always be the highest thread ID
84     public static final int indexThreadId=4;    // Thread for indexing words
85     public static final int saveThreadId=5;     // Thread used for processing data to saving content
86     public static final int notebookCounterThreadId=6;   // Notebook Thread
87     public static final int indexThread03Id=7;   // unused
88     public static final int indexThread04Id=8;   // unused
89     public static final int dbThreadId=9;   // This should always be the highest thread ID
90     public static final int threadCount = 10;
91     
92     
93     // These variables deal with where the list of notes appears
94     // They will either be vertical (View_List_Narrow) or will be
95     // on top of the note (View_List_Wide).  It also has the size of
96     // thumbnails displayed in each view
97     public static int View_List_Wide = 1;
98     public static int View_List_Narrow = 2;
99     public static QSize smallThumbnailSize = new QSize(100,75);
100     public static QSize largeThumbnailSize = new QSize(300,225);
101
102     // This is used to keep a running list of passwords that the user
103     // wants us to remember.
104     public static HashMap<String,Pair<String,String>> passwordSafe = new HashMap<String, Pair<String,String>>();
105     public static List<Pair<String,String>> passwordRemember = new ArrayList<Pair<String,String>>();
106     
107     
108     //public static String currentNotebookGuid;
109     
110     // These deal with Evernote user settings
111     public static User user; 
112     public static long authTimeRemaining;
113     public static long authRefreshTime;
114     public static long failedRefreshes = 0; 
115     public static String userStoreUrl;
116     public static String noteStoreUrl;
117     public static String noteStoreUrlBase;
118
119     // When we want to shut down we set this to true to short
120     // circut other threads
121     public static boolean keepRunning;
122         
123     // In the note list, these are the column numbers
124     // so I don't need to hard code numbers.
125     public static int noteTableCreationPosition = 0;
126     public static int noteTableTitlePosition = 1;
127     public static int noteTableTagPosition = 2;
128     public static int noteTableNotebookPosition = 3;
129     public static int noteTableChangedPosition = 4;
130     public static int noteTableGuidPosition = 5;
131     public static int noteTableAuthorPosition = 6;
132     public static int noteTableSourceUrlPosition = 7;
133     public static int noteTableSubjectDatePosition = 8;
134     public static int noteTableSynchronizedPosition = 9;
135     public static int noteTableThumbnailPosition = 10;
136     public static int noteTablePinnedPosition = 11;
137     public static int noteTableColumnCount = 12;
138     public static Integer cryptCounter = 0;
139     
140     //public static int minimumWordCount = 2;
141     
142     // Regular expression to parse text with when indexing
143 //    private static String wordRegex;
144     
145     // Experimental fixes.  Set via Edit/Preferences/Debugging
146     public static boolean enableCarriageReturnFix = false;
147     public static boolean enableHTMLEntitiesFix = false;
148     
149     // Used to set & retrieve ini & Windows registry settings
150     public static QSettings     settings;     // Set & get ini settings
151     public static boolean isConnected;    // Are we connected to Evernote
152     public static boolean showDeleted = false;   // Show deleted notes?
153     public static boolean disableUploads = false;  // Should we disable uploads (used in testing features)
154         public static int messageLevel;   // The level of messages to write to the log files
155         public static String tagDelimeter = ",";   // This is used to separate out tag names when entering above note
156         public static String attachmentNameDelimeter = "------";  // Used to separate out attachment names in the res directory
157         
158         
159         //* Database fields
160         public static String    databaseName = new String("NeverNote");  // database name.  used for multiple databases to separate settings.
161         public static String    indexDatabaseName = new String("Index"); // searchable words database
162         public static String    resourceDatabaseName = new String("Resources");  // attachments database
163         public static String behaviorDatabaseName = new String("Behavior"); // 操作履歴データベース   
164         
165         public static DateAttributeFilterTable createdSinceFilter;
166         public static DateAttributeFilterTable createdBeforeFilter;
167         public static DateAttributeFilterTable changedSinceFilter;
168         public static DateAttributeFilterTable changedBeforeFilter;
169         public static ContainsAttributeFilterTable containsFilter;
170         
171         // Log file used for debugging
172         public static ApplicationLogger    logger;
173         //PrintStream stdoutStream;
174         
175         // Application key shortcuts & appearance
176         public static QPalette                          originalPalette;
177         public static ShortcutKeys                      shortcutKeys;
178         
179         public static boolean                           disableViewing;  // used to disable the editor
180         
181         // When saving a note, this is a list of things we strip out because Evernote hates them
182         public static List<String>                              invalidElements = new ArrayList<String>();
183         public static HashMap<String, ArrayList<String>>        invalidAttributes = new HashMap<String, ArrayList<String>>();
184         
185         public static boolean mimicEvernoteInterface; // Try to mimic Evernote or allow multiple notebook selection
186         public static HashMap<String,String> resourceMap;   // List of attachments for a note.
187         public static String cipherPassword = "";    // If the database is encrypted, this stores the password
188         public static String databaseCache = "16384";  // Default DB cache size
189         
190         // These are used for performance testing
191         static Calendar startTraceTime;   
192         static Calendar intervalTraceTime;
193         
194         static boolean syncOnly;
195         
196         private static FileManager fileManager;  // Used to access files & directories
197         
198     // Do initial setup 
199     public static void setup(StartupConfig startupConfig) throws InitializationException  {
200         String settingFileName = new String("NeighborNote.ini");
201         
202         // バージョン0.1.2以下で作成された古い設定ファイルを見つけたら、ホームディレクトリに移動させる。
203         String oldSettingPath = new QSettings(settingFileName, QSettings.Format.IniFormat).fileName();
204         File homeDir = new File(FileManager.toPlatformPathSeparator(startupConfig.getHomeDirPath()));
205         String homePath = FileManager.slashTerminatePath(homeDir.getPath());
206         if (QFile.exists(oldSettingPath)) {
207                 QFile file = new QFile(oldSettingPath);
208                 file.copy(homePath + settingFileName);
209                 file.remove();
210         }
211         
212         settings = new QSettings(homePath + settingFileName, QSettings.Format.IniFormat);
213         
214         disableViewing = startupConfig.getDisableViewing();
215         syncOnly = startupConfig.isSyncOnly();
216
217         fileManager = new FileManager(startupConfig.getHomeDirPath(), startupConfig.getProgramDirPath());
218
219
220                 getServer();  // Setup URL to connect to
221                 
222                 // Get regular expressions used to parse out words
223 //              settings.beginGroup("General");
224 //              String regex = (String) settings.value("regex", "[,\\s]+");
225 //              setWordRegex(regex);
226 //              settings.endGroup();
227                 
228                 //Setup debugging information
229                 settings.beginGroup("Debug");
230                 String msglevel = (String) settings.value("messageLevel", "Low");
231                 settings.endGroup();
232                 
233                 
234                 //messageLevel = 1;
235                 setMessageLevel(msglevel);
236                 keepRunning = true;  // Make sure child threads stay running
237                 disableUploads = disableUploads();  // Should we upload anything?  Normally false.
238                 //disableUploads = true;  //***** DELETE THIS LINE *******
239                 enableCarriageReturnFix = enableCarriageReturnFix();  // Enable test fix?
240                 enableHTMLEntitiesFix = enableHtmlEntitiesFix();  // Enable test fix?
241                 
242                 logger = new ApplicationLogger("global.log");  // Setup log for this class 
243                 shortcutKeys = new ShortcutKeys();  // Setup keyboard shortcuts.
244                 mimicEvernoteInterface = getMimicEvernoteInterface();  // Should we mimic Evernote's notebook behavior
245                 resourceMap = new HashMap<String,String>();  // Setup resource map used to store attachments when editing
246                         
247                 databaseCache = getDatabaseCacheSize();  // Set database cache size     
248                 
249                 Global.username = getUserInformation().getUsername();
250     }
251
252     // Get/Set word parsing regular expression
253 //    public static String getWordRegex() {
254 //      return wordRegex;
255 //    }
256 //    public static void setWordRegex(String r) {
257 //      wordRegex = r;
258 //    }
259
260    // Set the debug message level
261    public static void setMessageLevel(String msglevel) {
262         if (msglevel.equalsIgnoreCase("low")) 
263                         messageLevel = 1;
264                 if (msglevel.equalsIgnoreCase("medium")) 
265                         messageLevel = 2;
266                 if (msglevel.equalsIgnoreCase("high")) 
267                                 messageLevel = 3;
268                 if (msglevel.equalsIgnoreCase("extreme")) 
269                                         messageLevel = 4;
270                 settings.beginGroup("Debug");
271                 settings.setValue("messageLevel", msglevel);
272                 settings.endGroup();            
273     }
274
275    //****************************************************
276    //****************************************************
277    //** Save user account information from Evernote
278    //****************************************************
279    //****************************************************
280     public static void saveUserInformation(User user) {
281         settings.beginGroup("User");
282                 settings.setValue("id", user.getId());
283                 settings.setValue("username", user.getUsername());
284                 settings.setValue("email", user.getEmail());
285                 settings.setValue("name", user.getName());
286                 settings.setValue("timezone", user.getTimezone());
287                 settings.setValue("privilege", user.getPrivilege().getValue());
288                 settings.setValue("created", user.getCreated());
289                 settings.setValue("updated", user.getUpdated());
290                 settings.setValue("deleted", user.getDeleted());
291                 settings.setValue("shard", user.getShardId());
292                 settings.endGroup();
293                 isPremium();
294                 if (user.getAttributes()!=null)
295                         saveUserAttributes(user.getAttributes());
296                 if (user.getAccounting()!=null)
297                         saveUserAccounting(user.getAccounting());
298
299     }
300     public static User getUserInformation() {
301         User user = new User();
302         settings.beginGroup("User");
303         try {   
304                 user.setId((Integer)settings.value("id", 0));                   
305         } catch  (java.lang.ClassCastException e) {
306                 user.setId(new Integer((String)settings.value("id", "0")));
307         }
308                 String username = (String)settings.value("username", "");
309                 String email = (String)settings.value("email", "");
310                 String name = (String)settings.value("name", "");
311                 String timezone = (String)settings.value("timezone", "");
312                 Integer privilege = 0;
313                 try {   
314                         privilege = new Integer((String)settings.value("privilege", "0"));                      
315                 } catch (java.lang.ClassCastException e) {
316                         privilege = (Integer)settings.value("privilege", 0);
317                 }
318
319                 try {   
320                         String date = (String)settings.value("created", "0");
321                         user.setCreated(new Long(date));
322                         date = (String)settings.value("updated", "0");
323                         user.setUpdated(new Long(date));
324                         date = (String)settings.value("deleted", "0");
325                         user.setDeleted(new Long(date));
326                 } catch (java.lang.ClassCastException e) {
327                         Long date = (Long)settings.value("created", 0);
328                         user.setCreated(date);
329                         date = (Long)settings.value("updated", 0);
330                         user.setUpdated(date);
331                         date = (Long)settings.value("deleted", 0);
332                         user.setDeleted(date);
333                 }
334
335                 String shard = (String)settings.value("shard", "");
336         settings.endGroup();
337         
338         user.setUsername(username);
339         user.setEmail(email);
340         user.setName(name);
341         user.setTimezone(timezone);
342         PrivilegeLevel userLevel = PrivilegeLevel.findByValue(privilege);
343         user.setPrivilege(userLevel);
344         user.setShardId(shard);
345         return user;
346     }
347     
348     public static void saveUserAttributes(UserAttributes attrib) {
349         settings.beginGroup("UserAttributes");
350                 settings.setValue("defaultLocationName", attrib.getDefaultLocationName());
351                 settings.setValue("defaultLatitude", attrib.getDefaultLocationName());
352                 settings.setValue("defaultLongitude", attrib.getDefaultLocationName());
353                 settings.setValue("incomingEmailAddress", attrib.getIncomingEmailAddress());
354                 settings.endGroup();
355     }
356     public static UserAttributes getUserAttributes() {
357         settings.beginGroup("UserAttributes");
358         UserAttributes attrib = new UserAttributes();
359                 attrib.setDefaultLocationName((String)settings.value("defaultLocationName",""));
360                 attrib.setDefaultLatitudeIsSet(false);
361                 attrib.setDefaultLongitudeIsSet(false);
362                 attrib.setIncomingEmailAddress((String)settings.value("incomingEmailAddress", ""));
363                 settings.endGroup();
364                 return attrib;
365     }
366     public static void saveUserAccounting(Accounting acc) {
367         settings.beginGroup("UserAccounting");
368                 settings.setValue("uploadLimit", acc.getUploadLimit());
369                 settings.setValue("uploadLimitEnd", acc.getUploadLimitEnd());
370                 settings.setValue("uploadLimitNextMonth", acc.getUploadLimitNextMonth());
371                 settings.setValue("premiumServiceStart", acc.getPremiumServiceStart());
372                 settings.setValue("nextPaymentDue", acc.getNextPaymentDue());
373                 settings.setValue("uploadAmount", acc.getUpdated());
374                 settings.endGroup();
375     }
376     public static long getUploadLimitEnd() {
377         Long limit;
378         settings.beginGroup("UserAccounting");
379         
380         // Upload limit
381                 try {
382                         String val  = (String)settings.value("uploadLimitEnd", "0");
383                         limit = new Long(val.trim());
384                 } catch (Exception e) {
385                         try {
386                                 limit = (Long)settings.value("uploadLimitEnd", 0);
387                         } catch (Exception e1) {
388                                 limit = new Long(0);
389                         }
390                 }
391         
392                 // return value
393         settings.endGroup();
394         return limit;
395     }
396     public static void saveUploadAmount(long amount) {
397         settings.beginGroup("UserAccounting");
398                 settings.setValue("uploadAmount", amount);
399                 settings.endGroup();
400    }
401     public static long getUploadAmount() {
402                 long amt=0;
403                 settings.beginGroup("UserAccounting");
404                 try {
405                         String num = (String)settings.value("uploadAmount", "0");
406                         amt = new Long(num.trim());
407                 } catch (Exception e) {
408                         try {
409                                 amt = (Integer)settings.value("uploadAmount", 0);
410                         } catch (Exception e1) {
411                                 amt = 0;
412                         }
413                 }
414                 settings.endGroup();
415                 return amt;
416     }
417     public static void saveEvernoteUpdateCount(long amount) {
418         settings.beginGroup("UserAccounting");
419                 settings.setValue("updateCount", amount);
420                 settings.endGroup();
421     }
422     public static long getEvernoteUpdateCount() {
423                 long amt;
424                 settings.beginGroup("UserAccounting");
425                 try {
426                         String num = (String)settings.value("updateCount", new Long(0).toString());
427                         amt = new Long(num.trim());
428                 } catch (java.lang.ClassCastException e) {
429                         amt = 0;
430                 }
431                 settings.endGroup();
432                 return amt;
433     }
434     public static boolean isPremium() {
435                 int level;
436                 settings.beginGroup("User");
437                 try {
438                         String num = (String)settings.value("privilege", "1");
439                         level = new Integer(num.trim());
440                 } catch (java.lang.ClassCastException e) {
441                         try {
442                                 level = (Integer)settings.value("privilege", 1);
443                         } catch (Exception e1) {
444                                 level = 1;
445                         }
446                 }
447                 settings.endGroup();
448                 PrivilegeLevel userLevel = PrivilegeLevel.findByValue(level);
449                 if (userLevel == PrivilegeLevel.NORMAL)
450                         return false;
451                 return true;
452                 
453    }
454     public static long getUploadLimit() {
455                 settings.beginGroup("UserAccounting");
456                 long limit;
457                 try {
458                         String num = (String)settings.value("uploadLimit", new Long(0).toString());
459                         limit = new Long(num.trim());
460                 } catch (java.lang.ClassCastException e) {
461                         limit = 0;
462                 }
463                 settings.endGroup();
464                 return limit;
465     }
466
467     
468     
469     //****************************************************
470     //****************************************************
471     //** View settings.  Used to restore settings 
472     //** when starting and to control how the program
473     //** behaves.
474     //****************************************************
475     //****************************************************
476     
477     //* Get/Set if we should show a tray icon
478     public static boolean showTrayIcon() {
479                 settings.beginGroup("General");
480                 try {
481                         String max = (String) settings.value("showTrayIcon", "false");
482                         settings.endGroup();
483                         if (!max.equalsIgnoreCase("true") || !QSystemTrayIcon.isSystemTrayAvailable())
484                                 return false;
485                         else
486                                 return true;    
487                 } catch (java.lang.ClassCastException e) {
488                         Boolean value = (Boolean) settings.value("showTrayIcon", false);
489                         settings.endGroup();
490                         return value;
491                 }
492     }
493     public static void setShowTrayIcon(boolean val) {
494                 settings.beginGroup("General");
495                 if (val)
496                         settings.setValue("showTrayIcon", "true");
497                 else
498                         settings.setValue("showTrayIcon", "false");
499                 settings.endGroup();
500     }
501     
502     // Get/Set window maximized when closed last
503     public static boolean wasWindowMaximized() {
504         try {
505                         settings.beginGroup("General");
506                         String max = (String) settings.value("isMaximized", "true");
507                         settings.endGroup();
508                         if (!max.equalsIgnoreCase("true"))
509                                 return false;
510                         return true;    
511                 } catch (java.lang.ClassCastException e) {
512                         Boolean value = (Boolean) settings.value("isMaximized", true);
513                         settings.endGroup();
514                         return value;
515                 }
516     }
517     public static void saveWindowMaximized(boolean isMax) {
518                 settings.beginGroup("General");
519                 if (isMax)
520                         settings.setValue("isMaximized", "true");
521                 else
522                         settings.setValue("isMaximized", "false");
523                 settings.endGroup();
524     }
525     
526     // Get/set currently viewed note Guid
527     public static String getLastViewedNoteGuid() {
528                 settings.beginGroup("General");
529                 String guid = (String) settings.value("lastViewedNote", "");
530                 settings.endGroup();
531                 return guid;    
532     }
533     public static void saveCurrentNoteGuid(String guid) {
534                 settings.beginGroup("General");
535                 if (guid != null)
536                         settings.setValue("lastViewedNote", guid);
537                 else
538                         settings.setValue("lastViewedNote", "");
539                 settings.endGroup();
540     }
541     
542     // Get/Set the note column we are sorted on and the order
543     public static void setSortColumn(int i) {
544         int view = Global.getListView();
545                 settings.beginGroup("General");
546         if (view == Global.View_List_Wide)
547                 settings.setValue("sortColumn", i);
548         else
549                 settings.setValue("sortColumn-Narrow", i);
550                 settings.endGroup();
551     }
552     public static int getSortColumn() {;
553     String key;
554         if (Global.getListView() == Global.View_List_Wide)
555                 key = "sortColumn";
556         else
557                 key = "sortColumn-Narrow";
558
559         settings.beginGroup("General");
560         int order;      
561         try {
562                 String val  = settings.value(key, new Integer(0)).toString();
563                 order = new Integer(val.trim());
564         } catch (Exception e) {
565                 try {
566                         order = (Integer)settings.value(key, 0);
567                 } catch (Exception e1) {
568                     order = 0;
569                 }
570         }
571         
572         settings.endGroup();
573         return order;
574     }
575     public static void setSortOrder(int i) {
576         int view = Global.getListView();
577                 settings.beginGroup("General");
578         if (view == Global.View_List_Wide)
579                 settings.setValue("sortOrder", i);
580         else
581                 settings.setValue("sortOrder-Narrow", i);
582                 settings.endGroup();
583     }
584     public static int getSortOrder() {
585         int view = Global.getListView();
586                 settings.beginGroup("General");
587                 String key;
588         if (view == Global.View_List_Wide)
589                 key = "sortOrder";
590                 else
591                         key = "sortOrder-Narrow";
592
593                 int order;      
594                 try {
595                         String val  = settings.value(key, new Integer(0)).toString();
596                         order = new Integer(val.trim());
597                 } catch (Exception e) {
598                         try {
599                                 order = (Integer)settings.value(key, 0);
600                         } catch (Exception e1) {
601                             order = 0;
602                         }
603                 }
604                 
605                 settings.endGroup();
606                 return order;
607     }
608     
609     // Should we automatically log in to Evernote when starting?
610     public static boolean automaticLogin() {
611         try {
612                 settings.beginGroup("General");
613                 String text = (String)settings.value("automaticLogin", "false");
614                 settings.endGroup();
615                 if (text.equalsIgnoreCase("true"))
616                         return true;
617                 else
618                         return false;           
619         } catch (java.lang.ClassCastException e) {
620                 Boolean value = (Boolean) settings.value("automaticLogin", false);
621                 settings.endGroup();
622                 return value;
623         }
624     }
625     public static void setAutomaticLogin(boolean val) {
626                 settings.beginGroup("General");
627                 if (val)
628                         settings.setValue("automaticLogin", "true");
629                 else
630                         settings.setValue("automaticLogin", "false");
631                 settings.endGroup();
632     }
633
634     // Get/set the Evernote server Url.  
635     public static void setServer(String server) {
636                 settings.beginGroup("General");
637                 settings.setValue("server", server);
638                 settings.endGroup();            
639     }
640     public static String getServer() {
641                 settings.beginGroup("General");
642                 String text = (String)settings.value("server", "www.evernote.com");
643                 if (text.equals("www.evernote.com")) {
644                         userStoreUrl = "https://www.evernote.com/edam/user";
645                     noteStoreUrlBase = "www.evernote.com/edam/note/";   
646                 } else {
647                         userStoreUrl = "https://sandbox.evernote.com/edam/user";
648                         noteStoreUrlBase = "sandbox.evernote.com/edam/note/";
649                 }
650                 settings.endGroup();
651 //              if (isPremium())
652                         noteStoreUrlBase = "https://" + noteStoreUrlBase;
653 //              else
654 //                      noteStoreUrlBase = "http://" + noteStoreUrlBase;
655                 return text;
656     }
657
658     // Get/Set if we should disable uploads to Evernote
659     public static boolean disableUploads() {
660         settings.beginGroup("General");
661         try {
662                 String text = (String)settings.value("disableUploads", "false");
663                 settings.endGroup();
664                 if (text.equalsIgnoreCase("true"))
665                         return true;
666                 else
667                         return false;
668                 } catch (java.lang.ClassCastException e) {
669                         Boolean value = (Boolean) settings.value("disableUploads", false);
670                         settings.endGroup();
671                         return value;
672                 }
673     }
674     public static void setDisableUploads(boolean val) {
675                 settings.beginGroup("General");
676                 if (val)
677                         settings.setValue("disableUploads", "true");
678                 else
679                         settings.setValue("disableUploads", "false");
680                 settings.endGroup();
681                 disableUploads = val;
682     }
683  
684     // Should we view PDF documents inline?
685     public static boolean pdfPreview() {
686                 settings.beginGroup("General");
687                 try {
688                         String text = (String)settings.value("pdfPreview", "true");
689                         settings.endGroup();
690                         if (text.equalsIgnoreCase("true"))
691                                 return true;
692                         else
693                                 return false;
694                 } catch (java.lang.ClassCastException e) {
695                         Boolean value = (Boolean) settings.value("pdfPreview", true);
696                         settings.endGroup();
697                         return value;
698                 }
699     }
700     public static void setPdfPreview(boolean val) {
701                 settings.beginGroup("General");
702                 if (val)
703                         settings.setValue("pdfPreview", "true");
704                 else
705                         settings.setValue("pdfPreview", "false");
706                 settings.endGroup();
707     }
708     
709     // When creating a new note, should it inherit tags that are currently selected?
710     public static boolean newNoteWithSelectedTags() {
711                 settings.beginGroup("General");
712                 try {
713                         String text = (String)settings.value("newNoteWithSelectedTags", "false");
714                         settings.endGroup();
715                         if (text.equalsIgnoreCase("true"))
716                                 return true;
717                         else
718                                 return false;
719                 } catch (java.lang.ClassCastException e) {
720                         Boolean value = (Boolean) settings.value("newNoteWithSelectedTags", false);
721                         settings.endGroup();
722                         return value;
723                 }
724     }
725     public static void setNewNoteWithSelectedTags(boolean val) {
726                 settings.beginGroup("General");
727                 if (val)
728                         settings.setValue("newNoteWithSelectedTags", "true");
729                 else
730                         settings.setValue("newNoteWithSelectedTags", "false");
731                 settings.endGroup();
732     }
733     
734     // Minimum weight for text OCRed from Evernote. Anything below this
735     // Won't be shown to the user when they search
736     public static void setRecognitionWeight(int len) {
737                 settings.beginGroup("General");
738                 settings.setValue("recognitionWeight", len);
739                 settings.endGroup();            
740     }
741     public static int getRecognitionWeight() {
742                 settings.beginGroup("General");
743                 Integer len;
744                 try {
745                         len = (Integer)settings.value("recognitionWeight", 30);
746                 } catch (Exception e) {
747                         len = 80;
748                 }
749                 settings.endGroup();
750                 return len;
751     }
752     
753     // get/set current debug message level
754     public static String getMessageLevel() {
755                 settings.beginGroup("Debug");
756                 String text = (String)settings.value("messageLevel", "Low");
757                 settings.endGroup();
758                 setMessageLevel(text);
759                 return text;
760     }
761     public static void setDateFormat(String format) {
762                 settings.beginGroup("General");
763                 settings.setValue("dateFormat", format);
764                 settings.endGroup();            
765     }
766     
767     // Get/Set user date/time formats
768     public static String getDateFormat() {
769                 settings.beginGroup("General");
770                 String text = (String)settings.value("dateFormat", "MM/dd/yyyy");
771                 settings.endGroup();
772                 return text;
773     }
774     public static void setTimeFormat(String format) {
775                 settings.beginGroup("General");
776                 settings.setValue("timeFormat", format);
777                 settings.endGroup();            
778     }
779     public static String getTimeFormat() {
780                 settings.beginGroup("General");
781                 String text = (String)settings.value("timeFormat", "HH:mm:ss");
782                 settings.endGroup();
783                 return text;
784     }
785     
786     // How often should we sync with Evernote?
787     public static String getSyncInterval() {
788                 settings.beginGroup("General");
789                 String text = (String)settings.value("syncInterval", "15 minutes");
790                 settings.endGroup();
791                 return text;            
792     }
793     public static void setSyncInterval(String format) {
794                 settings.beginGroup("General");
795                 settings.setValue("syncInterval", format);
796                 settings.endGroup();            
797     }
798     
799     // Get/Set the width of columns and their position for the 
800     // next start.
801     public static void setColumnWidth(String col, int width) {
802         if (Global.getListView() == Global.View_List_Wide)
803                 settings.beginGroup("ColumnWidths");
804         else 
805                 settings.beginGroup("ColumnWidths-Narrow");
806                 settings.setValue(col, width);
807                 settings.endGroup();
808         }
809     public static int getColumnWidth(String col) {
810         int view = Global.getListView();
811         if (view == Global.View_List_Wide)
812                 settings.beginGroup("ColumnWidths");
813         else
814                 settings.beginGroup("ColumnWidths-Narrow");
815                 Integer width;
816                 try {
817                         String val  = (String)settings.value(col, "0");
818                         width = new Integer(val.trim());
819                 } catch (Exception e) {
820                         try {
821                                 width = (Integer)settings.value(col, 0);
822                         } catch (Exception e1) {
823                                 width = 0;
824                         }
825                 }
826                 settings.endGroup();
827                 return width;
828     }
829     public static void setColumnPosition(String col, int width) {
830         if (Global.getListView() == Global.View_List_Wide)
831                 settings.beginGroup("ColumnPosition");
832         else
833                 settings.beginGroup("ColumnPosition-Narrow");
834                 settings.setValue(col, width);
835                 settings.endGroup();
836     }
837     public static int getColumnPosition(String col) {
838         if (Global.getListView() == Global.View_List_Wide)
839                 settings.beginGroup("ColumnPosition");
840         else
841                 settings.beginGroup("ColumnPosition-Narrow");
842                 Integer width;
843                 try {
844                         String val  = (String)settings.value(col, "-1");
845                         width = new Integer(val.trim());
846                 } catch (Exception e) {
847                         try {
848                                 width = (Integer)settings.value(col, 0);
849                         } catch (Exception e1) {
850                                 width = 0;
851                         }
852                 }
853                 settings.endGroup();
854                 return width;
855     }
856     
857     // Ping the user when they try to delete or just do it.
858     public static boolean verifyDelete() {
859                 settings.beginGroup("General");
860                 try {
861                         String text = (String)settings.value("verifyDelete", "true");
862                         settings.endGroup();
863                         if (text.equalsIgnoreCase("true"))
864                                 return true;
865                         else
866                                 return false;
867                 } catch (java.lang.ClassCastException e) {
868                         Boolean value = (Boolean) settings.value("verifyDelete", true);
869                         settings.endGroup();
870                         return value;
871                 }
872     }
873     public static void setVerifyDelete(boolean val) {
874                 settings.beginGroup("General");
875                 if (val)
876                         settings.setValue("verifyDelete", "true");
877                 else
878                         settings.setValue("verifyDelete", "false");
879                 settings.endGroup();
880     }
881     
882     // Should it start minimized?
883     public static boolean startMinimized() {
884                 settings.beginGroup("General");
885                 try {
886                         String text = (String)settings.value("startMinimized", "false");
887                         settings.endGroup();
888                         if (text.equalsIgnoreCase("true"))
889                                 return true;
890                         else
891                                 return false;
892                 } catch (java.lang.ClassCastException e) {
893                         Boolean value = (Boolean) settings.value("startMinimized", false);
894                         settings.endGroup();
895                         return value;
896                 }
897     }
898     public static void setStartMinimized(boolean val) {
899                 settings.beginGroup("General");
900                 if (val)
901                         settings.setValue("startMinimized", "true");
902                 else
903                         settings.setValue("startMinimized", "false");
904                 settings.endGroup();
905     }
906     
907     // Should we upload the content of any deleted notes
908     public static boolean synchronizeDeletedContent() {
909                 settings.beginGroup("General");
910                 try {
911                         String text = (String)settings.value("syncDeletedContent", "false");
912                         settings.endGroup();
913                         if (text.equalsIgnoreCase("true"))
914                                 return true;
915                         else
916                                 return false;
917                 } catch (java.lang.ClassCastException e) {
918                         Boolean value = (Boolean) settings.value("syncDeletedContent", false);
919                         settings.endGroup();
920                         return value;
921                 }
922     }   
923     public static void setSynchronizeDeletedContent(boolean val) {
924                 settings.beginGroup("General");
925                 if (val)
926                         settings.setValue("syncDeletedContent", "true");
927                 else
928                         settings.setValue("syncDeletedContent", "false");
929                 settings.endGroup();
930     }
931     
932     // Is a section of the window visible?  Used to hide things people don't
933     // want to see.
934     public static boolean isWindowVisible(String window) {
935                 settings.beginGroup("WindowsVisible");
936                 try {
937                         String defaultValue = "true";
938                         if (window.equalsIgnoreCase("noteInformation"))
939                                 defaultValue = "false";
940                         String text = (String)settings.value(window, defaultValue);
941                         settings.endGroup();
942                         if (text.equalsIgnoreCase("true"))
943                                 return true;
944                 else
945                         return false;           
946                 } catch (java.lang.ClassCastException e) {
947                         boolean defaultValue = true;
948                         if (window.equalsIgnoreCase("noteInformation"))
949                                 defaultValue = false;
950                         Boolean value = (Boolean) settings.value("showTrayIcon", defaultValue);
951                         settings.endGroup();
952                         return value;
953                 }
954     }
955     public static void saveWindowVisible(String window, boolean val) {
956                 settings.beginGroup("WindowsVisible");
957                 if (val)
958                         settings.setValue(window, "true");
959                 else
960                         settings.setValue(window, "false");
961                 settings.endGroup();
962     }
963     
964     // Is a list in the column in the note list visible?  
965     public static boolean isColumnVisible(String window) {
966         String defaultValue = "true";
967         int view = Global.getListView();
968         if (Global.getListView() == Global.View_List_Wide)
969                 settings.beginGroup("ColumnsVisible");
970         else
971                 settings.beginGroup("ColumnsVisible-Narrow"); 
972                 if (window.equalsIgnoreCase("thumbnail") && view == Global.View_List_Wide)
973                         defaultValue = "false";
974                 if (window.equalsIgnoreCase("thumbnail"))
975                         defaultValue = "false";
976                 if (window.equalsIgnoreCase("Guid"))
977                         defaultValue = "false";
978                 try {
979                         String text = (String)settings.value(window, defaultValue);
980                         settings.endGroup();
981                         if (text.equalsIgnoreCase("true"))
982                                 return true;
983                         else
984                                 return false;
985                 } catch (java.lang.ClassCastException e) {
986                         boolean defBool = false;
987                         if (window.equalsIgnoreCase("true"))
988                                 defBool = true;
989                         else
990                                 defBool = false;
991                         Boolean value = (Boolean) settings.value(window, defBool);
992                         settings.endGroup();
993                         return value;
994                 }
995     }
996     public static void saveColumnVisible(String column, boolean val) {
997         if (Global.getListView() == Global.View_List_Wide)
998                 settings.beginGroup("ColumnsVisible");
999         else
1000                 settings.beginGroup("ColumnsVisible-Narrow");                   
1001                 if (val)
1002                         settings.setValue(column, "true");
1003                 else
1004                         settings.setValue(column, "false");
1005                 settings.endGroup();
1006     }
1007     
1008     // Is a particular editor button visible?
1009     public static boolean isEditorButtonVisible(String window) {
1010                 settings.beginGroup("EditorButtonsVisible");
1011                 try {
1012                         String text = (String)settings.value(window, "true");
1013                         settings.endGroup();
1014                         if (text.equalsIgnoreCase("true"))
1015                                 return true;
1016                         else
1017                                 return false;
1018                 } catch (java.lang.ClassCastException e) {
1019                         Boolean value = (Boolean) settings.value(window, true);
1020                         settings.endGroup();
1021                         return value;
1022                 }
1023     }
1024     public static void saveEditorButtonsVisible(String column, boolean val) {
1025                 settings.beginGroup("EditorButtonsVisible");
1026                 if (val)
1027                         settings.setValue(column, "true");
1028                 else
1029                         settings.setValue(column, "false");
1030                 settings.endGroup();
1031     }
1032     
1033     // Should the test fixes be enabled
1034     public static boolean enableCarriageReturnFix() {
1035         try {
1036                 settings.beginGroup("Debug");
1037                 String text = (String)settings.value("enableCarriageReturnFix", "false");
1038                 settings.endGroup();
1039                 if (text.equalsIgnoreCase("true"))
1040                         return true;
1041                 else
1042                         return false;
1043                 } catch (java.lang.ClassCastException e) {
1044                         Boolean value = (Boolean) settings.value("enableCarriageReturnFix", false);
1045                         settings.endGroup();
1046                         return value;
1047                 }
1048     }
1049     public static void saveCarriageReturnFix(boolean val) {
1050                 settings.beginGroup("Debug");
1051                 if (val)
1052                         settings.setValue("enableCarriageReturnFix", "true");
1053                 else
1054                         settings.setValue("enableCarriageReturnFix", "false");
1055                 settings.endGroup();
1056     }
1057     public static boolean enableHtmlEntitiesFix() {
1058         try {
1059                 settings.beginGroup("Debug");
1060                 String text = (String)settings.value("enableHtmlEntitiesFix", "false");
1061                 settings.endGroup();
1062                 if (text.equalsIgnoreCase("true"))
1063                         return true;
1064                 else
1065                         return false;
1066                 } catch (java.lang.ClassCastException e) {
1067                         Boolean value = (Boolean) settings.value("enableHtmlEntitiesFix", false);
1068                         settings.endGroup();
1069                         return value;
1070                 }
1071     }
1072     public static void saveHtmlEntitiesFix(boolean val) {
1073                 settings.beginGroup("Debug");
1074                 if (val)
1075                         settings.setValue("enableHtmlEntitiesFix", "true");
1076                 else
1077                         settings.setValue("enableHtmlEntitiesFix", "false");
1078                 settings.endGroup();
1079     }
1080
1081 //    public static void setIndexThreads(int val) {
1082 //              settings.beginGroup("General");
1083 //              settings.setValue("indexThreads", val);
1084 //              settings.endGroup();
1085 //   }
1086 //    public static int getIndexThreads() {
1087 //              settings.beginGroup("General");
1088 //              Integer threads;
1089 //              try {
1090 //                      String val  = (String)settings.value("indexThreads", "1");
1091 //                      threads = new Integer(val.trim());
1092 //              } catch (Exception e) {
1093 //                      try {
1094 //                              threads = (Integer)settings.value("indexThreads", 1);
1095 //                      } catch (Exception e1) {
1096 //                              threads = 1;
1097 //                      }
1098 //              }
1099 //              settings.endGroup();
1100 //              threads = 1;
1101 //              return threads;
1102     
1103     // Get/Set text zoom factor
1104 //   }
1105     public static void setZoomFactor(double val) {
1106                 settings.beginGroup("General");
1107                 settings.setValue("zoomFactor", val);
1108                 settings.endGroup();
1109     }
1110     public static double getZoomFactor() {
1111                 settings.beginGroup("General");
1112                 Double threads;
1113                 try {
1114                         String val  = (String)settings.value("zoomFactor", "1.0");
1115                         threads = new Double(val.trim());
1116                 } catch (Exception e) {
1117                         try {
1118                                 threads = (Double)settings.value("zoomFactor", 1.0);
1119                         } catch (Exception e1) {
1120                                 threads = new Double(1);
1121                         }
1122                 }
1123                 settings.endGroup();
1124                 return threads;
1125     }
1126     public static void setTextSizeMultiplier(double val) {
1127                 settings.beginGroup("General");
1128                 settings.setValue("textMultiplier", val);
1129                 settings.endGroup();
1130     }
1131     public static double getTextSizeMultiplier() {
1132                 settings.beginGroup("General");
1133                 Double threads;
1134                 try {
1135                         String val  = (String)settings.value("textMultiplier", "1");
1136                         threads = new Double(val.trim());
1137                 } catch (Exception e) {
1138                         try {
1139                                 threads = (Double)settings.value("textMultiplier", 1);
1140                         } catch (Exception e1) {
1141                                 threads = new Double(1);
1142                         }
1143                 }
1144                 settings.endGroup();
1145                 return threads;
1146     }
1147     
1148     
1149     // Should we mimic Evernote and restrict the notebooks selected?
1150     public static boolean getMimicEvernoteInterface() {
1151                 settings.beginGroup("General");
1152                 try {
1153                         String text = (String)settings.value("mimicEvernoteInterface", "true");
1154                         settings.endGroup();
1155                         if (text.equalsIgnoreCase("true"))
1156                                 return true;
1157                         else
1158                                 return false;
1159                 } catch (java.lang.ClassCastException e) {
1160                         Boolean value = (Boolean) settings.value("mimicEvernoteInterface", true);
1161                         settings.endGroup();
1162                         return value;
1163                 }
1164     }
1165     public static void setMimicEvernoteInterface(boolean value) {
1166         settings.beginGroup("General");
1167         if (value)
1168                 settings.setValue("mimicEvernoteInterface", "true");
1169         else
1170                 settings.setValue("mimicEvernoteInterface", "false"); 
1171         settings.endGroup();
1172     }
1173     
1174     
1175     // Synchronize with Evernote when closing?
1176     public static boolean synchronizeOnClose() {
1177                 settings.beginGroup("General");
1178                 try {
1179                         String text = (String)settings.value("synchronizeOnClose", "false");
1180                         settings.endGroup();
1181                         if (text.equalsIgnoreCase("true"))
1182                                 return true;
1183                         else
1184                                 return false;
1185                 } catch (java.lang.ClassCastException e) {
1186                         Boolean value = (Boolean) settings.value("synchronizeOnClose", false);
1187                         settings.endGroup();
1188                         return value;
1189                 }
1190     }
1191     public static void setSynchronizeOnClose(boolean val) {
1192                 settings.beginGroup("General");
1193                 if (val)
1194                         settings.setValue("synchronizeOnClose", "true");
1195                 else
1196                         settings.setValue("synchronizeOnClose", "false");
1197                 settings.endGroup();
1198     }
1199
1200     // Get/set the database version.  Not really used any more, but kept
1201     // for compatibility.
1202     public static void setDatabaseVersion(String version) {
1203                 settings.beginGroup("General");
1204                 settings.setValue("databaseVersion", version);
1205                 settings.endGroup();
1206     }
1207     public static String getDatabaseVersion() {
1208                 settings.beginGroup("General");
1209                 String val  = (String)settings.value("databaseVersion", "0.70");
1210                 settings.endGroup();
1211                 return val;
1212     }
1213
1214     // Get the URL (full path) of the main database
1215     public static String getDatabaseUrl() {
1216                 settings.beginGroup("General");
1217                 String val  = (String)settings.value("DatabaseURL", "");
1218                 settings.endGroup();
1219                 if (val.equals(""))
1220                         val = "jdbc:h2:"+Global.getFileManager().getDbDirPath(Global.databaseName);
1221                 return val;
1222     }
1223     
1224     // get the url (full path) of the searchable word database
1225     public static String getIndexDatabaseUrl() {
1226                 settings.beginGroup("General");
1227                 String val  = (String)settings.value("IndexDatabaseURL", "");
1228                 settings.endGroup();
1229                 if (val.equals(""))
1230                         val = "jdbc:h2:"+Global.getFileManager().getDbDirPath(Global.indexDatabaseName);
1231                 return val;
1232     }
1233     
1234     // Get the url (full path) of the attachment database
1235     public static String getResourceDatabaseUrl() {
1236                 settings.beginGroup("General");
1237                 String val  = (String)settings.value("ResourceDatabaseURL", "");
1238                 settings.endGroup();
1239                 if (val.equals(""))
1240                         val = "jdbc:h2:"+Global.getFileManager().getDbDirPath(Global.resourceDatabaseName);
1241                 return val;
1242     }
1243     
1244         // 操作履歴データベースのURL(フルパス)をゲット
1245         public static String getBehaviorDatabaseUrl() {
1246                 settings.beginGroup("General");
1247                 String val = (String) settings.value("BehaviorDatabaseURL", "");
1248                 settings.endGroup();
1249                 if (val.equals(""))
1250                         val = "jdbc:h2:"
1251                                         + Global.getFileManager().getDbDirPath(
1252                                                         Global.behaviorDatabaseName);
1253                 return val;
1254         }
1255         
1256     public static void setDatabaseUrl(String value) {
1257                 settings.beginGroup("General");
1258                 settings.setValue("DatabaseURL", value);
1259                 settings.endGroup();
1260     }
1261     public static void setIndexDatabaseUrl(String value) {
1262                 settings.beginGroup("General");
1263                 settings.setValue("IndexDatabaseURL", value);
1264                 settings.endGroup();
1265     }
1266     public static void setResourceDatabaseUrl(String value) {
1267                 settings.beginGroup("General");
1268                 settings.setValue("ResourceDatabaseURL", value);
1269                 settings.endGroup();
1270     }
1271     
1272         public static void setBehaviorDatabaseUrl(String value) {
1273                 settings.beginGroup("General");
1274                 settings.setValue("BehaviorDatabaseURL", value);
1275                 settings.endGroup();
1276         }
1277         
1278     public static String getDatabaseUserid() {
1279                 settings.beginGroup("General");
1280                 String val  = (String)settings.value("databaseUserid", "");
1281                 settings.endGroup();
1282                 return val;
1283     }
1284     public static String getDatabaseUserPassword() {
1285                 settings.beginGroup("General");
1286                 String val  = (String)settings.value("databaseUserPassword", "");
1287                 settings.endGroup();
1288                 return val;
1289     }
1290     
1291     // get/Set the style sheet and the palette to control the look & feel
1292     public static void setStyle(String style) {
1293                 settings.beginGroup("General");
1294                 settings.setValue("style", style);
1295                 settings.endGroup();
1296     }
1297     public static String getStyle() {
1298                 settings.beginGroup("General");
1299                 String val  = (String)settings.value("style", "Cleanlooks");
1300                 settings.endGroup();
1301                 return val;
1302     }
1303     public static boolean useStandardPalette() {
1304                 settings.beginGroup("General");
1305                 try {
1306                         String text = (String)settings.value("standardPalette", "true");
1307                         settings.endGroup();
1308                         if (text.equalsIgnoreCase("true"))
1309                                 return true;
1310                         else
1311                                 return false;
1312                 } catch (java.lang.ClassCastException e) {
1313                         Boolean value = (Boolean) settings.value("standardPalette", true);
1314                         settings.endGroup();
1315                         return value;
1316                 }
1317     }
1318     public static void setStandardPalette(boolean val) {
1319                 settings.beginGroup("General");
1320                 if (val)
1321                         settings.setValue("standardPalette", "true");
1322                 else
1323                         settings.setValue("standardPalette", "false");
1324                 settings.endGroup();
1325     }
1326     
1327     // Set the amount of time to wait between indexing
1328     // Get/Set interval when the index thread wakes up.
1329     public static void setIndexThreadSleepInterval(int sleep) {
1330                 settings.beginGroup("General");
1331                 settings.setValue("IndexThreadSleepInterval", sleep);
1332                 settings.endGroup();
1333     }
1334     public static int getIndexThreadSleepInterval() {
1335                 settings.beginGroup("General");
1336                 Integer sleep;
1337                 try {
1338                         String val  = (String)settings.value("IndexThreadSleepInterval", "300");
1339                         sleep = new Integer(val.trim());
1340                 } catch (Exception e) {
1341                         try {
1342                                 sleep = (Integer)settings.value("IndexThreadSleepInterval", 0);
1343                         } catch (Exception e1) {
1344                                 sleep = 300;
1345                         }
1346                 }
1347                 settings.endGroup();
1348                 return sleep;
1349     }
1350     
1351     
1352     // Get/Set a window state for later restoring
1353     public static void saveState(String name, QByteArray state) {
1354         int view = Global.getListView();
1355         if (view == Global.View_List_Narrow)
1356                 name = name +"Narrow";
1357                 settings.beginGroup("SaveState");
1358                 settings.setValue(name, state);
1359                 settings.endGroup();
1360     }
1361     
1362     public static QByteArray restoreState(String name) {
1363         int view = Global.getListView();
1364         if (view == Global.View_List_Narrow)
1365                 name = name +"Narrow";
1366                 settings.beginGroup("SaveState");
1367                 QByteArray state = (QByteArray)settings.value(name);
1368                 settings.endGroup();
1369                 return state;
1370     }
1371     public static void saveGeometry(String name, QByteArray state) {
1372         int view = Global.getListView();
1373         if (view == Global.View_List_Narrow)
1374                 settings.beginGroup("SaveGeometryNarrow");
1375         else
1376                 settings.beginGroup("SaveGeometry");
1377                 settings.setValue(name, state);
1378                 settings.endGroup();
1379     }
1380     
1381     public static QByteArray restoreGeometry(String name) {
1382         int view = Global.getListView();
1383         if (view == Global.View_List_Narrow)
1384                 settings.beginGroup("SaveGeometryNarrow");
1385         else
1386                 settings.beginGroup("SaveGeometry");
1387                 QByteArray state = (QByteArray)settings.value(name);
1388                 settings.endGroup();
1389                 return state;
1390     }
1391     
1392     
1393     // Set how often to do an automatic save
1394     public static void setAutoSaveInterval(int interval) {
1395                 settings.beginGroup("General");
1396                 settings.setValue("autoSaveInterval", interval);
1397                 settings.endGroup();
1398     }
1399     public static int getAutoSaveInterval() {
1400                 settings.beginGroup("General");
1401                 Integer value;
1402                 try {
1403                         String val  = (String)settings.value("autoSaveInterval", "5");
1404                         value = new Integer(val.trim());
1405                 } catch (Exception e) {
1406                         try {
1407                                 value = (Integer)settings.value("autoSaveInterval", 5);
1408                         } catch (Exception e1) {
1409                                 value = 5;
1410                         }
1411                 }
1412                 settings.endGroup();
1413                 return value;
1414     }
1415      
1416     // Add an invalid attribute & element to the database so we don't bother parsing it in the future
1417     // These values we automatically remove from any note.
1418     // Add invalid attributes
1419     public static void addInvalidAttribute(String element, String attribute) {
1420         
1421                 List<String> attributes = invalidAttributes.get(element);
1422                 if (attributes != null) {
1423                         for (int i=0; i<attributes.size(); i++)
1424                                 if (attribute.equalsIgnoreCase(attributes.get(i))) {
1425                                         return;
1426                         }
1427         }
1428         
1429         ArrayList<String> attributeList;
1430         if (!invalidAttributes.containsKey(element)) {
1431                 attributeList = new ArrayList<String>();
1432                 attributeList.add(attribute);
1433                 invalidAttributes.put(element, attributeList);
1434         }
1435         else {
1436                 attributeList = invalidAttributes.get(element);
1437                 attributeList.add(attribute);
1438                 invalidAttributes.put(element,attributeList);
1439         }
1440     }
1441    
1442     // Add invalid attributes
1443     public static void addInvalidElement(String element) {
1444                 for (int i=0; i<invalidElements.size(); i++) {
1445                         if (element.equalsIgnoreCase(invalidElements.get(i)))
1446                                 return;
1447                 }
1448         invalidElements.add(element);
1449     }
1450     
1451     // Get/Set proxy information
1452     // Proxy settings
1453     public static String getProxyValue(String key) {
1454                 settings.beginGroup("Proxy");
1455                 String val  = (String)settings.value(key, "");
1456                 settings.endGroup();
1457                 return val;
1458     }
1459     public static void setProxyValue(String key, String value) {
1460                 settings.beginGroup("Proxy");
1461                 settings.setValue(key, value);
1462                 settings.endGroup();
1463     }
1464     
1465     // Change a byte array to a hex string
1466     // Convert a byte array to a hex string
1467         public static String byteArrayToHexString(byte data[]) {
1468                 StringBuffer buf = new StringBuffer();
1469             for (byte element : data) {
1470                 int halfbyte = (element >>> 4) & 0x0F;
1471                 int two_halfs = 0;
1472                 do {
1473                         if ((0 <= halfbyte) && (halfbyte <= 9))
1474                                buf.append((char) ('0' + halfbyte));
1475                            else
1476                                 buf.append((char) ('a' + (halfbyte - 10)));
1477                         halfbyte = element & 0x0F;
1478                 } while(two_halfs++ < 1);
1479             }
1480             return buf.toString();              
1481         }
1482
1483     
1484         // Get/Set spelling settings
1485         public static boolean getSpellSetting(String value) {
1486                 settings.beginGroup("Spell");
1487                 String text = (String)settings.value(value, "");
1488                 settings.endGroup();
1489                 if (text.equalsIgnoreCase("true"))
1490                         return true;
1491                 if (text.equalsIgnoreCase("false"))
1492                         return false;
1493                 if (value.equalsIgnoreCase(Configuration.SPELL_IGNOREDIGITWORDS))
1494                         return true;
1495                 if (value.equalsIgnoreCase(Configuration.SPELL_IGNOREINTERNETADDRESSES))
1496                         return true;
1497                 if (value.equalsIgnoreCase(Configuration.SPELL_IGNOREUPPERCASE))
1498                         return true;
1499                 if (value.equalsIgnoreCase(Configuration.SPELL_IGNORESENTENCECAPITALIZATION))
1500                         return true;
1501                 return false;
1502     }
1503     public static void setSpellSetting(String setting, boolean val) {
1504                 settings.beginGroup("Spell");
1505                 if (val)
1506                         settings.setValue(setting, "true");
1507                 else
1508                         settings.setValue(setting, "false");
1509                 settings.endGroup();
1510     }
1511         
1512         // Get/Set how we should display tags (color them, hide unused, or do nothing)
1513         // What to do with inactive tags?
1514         public static String tagBehavior() {
1515                 settings.beginGroup("General");
1516                 String text = (String)settings.value("tagBehavior", "DoNothing");
1517                 settings.endGroup();
1518                 return text;
1519         }
1520         // What to do with inactive tags?
1521         public static void setTagBehavior(String value) {
1522                 settings.beginGroup("General");
1523                 settings.setValue("tagBehavior", value);
1524                 settings.endGroup();
1525         }
1526
1527     
1528         // Should the toolbar be visible?
1529         public static boolean isToolbarButtonVisible(String window, Boolean val) {
1530                 settings.beginGroup("ToolbarButtonsVisible");
1531                 try {
1532                         String text = (String)settings.value(window, val.toString());
1533                         settings.endGroup();
1534                         if (text.equalsIgnoreCase("true"))
1535                                 return true;
1536                         else
1537                                 return false;   
1538                 } catch (java.lang.ClassCastException e) {
1539                         Boolean value = (Boolean) settings.value(window, val);
1540                         settings.endGroup();
1541                         return value;
1542                 }
1543     }
1544     public static void saveToolbarButtonsVisible(String column, boolean val) {
1545                 settings.beginGroup("ToolbarButtonsVisible");
1546                 if (val)
1547                         settings.setValue(column, "true");
1548                 else
1549                         settings.setValue(column, "false");
1550                 settings.endGroup();
1551     }
1552         
1553     // Are thumbnails enabled?
1554     
1555     public static boolean enableThumbnails() {
1556                 settings.beginGroup("Debug");
1557                 try {
1558                         String text = (String)settings.value("thumbnails", "true");
1559                         settings.endGroup();
1560                         if (text.equalsIgnoreCase("true"))
1561                                 return true;
1562                         else
1563                                 return false;
1564                 } catch (java.lang.ClassCastException e) {
1565                         Boolean value = (Boolean) settings.value("thumbnails", true);
1566                         settings.endGroup();
1567                         return value;
1568                 }
1569     }
1570     public static void setEnableThumbnails(boolean val) {
1571                 settings.beginGroup("Debug");
1572                 if (val)
1573                         settings.setValue("thumbnails", "true");
1574                 else
1575                         settings.setValue("thumbnails", "false");
1576                 settings.endGroup();
1577     }
1578         
1579     // Trace used for performance tuning.  Not normally used in production.
1580         // Print date/time.  Used mainly for performance tracing
1581         public static void trace(boolean resetInterval) {
1582                 String fmt = "MM/dd/yy HH:mm:ss.SSSSSS";
1583                 String dateTimeFormat = new String(fmt);
1584                 SimpleDateFormat simple = new SimpleDateFormat(dateTimeFormat);
1585                 Calendar cal = Calendar.getInstance();
1586                 if (intervalTraceTime == null) 
1587                         intervalTraceTime = Calendar.getInstance();
1588                 if (startTraceTime == null)
1589                         startTraceTime = Calendar.getInstance();
1590                 
1591                 float interval = (cal.getTimeInMillis() - intervalTraceTime.getTimeInMillis());
1592                 float total = (cal.getTimeInMillis() - startTraceTime.getTimeInMillis());
1593                 
1594 //              if (interval > 00.0) {
1595                         StackTraceElement[] exceptions = Thread.currentThread().getStackTrace();
1596                         System.out.println("------------------------------------------");
1597
1598                         System.out.println("Date/Time " +simple.format(cal.getTime()));
1599                         System.out.format("Interval Time: %-10.6f%n", interval);
1600                         System.out.format("Total Time: %-10.6f%n", total);
1601                         for (int i=2; i<5 && i<exceptions.length; i++) {
1602                                 System.out.println(exceptions[i]);
1603                         }
1604 //              }
1605                 if (resetInterval)
1606                         intervalTraceTime = cal;
1607         }
1608         public static void traceReset() {
1609                 intervalTraceTime = null;
1610                 startTraceTime = null;
1611         }
1612
1613     
1614         // Get the FileManager class to manage local files & directories
1615         public static FileManager getFileManager() {
1616         return fileManager;
1617     }
1618         
1619         // Should the note editor be disabled?
1620     public static boolean getDisableViewing() {
1621         return disableViewing;
1622     }
1623
1624     //**********************
1625     //* Thumbnail zoom level
1626     //**********************
1627     public static int calculateThumbnailZoom(String content) {
1628         int zoom = 1;
1629                 if (content.indexOf("application/pdf") == -1) {
1630                         if (content.indexOf("image/") == -1) {
1631                                 String text =  StringEscapeUtils.unescapeHtml4(content.replaceAll("\\<.*?\\>", ""));
1632                                 zoom = 2;
1633                                 if (text.length() < 500) 
1634                                         zoom = 2;
1635                                 if (text.length() < 250)
1636                                         zoom = 3;
1637                                 if (text.length() < 100)
1638                                         zoom = 4;
1639                                 if (text.length() < 50)
1640                                         zoom = 5;
1641                                 if (text.length() < 10)
1642                                         zoom = 6;
1643                         }
1644                 }
1645                 return zoom;
1646     }
1647     
1648     //**********************
1649     //* List View settings 
1650     //**********************
1651     public static void setListView(int view) {
1652                 settings.beginGroup("General");
1653                 settings.setValue("listView", view);
1654                 settings.endGroup();
1655     }
1656     public static int getListView() {
1657                 settings.beginGroup("General");
1658                 Integer value;
1659                 try {
1660                         String val  = (String)settings.value("listView", View_List_Wide);
1661                         value = new Integer(val.trim());
1662                 } catch (Exception e) {
1663                         try {
1664                                 value = (Integer)settings.value("listView", View_List_Wide);
1665                         } catch (Exception e1) {
1666                                 value = View_List_Wide;
1667                         }
1668                 }
1669                 settings.endGroup();
1670                 return value;
1671     }
1672
1673     
1674     
1675     //*******************
1676     // Font Settings
1677     //*******************
1678     public static boolean overrideDefaultFont() {
1679                 settings.beginGroup("Font");
1680                 try {
1681                         String text = (String)settings.value("overrideFont", "false");
1682                         settings.endGroup();
1683                         if (text.equalsIgnoreCase("true"))
1684                                 return true;
1685                         else
1686                                 return false;   
1687                 } catch (java.lang.ClassCastException e) {
1688                         Boolean value = (Boolean) settings.value("overrideFont", false);
1689                         settings.endGroup();
1690                         return value;
1691                 }
1692
1693     }
1694     
1695     //****************************************************
1696     // Get/Set the default font settings for a new note
1697     //****************************************************
1698     public static void setOverrideDefaultFont(boolean value) {
1699                 settings.beginGroup("Font");
1700                 settings.setValue("overrideFont", value);
1701                 settings.endGroup();    
1702     }
1703     public static String getDefaultFont() {
1704                 settings.beginGroup("Font");
1705                 String val  = (String)settings.value("font", "");
1706                 settings.endGroup();
1707                 return val;
1708     }
1709     public static void setDefaultFont(String value) {
1710                 settings.beginGroup("Font");
1711                 settings.setValue("font", value);
1712                 settings.endGroup();
1713     }
1714     public static String getDefaultFontSize() {
1715                 settings.beginGroup("Font");
1716                 String val  = (String)settings.value("fontSize", "");
1717                 settings.endGroup();
1718                 return val;
1719     }
1720     public static void setDefaultFontSize(String value) {
1721                 settings.beginGroup("Font");
1722                 settings.setValue("fontSize", value);
1723                 settings.endGroup();
1724     }
1725     
1726     
1727     //*******************************************
1728     // Override the close & minimize instead.
1729     //*******************************************
1730     public static boolean minimizeOnClose() {
1731                 settings.beginGroup("General");
1732                 try {
1733                         String text = (String)settings.value("minimizeOnClose", "false");
1734                         settings.endGroup();
1735                         if (text.equalsIgnoreCase("true") && QSystemTrayIcon.isSystemTrayAvailable())
1736                                 return true;
1737                         else
1738                                 return false;
1739                 } catch (java.lang.ClassCastException e) {
1740                         Boolean value = (Boolean) settings.value("minimizeOnClose", false);
1741                         settings.endGroup();
1742                         return value;
1743                 }
1744     }
1745     public static void setMinimizeOnClose(boolean value) {
1746                 settings.beginGroup("General");
1747                 settings.setValue("minimizeOnClose", value);
1748                 settings.endGroup();    
1749     }
1750
1751     //*********************************
1752     // Check version information
1753     //*********************************
1754     public static boolean checkVersionUpgrade() {
1755                 settings.beginGroup("Upgrade");
1756                 try {
1757                         String text = (String)settings.value("checkForUpdates", "true");
1758                         settings.endGroup();
1759                         if (text.equalsIgnoreCase("true"))
1760                                 return true;
1761                         else
1762                                 return false;
1763                 } catch (java.lang.ClassCastException e) {
1764                         Boolean value = (Boolean) settings.value("checkForUpdates", true);
1765                         settings.endGroup();
1766                         return value;
1767                 }
1768     }
1769     public static void setCheckVersionUpgrade(boolean value) {
1770                 settings.beginGroup("Upgrade");
1771                 settings.setValue("checkForUpdates", value);
1772                 settings.endGroup();    
1773     }
1774     public static String getUpdatesAvailableUrl() {
1775                 settings.beginGroup("Upgrade");
1776                 String text = (String)settings.value("avialableUrl", "http://puma.cis.ibaraki.ac.jp/products/neighbornote/develop/versions.txt");
1777                 settings.endGroup();    
1778                 return text;
1779     }
1780     public static String getUpdateAnnounceUrl() {
1781                 settings.beginGroup("Upgrade");
1782                 String text = (String)settings.value("announceUrl", "http://puma.cis.ibaraki.ac.jp/products/neighbornote/develop/upgrade.html");
1783                 settings.endGroup();    
1784                 return text;
1785     }
1786     public static String getUpdateDownloadUrl() {
1787                 settings.beginGroup("Upgrade");
1788                 String text = (String)settings.value("downloadUrl", "http://puma.cis.ibaraki.ac.jp/products/neighbornote/download.html");
1789                 settings.endGroup();    
1790                 return text;
1791     }
1792     
1793     //*******************
1794     // Index settings
1795     //*******************
1796     // Set/Get if we should index the text of a note
1797     public static boolean indexNoteBody() {
1798                 settings.beginGroup("Index");
1799                 try {
1800                         String value = (String)settings.value("indexNoteBody", "true");
1801                         settings.endGroup();
1802                         if (value.equals("true"))
1803                                 return true;
1804                         else
1805                                 return false;
1806                 } catch (java.lang.ClassCastException e) {
1807                         Boolean value = (Boolean) settings.value("indexNoteBody", true);
1808                         settings.endGroup();
1809                         return value;
1810                 }
1811     }
1812     public static void setIndexNoteTitle(boolean value) {
1813                 settings.beginGroup("Index");
1814                 settings.setValue("indexNoteTitle", value);
1815                 settings.endGroup();    
1816     }
1817     // Set/Get if we should index the title of a note
1818     public static boolean indexNoteTitle() {
1819                 settings.beginGroup("Index");
1820                 try {
1821                         String value = (String)settings.value("indexNoteTitle", "true");
1822                         settings.endGroup();
1823                         if (value.equals("true"))
1824                                 return true;
1825                         else
1826                                 return false;
1827                 } catch (java.lang.ClassCastException e) {
1828                         Boolean value = (Boolean) settings.value("indexNoteTitle", true);
1829                         settings.endGroup();
1830                         return value;
1831                 }
1832     }
1833     public static void setIndexNoteBody(boolean value) {
1834                 settings.beginGroup("Index");
1835                 settings.setValue("indexNoteBody", value);
1836                 settings.endGroup();    
1837     }
1838     // Set/Get if we should index any attachments
1839     public static boolean indexAttachmentsLocally() {
1840                 settings.beginGroup("Index");
1841                 try {
1842                         String value = (String)settings.value("indexAttachmentsLocally", "true");
1843                         settings.endGroup();
1844                         if (value.equals("true"))
1845                                 return true;
1846                         else
1847                                 return false;
1848                 } catch (java.lang.ClassCastException e) {
1849                         Boolean value = (Boolean) settings.value("indexAttachmentsLocally", true);
1850                         settings.endGroup();
1851                         return value;
1852                 }
1853     }
1854     public static void setIndexImageRecognition(boolean value) {
1855                 settings.beginGroup("Index");
1856                 settings.setValue("indexImageRecognition", value);
1857                 settings.endGroup();    
1858     }
1859     public static boolean indexImageRecognition() {
1860                 settings.beginGroup("Index");
1861                 try {
1862                         String value = (String)settings.value("indexImageRecognition", "true");
1863                         settings.endGroup();
1864                         if (value.equals("true"))
1865                                 return true;
1866                         else
1867                                 return false;
1868                 } catch (java.lang.ClassCastException e) {
1869                         Boolean value = (Boolean) settings.value("indexImageRecognition", true);
1870                         settings.endGroup();
1871                         return value;
1872                 }
1873     }
1874     public static void setIndexAttachmentsLocally(boolean value) {
1875                 settings.beginGroup("Index");
1876                 settings.setValue("indexAttachmentsLocally", value);
1877                 settings.endGroup();    
1878     }
1879     // Get/Set characters that shouldn't be removed from a word
1880 //    public static String getSpecialIndexCharacters() {
1881 //              settings.beginGroup("Index");
1882 //              String text = (String)settings.value("specialCharacters", "");
1883 //              settings.endGroup();    
1884 //              return text;
1885 //    }
1886 //    public static void setSpecialIndexCharacters(String value) {
1887 //              settings.beginGroup("Index");
1888 //              settings.setValue("specialCharacters", value);
1889 //              settings.endGroup();    
1890 //              databaseCache = value;
1891 //    }
1892     
1893     //*****************************************************************************
1894     // Control how tag selection behaves (should they be "and" or "or" selections
1895     //*****************************************************************************
1896     public static boolean anyTagSelectionMatch() {
1897                 settings.beginGroup("General");
1898                 try {
1899                         String value = (String)settings.value("anyTagSelectionMatch", "false");
1900                         settings.endGroup();
1901                         if (value.equals("true"))
1902                                 return true;
1903                         else
1904                                 return false;
1905                 } catch (java.lang.ClassCastException e) {
1906                         Boolean value = (Boolean) settings.value("anyTagSelectionMatch", false);
1907                         settings.endGroup();
1908                         return value;
1909                 }
1910     }
1911     public static void setAnyTagSelectionMatch(boolean value) {
1912                 settings.beginGroup("General");
1913                 settings.setValue("anyTagSelectionMatch", value);
1914                 settings.endGroup();    
1915     }
1916
1917     //*****************************************************************************
1918     // Control if a user receives a warning when trying to create a note-to-note link
1919     // when the DB is not synchronized.
1920     //*****************************************************************************
1921     public static boolean bypassSynchronizationWarning() {
1922                 settings.beginGroup("User");
1923                 try {
1924                         String value = (String)settings.value("bypassSynchronizationWarning", "false");
1925                         settings.endGroup();
1926                         if (value.equals("true"))
1927                                 return true;
1928                         else
1929                                 return false;
1930                 } catch (java.lang.ClassCastException e) {
1931                         Boolean value = (Boolean) settings.value("bypassSynchronizationWarning", false);
1932                         settings.endGroup();
1933                         return value;
1934                 }
1935     }
1936     public static void setBypassSynchronizationWarning(boolean value) {
1937                 settings.beginGroup("User");
1938                 settings.setValue("bypassSynchronizationWarning", value);
1939                 settings.endGroup();    
1940     }
1941
1942     
1943     //***********************
1944     //* Database cache size
1945     //***********************
1946     public static String getDatabaseCacheSize() {
1947                 settings.beginGroup("Debug");
1948                 String text = (String)settings.value("databaseCache", "16384");
1949                 settings.endGroup();    
1950                 return text;
1951     }
1952     public static void setDatabaseCache(String value) {
1953                 settings.beginGroup("Debug");
1954                 settings.setValue("databaseCache", value);
1955                 settings.endGroup();    
1956                 databaseCache = value;
1957     }
1958
1959     
1960     // This is used to copy a class since Java's normal deep copy is wacked
1961     public static Object deepCopy(Object oldObj) 
1962     {
1963        ObjectOutputStream oos = null;
1964        ObjectInputStream ois = null;
1965        try
1966        {
1967           ByteArrayOutputStream bos = 
1968                 new ByteArrayOutputStream(); // A
1969           oos = new ObjectOutputStream(bos); // B
1970           // serialize and pass the object
1971           oos.writeObject(oldObj);   // C
1972           oos.flush();               // D
1973           ByteArrayInputStream bin = 
1974                 new ByteArrayInputStream(bos.toByteArray()); // E
1975           ois = new ObjectInputStream(bin);                  // F
1976           // return the new object
1977           return ois.readObject(); // G
1978        }
1979        catch(Exception e)
1980        {
1981           Global.logger.log(logger.LOW, "Exception in ObjectCloner = " + e);
1982        }
1983           try {
1984                         oos.close();
1985                 ois.close();
1986                 } catch (IOException e) {
1987                         Global.logger.log(logger.LOW, "Exception in ObjectCloner = " + e);
1988                         e.printStackTrace();
1989                 }
1990
1991                 return null;
1992     }
1993
1994     // If we should automatically select the children of any tag
1995     public static boolean includeTagChildren() {
1996                 settings.beginGroup("General");
1997                 try {
1998                         String value = (String)settings.value("includeTagChildren", "false");
1999                         settings.endGroup();
2000                         if (value.equals("true"))
2001                                 return true;
2002                         else
2003                                 return false;
2004                 } catch (java.lang.ClassCastException e) {
2005                         Boolean value = (Boolean) settings.value("includeTagChildren", false);
2006                         settings.endGroup();
2007                         return value;
2008                 }
2009
2010     }
2011     public static void setIncludeTagChildren(boolean value) {
2012                 settings.beginGroup("General");
2013                 settings.setValue("includeTagChildren", value);
2014                 settings.endGroup();    
2015     }
2016     
2017     // If we should automatically wildcard searches
2018 //    public static boolean automaticWildcardSearches() {
2019 //              settings.beginGroup("General");
2020 //              try {
2021 //                      String value = (String)settings.value("automaticWildcard", "false");
2022 //                      settings.endGroup();
2023 //                      if (value.equals("true"))
2024 //                              return true;
2025 //                      else
2026 //                              return false;
2027 //              } catch (java.lang.ClassCastException e) {
2028 //                      Boolean value = (Boolean) settings.value("automaticWildcard", false);
2029 //                      settings.endGroup();
2030 //                      return value;
2031 //              }
2032 //
2033 //    }
2034 //    public static void setAutomaticWildcardSearches(boolean value) {
2035 //              settings.beginGroup("General");
2036 //              settings.setValue("automaticWildcard", value);
2037 //              settings.endGroup();    
2038 //    }
2039
2040     // If we should automatically select the children of any tag
2041     public static boolean displayRightToLeft() {
2042                 settings.beginGroup("General");
2043                 try {
2044                         String value = (String)settings.value("displayRightToLeft", "false");
2045                         settings.endGroup();
2046                         if (value.equals("true"))
2047                                 return true;
2048                         else
2049                                 return false;
2050                 } catch (java.lang.ClassCastException e) {
2051                         Boolean value = (Boolean) settings.value("displayRightToLeft", false);
2052                         settings.endGroup();
2053                         return value;
2054                 }
2055
2056     }
2057     public static void setDisplayRightToLeft(boolean value) {
2058                 settings.beginGroup("General");
2059                 settings.setValue("displayRightToLeft", value);
2060                 settings.endGroup();    
2061     }
2062
2063
2064     //***********************
2065     //* Startup Notebook
2066     //***********************
2067     public static String getStartupNotebook() {
2068                 settings.beginGroup("General");
2069                 String text = (String)settings.value("startupNotebook", "");
2070                 settings.endGroup();    
2071                 return text;
2072     }
2073     public static void setStartupNotebook(String value) {
2074                 settings.beginGroup("General");
2075                 settings.setValue("startupNotebook", value);
2076                 settings.endGroup();    
2077                 databaseCache = value;
2078     }
2079     
2080     // 複数ノート同時閲覧操作に対する重み付け
2081     public static void setBrowseWeight(int weight) {
2082                 settings.beginGroup("RensoNoteList");
2083                 settings.setValue("browseWeight", weight);
2084                 settings.endGroup();            
2085     }
2086     public static int getBrowseWeight() {
2087                 settings.beginGroup("RensoNoteList");
2088                 Integer value;
2089                 try {
2090                         String val  = (String)settings.value("browseWeight", 1);
2091                         value = new Integer(val.trim());
2092                 } catch (Exception e) {
2093                         try {
2094                                 value = (Integer)settings.value("browseWeight", 1);
2095                         } catch (Exception e1) {
2096                                 value = 1;
2097                         }
2098                 }
2099                 settings.endGroup();
2100                 return value;
2101     }
2102     
2103     // ノート内容のコピー&ペースト操作に対する重み付け
2104     public static void setCopyPasteWeight(int weight) {
2105                 settings.beginGroup("RensoNoteList");
2106                 settings.setValue("copyPasteWeight", weight);
2107                 settings.endGroup();            
2108     }
2109     public static int getCopyPasteWeight() {
2110                 settings.beginGroup("RensoNoteList");
2111                 Integer value;
2112                 try {
2113                         String val  = (String)settings.value("copyPasteWeight", 3);
2114                         value = new Integer(val.trim());
2115                 } catch (Exception e) {
2116                         try {
2117                                 value = (Integer)settings.value("copyPasteWeight", 3);
2118                         } catch (Exception e1) {
2119                                 value = 3;
2120                         }
2121                 }
2122                 settings.endGroup();
2123                 return value;
2124     }
2125     
2126     // 新規ノート追加操作に対する重み付け
2127     public static void setAddNewNoteWeight(int weight) {
2128                 settings.beginGroup("RensoNoteList");
2129                 settings.setValue("addNewNoteWeight", weight);
2130                 settings.endGroup();            
2131     }
2132         public static int getAddNewNoteWeight() {
2133                 settings.beginGroup("RensoNoteList");
2134                 Integer value;
2135                 try {
2136                         String val  = (String)settings.value("addNewNoteWeight", 3);
2137                         value = new Integer(val.trim());
2138                 } catch (Exception e) {
2139                         try {
2140                                 value = (Integer)settings.value("addNewNoteWeight", 3);
2141                         } catch (Exception e1) {
2142                                 value = 1;
2143                         }
2144                 }
2145                 settings.endGroup();
2146                 return value;
2147         }
2148         
2149         // 連想ノートクリック操作に対する重み付け
2150     public static void setRensoItemClickWeight(int weight) {
2151                 settings.beginGroup("RensoNoteList");
2152                 settings.setValue("rensoItemClickWeight", weight);
2153                 settings.endGroup();            
2154     }
2155         public static int getRensoItemClickWeight() {
2156                 settings.beginGroup("RensoNoteList");
2157                 Integer value;
2158                 try {
2159                         String val  = (String)settings.value("rensoItemClickWeight", 10);
2160                         value = new Integer(val.trim());
2161                 } catch (Exception e) {
2162                         try {
2163                                 value = (Integer)settings.value("rensoItemClickWeight", 10);
2164                         } catch (Exception e1) {
2165                                 value = 10;
2166                         }
2167                 }
2168                 settings.endGroup();
2169                 return value;
2170         }
2171         
2172         // タグ付け操作に対する重み付け
2173     public static void setSameTagWeight(int weight) {
2174                 settings.beginGroup("RensoNoteList");
2175                 settings.setValue("sameTagWeight", weight);
2176                 settings.endGroup();            
2177     }
2178         public static int getSameTagWeight() {
2179                 settings.beginGroup("RensoNoteList");
2180                 Integer value;
2181                 try {
2182                         String val  = (String)settings.value("sameTagWeight", 2);
2183                         value = new Integer(val.trim());
2184                 } catch (Exception e) {
2185                         try {
2186                                 value = (Integer)settings.value("sameTagWeight", 2);
2187                         } catch (Exception e1) {
2188                                 value = 2;
2189                         }
2190                 }
2191                 settings.endGroup();
2192                 return value;
2193         }
2194         
2195         // ノートブック変更操作に対する重み付け
2196     public static void setSameNotebookWeight(int weight) {
2197                 settings.beginGroup("RensoNoteList");
2198                 settings.setValue("sameNotebookWeight", weight);
2199                 settings.endGroup();            
2200     }
2201         public static int getSameNotebookWeight() {
2202                 settings.beginGroup("RensoNoteList");
2203                 Integer value;
2204                 try {
2205                         String val  = (String)settings.value("sameNotebookWeight", 2);
2206                         value = new Integer(val.trim());
2207                 } catch (Exception e) {
2208                         try {
2209                                 value = (Integer)settings.value("sameNotebookWeight", 2);
2210                         } catch (Exception e1) {
2211                                 value = 2;
2212                         }
2213                 }
2214                 settings.endGroup();
2215                 return value;
2216         }
2217         
2218         // Evernote関連ノート機能統合に対する重み付け
2219         public static void setENRelatedNotesWeight(int weight) {
2220                 settings.beginGroup("RensoNoteList");
2221                 settings.setValue("enRelatedNotesWeight", weight);
2222                 settings.endGroup();
2223         }
2224         public static int getENRelatedNotesWeight() {
2225                 settings.beginGroup("RensoNoteList");
2226                 Integer value;
2227                 try {
2228                         String val = (String)settings.value("enRelatedNotesWeight", 5);
2229                         value = new Integer(val.trim());
2230                 } catch (Exception e) {
2231                         try {
2232                                 value = (Integer)settings.value("enRelatedNotesWeight", 5);
2233                         } catch (Exception e1) {
2234                                 value = 10;
2235                         }
2236                 }
2237                 settings.endGroup();
2238                 return value;
2239         }
2240     
2241     //*******************
2242     // ノートのマージ・複製の関連ノートリストへの適用
2243     //*******************
2244     public static void setMergeRensoNote(boolean value) {
2245                 settings.beginGroup("RensoNoteList");
2246                 settings.setValue("mergeRensoNoteList", value);
2247                 settings.endGroup();    
2248     }
2249     
2250     public static boolean getMergeRensoNote() {
2251                 settings.beginGroup("RensoNoteList");
2252                 try {
2253                         String value = (String)settings.value("mergeRensoNoteList", "true");
2254                         settings.endGroup();
2255                         if (value.equals("true"))
2256                                 return true;
2257                         else
2258                                 return false;
2259                 } catch (java.lang.ClassCastException e) {
2260                         Boolean value = (Boolean) settings.value("mergeRensoNoteList", true);
2261                         settings.endGroup();
2262                         return value;
2263                 }
2264     }
2265     
2266     public static void setDuplicateRensoNote(boolean value) {
2267                 settings.beginGroup("RensoNoteList");
2268                 settings.setValue("duplicateRensoNoteList", value);
2269                 settings.endGroup();    
2270     }
2271     
2272     public static boolean getDuplicateRensoNote() {
2273                 settings.beginGroup("RensoNoteList");
2274                 try {
2275                         String value = (String)settings.value("duplicateRensoNoteList", "true");
2276                         settings.endGroup();
2277                         if (value.equals("true"))
2278                                 return true;
2279                         else
2280                                 return false;
2281                 } catch (java.lang.ClassCastException e) {
2282                         Boolean value = (Boolean) settings.value("duplicateRensoNoteList", true);
2283                         settings.endGroup();
2284                         return value;
2285                 }
2286     }
2287     
2288     // 連想ノートリストからノートを除外するときに確認メッセージを表示するかどうか
2289     public static boolean verifyExclude() {
2290                 settings.beginGroup("RensoNoteList");
2291                 try {
2292                         String text = (String)settings.value("verifyExclude", "true");
2293                         settings.endGroup();
2294                         if (text.equalsIgnoreCase("true"))
2295                                 return true;
2296                         else
2297                                 return false;
2298                 } catch (java.lang.ClassCastException e) {
2299                         Boolean value = (Boolean) settings.value("verifyExclude", true);
2300                         settings.endGroup();
2301                         return value;
2302                 }
2303     }
2304     
2305     public static void setVerifyExclude(boolean val) {
2306                 settings.beginGroup("RensoNoteList");
2307                 if (val)
2308                         settings.setValue("verifyExclude", "true");
2309                 else
2310                         settings.setValue("verifyExclude", "false");
2311                 settings.endGroup();
2312     }
2313     
2314         // 連想ノートリスト最大表示アイテム数
2315     public static void setRensoListItemMaximum(int maximum) {
2316                 settings.beginGroup("RensoNoteList");
2317                 settings.setValue("rensoListMaximum", maximum);
2318                 settings.endGroup();            
2319     }
2320         public static int getRensoListItemMaximum() {
2321                 settings.beginGroup("RensoNoteList");
2322                 Integer value;
2323                 try {
2324                         String val  = (String)settings.value("rensoListMaximum", 10);
2325                         value = new Integer(val.trim());
2326                 } catch (Exception e) {
2327                         try {
2328                                 value = (Integer)settings.value("rensoListMaximum", 10);
2329                         } catch (Exception e1) {
2330                                 value = 10;
2331                         }
2332                 }
2333                 settings.endGroup();
2334                 return value;
2335         }
2336         
2337         // タグを排除してプレーンテキストを抽出
2338         public static String extractPlainText(String sourceText) {
2339                 String plainText = sourceText.replaceAll("<.+?>", "");  // タグを除去
2340                 plainText = plainText.replaceAll("\\s{2,}", " ");               // 2個以上の空白文字を1文字の空白に変換
2341                 String kaigyo = System.getProperty("line.separator");
2342                 plainText = plainText.replaceAll(kaigyo, "");                   // 改行を除去
2343 //              plainText = plainText.replaceAll("&lt;.+?&gt;", "");    // &lt;で始まり&gt;で終わる文字列を除去
2344                 
2345                 // HTML特殊文字のサニタイジングを解除
2346                 plainText = plainText.replaceAll("&#39;", "'");
2347                 plainText = plainText.replaceAll("&quot;", "\"");
2348                 plainText = plainText.replaceAll("&gt;", ">");
2349                 plainText = plainText.replaceAll("&lt;", "<");
2350                 plainText = plainText.replaceAll("&amp;", "&");
2351                 
2352                 plainText = plainText.replaceAll("&.+?;", "");                  // その他HTML特殊文字があれば除去
2353                 
2354                 return plainText;
2355         }
2356         
2357         // 全文検索機能の対象となるテーブルとカラムを再構築
2358         public static boolean rebuildFullTextNoteTarget(DatabaseConnection dbConn) {
2359                 NSqlQuery nQuery = new NSqlQuery(dbConn.getConnection());
2360                 StringBuilder noteTableTarget = new StringBuilder();
2361                 boolean success = true;
2362                 
2363                 if (Global.indexNoteBody()) {
2364                         noteTableTarget.append("CONTENTTEXT");
2365                 }
2366                 if (Global.indexNoteTitle()) {
2367                         if (noteTableTarget.length() > 0) {
2368                                 noteTableTarget.append(", ");
2369                         }
2370                         noteTableTarget.append("TITLE");
2371                 }
2372                 
2373                 if (noteTableTarget.length() > 0) {
2374                         nQuery.prepare("CALL FTL_CREATE_INDEX('PUBLIC', 'NOTE', :column);");
2375                         nQuery.bindValue(":column", noteTableTarget.toString());
2376                         if (!nQuery.exec()) {
2377                                 success = false;
2378                         }
2379                 }
2380                 
2381                 return success;
2382         }
2383         
2384         public static boolean rebuildFullTextResourceTarget(DatabaseConnection dbConn) {
2385                 NSqlQuery rQuery = new NSqlQuery(dbConn.getResourceConnection());
2386                 StringBuilder resourceTableTarget = new StringBuilder();
2387                 boolean success = true;
2388                 
2389                 if (Global.indexAttachmentsLocally()) {
2390                         resourceTableTarget.append("RESOURCETEXT");
2391                 }
2392                 
2393                 if (resourceTableTarget.length() > 0) {
2394                         rQuery.prepare("CALL FTL_CREATE_INDEX('PUBLIC', 'NOTERESOURCES', :column);");
2395                         rQuery.bindValue(":column", resourceTableTarget.toString());
2396                         if (!rQuery.exec()) {
2397                                 success = false;
2398                         }
2399                 }
2400                 
2401                 return success;
2402         }
2403         
2404     // 操作ログを取らないモードのボタン状態
2405     public static boolean isHaltLogButton() {
2406                 settings.beginGroup("RensoNoteList");
2407                 try {
2408                         String text = (String)settings.value("haltOperationLog", "false");
2409                         settings.endGroup();
2410                         if (text.equalsIgnoreCase("true"))
2411                                 return true;
2412                         else
2413                                 return false;
2414                 } catch (java.lang.ClassCastException e) {
2415                         Boolean value = (Boolean) settings.value("haltOperationLog", true);
2416                         settings.endGroup();
2417                         return value;
2418                 }
2419     }
2420     public static void saveHaltLogButton(boolean val) {
2421                 settings.beginGroup("RensoNoteList");
2422                 if (val)
2423                         settings.setValue("haltOperationLog", "true");
2424                 else
2425                         settings.setValue("haltOperationLog", "false");
2426                 settings.endGroup();
2427     }
2428     
2429     // 連想ノートリストの重み付けモードの状態
2430     public static String rensoWeightingSelect() {
2431                 settings.beginGroup("RensoNoteList");
2432                 String text = (String)settings.value("rensoWeightingSelect", "Standard");
2433                 settings.endGroup();
2434                 return text;
2435     }
2436     public static void saveRensoWeightingSelect(String val) {
2437                 settings.beginGroup("RensoNoteList");
2438                 settings.setValue("rensoWeightingSelect", val);
2439                 settings.endGroup();
2440     }
2441     
2442     // ordinal から指定した Enum の要素に変換する汎用関数
2443         public static <E extends Enum<E>> E fromOrdinal(Class<E> enumClass, int ordinal) {
2444             E[] enumArray = enumClass.getEnumConstants();
2445             return enumArray[ordinal];
2446         }
2447         
2448         // 連想ノートリスト重み付けモード:カスタムの設定値(同時閲覧)
2449     public static int customBrowseWeight() {
2450                 settings.beginGroup("RensoNoteList");
2451                 Integer value;
2452                 try {
2453                         String val  = (String)settings.value("customBrowseWeight", 1);
2454                         value = new Integer(val.trim());
2455                 } catch (Exception e) {
2456                         try {
2457                                 value = (Integer)settings.value("customBrowseWeight", 1);
2458                         } catch (Exception e1) {
2459                                 value = 1;
2460                         }
2461                 }
2462                 settings.endGroup();
2463                 return value;
2464     }
2465         public static void saveCustomBrowseWeight(int weight) {
2466                 settings.beginGroup("RensoNoteList");
2467                 settings.setValue("customBrowseWeight", weight);
2468                 settings.endGroup();
2469         }
2470         // 連想ノートリスト重み付けモード:カスタムの設定値(コピー&ペースト)
2471     public static int customCopyPasteWeight() {
2472                 settings.beginGroup("RensoNoteList");
2473                 Integer value;
2474                 try {
2475                         String val  = (String)settings.value("customCopyPasteWeight", 3);
2476                         value = new Integer(val.trim());
2477                 } catch (Exception e) {
2478                         try {
2479                                 value = (Integer)settings.value("customCopyPasteWeight", 3);
2480                         } catch (Exception e1) {
2481                                 value = 3;
2482                         }
2483                 }
2484                 settings.endGroup();
2485                 return value;
2486     }
2487         public static void saveCustomCopyPasteWeight(int weight) {
2488                 settings.beginGroup("RensoNoteList");
2489                 settings.setValue("customCopyPasteWeight", weight);
2490                 settings.endGroup();
2491         }
2492         // 連想ノートリスト重み付けモード:カスタムの設定値(新規ノート追加)
2493     public static int customAddNewNoteWeight() {
2494                 settings.beginGroup("RensoNoteList");
2495                 Integer value;
2496                 try {
2497                         String val  = (String)settings.value("customAddNewNoteWeight", 3);
2498                         value = new Integer(val.trim());
2499                 } catch (Exception e) {
2500                         try {
2501                                 value = (Integer)settings.value("customAddNewNoteWeight", 3);
2502                         } catch (Exception e1) {
2503                                 value = 3;
2504                         }
2505                 }
2506                 settings.endGroup();
2507                 return value;
2508     }
2509         public static void saveCustomAddNewNoteWeight(int weight) {
2510                 settings.beginGroup("RensoNoteList");
2511                 settings.setValue("customAddNewNoteWeight", weight);
2512                 settings.endGroup();
2513         }
2514         // 連想ノートリスト重み付けモード:カスタムの設定値(連想ノートクリック)
2515     public static int customRensoItemClickWeight() {
2516                 settings.beginGroup("RensoNoteList");
2517                 Integer value;
2518                 try {
2519                         String val  = (String)settings.value("customRensoItemClickWeight", 10);
2520                         value = new Integer(val.trim());
2521                 } catch (Exception e) {
2522                         try {
2523                                 value = (Integer)settings.value("customRensoItemClickWeight", 10);
2524                         } catch (Exception e1) {
2525                                 value = 10;
2526                         }
2527                 }
2528                 settings.endGroup();
2529                 return value;
2530     }
2531         public static void saveCustomRensoItemClickWeight(int weight) {
2532                 settings.beginGroup("RensoNoteList");
2533                 settings.setValue("customRensoItemClickWeight", weight);
2534                 settings.endGroup();
2535         }
2536         // 連想ノートリスト重み付けモード:カスタムの設定値(同じタグ)
2537     public static int customSameTagWeight() {
2538                 settings.beginGroup("RensoNoteList");
2539                 Integer value;
2540                 try {
2541                         String val  = (String)settings.value("customSameTagWeight", 2);
2542                         value = new Integer(val.trim());
2543                 } catch (Exception e) {
2544                         try {
2545                                 value = (Integer)settings.value("customSameTagWeight", 2);
2546                         } catch (Exception e1) {
2547                                 value = 2;
2548                         }
2549                 }
2550                 settings.endGroup();
2551                 return value;
2552     }
2553         public static void saveCustomSameTagWeight(int weight) {
2554                 settings.beginGroup("RensoNoteList");
2555                 settings.setValue("customSameTagWeight", weight);
2556                 settings.endGroup();
2557         }
2558         // 連想ノートリスト重み付けモード:カスタムの設定値(同じノートブック)
2559     public static int customSameNotebookWeight() {
2560                 settings.beginGroup("RensoNoteList");
2561                 Integer value;
2562                 try {
2563                         String val  = (String)settings.value("customSameNotebookWeight", 2);
2564                         value = new Integer(val.trim());
2565                 } catch (Exception e) {
2566                         try {
2567                                 value = (Integer)settings.value("customSameNotebookWeight", 2);
2568                         } catch (Exception e1) {
2569                                 value = 2;
2570                         }
2571                 }
2572                 settings.endGroup();
2573                 return value;
2574     }
2575         public static void saveCustomSameNotebookWeight(int weight) {
2576                 settings.beginGroup("RensoNoteList");
2577                 settings.setValue("customSameNotebookWeight", weight);
2578                 settings.endGroup();
2579         }
2580         // 連想ノートリスト重み付けモード:カスタムの設定値(Evernote関連ノート)
2581     public static int customENRelatedNotesWeight() {
2582                 settings.beginGroup("RensoNoteList");
2583                 Integer value;
2584                 try {
2585                         String val  = (String)settings.value("customENRelatedNotesWeight", 5);
2586                         value = new Integer(val.trim());
2587                 } catch (Exception e) {
2588                         try {
2589                                 value = (Integer)settings.value("customENRelatedNotesWeight", 5);
2590                         } catch (Exception e1) {
2591                                 value = 5;
2592                         }
2593                 }
2594                 settings.endGroup();
2595                 return value;
2596     }
2597         public static void saveCustomENRelatedNotesWeight(int weight) {
2598                 settings.beginGroup("RensoNoteList");
2599                 settings.setValue("customENRelatedNotesWeight", weight);
2600                 settings.endGroup();
2601         }
2602
2603         // ツールバーの「新規」ボタンを押した時、新規ノートをタブで開くかどうか
2604         public static boolean toolBarNewAction() {
2605                 settings.beginGroup("General");
2606                 try {
2607                         String text = (String)settings.value("toolBarNewAction", "true");
2608                         settings.endGroup();
2609                         if (text.equalsIgnoreCase("true"))
2610                                 return true;
2611                         else
2612                                 return false;
2613                 } catch (java.lang.ClassCastException e) {
2614                         Boolean value = (Boolean) settings.value("toolBarNewAction", true);
2615                         settings.endGroup();
2616                         return value;
2617                 }
2618         }
2619         public static void setToolBarNewAction(boolean value) {
2620                 settings.beginGroup("General");
2621                 settings.setValue("toolBarNewAction", value);
2622                 settings.endGroup();    
2623         }
2624 }
2625