-<?xml version="1.0" encoding="UTF-8"?>\r
-<classpath>\r
- <classpathentry kind="src" path="src"/>\r
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>\r
- <classpathentry kind="lib" path="lib/evernote-api-1.20.jar"/>\r
- <classpathentry kind="lib" path="lib/h2-1.3.158.jar"/>\r
- <classpathentry kind="lib" path="lib/libthrift.jar"/>\r
- <classpathentry kind="lib" path="lib/log4j-1.2.14.jar"/>\r
- <classpathentry kind="lib" path="lib/commons-lang3-3.0.jar"/>\r
- <classpathentry kind="lib" path="lib/jtidy-r938.jar"/>\r
- <classpathentry kind="var" path="QT_JAMBI/qtjambi-4.5.2_01.jar"/>\r
- <classpathentry kind="var" path="QT_JAMBI/qtjambi-win32-msvc2005-4.5.2_01.jar"/>\r
- <classpathentry kind="lib" path="lib/poi-scratchpad-3.7-20101029.jar"/>\r
- <classpathentry kind="lib" path="lib/poi-3.7-20101029.jar"/>\r
- <classpathentry kind="lib" path="lib/poi-ooxml-schemas-3.7-20101029.jar"/>\r
- <classpathentry kind="lib" path="lib/xmlbeans-2.3.0.jar"/>\r
- <classpathentry kind="lib" path="lib/commons-compress-1.2.jar"/>\r
- <classpathentry kind="lib" path="lib/poi-ooxml-3.7.jar"/>\r
- <classpathentry kind="lib" path="lib/jaxen-1.1.3.jar"/>\r
- <classpathentry kind="lib" path="lib/xsdlib-20060615.jar"/>\r
- <classpathentry kind="lib" path="lib/jazzy.jar"/>\r
- <classpathentry kind="lib" path="lib/tika.jar"/>\r
- <classpathentry kind="lib" path="lib/apache-mime4j-0.6.jar"/>\r
- <classpathentry kind="lib" path="lib/commons-codec-1.5.jar"/>\r
- <classpathentry kind="lib" path="lib/commons-logging-1.1.1.jar"/>\r
- <classpathentry kind="lib" path="lib/httpclient-4.1.1.jar"/>\r
- <classpathentry kind="lib" path="lib/httpcore-4.1.jar"/>\r
- <classpathentry kind="lib" path="lib/httpmime-4.1.1.jar"/>\r
- <classpathentry kind="lib" path="lib/pdfbox-app-1.6.0.jar"/>\r
- <classpathentry kind="lib" path="C:/repository/nevernote/nixnote/lib/scribe-1.3.0.jar"/>\r
- <classpathentry kind="output" path="bin"/>\r
-</classpath>\r
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+ <classpathentry kind="lib" path="lib/evernote-api-1.20.jar"/>
+ <classpathentry kind="lib" path="lib/h2-1.3.158.jar"/>
+ <classpathentry kind="lib" path="lib/libthrift.jar"/>
+ <classpathentry kind="lib" path="lib/log4j-1.2.14.jar"/>
+ <classpathentry kind="lib" path="lib/commons-lang3-3.0.jar"/>
+ <classpathentry kind="lib" path="lib/jtidy-r938.jar"/>
+ <classpathentry kind="lib" path="lib/poi-scratchpad-3.7-20101029.jar"/>
+ <classpathentry kind="lib" path="lib/poi-3.7-20101029.jar"/>
+ <classpathentry kind="lib" path="lib/poi-ooxml-schemas-3.7-20101029.jar"/>
+ <classpathentry kind="lib" path="lib/xmlbeans-2.3.0.jar"/>
+ <classpathentry kind="lib" path="lib/commons-compress-1.2.jar"/>
+ <classpathentry kind="lib" path="lib/poi-ooxml-3.7.jar"/>
+ <classpathentry kind="lib" path="lib/jaxen-1.1.3.jar"/>
+ <classpathentry kind="lib" path="lib/xsdlib-20060615.jar"/>
+ <classpathentry kind="lib" path="lib/jazzy.jar"/>
+ <classpathentry kind="lib" path="lib/tika.jar"/>
+ <classpathentry kind="lib" path="lib/apache-mime4j-0.6.jar"/>
+ <classpathentry kind="lib" path="lib/commons-codec-1.5.jar"/>
+ <classpathentry kind="lib" path="lib/commons-logging-1.1.1.jar"/>
+ <classpathentry kind="lib" path="lib/httpclient-4.1.1.jar"/>
+ <classpathentry kind="lib" path="lib/httpcore-4.1.jar"/>
+ <classpathentry kind="lib" path="lib/httpmime-4.1.1.jar"/>
+ <classpathentry kind="lib" path="lib/pdfbox-app-1.6.0.jar"/>
+ <classpathentry kind="lib" path="/usr/local/Trolltech/qtjambi-linux32-lgpl-4.5.2_01/qtjambi-4.5.2_01.jar"/>
+ <classpathentry kind="lib" path="/usr/local/Trolltech/qtjambi-linux32-lgpl-4.5.2_01/qtjambi-linux32-gcc-4.5.2_01.jar"/>
+ <classpathentry kind="lib" path="/home/zigzag/workspace/NeighborNote/lib/scribe-1.3.0.jar"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
#Local platform binaries
/lib/*.dll
+
+#ini file
+NeighborNote.ini
<?xml version="1.0" encoding="UTF-8"?>\r
<projectDescription>\r
- <name>NixNote</name>\r
+ <name>NeighborNote</name>\r
<comment></comment>\r
<projects>\r
</projects>\r
+++ /dev/null
-NixNote:: Evernote client clone for Linux, Mac OS X and Windows
-
- Copyright 2009-2012, Randy Baumgarte
- Licensed under GNU General Public Lisence version 2
-
-This is an incomplete clone of Evernote designed to run on Linux.
-It is written in Java so it will also run on other platforms as well but the primary focus has been to try
-and get a usable environment for Linux. While this is designed to work with Evernote, it is in no way
-connected with or supported by Evernote. Any problems you encounter will not be corrected by them
-and, since this is GPL software, you are using this software at your own risk.
-
-See release.txt for details of what works and what doesn't work.
-
-People have used this with both 64 & 32 bit versions of Linux as well as OpenJDK & Sun's Java
-and (so far) have not encountered any problems with these different environments.
-
-Documents:
-
-release.txt: Includes new features, known bugs and limitations.
-
-changelog.txt: ChangeLog and development history
-install.txt: Build and install instructions
-credit.txt: Credit of nevernote developers
-gpl.txt: License description of GPL v2.
-license.txt: Legal notices for licenses and trademarks
-
-shortcut_howto.txt: How-to document to setup shortcut keys.
-shurtcut_sample.txt: Its configuration sample
-
<?xml version='1.0' encoding='utf-8'?>
<project default="jar" basedir=".">
<!-- program name -->
- <property name="project.name" value="nixnote"/>
+ <property name="project.name" value="neighbornote"/>
<property name="application.name" value="sandbox"/>
<!-- targeted QtJambi library version -->
<property name="jvm.gcs" value="incgc"/><!-- GC strategy -->
<!-- product jar file -->
- <property name="jar.name" value="nixnote.jar"/>
+ <property name="jar.name" value="neighbornote.jar"/>
<!-- product exec command -->
- <property name="shell.command" value="nixnote.sh"/>
- <property name="bat.command" value="nixnote.bat"/>
+ <property name="shell.command" value="neighbornote.sh"/>
+ <property name="bat.command" value="neighbornote.bat"/>
<!-- qt utils -->
<property name="linguist.update" value="lupdate"/>
<property name="linguist.release" value="lrelease"/>
<!-- translations -->
- <property name="linguist.project" value="nixnote.pro"/>
+ <property name="linguist.project" value="neighbornote.pro"/>
<!-- documents -->
<property name="doc.changelog" value="changelog.txt"/>
<fileset dir="${doc.dir}"/>
</copy>
<exec dir="dist" executable="tar">
- <arg line="czf ../../nixnote-bin.tar.gz ."/>
+ <arg line="czf ../../neighbornote-bin.tar.gz ."/>
</exec>
</target>
exit 1
fi
-cp $package_dir/usr/share/applications/nixnote.desktop /usr/share/applications/nixnote.desktop
-mkdir /usr/share/nixnote
-cp -r $package_dir/usr/share/nixnote/* /usr/share/nixnote/
+cp $package_dir/usr/share/applications/neighbornote.desktop /usr/share/applications/neighbornote.desktop
+mkdir /usr/share/neighbornote
+cp -r $package_dir/usr/share/neighbornote/* /usr/share/neighbornote/
echo "Install complete"
-Welcome to NixNote.
+Welcome to Neighbornote.
This is a very basic clone of Evernote designed to run on Linux.
It is written in Java so it will also run on other platforms as well but the primary focus has been to try
-- NOTE: I don't have OS-X so I can't verify the stability or usability of this under OS-X
1.) Download the Mac install version.
2.) Run the install program.
-3.) Run nixnote.sh from the installation directory.
+3.) Run neighbornote.sh from the installation directory.
=====================
There are additional options if you wish to run multiple copies under the same userid and options which impact how Java works. These settings are optional and, depending upon your needs, you probably don't need to touch them.
-To run under multiple IDs, you need to pass a parameter NN_NAME="<name>" to the nixnote.sh shell script where <name> is whatever name you want to identify this instance as. For example, ./nixnote.sh NN_NAME="test" will create a separate database called "test". Anything you put in there will be separate from the default NeverNote database, so the username can also be different.
+To run under multiple IDs, you need to pass a parameter NN_NAME="<name>" to the neighbornote.sh shell script where <name> is whatever name you want to identify this instance as. For example, ./nixnote.sh NN_NAME="test" will create a separate database called "test". Anything you put in there will be separate from the default NeverNote database, so the username can also be different.
<html><head></head>
<body>
-NixNote 1.0
+NeighborNote 1.0
<p>
-NixNote is licensed under the Gnu Public License (GPL) version 2.
+NeighborNote is licensed under the Gnu Public License (GPL) version 2.
<p>
-Evernote is Copyright © 2000-2010 Evernote Corporation.All rights reserved.
+Evernote is Copyright © 2000-2010 Evernote Corporation.All rights reserved.
<p>
Qt and Jambi the licensed property of Nokia Corporation and/or its subsidiaries. Nokia, Qt and their respective logos are trademarks of Nokia Corporation in Finland and/or other countries worldwide.
<p>
#! /bin/sh
###########################################
-# NixNote Startup script for OS-X
+# NeighborNote Startup script for OS-X
###########################################
# The ones below are examples only. #
###########################################
-NIXNOTE=$(cd `dirname $0` && pwd)
-# NIXNOTE=/usr/share/nixnote
+NEIGHBORNOTE=$(cd `dirname $0` && pwd)
+# NEIGHBORNOTE=/usr/share/neighbornote
########################################
# Memory settings. These can be tuned #
########################################
# This next variable is optional. It #
# is only needed if you want to run #
-# multiple copies of NixNote under #
+# multiple copies of NeighborNote under #
# the same Linux user id. Each #
# additional copy (after the first) #
# should have a unique name. This #
#####################
# Setup environment #
#####################
-NN_CLASSPATH=$NIXNOTE/nixnote.jar
-
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/apache-mime4j-0.6.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/commons-codec-1.5.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/commons-compress-1.2.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/commons-lang3-3.0.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/commons-logging-1.1.1.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/evernote-api-1.20.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/h2-1.3.158.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/httpclient-4.1.1.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/httpcore-4.1.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/httpmime-4.1.1.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/jaxen-1.1.3.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/jazzy.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/jtidy-r938.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/libthrift.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/log4j-1.2.14.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/pdfbox-app-1.6.0.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/poi-3.7-20101029.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/poi-ooxml-3.7.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/poi-ooxml-schemas-3.7-20101029.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/poi-scratchpad-3.7-20101029.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/scribe-1.3.0.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/tika.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/xmlbeans-2.3.0.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/xsdlib-20060615.jar
-
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/qtjambi-macosx-4.5.2_01.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/qtjambi-macosx-gcc-4.5.2_01.jar
+NN_CLASSPATH=$NEIGHBORNOTE/neighbornote.jar
+
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/apache-mime4j-0.6.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/commons-codec-1.5.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/commons-compress-1.2.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/commons-lang3-3.0.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/commons-logging-1.1.1.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/evernote-api-1.20.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/h2-1.3.158.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/httpclient-4.1.1.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/httpcore-4.1.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/httpmime-4.1.1.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/jaxen-1.1.3.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/jazzy.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/jtidy-r938.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/libthrift.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/log4j-1.2.14.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/pdfbox-app-1.6.0.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/poi-3.7-20101029.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/poi-ooxml-3.7.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/poi-ooxml-schemas-3.7-20101029.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/poi-scratchpad-3.7-20101029.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/scribe-1.3.0.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/tika.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/xmlbeans-2.3.0.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/xsdlib-20060615.jar
+
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/qtjambi-macosx-4.5.2_01.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/qtjambi-macosx-gcc-4.5.2_01.jar
###################
# Run the program #
###################
-cd $NIXNOTE
+cd $NEIGHBORNOTE
java -Xmx$NN_XMX -Xms$NN_XMS -XX:NewRatio=$NN_NEW_RATIO $NN_GC_OPT $NN_DEBUG -classpath $NN_CLASSPATH cx.fbn.nevernote.NeverNote --sync-only=$NN_SYNCONLY --home=$NN_HOME --name=$NN_NAME -XstartOnFirstThread -d32 -client
rem #####################\r
rem # Install variables #\r
rem #####################\r
-set NIXNOTE=%~dp0\r
+set NEIGHBORNOTE=%~dp0\r
\r
rem ########################################\r
rem # Memory settings. These can be tuned #\r
rem ########################################\r
rem # This next variable is optional. It #\r
rem # is only needed if you want to run #\r
-rem # multiple copies of NixNote under #\r
+rem # multiple copies of NeighborNote under#\r
rem # the same user id. Each #\r
rem # additional copy (after the first) #\r
rem # should have a unique name. This #\r
rem #####################\r
rem # Setup environment #\r
rem #####################\r
-set NN_CLASSPATH=%NIXNOTE%nixnote.jar\r
-\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\apache-mime4j-0.6.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\commons-codec-1.5.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\commons-compress-1.2.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\commons-lang3-3.0.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\commons-logging-1.1.1.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\evernote-api-1.20.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\h2-1.3.158.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\httpclient-4.1.1.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\httpcore-4.1.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\httpmime-4.1.1.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\jaxen-1.1.3.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\jazzy.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\jtidy-r938.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\libthrift.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\log4j-1.2.14.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\pdfbox-app-1.6.0.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\poi-3.7-20101029.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\poi-ooxml-3.7.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\poi-ooxml-schemas-3.7-20101029.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\poi-scratchpad-3.7-20101029.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\scribe-1.3.0.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\tika.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\xmlbeans-2.3.0.jar\r
-set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\xsdlib-20060615.jar\r
-\r
-if exist "%NIXNOTE%lib\qtjambi-win32-4.5.2_01.jar" set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\qtjambi-win32-4.5.2_01.jar\r
-if exist "%NIXNOTE%lib\qtjambi-win32-msvc2005-4.5.2_01.jar" set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\qtjambi-win32-msvc2005-4.5.2_01.jar\r
-if exist "%NIXNOTE%lib\qtjambi-win64-4.5.2_01.jar" set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\qtjambi-win64-4.5.2_01.jar\r
-if exist "%NIXNOTE%lib\qtjambi-win64-msvc2005x64-4.5.2_01.jar" set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\qtjambi-win64-msvc2005x64-4.5.2_01.jar\r
+set NN_CLASSPATH=%NEIGHBORNOTE%neighbornote.jar\r
+\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\apache-mime4j-0.6.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\commons-codec-1.5.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\commons-compress-1.2.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\commons-lang3-3.0.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\commons-logging-1.1.1.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\evernote-api-1.20.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\h2-1.3.158.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\httpclient-4.1.1.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\httpcore-4.1.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\httpmime-4.1.1.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\jaxen-1.1.3.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\jazzy.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\jtidy-r938.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\libthrift.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\log4j-1.2.14.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\pdfbox-app-1.6.0.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\poi-3.7-20101029.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\poi-ooxml-3.7.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\poi-ooxml-schemas-3.7-20101029.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\poi-scratchpad-3.7-20101029.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\scribe-1.3.0.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\tika.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\xmlbeans-2.3.0.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\xsdlib-20060615.jar\r
+\r
+if exist "%NEIGHBORNOTE%lib\qtjambi-win32-4.5.2_01.jar" set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\qtjambi-win32-4.5.2_01.jar\r
+if exist "%NEIGHBORNOTE%lib\qtjambi-win32-msvc2005-4.5.2_01.jar" set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\qtjambi-win32-msvc2005-4.5.2_01.jar\r
+if exist "%NEIGHBORNOTE%lib\qtjambi-win64-4.5.2_01.jar" set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\qtjambi-win64-4.5.2_01.jar\r
+if exist "%NEIGHBORNOTE%lib\qtjambi-win64-msvc2005x64-4.5.2_01.jar" set NN_CLASSPATH=%NN_CLASSPATH%;%NEIGHBORNOTE%lib\qtjambi-win64-msvc2005x64-4.5.2_01.jar\r
\r
rem set NN_CLASSPATH="%NN_CLASSPATH%"\r
\r
+
[Desktop Entry]
-Name=NixNote
+Name=NeighborNote
Comment=Use with Evernote to remember everything
GenericName=Evernote-clone
-Exec=/usr/share/nixnote/nixnote.sh
-Icon=/usr/share/nixnote/nixnote.png
+Exec=/usr/share/neighbornote/neighbornote.sh
+Icon=/usr/share/neighbornote/neighbornote.png
StartupNotify=true
Terminal=false
Type=Application
Categories=Network;
+Name[ja_JP]=neighbornote.desktop
# The ones below are examples only. #
###########################################
-NIXNOTE=$(cd `dirname $0` && pwd)
-# NIXNOTE=/usr/share/nixnote
+NEIGHBORNOTE=$(cd `dirname $0` && pwd)
+# NEIGHBORNOTE=/usr/share/neighbornote
########################################
# Memory settings. These can be tuned #
########################################
# This next variable is optional. It #
# is only needed if you want to run #
-# multiple copies of NixNote under #
+# multiple copies of NeighborNote under #
# the same Linux user id. Each #
# additional copy (after the first) #
# should have a unique name. This #
#####################
# Setup environment #
#####################
-NN_CLASSPATH=$NIXNOTE/nixnote.jar
-
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/apache-mime4j-0.6.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/commons-codec-1.5.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/commons-compress-1.2.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/commons-lang3-3.0.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/commons-logging-1.1.1.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/evernote-api-1.20.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/h2-1.3.158.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/httpclient-4.1.1.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/httpcore-4.1.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/httpmime-4.1.1.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/jaxen-1.1.3.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/jazzy.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/jtidy-r938.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/libthrift.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/log4j-1.2.14.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/scribe-1.3.0.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/pdfbox-app-1.6.0.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/poi-3.7-20101029.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/poi-ooxml-3.7.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/poi-ooxml-schemas-3.7-20101029.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/poi-scratchpad-3.7-20101029.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/tika.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/xmlbeans-2.3.0.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/xsdlib-20060615.jar
-
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/qtjambi-linux32-4.5.2_01.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/qtjambi-linux32-gcc-4.5.2_01.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/qtjambi-linux64-4.5.2_01.jar
-NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/qtjambi-linux64-gcc-4.5.2_01.jar
+NN_CLASSPATH=$NEIGHBORNOTE/neighbornote.jar
+
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/apache-mime4j-0.6.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/commons-codec-1.5.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/commons-compress-1.2.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/commons-lang3-3.0.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/commons-logging-1.1.1.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/evernote-api-1.20.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/h2-1.3.158.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/httpclient-4.1.1.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/httpcore-4.1.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/httpmime-4.1.1.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/jaxen-1.1.3.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/jazzy.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/jtidy-r938.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/libthrift.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/log4j-1.2.14.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/scribe-1.3.0.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/pdfbox-app-1.6.0.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/poi-3.7-20101029.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/poi-ooxml-3.7.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/poi-ooxml-schemas-3.7-20101029.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/poi-scratchpad-3.7-20101029.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/tika.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/xmlbeans-2.3.0.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/xsdlib-20060615.jar
+
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/qtjambi-linux32-4.5.2_01.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/qtjambi-linux32-gcc-4.5.2_01.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/qtjambi-linux64-4.5.2_01.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NEIGHBORNOTE/lib/qtjambi-linux64-gcc-4.5.2_01.jar
###################
# Run the program #
###################
-cd $NIXNOTE
+cd $NEIGHBORNOTE
java -Xmx$NN_XMX -Xms$NN_XMS -XX:NewRatio=$NN_NEW_RATIO $NN_GC_OPT $NN_DEBUG -classpath $NN_CLASSPATH cx.fbn.nevernote.NeverNote --name=$NN_NAME --home=$NN_HOME --sync-only=$NN_SYNCONLY
cd -
--- /dev/null
+#! /bin/sh
+/usr/share/neighbornote/neighbornote.sh $*
+++ /dev/null
-#! /bin/sh
-/usr/share/nixnote/nixnote.sh $*
-Welcome to NixNote
+Welcome to NeighborNote
This is an open source clone of Evernote designed to run on Linux. It is written in Java so it will also run on Windows & OS-X, but the primary focus has been to try and get a usable environment for Linux. While this is designed to work with Evernote, it is in no way connectedwith or supported by Evernote. Any problems you encounter will not be corrected by them and,since this is GPL software, you are using this software at your own risk.
-I've tried to add the ability to customize your NixNote menu shortcuts,
+I've tried to add the ability to customize your NeighborNote menu shortcuts,
but I don't want to take the time to setup a new dialog box and all the
junk that entails. So, I chose a text file config instead. Eventually I
may change it so the text file can be edited within the running program, but
I have other things to spend my time on at the moment.
-First, you don't need to do this. Nixnote comes with a default set of
+First, you don't need to do this. Neighbornote comes with a default set of
shortcuts. If you are happy with those then you don't need to do a thing.
If you want to customize your shortcuts then you need to do a little work.
You should have a shortcuts_sample.txt file. Copy this to shortcuts.txt
-in your Nixnote home directory (~/.nevernote on Linux & OS-X and your user
+in your Neighbornote home directory (~/.nevernote on Linux & OS-X and your user
home directory on Windows). This is the file that is read
-when Nixnote starts. Any changes to this file only happen at startup
+when Neighbornote starts. Any changes to this file only happen at startup
so if you change it you need to restart the program to see those changes.
This file has three main columns.
-/*\r
- * This file is part of NixNote \r
- * Copyright 2009 Randy Baumgarte\r
- * \r
- * This file may be licensed under the terms of of the\r
- * GNU General Public License Version 2 (the ``GPL'').\r
- *\r
- * Software distributed under the License is distributed\r
- * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either\r
- * express or implied. See the GPL for the specific language\r
- * governing rights and limitations.\r
- *\r
- * You should have received a copy of the GPL along with this\r
- * program. If not, go to http://www.gnu.org/licenses/gpl.html\r
- * or write to the Free Software Foundation, Inc.,\r
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
- *\r
-*/\r
-\r
-package cx.fbn.nevernote;\r
-\r
-\r
-import java.io.ByteArrayInputStream;\r
-import java.io.ByteArrayOutputStream;\r
-import java.io.IOException;\r
-import java.io.ObjectInputStream;\r
-import java.io.ObjectOutputStream;\r
-import java.text.SimpleDateFormat;\r
-import java.util.ArrayList;\r
-import java.util.Calendar;\r
-import java.util.HashMap;\r
-import java.util.List;\r
-\r
-import org.apache.commons.lang3.StringEscapeUtils;\r
-\r
-import com.evernote.edam.type.Accounting;\r
-import com.evernote.edam.type.PrivilegeLevel;\r
-import com.evernote.edam.type.User;\r
-import com.evernote.edam.type.UserAttributes;\r
-import com.swabunga.spell.engine.Configuration;\r
-import com.trolltech.qt.core.QByteArray;\r
-import com.trolltech.qt.core.QSettings;\r
-import com.trolltech.qt.core.QSize;\r
-import com.trolltech.qt.gui.QPalette;\r
-import com.trolltech.qt.gui.QSystemTrayIcon;\r
-\r
-import cx.fbn.nevernote.config.FileManager;\r
-import cx.fbn.nevernote.config.InitializationException;\r
-import cx.fbn.nevernote.config.StartupConfig;\r
-import cx.fbn.nevernote.gui.ContainsAttributeFilterTable;\r
-import cx.fbn.nevernote.gui.DateAttributeFilterTable;\r
-import cx.fbn.nevernote.gui.ShortcutKeys;\r
-import cx.fbn.nevernote.utilities.ApplicationLogger;\r
-import cx.fbn.nevernote.utilities.Pair;\r
-\r
-\r
-//*****************************************************\r
-//*****************************************************\r
-//* Global constants & static functions used by \r
-//* multiple threads.\r
-//*****************************************************\r
-//*****************************************************\r
-\r
-public class Global {\r
- // Set current version and the known versions.\r
- public static String version = "1.5";\r
- public static String[] validVersions = {"1.5", "1.4", "1.3", "1.2", "1.1", "1.0", "0.99", "0.98", "0.97", "0.96"};\r
- public static String username = ""; \r
- //public static String password = ""; \r
- \r
-\r
- // Each thread has an ID. This is used primarily to check the status\r
- // of running threads.\r
- public static final int mainThreadId=0;\r
- public static final int syncThreadId=1;\r
- public static final int tagCounterThreadId=2;\r
- public static final int trashCounterThreadId=3; // This should always be the highest thread ID\r
- public static final int indexThreadId=4; // Thread for indexing words\r
- public static final int saveThreadId=5; // Thread used for processing data to saving content\r
- public static final int notebookCounterThreadId=6; // Notebook Thread\r
- public static final int indexThread03Id=7; // unused\r
- public static final int indexThread04Id=8; // unused\r
- public static final int dbThreadId=9; // This should always be the highest thread ID\r
- public static final int threadCount = 10;\r
- \r
- \r
- // These variables deal with where the list of notes appears\r
- // They will either be vertical (View_List_Narrow) or will be\r
- // on top of the note (View_List_Wide). It also has the size of\r
- // thumbnails displayed in each view\r
- public static int View_List_Wide = 1;\r
- public static int View_List_Narrow = 2;\r
- public static QSize smallThumbnailSize = new QSize(100,75);\r
- public static QSize largeThumbnailSize = new QSize(300,225);\r
-\r
- // This is used to keep a running list of passwords that the user\r
- // wants us to remember.\r
- public static HashMap<String,Pair<String,String>> passwordSafe = new HashMap<String, Pair<String,String>>();\r
- public static List<Pair<String,String>> passwordRemember = new ArrayList<Pair<String,String>>();\r
- \r
- \r
- //public static String currentNotebookGuid;\r
- \r
- // These deal with Evernote user settings\r
- public static User user; \r
- public static long authTimeRemaining;\r
- public static long authRefreshTime;\r
- public static long failedRefreshes = 0; \r
- public static String userStoreUrl;\r
- public static String noteStoreUrl;\r
- public static String noteStoreUrlBase;\r
-\r
- // When we want to shut down we set this to true to short\r
- // circut other threads\r
- public static boolean keepRunning;\r
- \r
- // In the note list, these are the column numbers\r
- // so I don't need to hard code numbers.\r
- public static int noteTableCreationPosition = 0;\r
- public static int noteTableTitlePosition = 1;\r
- public static int noteTableTagPosition = 2;\r
- public static int noteTableNotebookPosition = 3;\r
- public static int noteTableChangedPosition = 4;\r
- public static int noteTableGuidPosition = 5;\r
- public static int noteTableAuthorPosition = 6;\r
- public static int noteTableSourceUrlPosition = 7;\r
- public static int noteTableSubjectDatePosition = 8;\r
- public static int noteTableSynchronizedPosition = 9;\r
- public static int noteTableThumbnailPosition = 10;\r
- public static int noteTablePinnedPosition = 11;\r
- public static int noteTableColumnCount = 12;\r
- public static Integer cryptCounter = 0;\r
- \r
- //public static int minimumWordCount = 2;\r
- \r
- // Regular expression to parse text with when indexing\r
- private static String wordRegex;\r
- \r
- // Experimental fixes. Set via Edit/Preferences/Debugging\r
- public static boolean enableCarriageReturnFix = false;\r
- public static boolean enableHTMLEntitiesFix = false;\r
- \r
- // Used to set & retrieve ini & Windows registry settings\r
- public static QSettings settings; // Set & get ini settings\r
- public static boolean isConnected; // Are we connected to Evernote\r
- public static boolean showDeleted = false; // Show deleted notes?\r
- public static boolean disableUploads = false; // Should we disable uploads (used in testing features)\r
- public static int messageLevel; // The level of messages to write to the log files\r
- public static String tagDelimeter = ","; // This is used to separate out tag names when entering above note\r
- public static String attachmentNameDelimeter = "------"; // Used to separate out attachment names in the res directory\r
- \r
- \r
- //* Database fields\r
- public static String databaseName = new String("NeverNote"); // database name. used for multiple databases to separate settings.\r
- public static String indexDatabaseName = new String("Index"); // searchable words database\r
- public static String resourceDatabaseName = new String("Resources"); // attachments database\r
- public static DateAttributeFilterTable createdSinceFilter;\r
- public static DateAttributeFilterTable createdBeforeFilter;\r
- public static DateAttributeFilterTable changedSinceFilter;\r
- public static DateAttributeFilterTable changedBeforeFilter;\r
- public static ContainsAttributeFilterTable containsFilter;\r
- \r
- // Log file used for debugging\r
- public static ApplicationLogger logger;\r
- //PrintStream stdoutStream;\r
- \r
- // Application key shortcuts & appearance\r
- public static QPalette originalPalette;\r
- public static ShortcutKeys shortcutKeys;\r
- \r
- public static boolean disableViewing; // used to disable the editor\r
- \r
- // When saving a note, this is a list of things we strip out because Evernote hates them\r
- public static List<String> invalidElements = new ArrayList<String>();\r
- public static HashMap<String, ArrayList<String>> invalidAttributes = new HashMap<String, ArrayList<String>>();\r
- \r
- public static boolean mimicEvernoteInterface; // Try to mimic Evernote or allow multiple notebook selection\r
- public static HashMap<String,String> resourceMap; // List of attachments for a note.\r
- public static String cipherPassword = ""; // If the database is encrypted, this stores the password\r
- public static String databaseCache = "16384"; // Default DB cache size\r
- \r
- // These are used for performance testing\r
- static Calendar startTraceTime; \r
- static Calendar intervalTraceTime;\r
- \r
- static boolean syncOnly;\r
- \r
- private static FileManager fileManager; // Used to access files & directories\r
- \r
- // Do initial setup \r
- public static void setup(StartupConfig startupConfig) throws InitializationException {\r
- settings = new QSettings("fbn.cx", startupConfig.getName());\r
- disableViewing = startupConfig.getDisableViewing();\r
- syncOnly = startupConfig.isSyncOnly();\r
-\r
- fileManager = new FileManager(startupConfig.getHomeDirPath(), startupConfig.getProgramDirPath());\r
-\r
-\r
- getServer(); // Setup URL to connect to\r
- \r
- // Get regular expressions used to parse out words\r
- settings.beginGroup("General");\r
- String regex = (String) settings.value("regex", "[,\\s]+");\r
- setWordRegex(regex);\r
- settings.endGroup();\r
- \r
- //Setup debugging information\r
- settings.beginGroup("Debug");\r
- String msglevel = (String) settings.value("messageLevel", "Low");\r
- settings.endGroup();\r
- \r
- \r
- //messageLevel = 1;\r
- setMessageLevel(msglevel);\r
- keepRunning = true; // Make sure child threads stay running\r
+/*
+ * This file is part of NixNote
+ * Copyright 2009 Randy Baumgarte
+ *
+ * This file may be licensed under the terms of of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+*/
+
+package cx.fbn.nevernote;
+
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.commons.lang3.StringEscapeUtils;
+
+import com.evernote.edam.type.Accounting;
+import com.evernote.edam.type.PrivilegeLevel;
+import com.evernote.edam.type.User;
+import com.evernote.edam.type.UserAttributes;
+import com.swabunga.spell.engine.Configuration;
+import com.trolltech.qt.core.QByteArray;
+import com.trolltech.qt.core.QSettings;
+import com.trolltech.qt.core.QSize;
+import com.trolltech.qt.gui.QPalette;
+import com.trolltech.qt.gui.QSystemTrayIcon;
+
+import cx.fbn.nevernote.config.FileManager;
+import cx.fbn.nevernote.config.InitializationException;
+import cx.fbn.nevernote.config.StartupConfig;
+import cx.fbn.nevernote.gui.ContainsAttributeFilterTable;
+import cx.fbn.nevernote.gui.DateAttributeFilterTable;
+import cx.fbn.nevernote.gui.ShortcutKeys;
+import cx.fbn.nevernote.utilities.ApplicationLogger;
+import cx.fbn.nevernote.utilities.Pair;
+
+
+//*****************************************************
+//*****************************************************
+//* Global constants & static functions used by
+//* multiple threads.
+//*****************************************************
+//*****************************************************
+
+public class Global {
+ // Set current version and the known versions.
+ // ICHANGED 自分用に変更
+ public static String version = "0.1";
+ public static String[] validVersions = {"0.1"};
+
+ public static String username = "";
+ //public static String password = "";
+
+
+ // Each thread has an ID. This is used primarily to check the status
+ // of running threads.
+ public static final int mainThreadId=0;
+ public static final int syncThreadId=1;
+ public static final int tagCounterThreadId=2;
+ public static final int trashCounterThreadId=3; // This should always be the highest thread ID
+ public static final int indexThreadId=4; // Thread for indexing words
+ public static final int saveThreadId=5; // Thread used for processing data to saving content
+ public static final int notebookCounterThreadId=6; // Notebook Thread
+ public static final int indexThread03Id=7; // unused
+ public static final int indexThread04Id=8; // unused
+ public static final int dbThreadId=9; // This should always be the highest thread ID
+ public static final int threadCount = 10;
+
+
+ // These variables deal with where the list of notes appears
+ // They will either be vertical (View_List_Narrow) or will be
+ // on top of the note (View_List_Wide). It also has the size of
+ // thumbnails displayed in each view
+ public static int View_List_Wide = 1;
+ public static int View_List_Narrow = 2;
+ public static QSize smallThumbnailSize = new QSize(100,75);
+ public static QSize largeThumbnailSize = new QSize(300,225);
+
+ // This is used to keep a running list of passwords that the user
+ // wants us to remember.
+ public static HashMap<String,Pair<String,String>> passwordSafe = new HashMap<String, Pair<String,String>>();
+ public static List<Pair<String,String>> passwordRemember = new ArrayList<Pair<String,String>>();
+
+
+ //public static String currentNotebookGuid;
+
+ // These deal with Evernote user settings
+ public static User user;
+ public static long authTimeRemaining;
+ public static long authRefreshTime;
+ public static long failedRefreshes = 0;
+ public static String userStoreUrl;
+ public static String noteStoreUrl;
+ public static String noteStoreUrlBase;
+
+ // When we want to shut down we set this to true to short
+ // circut other threads
+ public static boolean keepRunning;
+
+ // In the note list, these are the column numbers
+ // so I don't need to hard code numbers.
+ public static int noteTableCreationPosition = 0;
+ public static int noteTableTitlePosition = 1;
+ public static int noteTableTagPosition = 2;
+ public static int noteTableNotebookPosition = 3;
+ public static int noteTableChangedPosition = 4;
+ public static int noteTableGuidPosition = 5;
+ public static int noteTableAuthorPosition = 6;
+ public static int noteTableSourceUrlPosition = 7;
+ public static int noteTableSubjectDatePosition = 8;
+ public static int noteTableSynchronizedPosition = 9;
+ public static int noteTableThumbnailPosition = 10;
+ public static int noteTablePinnedPosition = 11;
+ public static int noteTableColumnCount = 12;
+ public static Integer cryptCounter = 0;
+
+ //public static int minimumWordCount = 2;
+
+ // Regular expression to parse text with when indexing
+ private static String wordRegex;
+
+ // Experimental fixes. Set via Edit/Preferences/Debugging
+ public static boolean enableCarriageReturnFix = false;
+ public static boolean enableHTMLEntitiesFix = false;
+
+ // Used to set & retrieve ini & Windows registry settings
+ public static QSettings settings; // Set & get ini settings
+ public static boolean isConnected; // Are we connected to Evernote
+ public static boolean showDeleted = false; // Show deleted notes?
+ public static boolean disableUploads = false; // Should we disable uploads (used in testing features)
+ public static int messageLevel; // The level of messages to write to the log files
+ public static String tagDelimeter = ","; // This is used to separate out tag names when entering above note
+ public static String attachmentNameDelimeter = "------"; // Used to separate out attachment names in the res directory
+
+
+ //* Database fields
+ public static String databaseName = new String("NeverNote"); // database name. used for multiple databases to separate settings.
+ public static String indexDatabaseName = new String("Index"); // searchable words database
+ public static String resourceDatabaseName = new String("Resources"); // attachments database
+
+ // ICHANGED
+ public static String behaviorDatabaseName = new String("Behavior"); // 操作履歴データベース
+
+ public static DateAttributeFilterTable createdSinceFilter;
+ public static DateAttributeFilterTable createdBeforeFilter;
+ public static DateAttributeFilterTable changedSinceFilter;
+ public static DateAttributeFilterTable changedBeforeFilter;
+ public static ContainsAttributeFilterTable containsFilter;
+
+ // Log file used for debugging
+ public static ApplicationLogger logger;
+ //PrintStream stdoutStream;
+
+ // Application key shortcuts & appearance
+ public static QPalette originalPalette;
+ public static ShortcutKeys shortcutKeys;
+
+ public static boolean disableViewing; // used to disable the editor
+
+ // When saving a note, this is a list of things we strip out because Evernote hates them
+ public static List<String> invalidElements = new ArrayList<String>();
+ public static HashMap<String, ArrayList<String>> invalidAttributes = new HashMap<String, ArrayList<String>>();
+
+ public static boolean mimicEvernoteInterface; // Try to mimic Evernote or allow multiple notebook selection
+ public static HashMap<String,String> resourceMap; // List of attachments for a note.
+ public static String cipherPassword = ""; // If the database is encrypted, this stores the password
+ public static String databaseCache = "16384"; // Default DB cache size
+
+ // These are used for performance testing
+ static Calendar startTraceTime;
+ static Calendar intervalTraceTime;
+
+ static boolean syncOnly;
+
+ private static FileManager fileManager; // Used to access files & directories
+
+ // Do initial setup
+ public static void setup(StartupConfig startupConfig) throws InitializationException {
+ // ICHANGED 設定値の保存先を変更
+ settings = new QSettings("NeighborNote.ini", QSettings.Format.IniFormat);
+
+ disableViewing = startupConfig.getDisableViewing();
+ syncOnly = startupConfig.isSyncOnly();
+
+ fileManager = new FileManager(startupConfig.getHomeDirPath(), startupConfig.getProgramDirPath());
+
+
+ getServer(); // Setup URL to connect to
+
+ // Get regular expressions used to parse out words
+ settings.beginGroup("General");
+ String regex = (String) settings.value("regex", "[,\\s]+");
+ setWordRegex(regex);
+ settings.endGroup();
+
+ //Setup debugging information
+ settings.beginGroup("Debug");
+ String msglevel = (String) settings.value("messageLevel", "Low");
+ settings.endGroup();
+
+
+ //messageLevel = 1;
+ setMessageLevel(msglevel);
+ keepRunning = true; // Make sure child threads stay running
disableUploads = disableUploads(); // Should we upload anything? Normally false.\r
//disableUploads = true; //***** DELETE THIS LINE *******\r
- enableCarriageReturnFix = enableCarriageReturnFix(); // Enable test fix?\r
- enableHTMLEntitiesFix = enableHtmlEntitiesFix(); // Enable test fix?\r
- \r
- logger = new ApplicationLogger("global.log"); // Setup log for this class \r
- shortcutKeys = new ShortcutKeys(); // Setup keyboard shortcuts.\r
- mimicEvernoteInterface = getMimicEvernoteInterface(); // Should we mimic Evernote's notebook behavior\r
- resourceMap = new HashMap<String,String>(); // Setup resource map used to store attachments when editing\r
- \r
- databaseCache = getDatabaseCacheSize(); // Set database cache size \r
- \r
- Global.username = getUserInformation().getUsername();\r
- }\r
-\r
- // Get/Set word parsing regular expression\r
- public static String getWordRegex() {\r
- return wordRegex;\r
- }\r
- public static void setWordRegex(String r) {\r
- wordRegex = r;\r
- }\r
-\r
- // Set the debug message level\r
- public static void setMessageLevel(String msglevel) {\r
- if (msglevel.equalsIgnoreCase("low")) \r
- messageLevel = 1;\r
- if (msglevel.equalsIgnoreCase("medium")) \r
- messageLevel = 2;\r
- if (msglevel.equalsIgnoreCase("high")) \r
- messageLevel = 3;\r
- if (msglevel.equalsIgnoreCase("extreme")) \r
- messageLevel = 4;\r
- settings.beginGroup("Debug");\r
- settings.setValue("messageLevel", msglevel);\r
- settings.endGroup(); \r
- }\r
-\r
- //****************************************************\r
- //****************************************************\r
- //** Save user account information from Evernote\r
- //****************************************************\r
- //****************************************************\r
- public static void saveUserInformation(User user) {\r
- settings.beginGroup("User");\r
- settings.setValue("id", user.getId());\r
- settings.setValue("username", user.getUsername());\r
- settings.setValue("email", user.getEmail());\r
- settings.setValue("name", user.getName());\r
- settings.setValue("timezone", user.getTimezone());\r
- settings.setValue("privilege", user.getPrivilege().getValue());\r
- settings.setValue("created", user.getCreated());\r
- settings.setValue("updated", user.getUpdated());\r
- settings.setValue("deleted", user.getDeleted());\r
- settings.setValue("shard", user.getShardId());\r
- settings.endGroup();\r
- isPremium();\r
- if (user.getAttributes()!=null)\r
- saveUserAttributes(user.getAttributes());\r
- if (user.getAccounting()!=null)\r
- saveUserAccounting(user.getAccounting());\r
-\r
- }\r
- public static User getUserInformation() {\r
- User user = new User();\r
- settings.beginGroup("User");\r
- try { \r
- user.setId((Integer)settings.value("id", 0)); \r
- } catch (java.lang.ClassCastException e) {\r
- user.setId(new Integer((String)settings.value("id", "0")));\r
- }\r
- String username = (String)settings.value("username", "");\r
- String email = (String)settings.value("email", "");\r
- String name = (String)settings.value("name", "");\r
- String timezone = (String)settings.value("timezone", "");\r
- Integer privilege = 0;\r
- try { \r
- privilege = new Integer((String)settings.value("privilege", "0")); \r
- } catch (java.lang.ClassCastException e) {\r
- privilege = (Integer)settings.value("privilege", 0);\r
- }\r
-\r
- try { \r
- String date = (String)settings.value("created", "0");\r
- user.setCreated(new Long(date));\r
- date = (String)settings.value("updated", "0");\r
- user.setUpdated(new Long(date));\r
- date = (String)settings.value("deleted", "0");\r
- user.setDeleted(new Long(date));\r
- } catch (java.lang.ClassCastException e) {\r
- Long date = (Long)settings.value("created", 0);\r
- user.setCreated(date);\r
- date = (Long)settings.value("updated", 0);\r
- user.setUpdated(date);\r
- date = (Long)settings.value("deleted", 0);\r
- user.setDeleted(date);\r
- }\r
-\r
- String shard = (String)settings.value("shard", "");\r
- settings.endGroup();\r
- \r
- user.setUsername(username);\r
- user.setEmail(email);\r
- user.setName(name);\r
- user.setTimezone(timezone);\r
- PrivilegeLevel userLevel = PrivilegeLevel.findByValue(privilege);\r
- user.setPrivilege(userLevel);\r
- user.setShardId(shard);\r
- return user;\r
- }\r
- \r
- public static void saveUserAttributes(UserAttributes attrib) {\r
- settings.beginGroup("UserAttributes");\r
- settings.setValue("defaultLocationName", attrib.getDefaultLocationName());\r
- settings.setValue("defaultLatitude", attrib.getDefaultLocationName());\r
- settings.setValue("defaultLongitude", attrib.getDefaultLocationName());\r
- settings.setValue("incomingEmailAddress", attrib.getIncomingEmailAddress());\r
- settings.endGroup();\r
- }\r
- public static UserAttributes getUserAttributes() {\r
- settings.beginGroup("UserAttributes");\r
- UserAttributes attrib = new UserAttributes();\r
- attrib.setDefaultLocationName((String)settings.value("defaultLocationName",""));\r
- attrib.setDefaultLatitudeIsSet(false);\r
- attrib.setDefaultLongitudeIsSet(false);\r
- attrib.setIncomingEmailAddress((String)settings.value("incomingEmailAddress", ""));\r
- settings.endGroup();\r
- return attrib;\r
- }\r
- public static void saveUserAccounting(Accounting acc) {\r
- settings.beginGroup("UserAccounting");\r
- settings.setValue("uploadLimit", acc.getUploadLimit());\r
- settings.setValue("uploadLimitEnd", acc.getUploadLimitEnd());\r
- settings.setValue("uploadLimitNextMonth", acc.getUploadLimitNextMonth());\r
- settings.setValue("premiumServiceStart", acc.getPremiumServiceStart());\r
- settings.setValue("nextPaymentDue", acc.getNextPaymentDue());\r
- settings.setValue("uploadAmount", acc.getUpdated());\r
- settings.endGroup();\r
- }\r
- public static long getUploadLimitEnd() {\r
- Long limit;\r
- settings.beginGroup("UserAccounting");\r
- \r
- // Upload limit\r
- try {\r
- String val = (String)settings.value("uploadLimitEnd", "0");\r
- limit = new Long(val.trim());\r
- } catch (Exception e) {\r
- try {\r
- limit = (Long)settings.value("uploadLimitEnd", 0);\r
- } catch (Exception e1) {\r
- limit = new Long(0);\r
- }\r
- }\r
- \r
- // return value\r
- settings.endGroup();\r
- return limit;\r
- }\r
- public static void saveUploadAmount(long amount) {\r
- settings.beginGroup("UserAccounting");\r
- settings.setValue("uploadAmount", amount);\r
- settings.endGroup();\r
- }\r
- public static long getUploadAmount() {\r
- long amt=0;\r
- settings.beginGroup("UserAccounting");\r
- try {\r
- String num = (String)settings.value("uploadAmount", "0");\r
- amt = new Long(num.trim());\r
- } catch (Exception e) {\r
- try {\r
- amt = (Integer)settings.value("uploadAmount", 0);\r
- } catch (Exception e1) {\r
- amt = 0;\r
- }\r
- }\r
- settings.endGroup();\r
- return amt;\r
- }\r
- public static void saveEvernoteUpdateCount(long amount) {\r
- settings.beginGroup("UserAccounting");\r
- settings.setValue("updateCount", amount);\r
- settings.endGroup();\r
- }\r
- public static long getEvernoteUpdateCount() {\r
- long amt;\r
- settings.beginGroup("UserAccounting");\r
- try {\r
- String num = (String)settings.value("updateCount", new Long(0).toString());\r
- amt = new Long(num.trim());\r
- } catch (java.lang.ClassCastException e) {\r
- amt = 0;\r
- }\r
- settings.endGroup();\r
- return amt;\r
- }\r
- public static boolean isPremium() {\r
- int level;\r
- settings.beginGroup("User");\r
- try {\r
- String num = (String)settings.value("privilege", "1");\r
- level = new Integer(num.trim());\r
- } catch (java.lang.ClassCastException e) {\r
- try {\r
- level = (Integer)settings.value("privilege", 1);\r
- } catch (Exception e1) {\r
- level = 1;\r
- }\r
- }\r
- settings.endGroup();\r
- PrivilegeLevel userLevel = PrivilegeLevel.findByValue(level);\r
- if (userLevel == PrivilegeLevel.NORMAL)\r
- return false;\r
- return true;\r
- \r
- }\r
- public static long getUploadLimit() {\r
- settings.beginGroup("UserAccounting");\r
- long limit;\r
- try {\r
- String num = (String)settings.value("uploadLimit", new Long(0).toString());\r
- limit = new Long(num.trim());\r
- } catch (java.lang.ClassCastException e) {\r
- limit = 0;\r
- }\r
- settings.endGroup();\r
- return limit;\r
- }\r
-\r
- \r
- \r
- //****************************************************\r
- //****************************************************\r
- //** View settings. Used to restore settings \r
- //** when starting and to control how the program\r
- //** behaves.\r
- //****************************************************\r
- //****************************************************\r
- \r
- //* Get/Set if we should show a tray icon\r
- public static boolean showTrayIcon() {\r
- settings.beginGroup("General");\r
- try {\r
- String max = (String) settings.value("showTrayIcon", "false");\r
- settings.endGroup();\r
- if (!max.equalsIgnoreCase("true") || !QSystemTrayIcon.isSystemTrayAvailable())\r
- return false;\r
- else\r
- return true; \r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("showTrayIcon", false);\r
- settings.endGroup();\r
- return value;\r
- }\r
- }\r
- public static void setShowTrayIcon(boolean val) {\r
- settings.beginGroup("General");\r
- if (val)\r
- settings.setValue("showTrayIcon", "true");\r
- else\r
- settings.setValue("showTrayIcon", "false");\r
- settings.endGroup();\r
- }\r
- \r
- // Get/Set window maximized when closed last\r
- public static boolean wasWindowMaximized() {\r
- try {\r
- settings.beginGroup("General");\r
- String max = (String) settings.value("isMaximized", "true");\r
- settings.endGroup();\r
- if (!max.equalsIgnoreCase("true"))\r
- return false;\r
- return true; \r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("isMaximized", true);\r
- settings.endGroup();\r
- return value;\r
- }\r
- }\r
- public static void saveWindowMaximized(boolean isMax) {\r
- settings.beginGroup("General");\r
- if (isMax)\r
- settings.setValue("isMaximized", "true");\r
- else\r
- settings.setValue("isMaximized", "false");\r
- settings.endGroup();\r
- }\r
- \r
- // Get/set currently viewed note Guid\r
- public static String getLastViewedNoteGuid() {\r
- settings.beginGroup("General");\r
- String guid = (String) settings.value("lastViewedNote", "");\r
- settings.endGroup();\r
- return guid; \r
- }\r
- public static void saveCurrentNoteGuid(String guid) {\r
- settings.beginGroup("General");\r
- if (guid != null)\r
- settings.setValue("lastViewedNote", guid);\r
- else\r
- settings.setValue("lastViewedNote", "");\r
- settings.endGroup();\r
- }\r
- \r
- // Get/Set the note column we are sorted on and the order\r
- public static void setSortColumn(int i) {\r
- int view = Global.getListView();\r
- settings.beginGroup("General");\r
- if (view == Global.View_List_Wide)\r
- settings.setValue("sortColumn", i);\r
- else\r
- settings.setValue("sortColumn-Narrow", i);\r
- settings.endGroup();\r
- }\r
- public static int getSortColumn() {;\r
- String key;\r
- if (Global.getListView() == Global.View_List_Wide)\r
- key = "sortColumn";\r
- else\r
- key = "sortColumn-Narrow";\r
-\r
- settings.beginGroup("General");\r
- int order; \r
- try {\r
- String val = settings.value(key, new Integer(0)).toString();\r
- order = new Integer(val.trim());\r
- } catch (Exception e) {\r
- try {\r
- order = (Integer)settings.value(key, 0);\r
- } catch (Exception e1) {\r
- order = 0;\r
- }\r
- }\r
- \r
- settings.endGroup();\r
- return order;\r
- }\r
- public static void setSortOrder(int i) {\r
- int view = Global.getListView();\r
- settings.beginGroup("General");\r
- if (view == Global.View_List_Wide)\r
- settings.setValue("sortOrder", i);\r
- else\r
- settings.setValue("sortOrder-Narrow", i);\r
- settings.endGroup();\r
- }\r
- public static int getSortOrder() {\r
- int view = Global.getListView();\r
- settings.beginGroup("General");\r
- String key;\r
- if (view == Global.View_List_Wide)\r
- key = "sortOrder";\r
- else\r
- key = "sortOrder-Narrow";\r
-\r
- int order; \r
- try {\r
- String val = settings.value(key, new Integer(0)).toString();\r
- order = new Integer(val.trim());\r
- } catch (Exception e) {\r
- try {\r
- order = (Integer)settings.value(key, 0);\r
- } catch (Exception e1) {\r
- order = 0;\r
- }\r
- }\r
- \r
- settings.endGroup();\r
- return order;\r
- }\r
- \r
- // Should we automatically log in to Evernote when starting?\r
- public static boolean automaticLogin() {\r
- try {\r
- settings.beginGroup("General");\r
- String text = (String)settings.value("automaticLogin", "false");\r
- settings.endGroup();\r
- if (text.equalsIgnoreCase("true"))\r
- return true;\r
- else\r
- return false; \r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("automaticLogin", false);\r
- settings.endGroup();\r
- return value;\r
- }\r
- }\r
- public static void setAutomaticLogin(boolean val) {\r
- settings.beginGroup("General");\r
- if (val)\r
- settings.setValue("automaticLogin", "true");\r
- else\r
- settings.setValue("automaticLogin", "false");\r
- settings.endGroup();\r
- }\r
-\r
- // Get/set the Evernote server Url. \r
- public static void setServer(String server) {\r
- settings.beginGroup("General");\r
- settings.setValue("server", server);\r
- settings.endGroup(); \r
- }\r
- public static String getServer() {\r
- settings.beginGroup("General");\r
- String text = (String)settings.value("server", "www.evernote.com");\r
- if (text.equals("www.evernote.com")) {\r
- userStoreUrl = "https://www.evernote.com/edam/user";\r
- noteStoreUrlBase = "www.evernote.com/edam/note/"; \r
- } else {\r
- userStoreUrl = "https://sandbox.evernote.com/edam/user";\r
- noteStoreUrlBase = "sandbox.evernote.com/edam/note/";\r
- }\r
- settings.endGroup();\r
-// if (isPremium())\r
- noteStoreUrlBase = "https://" + noteStoreUrlBase;\r
-// else\r
-// noteStoreUrlBase = "http://" + noteStoreUrlBase;\r
- return text;\r
- }\r
-\r
- // Get/Set if we should disable uploads to Evernote\r
- public static boolean disableUploads() {\r
- settings.beginGroup("General");\r
- try {\r
- String text = (String)settings.value("disableUploads", "false");\r
- settings.endGroup();\r
- if (text.equalsIgnoreCase("true"))\r
- return true;\r
- else\r
- return false;\r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("disableUploads", false);\r
- settings.endGroup();\r
- return value;\r
- }\r
- }\r
- public static void setDisableUploads(boolean val) {\r
- settings.beginGroup("General");\r
- if (val)\r
- settings.setValue("disableUploads", "true");\r
- else\r
- settings.setValue("disableUploads", "false");\r
- settings.endGroup();\r
- disableUploads = val;\r
- }\r
- \r
- // Should we view PDF documents inline?\r
- public static boolean pdfPreview() {\r
- settings.beginGroup("General");\r
- try {\r
- String text = (String)settings.value("pdfPreview", "true");\r
- settings.endGroup();\r
- if (text.equalsIgnoreCase("true"))\r
- return true;\r
- else\r
- return false;\r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("pdfPreview", true);\r
- settings.endGroup();\r
- return value;\r
- }\r
- }\r
- public static void setPdfPreview(boolean val) {\r
- settings.beginGroup("General");\r
- if (val)\r
- settings.setValue("pdfPreview", "true");\r
- else\r
- settings.setValue("pdfPreview", "false");\r
- settings.endGroup();\r
- }\r
- \r
- // When creating a new note, should it inherit tags that are currently selected?\r
- public static boolean newNoteWithSelectedTags() {\r
- settings.beginGroup("General");\r
- try {\r
- String text = (String)settings.value("newNoteWithSelectedTags", "false");\r
- settings.endGroup();\r
- if (text.equalsIgnoreCase("true"))\r
- return true;\r
- else\r
- return false;\r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("newNoteWithSelectedTags", false);\r
- settings.endGroup();\r
- return value;\r
- }\r
- }\r
- public static void setNewNoteWithSelectedTags(boolean val) {\r
- settings.beginGroup("General");\r
- if (val)\r
- settings.setValue("newNoteWithSelectedTags", "true");\r
- else\r
- settings.setValue("newNoteWithSelectedTags", "false");\r
- settings.endGroup();\r
- }\r
- \r
- // Minimum weight for text OCRed from Evernote. Anything below this\r
- // Won't be shown to the user when they search\r
- public static void setRecognitionWeight(int len) {\r
- settings.beginGroup("General");\r
- settings.setValue("recognitionWeight", len);\r
- settings.endGroup(); \r
- }\r
- public static int getRecognitionWeight() {\r
- settings.beginGroup("General");\r
- Integer len;\r
- try {\r
+ enableCarriageReturnFix = enableCarriageReturnFix(); // Enable test fix?
+ enableHTMLEntitiesFix = enableHtmlEntitiesFix(); // Enable test fix?
+
+ logger = new ApplicationLogger("global.log"); // Setup log for this class
+ shortcutKeys = new ShortcutKeys(); // Setup keyboard shortcuts.
+ mimicEvernoteInterface = getMimicEvernoteInterface(); // Should we mimic Evernote's notebook behavior
+ resourceMap = new HashMap<String,String>(); // Setup resource map used to store attachments when editing
+
+ databaseCache = getDatabaseCacheSize(); // Set database cache size
+
+ Global.username = getUserInformation().getUsername();
+ }
+
+ // Get/Set word parsing regular expression
+ public static String getWordRegex() {
+ return wordRegex;
+ }
+ public static void setWordRegex(String r) {
+ wordRegex = r;
+ }
+
+ // Set the debug message level
+ public static void setMessageLevel(String msglevel) {
+ if (msglevel.equalsIgnoreCase("low"))
+ messageLevel = 1;
+ if (msglevel.equalsIgnoreCase("medium"))
+ messageLevel = 2;
+ if (msglevel.equalsIgnoreCase("high"))
+ messageLevel = 3;
+ if (msglevel.equalsIgnoreCase("extreme"))
+ messageLevel = 4;
+ settings.beginGroup("Debug");
+ settings.setValue("messageLevel", msglevel);
+ settings.endGroup();
+ }
+
+ //****************************************************
+ //****************************************************
+ //** Save user account information from Evernote
+ //****************************************************
+ //****************************************************
+ public static void saveUserInformation(User user) {
+ settings.beginGroup("User");
+ settings.setValue("id", user.getId());
+ settings.setValue("username", user.getUsername());
+ settings.setValue("email", user.getEmail());
+ settings.setValue("name", user.getName());
+ settings.setValue("timezone", user.getTimezone());
+ settings.setValue("privilege", user.getPrivilege().getValue());
+ settings.setValue("created", user.getCreated());
+ settings.setValue("updated", user.getUpdated());
+ settings.setValue("deleted", user.getDeleted());
+ settings.setValue("shard", user.getShardId());
+ settings.endGroup();
+ isPremium();
+ if (user.getAttributes()!=null)
+ saveUserAttributes(user.getAttributes());
+ if (user.getAccounting()!=null)
+ saveUserAccounting(user.getAccounting());
+
+ }
+ public static User getUserInformation() {
+ User user = new User();
+ settings.beginGroup("User");
+ try {
+ user.setId((Integer)settings.value("id", 0));
+ } catch (java.lang.ClassCastException e) {
+ user.setId(new Integer((String)settings.value("id", "0")));
+ }
+ String username = (String)settings.value("username", "");
+ String email = (String)settings.value("email", "");
+ String name = (String)settings.value("name", "");
+ String timezone = (String)settings.value("timezone", "");
+ Integer privilege = 0;
+ try {
+ privilege = new Integer((String)settings.value("privilege", "0"));
+ } catch (java.lang.ClassCastException e) {
+ privilege = (Integer)settings.value("privilege", 0);
+ }
+
+ try {
+ String date = (String)settings.value("created", "0");
+ user.setCreated(new Long(date));
+ date = (String)settings.value("updated", "0");
+ user.setUpdated(new Long(date));
+ date = (String)settings.value("deleted", "0");
+ user.setDeleted(new Long(date));
+ } catch (java.lang.ClassCastException e) {
+ Long date = (Long)settings.value("created", 0);
+ user.setCreated(date);
+ date = (Long)settings.value("updated", 0);
+ user.setUpdated(date);
+ date = (Long)settings.value("deleted", 0);
+ user.setDeleted(date);
+ }
+
+ String shard = (String)settings.value("shard", "");
+ settings.endGroup();
+
+ user.setUsername(username);
+ user.setEmail(email);
+ user.setName(name);
+ user.setTimezone(timezone);
+ PrivilegeLevel userLevel = PrivilegeLevel.findByValue(privilege);
+ user.setPrivilege(userLevel);
+ user.setShardId(shard);
+ return user;
+ }
+
+ public static void saveUserAttributes(UserAttributes attrib) {
+ settings.beginGroup("UserAttributes");
+ settings.setValue("defaultLocationName", attrib.getDefaultLocationName());
+ settings.setValue("defaultLatitude", attrib.getDefaultLocationName());
+ settings.setValue("defaultLongitude", attrib.getDefaultLocationName());
+ settings.setValue("incomingEmailAddress", attrib.getIncomingEmailAddress());
+ settings.endGroup();
+ }
+ public static UserAttributes getUserAttributes() {
+ settings.beginGroup("UserAttributes");
+ UserAttributes attrib = new UserAttributes();
+ attrib.setDefaultLocationName((String)settings.value("defaultLocationName",""));
+ attrib.setDefaultLatitudeIsSet(false);
+ attrib.setDefaultLongitudeIsSet(false);
+ attrib.setIncomingEmailAddress((String)settings.value("incomingEmailAddress", ""));
+ settings.endGroup();
+ return attrib;
+ }
+ public static void saveUserAccounting(Accounting acc) {
+ settings.beginGroup("UserAccounting");
+ settings.setValue("uploadLimit", acc.getUploadLimit());
+ settings.setValue("uploadLimitEnd", acc.getUploadLimitEnd());
+ settings.setValue("uploadLimitNextMonth", acc.getUploadLimitNextMonth());
+ settings.setValue("premiumServiceStart", acc.getPremiumServiceStart());
+ settings.setValue("nextPaymentDue", acc.getNextPaymentDue());
+ settings.setValue("uploadAmount", acc.getUpdated());
+ settings.endGroup();
+ }
+ public static long getUploadLimitEnd() {
+ Long limit;
+ settings.beginGroup("UserAccounting");
+
+ // Upload limit
+ try {
+ String val = (String)settings.value("uploadLimitEnd", "0");
+ limit = new Long(val.trim());
+ } catch (Exception e) {
+ try {
+ limit = (Long)settings.value("uploadLimitEnd", 0);
+ } catch (Exception e1) {
+ limit = new Long(0);
+ }
+ }
+
+ // return value
+ settings.endGroup();
+ return limit;
+ }
+ public static void saveUploadAmount(long amount) {
+ settings.beginGroup("UserAccounting");
+ settings.setValue("uploadAmount", amount);
+ settings.endGroup();
+ }
+ public static long getUploadAmount() {
+ long amt=0;
+ settings.beginGroup("UserAccounting");
+ try {
+ String num = (String)settings.value("uploadAmount", "0");
+ amt = new Long(num.trim());
+ } catch (Exception e) {
+ try {
+ amt = (Integer)settings.value("uploadAmount", 0);
+ } catch (Exception e1) {
+ amt = 0;
+ }
+ }
+ settings.endGroup();
+ return amt;
+ }
+ public static void saveEvernoteUpdateCount(long amount) {
+ settings.beginGroup("UserAccounting");
+ settings.setValue("updateCount", amount);
+ settings.endGroup();
+ }
+ public static long getEvernoteUpdateCount() {
+ long amt;
+ settings.beginGroup("UserAccounting");
+ try {
+ String num = (String)settings.value("updateCount", new Long(0).toString());
+ amt = new Long(num.trim());
+ } catch (java.lang.ClassCastException e) {
+ amt = 0;
+ }
+ settings.endGroup();
+ return amt;
+ }
+ public static boolean isPremium() {
+ int level;
+ settings.beginGroup("User");
+ try {
+ String num = (String)settings.value("privilege", "1");
+ level = new Integer(num.trim());
+ } catch (java.lang.ClassCastException e) {
+ try {
+ level = (Integer)settings.value("privilege", 1);
+ } catch (Exception e1) {
+ level = 1;
+ }
+ }
+ settings.endGroup();
+ PrivilegeLevel userLevel = PrivilegeLevel.findByValue(level);
+ if (userLevel == PrivilegeLevel.NORMAL)
+ return false;
+ return true;
+
+ }
+ public static long getUploadLimit() {
+ settings.beginGroup("UserAccounting");
+ long limit;
+ try {
+ String num = (String)settings.value("uploadLimit", new Long(0).toString());
+ limit = new Long(num.trim());
+ } catch (java.lang.ClassCastException e) {
+ limit = 0;
+ }
+ settings.endGroup();
+ return limit;
+ }
+
+
+
+ //****************************************************
+ //****************************************************
+ //** View settings. Used to restore settings
+ //** when starting and to control how the program
+ //** behaves.
+ //****************************************************
+ //****************************************************
+
+ //* Get/Set if we should show a tray icon
+ public static boolean showTrayIcon() {
+ settings.beginGroup("General");
+ try {
+ String max = (String) settings.value("showTrayIcon", "false");
+ settings.endGroup();
+ if (!max.equalsIgnoreCase("true") || !QSystemTrayIcon.isSystemTrayAvailable())
+ return false;
+ else
+ return true;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("showTrayIcon", false);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void setShowTrayIcon(boolean val) {
+ settings.beginGroup("General");
+ if (val)
+ settings.setValue("showTrayIcon", "true");
+ else
+ settings.setValue("showTrayIcon", "false");
+ settings.endGroup();
+ }
+
+ // Get/Set window maximized when closed last
+ public static boolean wasWindowMaximized() {
+ try {
+ settings.beginGroup("General");
+ String max = (String) settings.value("isMaximized", "true");
+ settings.endGroup();
+ if (!max.equalsIgnoreCase("true"))
+ return false;
+ return true;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("isMaximized", true);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void saveWindowMaximized(boolean isMax) {
+ settings.beginGroup("General");
+ if (isMax)
+ settings.setValue("isMaximized", "true");
+ else
+ settings.setValue("isMaximized", "false");
+ settings.endGroup();
+ }
+
+ // Get/set currently viewed note Guid
+ public static String getLastViewedNoteGuid() {
+ settings.beginGroup("General");
+ String guid = (String) settings.value("lastViewedNote", "");
+ settings.endGroup();
+ return guid;
+ }
+ public static void saveCurrentNoteGuid(String guid) {
+ settings.beginGroup("General");
+ if (guid != null)
+ settings.setValue("lastViewedNote", guid);
+ else
+ settings.setValue("lastViewedNote", "");
+ settings.endGroup();
+ }
+
+ // Get/Set the note column we are sorted on and the order
+ public static void setSortColumn(int i) {
+ int view = Global.getListView();
+ settings.beginGroup("General");
+ if (view == Global.View_List_Wide)
+ settings.setValue("sortColumn", i);
+ else
+ settings.setValue("sortColumn-Narrow", i);
+ settings.endGroup();
+ }
+ public static int getSortColumn() {;
+ String key;
+ if (Global.getListView() == Global.View_List_Wide)
+ key = "sortColumn";
+ else
+ key = "sortColumn-Narrow";
+
+ settings.beginGroup("General");
+ int order;
+ try {
+ String val = settings.value(key, new Integer(0)).toString();
+ order = new Integer(val.trim());
+ } catch (Exception e) {
+ try {
+ order = (Integer)settings.value(key, 0);
+ } catch (Exception e1) {
+ order = 0;
+ }
+ }
+
+ settings.endGroup();
+ return order;
+ }
+ public static void setSortOrder(int i) {
+ int view = Global.getListView();
+ settings.beginGroup("General");
+ if (view == Global.View_List_Wide)
+ settings.setValue("sortOrder", i);
+ else
+ settings.setValue("sortOrder-Narrow", i);
+ settings.endGroup();
+ }
+ public static int getSortOrder() {
+ int view = Global.getListView();
+ settings.beginGroup("General");
+ String key;
+ if (view == Global.View_List_Wide)
+ key = "sortOrder";
+ else
+ key = "sortOrder-Narrow";
+
+ int order;
+ try {
+ String val = settings.value(key, new Integer(0)).toString();
+ order = new Integer(val.trim());
+ } catch (Exception e) {
+ try {
+ order = (Integer)settings.value(key, 0);
+ } catch (Exception e1) {
+ order = 0;
+ }
+ }
+
+ settings.endGroup();
+ return order;
+ }
+
+ // Should we automatically log in to Evernote when starting?
+ public static boolean automaticLogin() {
+ try {
+ settings.beginGroup("General");
+ String text = (String)settings.value("automaticLogin", "false");
+ settings.endGroup();
+ if (text.equalsIgnoreCase("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("automaticLogin", false);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void setAutomaticLogin(boolean val) {
+ settings.beginGroup("General");
+ if (val)
+ settings.setValue("automaticLogin", "true");
+ else
+ settings.setValue("automaticLogin", "false");
+ settings.endGroup();
+ }
+
+ // Get/set the Evernote server Url.
+ public static void setServer(String server) {
+ settings.beginGroup("General");
+ settings.setValue("server", server);
+ settings.endGroup();
+ }
+ public static String getServer() {
+ settings.beginGroup("General");
+ String text = (String)settings.value("server", "www.evernote.com");
+ if (text.equals("www.evernote.com")) {
+ userStoreUrl = "https://www.evernote.com/edam/user";
+ noteStoreUrlBase = "www.evernote.com/edam/note/";
+ } else {
+ userStoreUrl = "https://sandbox.evernote.com/edam/user";
+ noteStoreUrlBase = "sandbox.evernote.com/edam/note/";
+ }
+ settings.endGroup();
+// if (isPremium())
+ noteStoreUrlBase = "https://" + noteStoreUrlBase;
+// else
+// noteStoreUrlBase = "http://" + noteStoreUrlBase;
+ return text;
+ }
+
+ // Get/Set if we should disable uploads to Evernote
+ public static boolean disableUploads() {
+ settings.beginGroup("General");
+ try {
+ String text = (String)settings.value("disableUploads", "false");
+ settings.endGroup();
+ if (text.equalsIgnoreCase("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("disableUploads", false);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void setDisableUploads(boolean val) {
+ settings.beginGroup("General");
+ if (val)
+ settings.setValue("disableUploads", "true");
+ else
+ settings.setValue("disableUploads", "false");
+ settings.endGroup();
+ disableUploads = val;
+ }
+
+ // Should we view PDF documents inline?
+ public static boolean pdfPreview() {
+ settings.beginGroup("General");
+ try {
+ String text = (String)settings.value("pdfPreview", "true");
+ settings.endGroup();
+ if (text.equalsIgnoreCase("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("pdfPreview", true);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void setPdfPreview(boolean val) {
+ settings.beginGroup("General");
+ if (val)
+ settings.setValue("pdfPreview", "true");
+ else
+ settings.setValue("pdfPreview", "false");
+ settings.endGroup();
+ }
+
+ // When creating a new note, should it inherit tags that are currently selected?
+ public static boolean newNoteWithSelectedTags() {
+ settings.beginGroup("General");
+ try {
+ String text = (String)settings.value("newNoteWithSelectedTags", "false");
+ settings.endGroup();
+ if (text.equalsIgnoreCase("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("newNoteWithSelectedTags", false);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void setNewNoteWithSelectedTags(boolean val) {
+ settings.beginGroup("General");
+ if (val)
+ settings.setValue("newNoteWithSelectedTags", "true");
+ else
+ settings.setValue("newNoteWithSelectedTags", "false");
+ settings.endGroup();
+ }
+
+ // Minimum weight for text OCRed from Evernote. Anything below this
+ // Won't be shown to the user when they search
+ public static void setRecognitionWeight(int len) {
+ settings.beginGroup("General");
+ settings.setValue("recognitionWeight", len);
+ settings.endGroup();
+ }
+ public static int getRecognitionWeight() {
+ settings.beginGroup("General");
+ Integer len;
+ try {
len = (Integer)settings.value("recognitionWeight", 30);\r
- } catch (Exception e) {\r
+ } catch (Exception e) {
len = 80;\r
- }\r
- settings.endGroup();\r
- return len;\r
- }\r
- \r
- // get/set current debug message level\r
- public static String getMessageLevel() {\r
- settings.beginGroup("Debug");\r
- String text = (String)settings.value("messageLevel", "Low");\r
- settings.endGroup();\r
- setMessageLevel(text);\r
- return text;\r
- }\r
- public static void setDateFormat(String format) {\r
- settings.beginGroup("General");\r
- settings.setValue("dateFormat", format);\r
- settings.endGroup(); \r
- }\r
- \r
- // Get/Set user date/time formats\r
- public static String getDateFormat() {\r
- settings.beginGroup("General");\r
- String text = (String)settings.value("dateFormat", "MM/dd/yyyy");\r
- settings.endGroup();\r
- return text;\r
- }\r
- public static void setTimeFormat(String format) {\r
- settings.beginGroup("General");\r
- settings.setValue("timeFormat", format);\r
- settings.endGroup(); \r
- }\r
- public static String getTimeFormat() {\r
- settings.beginGroup("General");\r
- String text = (String)settings.value("timeFormat", "HH:mm:ss");\r
- settings.endGroup();\r
- return text;\r
- }\r
- \r
- // How often should we sync with Evernote?\r
- public static String getSyncInterval() {\r
- settings.beginGroup("General");\r
- String text = (String)settings.value("syncInterval", "15 minutes");\r
- settings.endGroup();\r
- return text; \r
- }\r
- public static void setSyncInterval(String format) {\r
- settings.beginGroup("General");\r
- settings.setValue("syncInterval", format);\r
- settings.endGroup(); \r
- }\r
- \r
- // Get/Set the width of columns and their position for the \r
- // next start.\r
- public static void setColumnWidth(String col, int width) {\r
- if (Global.getListView() == Global.View_List_Wide)\r
- settings.beginGroup("ColumnWidths");\r
- else \r
- settings.beginGroup("ColumnWidths-Narrow");\r
- settings.setValue(col, width);\r
- settings.endGroup();\r
- }\r
- public static int getColumnWidth(String col) {\r
- int view = Global.getListView();\r
- if (view == Global.View_List_Wide)\r
- settings.beginGroup("ColumnWidths");\r
- else\r
- settings.beginGroup("ColumnWidths-Narrow");\r
- Integer width;\r
- try {\r
- String val = (String)settings.value(col, "0");\r
- width = new Integer(val.trim());\r
- } catch (Exception e) {\r
- try {\r
- width = (Integer)settings.value(col, 0);\r
- } catch (Exception e1) {\r
- width = 0;\r
- }\r
- }\r
- settings.endGroup();\r
- return width;\r
- }\r
- public static void setColumnPosition(String col, int width) {\r
- if (Global.getListView() == Global.View_List_Wide)\r
- settings.beginGroup("ColumnPosition");\r
- else\r
- settings.beginGroup("ColumnPosition-Narrow");\r
- settings.setValue(col, width);\r
- settings.endGroup();\r
- }\r
- public static int getColumnPosition(String col) {\r
- if (Global.getListView() == Global.View_List_Wide)\r
- settings.beginGroup("ColumnPosition");\r
- else\r
- settings.beginGroup("ColumnPosition-Narrow");\r
- Integer width;\r
- try {\r
- String val = (String)settings.value(col, "-1");\r
- width = new Integer(val.trim());\r
- } catch (Exception e) {\r
- try {\r
- width = (Integer)settings.value(col, 0);\r
- } catch (Exception e1) {\r
- width = 0;\r
- }\r
- }\r
- settings.endGroup();\r
- return width;\r
- }\r
- \r
- // Ping the user when they try to delete or just do it.\r
- public static boolean verifyDelete() {\r
- settings.beginGroup("General");\r
- try {\r
- String text = (String)settings.value("verifyDelete", "true");\r
- settings.endGroup();\r
- if (text.equalsIgnoreCase("true"))\r
- return true;\r
- else\r
- return false;\r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("verifyDelete", true);\r
- settings.endGroup();\r
- return value;\r
- }\r
- }\r
- public static void setVerifyDelete(boolean val) {\r
- settings.beginGroup("General");\r
- if (val)\r
- settings.setValue("verifyDelete", "true");\r
- else\r
- settings.setValue("verifyDelete", "false");\r
- settings.endGroup();\r
- }\r
- \r
- // Should it start minimized?\r
- public static boolean startMinimized() {\r
- settings.beginGroup("General");\r
- try {\r
- String text = (String)settings.value("startMinimized", "false");\r
- settings.endGroup();\r
- if (text.equalsIgnoreCase("true"))\r
- return true;\r
- else\r
- return false;\r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("startMinimized", false);\r
- settings.endGroup();\r
- return value;\r
- }\r
- }\r
- public static void setStartMinimized(boolean val) {\r
- settings.beginGroup("General");\r
- if (val)\r
- settings.setValue("startMinimized", "true");\r
- else\r
- settings.setValue("startMinimized", "false");\r
- settings.endGroup();\r
- }\r
- \r
- // Should we upload the content of any deleted notes\r
- public static boolean synchronizeDeletedContent() {\r
- settings.beginGroup("General");\r
- try {\r
- String text = (String)settings.value("syncDeletedContent", "false");\r
- settings.endGroup();\r
- if (text.equalsIgnoreCase("true"))\r
- return true;\r
- else\r
- return false;\r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("syncDeletedContent", false);\r
- settings.endGroup();\r
- return value;\r
- }\r
- } \r
- public static void setSynchronizeDeletedContent(boolean val) {\r
- settings.beginGroup("General");\r
- if (val)\r
- settings.setValue("syncDeletedContent", "true");\r
- else\r
- settings.setValue("syncDeletedContent", "false");\r
- settings.endGroup();\r
- }\r
- \r
- // Is a section of the window visible? Used to hide things people don't\r
- // want to see.\r
- public static boolean isWindowVisible(String window) {\r
- settings.beginGroup("WindowsVisible");\r
- try {\r
- String defaultValue = "true";\r
- if (window.equalsIgnoreCase("noteInformation"))\r
- defaultValue = "false";\r
- String text = (String)settings.value(window, defaultValue);\r
- settings.endGroup();\r
- if (text.equalsIgnoreCase("true"))\r
- return true;\r
- else\r
- return false; \r
- } catch (java.lang.ClassCastException e) {\r
- boolean defaultValue = true;\r
- if (window.equalsIgnoreCase("noteInformation"))\r
- defaultValue = false;\r
- Boolean value = (Boolean) settings.value("showTrayIcon", defaultValue);\r
- settings.endGroup();\r
- return value;\r
- }\r
- }\r
- public static void saveWindowVisible(String window, boolean val) {\r
- settings.beginGroup("WindowsVisible");\r
- if (val)\r
- settings.setValue(window, "true");\r
- else\r
- settings.setValue(window, "false");\r
- settings.endGroup();\r
- }\r
- \r
- // Is a list in the column in the note list visible? \r
- public static boolean isColumnVisible(String window) {\r
- String defaultValue = "true";\r
- int view = Global.getListView();\r
- if (Global.getListView() == Global.View_List_Wide)\r
- settings.beginGroup("ColumnsVisible");\r
- else\r
- settings.beginGroup("ColumnsVisible-Narrow"); \r
- if (window.equalsIgnoreCase("thumbnail") && view == Global.View_List_Wide)\r
- defaultValue = "false";\r
- if (window.equalsIgnoreCase("thumbnail"))\r
- defaultValue = "false";\r
- if (window.equalsIgnoreCase("Guid"))\r
- defaultValue = "false";\r
- try {\r
- String text = (String)settings.value(window, defaultValue);\r
- settings.endGroup();\r
- if (text.equalsIgnoreCase("true"))\r
- return true;\r
- else\r
- return false;\r
- } catch (java.lang.ClassCastException e) {\r
- boolean defBool = false;\r
- if (window.equalsIgnoreCase("true"))\r
- defBool = true;\r
- else\r
- defBool = false;\r
- Boolean value = (Boolean) settings.value(window, defBool);\r
- settings.endGroup();\r
- return value;\r
- }\r
- }\r
- public static void saveColumnVisible(String column, boolean val) {\r
- if (Global.getListView() == Global.View_List_Wide)\r
- settings.beginGroup("ColumnsVisible");\r
- else\r
- settings.beginGroup("ColumnsVisible-Narrow"); \r
- if (val)\r
- settings.setValue(column, "true");\r
- else\r
- settings.setValue(column, "false");\r
- settings.endGroup();\r
- }\r
- \r
- // Is a particular editor button visible?\r
- public static boolean isEditorButtonVisible(String window) {\r
- settings.beginGroup("EditorButtonsVisible");\r
- try {\r
- String text = (String)settings.value(window, "true");\r
- settings.endGroup();\r
- if (text.equalsIgnoreCase("true"))\r
- return true;\r
- else\r
- return false;\r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value(window, true);\r
- settings.endGroup();\r
- return value;\r
- }\r
- }\r
- public static void saveEditorButtonsVisible(String column, boolean val) {\r
- settings.beginGroup("EditorButtonsVisible");\r
- if (val)\r
- settings.setValue(column, "true");\r
- else\r
- settings.setValue(column, "false");\r
- settings.endGroup();\r
- }\r
- \r
- // Should the test fixes be enabled\r
- public static boolean enableCarriageReturnFix() {\r
- try {\r
- settings.beginGroup("Debug");\r
- String text = (String)settings.value("enableCarriageReturnFix", "false");\r
- settings.endGroup();\r
- if (text.equalsIgnoreCase("true"))\r
- return true;\r
- else\r
- return false;\r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("enableCarriageReturnFix", false);\r
- settings.endGroup();\r
- return value;\r
- }\r
- }\r
- public static void saveCarriageReturnFix(boolean val) {\r
- settings.beginGroup("Debug");\r
- if (val)\r
- settings.setValue("enableCarriageReturnFix", "true");\r
- else\r
- settings.setValue("enableCarriageReturnFix", "false");\r
- settings.endGroup();\r
- }\r
- public static boolean enableHtmlEntitiesFix() {\r
- try {\r
- settings.beginGroup("Debug");\r
- String text = (String)settings.value("enableHtmlEntitiesFix", "false");\r
- settings.endGroup();\r
- if (text.equalsIgnoreCase("true"))\r
- return true;\r
- else\r
- return false;\r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("enableHtmlEntitiesFix", false);\r
- settings.endGroup();\r
- return value;\r
- }\r
- }\r
- public static void saveHtmlEntitiesFix(boolean val) {\r
- settings.beginGroup("Debug");\r
- if (val)\r
- settings.setValue("enableHtmlEntitiesFix", "true");\r
- else\r
- settings.setValue("enableHtmlEntitiesFix", "false");\r
- settings.endGroup();\r
- }\r
-\r
-// public static void setIndexThreads(int val) {\r
-// settings.beginGroup("General");\r
-// settings.setValue("indexThreads", val);\r
-// settings.endGroup();\r
-// }\r
-// public static int getIndexThreads() {\r
-// settings.beginGroup("General");\r
-// Integer threads;\r
-// try {\r
-// String val = (String)settings.value("indexThreads", "1");\r
-// threads = new Integer(val.trim());\r
-// } catch (Exception e) {\r
-// try {\r
-// threads = (Integer)settings.value("indexThreads", 1);\r
-// } catch (Exception e1) {\r
-// threads = 1;\r
-// }\r
-// }\r
-// settings.endGroup();\r
-// threads = 1;\r
-// return threads;\r
- \r
- // Get/Set text zoom factor\r
-// }\r
- public static void setZoomFactor(double val) {\r
- settings.beginGroup("General");\r
- settings.setValue("zoomFactor", val);\r
- settings.endGroup();\r
- }\r
- public static double getZoomFactor() {\r
- settings.beginGroup("General");\r
- Double threads;\r
- try {\r
- String val = (String)settings.value("zoomFactor", "1.0");\r
- threads = new Double(val.trim());\r
- } catch (Exception e) {\r
- try {\r
- threads = (Double)settings.value("zoomFactor", 1.0);\r
- } catch (Exception e1) {\r
- threads = new Double(1);\r
- }\r
- }\r
- settings.endGroup();\r
- return threads;\r
- }\r
- public static void setTextSizeMultiplier(double val) {\r
- settings.beginGroup("General");\r
- settings.setValue("textMultiplier", val);\r
- settings.endGroup();\r
- }\r
- public static double getTextSizeMultiplier() {\r
- settings.beginGroup("General");\r
- Double threads;\r
- try {\r
- String val = (String)settings.value("textMultiplier", "1");\r
- threads = new Double(val.trim());\r
- } catch (Exception e) {\r
- try {\r
- threads = (Double)settings.value("textMultiplier", 1);\r
- } catch (Exception e1) {\r
- threads = new Double(1);\r
- }\r
- }\r
- settings.endGroup();\r
- return threads;\r
- }\r
- \r
- \r
- // Should we mimic Evernote and restrict the notebooks selected?\r
- public static boolean getMimicEvernoteInterface() {\r
- settings.beginGroup("General");\r
- try {\r
- String text = (String)settings.value("mimicEvernoteInterface", "true");\r
- settings.endGroup();\r
- if (text.equalsIgnoreCase("true"))\r
- return true;\r
- else\r
- return false;\r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("mimicEvernoteInterface", true);\r
- settings.endGroup();\r
- return value;\r
- }\r
- }\r
- public static void setMimicEvernoteInterface(boolean value) {\r
- settings.beginGroup("General");\r
- if (value)\r
- settings.setValue("mimicEvernoteInterface", "true");\r
- else\r
- settings.setValue("mimicEvernoteInterface", "false"); \r
- settings.endGroup();\r
- }\r
- \r
- \r
- // Synchronize with Evernote when closing?\r
- public static boolean synchronizeOnClose() {\r
- settings.beginGroup("General");\r
- try {\r
- String text = (String)settings.value("synchronizeOnClose", "false");\r
- settings.endGroup();\r
- if (text.equalsIgnoreCase("true"))\r
- return true;\r
- else\r
- return false;\r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("synchronizeOnClose", false);\r
- settings.endGroup();\r
- return value;\r
- }\r
- }\r
- public static void setSynchronizeOnClose(boolean val) {\r
- settings.beginGroup("General");\r
- if (val)\r
- settings.setValue("synchronizeOnClose", "true");\r
- else\r
- settings.setValue("synchronizeOnClose", "false");\r
- settings.endGroup();\r
- }\r
-\r
- // Get/set the database version. Not really used any more, but kept\r
- // for compatibility.\r
- public static void setDatabaseVersion(String version) {\r
- settings.beginGroup("General");\r
- settings.setValue("databaseVersion", version);\r
- settings.endGroup();\r
- }\r
- public static String getDatabaseVersion() {\r
- settings.beginGroup("General");\r
- String val = (String)settings.value("databaseVersion", "0.70");\r
- settings.endGroup();\r
- return val;\r
- }\r
-\r
- // Get the URL (full path) of the main database\r
- public static String getDatabaseUrl() {\r
- settings.beginGroup("General");\r
- String val = (String)settings.value("DatabaseURL", "");\r
- settings.endGroup();\r
- if (val.equals(""))\r
- val = "jdbc:h2:"+Global.getFileManager().getDbDirPath(Global.databaseName);\r
- return val;\r
- }\r
- \r
- // get the url (full path) of the searchable word database\r
- public static String getIndexDatabaseUrl() {\r
- settings.beginGroup("General");\r
- String val = (String)settings.value("IndexDatabaseURL", "");\r
- settings.endGroup();\r
- if (val.equals(""))\r
- val = "jdbc:h2:"+Global.getFileManager().getDbDirPath(Global.indexDatabaseName);\r
- return val;\r
- }\r
- \r
- // Get the url (full path) of the attachment database\r
- public static String getResourceDatabaseUrl() {\r
- settings.beginGroup("General");\r
- String val = (String)settings.value("ResourceDatabaseURL", "");\r
- settings.endGroup();\r
- if (val.equals(""))\r
- val = "jdbc:h2:"+Global.getFileManager().getDbDirPath(Global.resourceDatabaseName);\r
- return val;\r
- }\r
- public static void setDatabaseUrl(String value) {\r
- settings.beginGroup("General");\r
- settings.setValue("DatabaseURL", value);\r
- settings.endGroup();\r
- }\r
- public static void setIndexDatabaseUrl(String value) {\r
- settings.beginGroup("General");\r
- settings.setValue("IndexDatabaseURL", value);\r
- settings.endGroup();\r
- }\r
- public static void setResourceDatabaseUrl(String value) {\r
- settings.beginGroup("General");\r
- settings.setValue("ResourceDatabaseURL", value);\r
- settings.endGroup();\r
- }\r
- public static String getDatabaseUserid() {\r
- settings.beginGroup("General");\r
- String val = (String)settings.value("databaseUserid", "");\r
- settings.endGroup();\r
- return val;\r
- }\r
- public static String getDatabaseUserPassword() {\r
- settings.beginGroup("General");\r
- String val = (String)settings.value("databaseUserPassword", "");\r
- settings.endGroup();\r
- return val;\r
- }\r
- \r
- // get/Set the style sheet and the palette to control the look & feel\r
- public static void setStyle(String style) {\r
- settings.beginGroup("General");\r
- settings.setValue("style", style);\r
- settings.endGroup();\r
- }\r
- public static String getStyle() {\r
- settings.beginGroup("General");\r
- String val = (String)settings.value("style", "Cleanlooks");\r
- settings.endGroup();\r
- return val;\r
- }\r
- public static boolean useStandardPalette() {\r
- settings.beginGroup("General");\r
- try {\r
- String text = (String)settings.value("standardPalette", "true");\r
- settings.endGroup();\r
- if (text.equalsIgnoreCase("true"))\r
- return true;\r
- else\r
- return false;\r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("standardPalette", true);\r
- settings.endGroup();\r
- return value;\r
- }\r
- }\r
- public static void setStandardPalette(boolean val) {\r
- settings.beginGroup("General");\r
- if (val)\r
- settings.setValue("standardPalette", "true");\r
- else\r
- settings.setValue("standardPalette", "false");\r
- settings.endGroup();\r
- }\r
- \r
- // Set the amount of time to wait between indexing\r
- // Get/Set interval when the index thread wakes up.\r
- public static void setIndexThreadSleepInterval(int sleep) {\r
- settings.beginGroup("General");\r
- settings.setValue("IndexThreadSleepInterval", sleep);\r
- settings.endGroup();\r
- }\r
- public static int getIndexThreadSleepInterval() {\r
- settings.beginGroup("General");\r
- Integer sleep;\r
- try {\r
- String val = (String)settings.value("IndexThreadSleepInterval", "300");\r
- sleep = new Integer(val.trim());\r
- } catch (Exception e) {\r
- try {\r
- sleep = (Integer)settings.value("IndexThreadSleepInterval", 0);\r
- } catch (Exception e1) {\r
- sleep = 300;\r
- }\r
- }\r
- settings.endGroup();\r
- return sleep;\r
- }\r
- \r
- \r
- // Get/Set a window state for later restoring\r
- public static void saveState(String name, QByteArray state) {\r
- int view = Global.getListView();\r
- if (view == Global.View_List_Narrow)\r
- name = name +"Narrow";\r
- settings.beginGroup("SaveState");\r
- settings.setValue(name, state);\r
- settings.endGroup();\r
- }\r
- \r
- public static QByteArray restoreState(String name) {\r
- int view = Global.getListView();\r
- if (view == Global.View_List_Narrow)\r
- name = name +"Narrow";\r
- settings.beginGroup("SaveState");\r
- QByteArray state = (QByteArray)settings.value(name);\r
- settings.endGroup();\r
- return state;\r
- }\r
- public static void saveGeometry(String name, QByteArray state) {\r
- int view = Global.getListView();\r
- if (view == Global.View_List_Narrow)\r
- settings.beginGroup("SaveGeometryNarrow");\r
- else\r
- settings.beginGroup("SaveGeometry");\r
- settings.setValue(name, state);\r
- settings.endGroup();\r
- }\r
- \r
- public static QByteArray restoreGeometry(String name) {\r
- int view = Global.getListView();\r
- if (view == Global.View_List_Narrow)\r
- settings.beginGroup("SaveGeometryNarrow");\r
- else\r
- settings.beginGroup("SaveGeometry");\r
- QByteArray state = (QByteArray)settings.value(name);\r
- settings.endGroup();\r
- return state;\r
- }\r
- \r
- \r
- // Set how often to do an automatic save\r
- public static void setAutoSaveInterval(int interval) {\r
- settings.beginGroup("General");\r
- settings.setValue("autoSaveInterval", interval);\r
- settings.endGroup();\r
- }\r
- public static int getAutoSaveInterval() {\r
- settings.beginGroup("General");\r
- Integer value;\r
- try {\r
- String val = (String)settings.value("autoSaveInterval", "5");\r
- value = new Integer(val.trim());\r
- } catch (Exception e) {\r
- try {\r
- value = (Integer)settings.value("autoSaveInterval", 5);\r
- } catch (Exception e1) {\r
- value = 5;\r
- }\r
- }\r
- settings.endGroup();\r
- return value;\r
- }\r
- \r
- // Add an invalid attribute & element to the database so we don't bother parsing it in the future\r
- // These values we automatically remove from any note.\r
- // Add invalid attributes\r
- public static void addInvalidAttribute(String element, String attribute) {\r
- \r
- List<String> attributes = invalidAttributes.get(element);\r
- if (attributes != null) {\r
- for (int i=0; i<attributes.size(); i++)\r
- if (attribute.equalsIgnoreCase(attributes.get(i))) {\r
- return;\r
- }\r
- }\r
- \r
- ArrayList<String> attributeList;\r
- if (!invalidAttributes.containsKey(element)) {\r
- attributeList = new ArrayList<String>();\r
- attributeList.add(attribute);\r
- invalidAttributes.put(element, attributeList);\r
- }\r
- else {\r
- attributeList = invalidAttributes.get(element);\r
- attributeList.add(attribute);\r
- invalidAttributes.put(element,attributeList);\r
- }\r
- }\r
- \r
- // Add invalid attributes\r
- public static void addInvalidElement(String element) {\r
- for (int i=0; i<invalidElements.size(); i++) {\r
- if (element.equalsIgnoreCase(invalidElements.get(i)))\r
- return;\r
- }\r
- invalidElements.add(element);\r
- }\r
- \r
- // Get/Set proxy information\r
- // Proxy settings\r
- public static String getProxyValue(String key) {\r
- settings.beginGroup("Proxy");\r
- String val = (String)settings.value(key, "");\r
- settings.endGroup();\r
- return val;\r
- }\r
- public static void setProxyValue(String key, String value) {\r
- settings.beginGroup("Proxy");\r
- settings.setValue(key, value);\r
- settings.endGroup();\r
- }\r
- \r
- // Change a byte array to a hex string\r
- // Convert a byte array to a hex string\r
- public static String byteArrayToHexString(byte data[]) {\r
- StringBuffer buf = new StringBuffer();\r
- for (byte element : data) {\r
- int halfbyte = (element >>> 4) & 0x0F;\r
- int two_halfs = 0;\r
- do {\r
- if ((0 <= halfbyte) && (halfbyte <= 9))\r
- buf.append((char) ('0' + halfbyte));\r
- else\r
- buf.append((char) ('a' + (halfbyte - 10)));\r
- halfbyte = element & 0x0F;\r
- } while(two_halfs++ < 1);\r
- }\r
- return buf.toString(); \r
- }\r
-\r
- \r
- // Get/Set spelling settings\r
- public static boolean getSpellSetting(String value) {\r
- settings.beginGroup("Spell");\r
- String text = (String)settings.value(value, "");\r
- settings.endGroup();\r
- if (text.equalsIgnoreCase("true"))\r
- return true;\r
- if (text.equalsIgnoreCase("false"))\r
- return false;\r
- if (value.equalsIgnoreCase(Configuration.SPELL_IGNOREDIGITWORDS))\r
- return true;\r
- if (value.equalsIgnoreCase(Configuration.SPELL_IGNOREINTERNETADDRESSES))\r
- return true;\r
- if (value.equalsIgnoreCase(Configuration.SPELL_IGNOREUPPERCASE))\r
- return true;\r
- if (value.equalsIgnoreCase(Configuration.SPELL_IGNORESENTENCECAPITALIZATION))\r
- return true;\r
- return false;\r
- }\r
- public static void setSpellSetting(String setting, boolean val) {\r
- settings.beginGroup("Spell");\r
- if (val)\r
- settings.setValue(setting, "true");\r
- else\r
- settings.setValue(setting, "false");\r
- settings.endGroup();\r
- }\r
- \r
- // Get/Set how we should display tags (color them, hide unused, or do nothing)\r
- // What to do with inactive tags?\r
- public static String tagBehavior() {\r
- settings.beginGroup("General");\r
- String text = (String)settings.value("tagBehavior", "DoNothing");\r
- settings.endGroup();\r
- return text;\r
- }\r
- // What to do with inactive tags?\r
- public static void setTagBehavior(String value) {\r
- settings.beginGroup("General");\r
- settings.setValue("tagBehavior", value);\r
- settings.endGroup();\r
- }\r
-\r
- \r
- // Should the toolbar be visible?\r
- public static boolean isToolbarButtonVisible(String window) {\r
- settings.beginGroup("ToolbarButtonsVisible");\r
- try {\r
- String text = (String)settings.value(window, "true");\r
- settings.endGroup();\r
- if (text.equalsIgnoreCase("true"))\r
- return true;\r
- else\r
- return false; \r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value(window, true);\r
- settings.endGroup();\r
- return value;\r
- }\r
- }\r
- public static void saveToolbarButtonsVisible(String column, boolean val) {\r
- settings.beginGroup("ToolbarButtonsVisible");\r
- if (val)\r
- settings.setValue(column, "true");\r
- else\r
- settings.setValue(column, "false");\r
- settings.endGroup();\r
- }\r
- \r
- // Are thumbnails enabled?\r
- \r
- public static boolean enableThumbnails() {\r
- settings.beginGroup("Debug");\r
- try {\r
- String text = (String)settings.value("thumbnails", "true");\r
- settings.endGroup();\r
- if (text.equalsIgnoreCase("true"))\r
- return true;\r
- else\r
- return false;\r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("thumbnails", true);\r
- settings.endGroup();\r
- return value;\r
- }\r
- }\r
- public static void setEnableThumbnails(boolean val) {\r
- settings.beginGroup("Debug");\r
- if (val)\r
- settings.setValue("thumbnails", "true");\r
- else\r
- settings.setValue("thumbnails", "false");\r
- settings.endGroup();\r
- }\r
- \r
- // Trace used for performance tuning. Not normally used in production.\r
- // Print date/time. Used mainly for performance tracing\r
- public static void trace(boolean resetInterval) {\r
- String fmt = "MM/dd/yy HH:mm:ss.SSSSSS";\r
- String dateTimeFormat = new String(fmt);\r
- SimpleDateFormat simple = new SimpleDateFormat(dateTimeFormat);\r
- Calendar cal = Calendar.getInstance();\r
- if (intervalTraceTime == null) \r
- intervalTraceTime = Calendar.getInstance();\r
- if (startTraceTime == null)\r
- startTraceTime = Calendar.getInstance();\r
- \r
- float interval = (cal.getTimeInMillis() - intervalTraceTime.getTimeInMillis());\r
- float total = (cal.getTimeInMillis() - startTraceTime.getTimeInMillis());\r
- \r
-// if (interval > 00.0) {\r
- StackTraceElement[] exceptions = Thread.currentThread().getStackTrace();\r
- System.out.println("------------------------------------------");\r
-\r
- System.out.println("Date/Time " +simple.format(cal.getTime()));\r
- System.out.format("Interval Time: %-10.6f%n", interval);\r
- System.out.format("Total Time: %-10.6f%n", total);\r
- for (int i=2; i<5 && i<exceptions.length; i++) {\r
- System.out.println(exceptions[i]);\r
- }\r
-// }\r
- if (resetInterval)\r
- intervalTraceTime = cal;\r
- }\r
- public static void traceReset() {\r
- intervalTraceTime = null;\r
- startTraceTime = null;\r
- }\r
-\r
- \r
- // Get the FileManager class to manage local files & directories\r
- public static FileManager getFileManager() {\r
- return fileManager;\r
- }\r
- \r
- // Should the note editor be disabled?\r
- public static boolean getDisableViewing() {\r
- return disableViewing;\r
- }\r
-\r
- //**********************\r
- //* Thumbnail zoom level\r
- //**********************\r
- public static int calculateThumbnailZoom(String content) {\r
- int zoom = 1;\r
- if (content.indexOf("application/pdf") == -1) {\r
- if (content.indexOf("image/") == -1) {\r
- String text = StringEscapeUtils.unescapeHtml4(content.replaceAll("\\<.*?\\>", ""));\r
- zoom = 2;\r
- if (text.length() < 500) \r
- zoom = 2;\r
- if (text.length() < 250)\r
- zoom = 3;\r
- if (text.length() < 100)\r
- zoom = 4;\r
- if (text.length() < 50)\r
- zoom = 5;\r
- if (text.length() < 10)\r
- zoom = 6;\r
- }\r
- }\r
- return zoom;\r
- }\r
- \r
- //**********************\r
- //* List View settings \r
- //**********************\r
- public static void setListView(int view) {\r
- settings.beginGroup("General");\r
- settings.setValue("listView", view);\r
- settings.endGroup();\r
- }\r
- public static int getListView() {\r
- settings.beginGroup("General");\r
- Integer value;\r
- try {\r
- String val = (String)settings.value("listView", View_List_Wide);\r
- value = new Integer(val.trim());\r
- } catch (Exception e) {\r
- try {\r
- value = (Integer)settings.value("listView", View_List_Wide);\r
- } catch (Exception e1) {\r
- value = View_List_Wide;\r
- }\r
- }\r
- settings.endGroup();\r
- return value;\r
- }\r
-\r
- \r
- \r
- //*******************\r
- // Font Settings\r
- //*******************\r
- public static boolean overrideDefaultFont() {\r
- settings.beginGroup("Font");\r
- try {\r
- String text = (String)settings.value("overrideFont", "false");\r
- settings.endGroup();\r
- if (text.equalsIgnoreCase("true"))\r
- return true;\r
- else\r
- return false; \r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("overrideFont", false);\r
- settings.endGroup();\r
- return value;\r
- }\r
-\r
- }\r
- \r
- //****************************************************\r
- // Get/Set the default font settings for a new note\r
- //****************************************************\r
- public static void setOverrideDefaultFont(boolean value) {\r
- settings.beginGroup("Font");\r
- settings.setValue("overrideFont", value);\r
- settings.endGroup(); \r
- }\r
- public static String getDefaultFont() {\r
- settings.beginGroup("Font");\r
- String val = (String)settings.value("font", "");\r
- settings.endGroup();\r
- return val;\r
- }\r
- public static void setDefaultFont(String value) {\r
- settings.beginGroup("Font");\r
- settings.setValue("font", value);\r
- settings.endGroup();\r
- }\r
- public static String getDefaultFontSize() {\r
- settings.beginGroup("Font");\r
- String val = (String)settings.value("fontSize", "");\r
- settings.endGroup();\r
- return val;\r
- }\r
- public static void setDefaultFontSize(String value) {\r
- settings.beginGroup("Font");\r
- settings.setValue("fontSize", value);\r
- settings.endGroup();\r
- }\r
- \r
- \r
- //*******************************************\r
- // Override the close & minimize instead.\r
- //*******************************************\r
- public static boolean minimizeOnClose() {\r
- settings.beginGroup("General");\r
- try {\r
- String text = (String)settings.value("minimizeOnClose", "false");\r
- settings.endGroup();\r
- if (text.equalsIgnoreCase("true") && QSystemTrayIcon.isSystemTrayAvailable())\r
- return true;\r
- else\r
- return false;\r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("minimizeOnClose", false);\r
- settings.endGroup();\r
- return value;\r
- }\r
- }\r
- public static void setMinimizeOnClose(boolean value) {\r
- settings.beginGroup("General");\r
- settings.setValue("minimizeOnClose", value);\r
- settings.endGroup(); \r
- }\r
-\r
- //*********************************\r
- // Check version information\r
- //*********************************\r
- public static boolean checkVersionUpgrade() {\r
- settings.beginGroup("Upgrade");\r
- try {\r
- String text = (String)settings.value("checkForUpdates", "true");\r
- settings.endGroup();\r
- if (text.equalsIgnoreCase("true"))\r
- return true;\r
- else\r
- return false;\r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("checkForUpdates", true);\r
- settings.endGroup();\r
- return value;\r
- }\r
- }\r
- public static void setCheckVersionUpgrade(boolean value) {\r
- settings.beginGroup("Upgrade");\r
- settings.setValue("checkForUpdates", value);\r
- settings.endGroup(); \r
- }\r
- public static String getUpdatesAvailableUrl() {\r
- settings.beginGroup("Upgrade");\r
- String text = (String)settings.value("avialableUrl", "http://nevernote.sourceforge.net/versions.txt");\r
- settings.endGroup(); \r
- return text;\r
- }\r
- public static String getUpdateAnnounceUrl() {\r
- settings.beginGroup("Upgrade");\r
- String text = (String)settings.value("announceUrl", "http://nevernote.sourceforge.net/upgrade.html");\r
- settings.endGroup(); \r
- return text;\r
- }\r
- \r
- //*******************\r
- // Index settings\r
- //*******************\r
- // Set/Get if we should index the text of a note\r
- public static boolean indexNoteBody() {\r
- settings.beginGroup("Index");\r
- try {\r
- String value = (String)settings.value("indexNoteBody", "true");\r
- settings.endGroup();\r
- if (value.equals("true"))\r
- return true;\r
- else\r
- return false;\r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("indexNoteBody", true);\r
- settings.endGroup();\r
- return value;\r
- }\r
- }\r
- public static void setIndexNoteTitle(boolean value) {\r
- settings.beginGroup("Index");\r
- settings.setValue("indexNoteTitle", value);\r
- settings.endGroup(); \r
- }\r
- // Set/Get if we should index the title of a note\r
- public static boolean indexNoteTitle() {\r
- settings.beginGroup("Index");\r
- try {\r
- String value = (String)settings.value("indexNoteTitle", "true");\r
- settings.endGroup();\r
- if (value.equals("true"))\r
- return true;\r
- else\r
- return false;\r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("indexNoteTitle", true);\r
- settings.endGroup();\r
- return value;\r
- }\r
- }\r
- public static void setIndexNoteBody(boolean value) {\r
- settings.beginGroup("Index");\r
- settings.setValue("indexNoteBody", value);\r
- settings.endGroup(); \r
- }\r
- // Set/Get if we should index any attachments\r
- public static boolean indexAttachmentsLocally() {\r
- settings.beginGroup("Index");\r
- try {\r
- String value = (String)settings.value("indexAttachmentsLocally", "true");\r
- settings.endGroup();\r
- if (value.equals("true"))\r
- return true;\r
- else\r
- return false;\r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("indexAttachmentsLocally", true);\r
- settings.endGroup();\r
- return value;\r
- }\r
- }\r
- public static void setIndexImageRecognition(boolean value) {\r
- settings.beginGroup("Index");\r
- settings.setValue("indexImageRecognition", value);\r
- settings.endGroup(); \r
- }\r
- public static boolean indexImageRecognition() {\r
- settings.beginGroup("Index");\r
- try {\r
- String value = (String)settings.value("indexImageRecognition", "true");\r
- settings.endGroup();\r
- if (value.equals("true"))\r
- return true;\r
- else\r
- return false;\r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("indexImageRecognition", true);\r
- settings.endGroup();\r
- return value;\r
- }\r
- }\r
- public static void setIndexAttachmentsLocally(boolean value) {\r
- settings.beginGroup("Index");\r
- settings.setValue("indexAttachmentsLocally", value);\r
- settings.endGroup(); \r
- }\r
- // Get/Set characters that shouldn't be removed from a word\r
- public static String getSpecialIndexCharacters() {\r
- settings.beginGroup("Index");\r
- String text = (String)settings.value("specialCharacters", "");\r
- settings.endGroup(); \r
- return text;\r
- }\r
- public static void setSpecialIndexCharacters(String value) {\r
- settings.beginGroup("Index");\r
- settings.setValue("specialCharacters", value);\r
- settings.endGroup(); \r
- databaseCache = value;\r
- }\r
- \r
- //*****************************************************************************\r
- // Control how tag selection behaves (should they be "and" or "or" selections\r
- //*****************************************************************************\r
- public static boolean anyTagSelectionMatch() {\r
- settings.beginGroup("General");\r
- try {\r
- String value = (String)settings.value("anyTagSelectionMatch", "false");\r
- settings.endGroup();\r
- if (value.equals("true"))\r
- return true;\r
- else\r
- return false;\r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("anyTagSelectionMatch", false);\r
- settings.endGroup();\r
- return value;\r
- }\r
- }\r
- public static void setAnyTagSelectionMatch(boolean value) {\r
- settings.beginGroup("General");\r
- settings.setValue("anyTagSelectionMatch", value);\r
- settings.endGroup(); \r
- }\r
-\r
- //*****************************************************************************\r
- // Control if a user receives a warning when trying to create a note-to-note link\r
- // when the DB is not synchronized.\r
- //*****************************************************************************\r
- public static boolean bypassSynchronizationWarning() {\r
- settings.beginGroup("User");\r
- try {\r
- String value = (String)settings.value("bypassSynchronizationWarning", "false");\r
- settings.endGroup();\r
- if (value.equals("true"))\r
- return true;\r
- else\r
- return false;\r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("bypassSynchronizationWarning", false);\r
- settings.endGroup();\r
- return value;\r
- }\r
- }\r
- public static void setBypassSynchronizationWarning(boolean value) {\r
- settings.beginGroup("User");\r
- settings.setValue("bypassSynchronizationWarning", value);\r
- settings.endGroup(); \r
- }\r
-\r
- \r
- //***********************\r
- //* Database cache size\r
- //***********************\r
- public static String getDatabaseCacheSize() {\r
- settings.beginGroup("Debug");\r
- String text = (String)settings.value("databaseCache", "16384");\r
- settings.endGroup(); \r
- return text;\r
- }\r
- public static void setDatabaseCache(String value) {\r
- settings.beginGroup("Debug");\r
- settings.setValue("databaseCache", value);\r
- settings.endGroup(); \r
- databaseCache = value;\r
- }\r
-\r
- \r
- // This is used to copy a class since Java's normal deep copy is wacked\r
- public static Object deepCopy(Object oldObj) \r
- {\r
- ObjectOutputStream oos = null;\r
- ObjectInputStream ois = null;\r
- try\r
- {\r
- ByteArrayOutputStream bos = \r
- new ByteArrayOutputStream(); // A\r
- oos = new ObjectOutputStream(bos); // B\r
- // serialize and pass the object\r
- oos.writeObject(oldObj); // C\r
- oos.flush(); // D\r
- ByteArrayInputStream bin = \r
- new ByteArrayInputStream(bos.toByteArray()); // E\r
- ois = new ObjectInputStream(bin); // F\r
- // return the new object\r
- return ois.readObject(); // G\r
- }\r
- catch(Exception e)\r
- {\r
- Global.logger.log(logger.LOW, "Exception in ObjectCloner = " + e);\r
- }\r
- try {\r
- oos.close();\r
- ois.close();\r
- } catch (IOException e) {\r
- Global.logger.log(logger.LOW, "Exception in ObjectCloner = " + e);\r
- e.printStackTrace();\r
- }\r
-\r
- return null;\r
- }\r
-\r
- // If we should automatically select the children of any tag\r
- public static boolean includeTagChildren() {\r
- settings.beginGroup("General");\r
- try {\r
- String value = (String)settings.value("includeTagChildren", "false");\r
- settings.endGroup();\r
- if (value.equals("true"))\r
- return true;\r
- else\r
- return false;\r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("includeTagChildren", false);\r
- settings.endGroup();\r
- return value;\r
- }\r
-\r
- }\r
- public static void setIncludeTagChildren(boolean value) {\r
- settings.beginGroup("General");\r
- settings.setValue("includeTagChildren", value);\r
- settings.endGroup(); \r
- }\r
- \r
- // If we should automatically wildcard searches\r
- public static boolean automaticWildcardSearches() {\r
- settings.beginGroup("General");\r
- try {\r
- String value = (String)settings.value("automaticWildcard", "false");\r
- settings.endGroup();\r
- if (value.equals("true"))\r
- return true;\r
- else\r
- return false;\r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("automaticWildcard", false);\r
- settings.endGroup();\r
- return value;\r
- }\r
-\r
- }\r
- public static void setAutomaticWildcardSearches(boolean value) {\r
- settings.beginGroup("General");\r
- settings.setValue("automaticWildcard", value);\r
- settings.endGroup(); \r
- }\r
-\r
- // If we should automatically select the children of any tag\r
- public static boolean displayRightToLeft() {\r
- settings.beginGroup("General");\r
- try {\r
- String value = (String)settings.value("displayRightToLeft", "false");\r
- settings.endGroup();\r
- if (value.equals("true"))\r
- return true;\r
- else\r
- return false;\r
- } catch (java.lang.ClassCastException e) {\r
- Boolean value = (Boolean) settings.value("displayRightToLeft", false);\r
- settings.endGroup();\r
- return value;\r
- }\r
-\r
- }\r
- public static void setDisplayRightToLeft(boolean value) {\r
- settings.beginGroup("General");\r
- settings.setValue("displayRightToLeft", value);\r
- settings.endGroup(); \r
- }\r
-\r
-\r
- //***********************\r
- //* Startup Notebook\r
- //***********************\r
- public static String getStartupNotebook() {\r
- settings.beginGroup("General");\r
- String text = (String)settings.value("startupNotebook", "");\r
- settings.endGroup(); \r
- return text;\r
- }\r
- public static void setStartupNotebook(String value) {\r
- settings.beginGroup("General");\r
- settings.setValue("startupNotebook", value);\r
- settings.endGroup(); \r
- databaseCache = value;\r
- }\r
-}\r
-\r
+ }
+ settings.endGroup();
+ return len;
+ }
+
+ // get/set current debug message level
+ public static String getMessageLevel() {
+ settings.beginGroup("Debug");
+ String text = (String)settings.value("messageLevel", "Low");
+ settings.endGroup();
+ setMessageLevel(text);
+ return text;
+ }
+ public static void setDateFormat(String format) {
+ settings.beginGroup("General");
+ settings.setValue("dateFormat", format);
+ settings.endGroup();
+ }
+
+ // Get/Set user date/time formats
+ public static String getDateFormat() {
+ settings.beginGroup("General");
+ String text = (String)settings.value("dateFormat", "MM/dd/yyyy");
+ settings.endGroup();
+ return text;
+ }
+ public static void setTimeFormat(String format) {
+ settings.beginGroup("General");
+ settings.setValue("timeFormat", format);
+ settings.endGroup();
+ }
+ public static String getTimeFormat() {
+ settings.beginGroup("General");
+ String text = (String)settings.value("timeFormat", "HH:mm:ss");
+ settings.endGroup();
+ return text;
+ }
+
+ // How often should we sync with Evernote?
+ public static String getSyncInterval() {
+ settings.beginGroup("General");
+ String text = (String)settings.value("syncInterval", "15 minutes");
+ settings.endGroup();
+ return text;
+ }
+ public static void setSyncInterval(String format) {
+ settings.beginGroup("General");
+ settings.setValue("syncInterval", format);
+ settings.endGroup();
+ }
+
+ // Get/Set the width of columns and their position for the
+ // next start.
+ public static void setColumnWidth(String col, int width) {
+ if (Global.getListView() == Global.View_List_Wide)
+ settings.beginGroup("ColumnWidths");
+ else
+ settings.beginGroup("ColumnWidths-Narrow");
+ settings.setValue(col, width);
+ settings.endGroup();
+ }
+ public static int getColumnWidth(String col) {
+ int view = Global.getListView();
+ if (view == Global.View_List_Wide)
+ settings.beginGroup("ColumnWidths");
+ else
+ settings.beginGroup("ColumnWidths-Narrow");
+ Integer width;
+ try {
+ String val = (String)settings.value(col, "0");
+ width = new Integer(val.trim());
+ } catch (Exception e) {
+ try {
+ width = (Integer)settings.value(col, 0);
+ } catch (Exception e1) {
+ width = 0;
+ }
+ }
+ settings.endGroup();
+ return width;
+ }
+ public static void setColumnPosition(String col, int width) {
+ if (Global.getListView() == Global.View_List_Wide)
+ settings.beginGroup("ColumnPosition");
+ else
+ settings.beginGroup("ColumnPosition-Narrow");
+ settings.setValue(col, width);
+ settings.endGroup();
+ }
+ public static int getColumnPosition(String col) {
+ if (Global.getListView() == Global.View_List_Wide)
+ settings.beginGroup("ColumnPosition");
+ else
+ settings.beginGroup("ColumnPosition-Narrow");
+ Integer width;
+ try {
+ String val = (String)settings.value(col, "-1");
+ width = new Integer(val.trim());
+ } catch (Exception e) {
+ try {
+ width = (Integer)settings.value(col, 0);
+ } catch (Exception e1) {
+ width = 0;
+ }
+ }
+ settings.endGroup();
+ return width;
+ }
+
+ // Ping the user when they try to delete or just do it.
+ public static boolean verifyDelete() {
+ settings.beginGroup("General");
+ try {
+ String text = (String)settings.value("verifyDelete", "true");
+ settings.endGroup();
+ if (text.equalsIgnoreCase("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("verifyDelete", true);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void setVerifyDelete(boolean val) {
+ settings.beginGroup("General");
+ if (val)
+ settings.setValue("verifyDelete", "true");
+ else
+ settings.setValue("verifyDelete", "false");
+ settings.endGroup();
+ }
+
+ // Should it start minimized?
+ public static boolean startMinimized() {
+ settings.beginGroup("General");
+ try {
+ String text = (String)settings.value("startMinimized", "false");
+ settings.endGroup();
+ if (text.equalsIgnoreCase("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("startMinimized", false);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void setStartMinimized(boolean val) {
+ settings.beginGroup("General");
+ if (val)
+ settings.setValue("startMinimized", "true");
+ else
+ settings.setValue("startMinimized", "false");
+ settings.endGroup();
+ }
+
+ // Should we upload the content of any deleted notes
+ public static boolean synchronizeDeletedContent() {
+ settings.beginGroup("General");
+ try {
+ String text = (String)settings.value("syncDeletedContent", "false");
+ settings.endGroup();
+ if (text.equalsIgnoreCase("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("syncDeletedContent", false);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void setSynchronizeDeletedContent(boolean val) {
+ settings.beginGroup("General");
+ if (val)
+ settings.setValue("syncDeletedContent", "true");
+ else
+ settings.setValue("syncDeletedContent", "false");
+ settings.endGroup();
+ }
+
+ // Is a section of the window visible? Used to hide things people don't
+ // want to see.
+ public static boolean isWindowVisible(String window) {
+ settings.beginGroup("WindowsVisible");
+ try {
+ String defaultValue = "true";
+ if (window.equalsIgnoreCase("noteInformation"))
+ defaultValue = "false";
+ String text = (String)settings.value(window, defaultValue);
+ settings.endGroup();
+ if (text.equalsIgnoreCase("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ boolean defaultValue = true;
+ if (window.equalsIgnoreCase("noteInformation"))
+ defaultValue = false;
+ Boolean value = (Boolean) settings.value("showTrayIcon", defaultValue);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void saveWindowVisible(String window, boolean val) {
+ settings.beginGroup("WindowsVisible");
+ if (val)
+ settings.setValue(window, "true");
+ else
+ settings.setValue(window, "false");
+ settings.endGroup();
+ }
+
+ // Is a list in the column in the note list visible?
+ public static boolean isColumnVisible(String window) {
+ String defaultValue = "true";
+ int view = Global.getListView();
+ if (Global.getListView() == Global.View_List_Wide)
+ settings.beginGroup("ColumnsVisible");
+ else
+ settings.beginGroup("ColumnsVisible-Narrow");
+ if (window.equalsIgnoreCase("thumbnail") && view == Global.View_List_Wide)
+ defaultValue = "false";
+ if (window.equalsIgnoreCase("thumbnail"))
+ defaultValue = "false";
+ if (window.equalsIgnoreCase("Guid"))
+ defaultValue = "false";
+ try {
+ String text = (String)settings.value(window, defaultValue);
+ settings.endGroup();
+ if (text.equalsIgnoreCase("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ boolean defBool = false;
+ if (window.equalsIgnoreCase("true"))
+ defBool = true;
+ else
+ defBool = false;
+ Boolean value = (Boolean) settings.value(window, defBool);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void saveColumnVisible(String column, boolean val) {
+ if (Global.getListView() == Global.View_List_Wide)
+ settings.beginGroup("ColumnsVisible");
+ else
+ settings.beginGroup("ColumnsVisible-Narrow");
+ if (val)
+ settings.setValue(column, "true");
+ else
+ settings.setValue(column, "false");
+ settings.endGroup();
+ }
+
+ // Is a particular editor button visible?
+ public static boolean isEditorButtonVisible(String window) {
+ settings.beginGroup("EditorButtonsVisible");
+ try {
+ String text = (String)settings.value(window, "true");
+ settings.endGroup();
+ if (text.equalsIgnoreCase("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value(window, true);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void saveEditorButtonsVisible(String column, boolean val) {
+ settings.beginGroup("EditorButtonsVisible");
+ if (val)
+ settings.setValue(column, "true");
+ else
+ settings.setValue(column, "false");
+ settings.endGroup();
+ }
+
+ // Should the test fixes be enabled
+ public static boolean enableCarriageReturnFix() {
+ try {
+ settings.beginGroup("Debug");
+ String text = (String)settings.value("enableCarriageReturnFix", "false");
+ settings.endGroup();
+ if (text.equalsIgnoreCase("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("enableCarriageReturnFix", false);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void saveCarriageReturnFix(boolean val) {
+ settings.beginGroup("Debug");
+ if (val)
+ settings.setValue("enableCarriageReturnFix", "true");
+ else
+ settings.setValue("enableCarriageReturnFix", "false");
+ settings.endGroup();
+ }
+ public static boolean enableHtmlEntitiesFix() {
+ try {
+ settings.beginGroup("Debug");
+ String text = (String)settings.value("enableHtmlEntitiesFix", "false");
+ settings.endGroup();
+ if (text.equalsIgnoreCase("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("enableHtmlEntitiesFix", false);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void saveHtmlEntitiesFix(boolean val) {
+ settings.beginGroup("Debug");
+ if (val)
+ settings.setValue("enableHtmlEntitiesFix", "true");
+ else
+ settings.setValue("enableHtmlEntitiesFix", "false");
+ settings.endGroup();
+ }
+
+// public static void setIndexThreads(int val) {
+// settings.beginGroup("General");
+// settings.setValue("indexThreads", val);
+// settings.endGroup();
+// }
+// public static int getIndexThreads() {
+// settings.beginGroup("General");
+// Integer threads;
+// try {
+// String val = (String)settings.value("indexThreads", "1");
+// threads = new Integer(val.trim());
+// } catch (Exception e) {
+// try {
+// threads = (Integer)settings.value("indexThreads", 1);
+// } catch (Exception e1) {
+// threads = 1;
+// }
+// }
+// settings.endGroup();
+// threads = 1;
+// return threads;
+
+ // Get/Set text zoom factor
+// }
+ public static void setZoomFactor(double val) {
+ settings.beginGroup("General");
+ settings.setValue("zoomFactor", val);
+ settings.endGroup();
+ }
+ public static double getZoomFactor() {
+ settings.beginGroup("General");
+ Double threads;
+ try {
+ String val = (String)settings.value("zoomFactor", "1.0");
+ threads = new Double(val.trim());
+ } catch (Exception e) {
+ try {
+ threads = (Double)settings.value("zoomFactor", 1.0);
+ } catch (Exception e1) {
+ threads = new Double(1);
+ }
+ }
+ settings.endGroup();
+ return threads;
+ }
+ public static void setTextSizeMultiplier(double val) {
+ settings.beginGroup("General");
+ settings.setValue("textMultiplier", val);
+ settings.endGroup();
+ }
+ public static double getTextSizeMultiplier() {
+ settings.beginGroup("General");
+ Double threads;
+ try {
+ String val = (String)settings.value("textMultiplier", "1");
+ threads = new Double(val.trim());
+ } catch (Exception e) {
+ try {
+ threads = (Double)settings.value("textMultiplier", 1);
+ } catch (Exception e1) {
+ threads = new Double(1);
+ }
+ }
+ settings.endGroup();
+ return threads;
+ }
+
+
+ // Should we mimic Evernote and restrict the notebooks selected?
+ public static boolean getMimicEvernoteInterface() {
+ settings.beginGroup("General");
+ try {
+ String text = (String)settings.value("mimicEvernoteInterface", "true");
+ settings.endGroup();
+ if (text.equalsIgnoreCase("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("mimicEvernoteInterface", true);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void setMimicEvernoteInterface(boolean value) {
+ settings.beginGroup("General");
+ if (value)
+ settings.setValue("mimicEvernoteInterface", "true");
+ else
+ settings.setValue("mimicEvernoteInterface", "false");
+ settings.endGroup();
+ }
+
+
+ // Synchronize with Evernote when closing?
+ public static boolean synchronizeOnClose() {
+ settings.beginGroup("General");
+ try {
+ String text = (String)settings.value("synchronizeOnClose", "false");
+ settings.endGroup();
+ if (text.equalsIgnoreCase("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("synchronizeOnClose", false);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void setSynchronizeOnClose(boolean val) {
+ settings.beginGroup("General");
+ if (val)
+ settings.setValue("synchronizeOnClose", "true");
+ else
+ settings.setValue("synchronizeOnClose", "false");
+ settings.endGroup();
+ }
+
+ // Get/set the database version. Not really used any more, but kept
+ // for compatibility.
+ public static void setDatabaseVersion(String version) {
+ settings.beginGroup("General");
+ settings.setValue("databaseVersion", version);
+ settings.endGroup();
+ }
+ public static String getDatabaseVersion() {
+ settings.beginGroup("General");
+ String val = (String)settings.value("databaseVersion", "0.70");
+ settings.endGroup();
+ return val;
+ }
+
+ // Get the URL (full path) of the main database
+ public static String getDatabaseUrl() {
+ settings.beginGroup("General");
+ String val = (String)settings.value("DatabaseURL", "");
+ settings.endGroup();
+ if (val.equals(""))
+ val = "jdbc:h2:"+Global.getFileManager().getDbDirPath(Global.databaseName);
+ return val;
+ }
+
+ // get the url (full path) of the searchable word database
+ public static String getIndexDatabaseUrl() {
+ settings.beginGroup("General");
+ String val = (String)settings.value("IndexDatabaseURL", "");
+ settings.endGroup();
+ if (val.equals(""))
+ val = "jdbc:h2:"+Global.getFileManager().getDbDirPath(Global.indexDatabaseName);
+ return val;
+ }
+
+ // Get the url (full path) of the attachment database
+ public static String getResourceDatabaseUrl() {
+ settings.beginGroup("General");
+ String val = (String)settings.value("ResourceDatabaseURL", "");
+ settings.endGroup();
+ if (val.equals(""))
+ val = "jdbc:h2:"+Global.getFileManager().getDbDirPath(Global.resourceDatabaseName);
+ return val;
+ }
+
+ // ICHANGED
+ // 操作履歴データベースのURL(フルパス)をゲット
+ public static String getBehaviorDatabaseUrl() {
+ settings.beginGroup("General");
+ String val = (String) settings.value("BehaviorDatabaseURL", "");
+ settings.endGroup();
+ if (val.equals(""))
+ val = "jdbc:h2:"
+ + Global.getFileManager().getDbDirPath(
+ Global.behaviorDatabaseName);
+ return val;
+ }
+
+ public static void setDatabaseUrl(String value) {
+ settings.beginGroup("General");
+ settings.setValue("DatabaseURL", value);
+ settings.endGroup();
+ }
+ public static void setIndexDatabaseUrl(String value) {
+ settings.beginGroup("General");
+ settings.setValue("IndexDatabaseURL", value);
+ settings.endGroup();
+ }
+ public static void setResourceDatabaseUrl(String value) {
+ settings.beginGroup("General");
+ settings.setValue("ResourceDatabaseURL", value);
+ settings.endGroup();
+ }
+
+ // ICHANGED
+ public static void setBehaviorDatabaseUrl(String value) {
+ settings.beginGroup("General");
+ settings.setValue("BehaviorDatabaseURL", value);
+ settings.endGroup();
+ }
+
+ public static String getDatabaseUserid() {
+ settings.beginGroup("General");
+ String val = (String)settings.value("databaseUserid", "");
+ settings.endGroup();
+ return val;
+ }
+ public static String getDatabaseUserPassword() {
+ settings.beginGroup("General");
+ String val = (String)settings.value("databaseUserPassword", "");
+ settings.endGroup();
+ return val;
+ }
+
+ // get/Set the style sheet and the palette to control the look & feel
+ public static void setStyle(String style) {
+ settings.beginGroup("General");
+ settings.setValue("style", style);
+ settings.endGroup();
+ }
+ public static String getStyle() {
+ settings.beginGroup("General");
+ String val = (String)settings.value("style", "Cleanlooks");
+ settings.endGroup();
+ return val;
+ }
+ public static boolean useStandardPalette() {
+ settings.beginGroup("General");
+ try {
+ String text = (String)settings.value("standardPalette", "true");
+ settings.endGroup();
+ if (text.equalsIgnoreCase("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("standardPalette", true);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void setStandardPalette(boolean val) {
+ settings.beginGroup("General");
+ if (val)
+ settings.setValue("standardPalette", "true");
+ else
+ settings.setValue("standardPalette", "false");
+ settings.endGroup();
+ }
+
+ // Set the amount of time to wait between indexing
+ // Get/Set interval when the index thread wakes up.
+ public static void setIndexThreadSleepInterval(int sleep) {
+ settings.beginGroup("General");
+ settings.setValue("IndexThreadSleepInterval", sleep);
+ settings.endGroup();
+ }
+ public static int getIndexThreadSleepInterval() {
+ settings.beginGroup("General");
+ Integer sleep;
+ try {
+ String val = (String)settings.value("IndexThreadSleepInterval", "300");
+ sleep = new Integer(val.trim());
+ } catch (Exception e) {
+ try {
+ sleep = (Integer)settings.value("IndexThreadSleepInterval", 0);
+ } catch (Exception e1) {
+ sleep = 300;
+ }
+ }
+ settings.endGroup();
+ return sleep;
+ }
+
+
+ // Get/Set a window state for later restoring
+ public static void saveState(String name, QByteArray state) {
+ int view = Global.getListView();
+ if (view == Global.View_List_Narrow)
+ name = name +"Narrow";
+ settings.beginGroup("SaveState");
+ settings.setValue(name, state);
+ settings.endGroup();
+ }
+
+ public static QByteArray restoreState(String name) {
+ int view = Global.getListView();
+ if (view == Global.View_List_Narrow)
+ name = name +"Narrow";
+ settings.beginGroup("SaveState");
+ QByteArray state = (QByteArray)settings.value(name);
+ settings.endGroup();
+ return state;
+ }
+ public static void saveGeometry(String name, QByteArray state) {
+ int view = Global.getListView();
+ if (view == Global.View_List_Narrow)
+ settings.beginGroup("SaveGeometryNarrow");
+ else
+ settings.beginGroup("SaveGeometry");
+ settings.setValue(name, state);
+ settings.endGroup();
+ }
+
+ public static QByteArray restoreGeometry(String name) {
+ int view = Global.getListView();
+ if (view == Global.View_List_Narrow)
+ settings.beginGroup("SaveGeometryNarrow");
+ else
+ settings.beginGroup("SaveGeometry");
+ QByteArray state = (QByteArray)settings.value(name);
+ settings.endGroup();
+ return state;
+ }
+
+
+ // Set how often to do an automatic save
+ public static void setAutoSaveInterval(int interval) {
+ settings.beginGroup("General");
+ settings.setValue("autoSaveInterval", interval);
+ settings.endGroup();
+ }
+ public static int getAutoSaveInterval() {
+ settings.beginGroup("General");
+ Integer value;
+ try {
+ String val = (String)settings.value("autoSaveInterval", "5");
+ value = new Integer(val.trim());
+ } catch (Exception e) {
+ try {
+ value = (Integer)settings.value("autoSaveInterval", 5);
+ } catch (Exception e1) {
+ value = 5;
+ }
+ }
+ settings.endGroup();
+ return value;
+ }
+
+ // Add an invalid attribute & element to the database so we don't bother parsing it in the future
+ // These values we automatically remove from any note.
+ // Add invalid attributes
+ public static void addInvalidAttribute(String element, String attribute) {
+
+ List<String> attributes = invalidAttributes.get(element);
+ if (attributes != null) {
+ for (int i=0; i<attributes.size(); i++)
+ if (attribute.equalsIgnoreCase(attributes.get(i))) {
+ return;
+ }
+ }
+
+ ArrayList<String> attributeList;
+ if (!invalidAttributes.containsKey(element)) {
+ attributeList = new ArrayList<String>();
+ attributeList.add(attribute);
+ invalidAttributes.put(element, attributeList);
+ }
+ else {
+ attributeList = invalidAttributes.get(element);
+ attributeList.add(attribute);
+ invalidAttributes.put(element,attributeList);
+ }
+ }
+
+ // Add invalid attributes
+ public static void addInvalidElement(String element) {
+ for (int i=0; i<invalidElements.size(); i++) {
+ if (element.equalsIgnoreCase(invalidElements.get(i)))
+ return;
+ }
+ invalidElements.add(element);
+ }
+
+ // Get/Set proxy information
+ // Proxy settings
+ public static String getProxyValue(String key) {
+ settings.beginGroup("Proxy");
+ String val = (String)settings.value(key, "");
+ settings.endGroup();
+ return val;
+ }
+ public static void setProxyValue(String key, String value) {
+ settings.beginGroup("Proxy");
+ settings.setValue(key, value);
+ settings.endGroup();
+ }
+
+ // Change a byte array to a hex string
+ // Convert a byte array to a hex string
+ public static String byteArrayToHexString(byte data[]) {
+ StringBuffer buf = new StringBuffer();
+ for (byte element : data) {
+ int halfbyte = (element >>> 4) & 0x0F;
+ int two_halfs = 0;
+ do {
+ if ((0 <= halfbyte) && (halfbyte <= 9))
+ buf.append((char) ('0' + halfbyte));
+ else
+ buf.append((char) ('a' + (halfbyte - 10)));
+ halfbyte = element & 0x0F;
+ } while(two_halfs++ < 1);
+ }
+ return buf.toString();
+ }
+
+
+ // Get/Set spelling settings
+ public static boolean getSpellSetting(String value) {
+ settings.beginGroup("Spell");
+ String text = (String)settings.value(value, "");
+ settings.endGroup();
+ if (text.equalsIgnoreCase("true"))
+ return true;
+ if (text.equalsIgnoreCase("false"))
+ return false;
+ if (value.equalsIgnoreCase(Configuration.SPELL_IGNOREDIGITWORDS))
+ return true;
+ if (value.equalsIgnoreCase(Configuration.SPELL_IGNOREINTERNETADDRESSES))
+ return true;
+ if (value.equalsIgnoreCase(Configuration.SPELL_IGNOREUPPERCASE))
+ return true;
+ if (value.equalsIgnoreCase(Configuration.SPELL_IGNORESENTENCECAPITALIZATION))
+ return true;
+ return false;
+ }
+ public static void setSpellSetting(String setting, boolean val) {
+ settings.beginGroup("Spell");
+ if (val)
+ settings.setValue(setting, "true");
+ else
+ settings.setValue(setting, "false");
+ settings.endGroup();
+ }
+
+ // Get/Set how we should display tags (color them, hide unused, or do nothing)
+ // What to do with inactive tags?
+ public static String tagBehavior() {
+ settings.beginGroup("General");
+ String text = (String)settings.value("tagBehavior", "DoNothing");
+ settings.endGroup();
+ return text;
+ }
+ // What to do with inactive tags?
+ public static void setTagBehavior(String value) {
+ settings.beginGroup("General");
+ settings.setValue("tagBehavior", value);
+ settings.endGroup();
+ }
+
+
+ // Should the toolbar be visible?
+ public static boolean isToolbarButtonVisible(String window) {
+ settings.beginGroup("ToolbarButtonsVisible");
+ try {
+ String text = (String)settings.value(window, "true");
+ settings.endGroup();
+ if (text.equalsIgnoreCase("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value(window, true);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void saveToolbarButtonsVisible(String column, boolean val) {
+ settings.beginGroup("ToolbarButtonsVisible");
+ if (val)
+ settings.setValue(column, "true");
+ else
+ settings.setValue(column, "false");
+ settings.endGroup();
+ }
+
+ // Are thumbnails enabled?
+
+ public static boolean enableThumbnails() {
+ settings.beginGroup("Debug");
+ try {
+ String text = (String)settings.value("thumbnails", "true");
+ settings.endGroup();
+ if (text.equalsIgnoreCase("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("thumbnails", true);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void setEnableThumbnails(boolean val) {
+ settings.beginGroup("Debug");
+ if (val)
+ settings.setValue("thumbnails", "true");
+ else
+ settings.setValue("thumbnails", "false");
+ settings.endGroup();
+ }
+
+ // Trace used for performance tuning. Not normally used in production.
+ // Print date/time. Used mainly for performance tracing
+ public static void trace(boolean resetInterval) {
+ String fmt = "MM/dd/yy HH:mm:ss.SSSSSS";
+ String dateTimeFormat = new String(fmt);
+ SimpleDateFormat simple = new SimpleDateFormat(dateTimeFormat);
+ Calendar cal = Calendar.getInstance();
+ if (intervalTraceTime == null)
+ intervalTraceTime = Calendar.getInstance();
+ if (startTraceTime == null)
+ startTraceTime = Calendar.getInstance();
+
+ float interval = (cal.getTimeInMillis() - intervalTraceTime.getTimeInMillis());
+ float total = (cal.getTimeInMillis() - startTraceTime.getTimeInMillis());
+
+// if (interval > 00.0) {
+ StackTraceElement[] exceptions = Thread.currentThread().getStackTrace();
+ System.out.println("------------------------------------------");
+
+ System.out.println("Date/Time " +simple.format(cal.getTime()));
+ System.out.format("Interval Time: %-10.6f%n", interval);
+ System.out.format("Total Time: %-10.6f%n", total);
+ for (int i=2; i<5 && i<exceptions.length; i++) {
+ System.out.println(exceptions[i]);
+ }
+// }
+ if (resetInterval)
+ intervalTraceTime = cal;
+ }
+ public static void traceReset() {
+ intervalTraceTime = null;
+ startTraceTime = null;
+ }
+
+
+ // Get the FileManager class to manage local files & directories
+ public static FileManager getFileManager() {
+ return fileManager;
+ }
+
+ // Should the note editor be disabled?
+ public static boolean getDisableViewing() {
+ return disableViewing;
+ }
+
+ //**********************
+ //* Thumbnail zoom level
+ //**********************
+ public static int calculateThumbnailZoom(String content) {
+ int zoom = 1;
+ if (content.indexOf("application/pdf") == -1) {
+ if (content.indexOf("image/") == -1) {
+ String text = StringEscapeUtils.unescapeHtml4(content.replaceAll("\\<.*?\\>", ""));
+ zoom = 2;
+ if (text.length() < 500)
+ zoom = 2;
+ if (text.length() < 250)
+ zoom = 3;
+ if (text.length() < 100)
+ zoom = 4;
+ if (text.length() < 50)
+ zoom = 5;
+ if (text.length() < 10)
+ zoom = 6;
+ }
+ }
+ return zoom;
+ }
+
+ //**********************
+ //* List View settings
+ //**********************
+ public static void setListView(int view) {
+ settings.beginGroup("General");
+ settings.setValue("listView", view);
+ settings.endGroup();
+ }
+ public static int getListView() {
+ settings.beginGroup("General");
+ Integer value;
+ try {
+ String val = (String)settings.value("listView", View_List_Wide);
+ value = new Integer(val.trim());
+ } catch (Exception e) {
+ try {
+ value = (Integer)settings.value("listView", View_List_Wide);
+ } catch (Exception e1) {
+ value = View_List_Wide;
+ }
+ }
+ settings.endGroup();
+ return value;
+ }
+
+
+
+ //*******************
+ // Font Settings
+ //*******************
+ public static boolean overrideDefaultFont() {
+ settings.beginGroup("Font");
+ try {
+ String text = (String)settings.value("overrideFont", "false");
+ settings.endGroup();
+ if (text.equalsIgnoreCase("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("overrideFont", false);
+ settings.endGroup();
+ return value;
+ }
+
+ }
+
+ //****************************************************
+ // Get/Set the default font settings for a new note
+ //****************************************************
+ public static void setOverrideDefaultFont(boolean value) {
+ settings.beginGroup("Font");
+ settings.setValue("overrideFont", value);
+ settings.endGroup();
+ }
+ public static String getDefaultFont() {
+ settings.beginGroup("Font");
+ String val = (String)settings.value("font", "");
+ settings.endGroup();
+ return val;
+ }
+ public static void setDefaultFont(String value) {
+ settings.beginGroup("Font");
+ settings.setValue("font", value);
+ settings.endGroup();
+ }
+ public static String getDefaultFontSize() {
+ settings.beginGroup("Font");
+ String val = (String)settings.value("fontSize", "");
+ settings.endGroup();
+ return val;
+ }
+ public static void setDefaultFontSize(String value) {
+ settings.beginGroup("Font");
+ settings.setValue("fontSize", value);
+ settings.endGroup();
+ }
+
+
+ //*******************************************
+ // Override the close & minimize instead.
+ //*******************************************
+ public static boolean minimizeOnClose() {
+ settings.beginGroup("General");
+ try {
+ String text = (String)settings.value("minimizeOnClose", "false");
+ settings.endGroup();
+ if (text.equalsIgnoreCase("true") && QSystemTrayIcon.isSystemTrayAvailable())
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("minimizeOnClose", false);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void setMinimizeOnClose(boolean value) {
+ settings.beginGroup("General");
+ settings.setValue("minimizeOnClose", value);
+ settings.endGroup();
+ }
+
+ //*********************************
+ // Check version information
+ //*********************************
+ public static boolean checkVersionUpgrade() {
+ settings.beginGroup("Upgrade");
+ try {
+ String text = (String)settings.value("checkForUpdates", "true");
+ settings.endGroup();
+ if (text.equalsIgnoreCase("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("checkForUpdates", true);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void setCheckVersionUpgrade(boolean value) {
+ settings.beginGroup("Upgrade");
+ settings.setValue("checkForUpdates", value);
+ settings.endGroup();
+ }
+ public static String getUpdatesAvailableUrl() {
+ settings.beginGroup("Upgrade");
+ String text = (String)settings.value("avialableUrl", "http://nevernote.sourceforge.net/versions.txt");
+ settings.endGroup();
+ return text;
+ }
+ public static String getUpdateAnnounceUrl() {
+ settings.beginGroup("Upgrade");
+ String text = (String)settings.value("announceUrl", "http://nevernote.sourceforge.net/upgrade.html");
+ settings.endGroup();
+ return text;
+ }
+
+ //*******************
+ // Index settings
+ //*******************
+ // Set/Get if we should index the text of a note
+ public static boolean indexNoteBody() {
+ settings.beginGroup("Index");
+ try {
+ String value = (String)settings.value("indexNoteBody", "true");
+ settings.endGroup();
+ if (value.equals("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("indexNoteBody", true);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void setIndexNoteTitle(boolean value) {
+ settings.beginGroup("Index");
+ settings.setValue("indexNoteTitle", value);
+ settings.endGroup();
+ }
+ // Set/Get if we should index the title of a note
+ public static boolean indexNoteTitle() {
+ settings.beginGroup("Index");
+ try {
+ String value = (String)settings.value("indexNoteTitle", "true");
+ settings.endGroup();
+ if (value.equals("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("indexNoteTitle", true);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void setIndexNoteBody(boolean value) {
+ settings.beginGroup("Index");
+ settings.setValue("indexNoteBody", value);
+ settings.endGroup();
+ }
+ // Set/Get if we should index any attachments
+ public static boolean indexAttachmentsLocally() {
+ settings.beginGroup("Index");
+ try {
+ String value = (String)settings.value("indexAttachmentsLocally", "true");
+ settings.endGroup();
+ if (value.equals("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("indexAttachmentsLocally", true);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void setIndexImageRecognition(boolean value) {
+ settings.beginGroup("Index");
+ settings.setValue("indexImageRecognition", value);
+ settings.endGroup();
+ }
+ public static boolean indexImageRecognition() {
+ settings.beginGroup("Index");
+ try {
+ String value = (String)settings.value("indexImageRecognition", "true");
+ settings.endGroup();
+ if (value.equals("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("indexImageRecognition", true);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void setIndexAttachmentsLocally(boolean value) {
+ settings.beginGroup("Index");
+ settings.setValue("indexAttachmentsLocally", value);
+ settings.endGroup();
+ }
+ // Get/Set characters that shouldn't be removed from a word
+ public static String getSpecialIndexCharacters() {
+ settings.beginGroup("Index");
+ String text = (String)settings.value("specialCharacters", "");
+ settings.endGroup();
+ return text;
+ }
+ public static void setSpecialIndexCharacters(String value) {
+ settings.beginGroup("Index");
+ settings.setValue("specialCharacters", value);
+ settings.endGroup();
+ databaseCache = value;
+ }
+
+ //*****************************************************************************
+ // Control how tag selection behaves (should they be "and" or "or" selections
+ //*****************************************************************************
+ public static boolean anyTagSelectionMatch() {
+ settings.beginGroup("General");
+ try {
+ String value = (String)settings.value("anyTagSelectionMatch", "false");
+ settings.endGroup();
+ if (value.equals("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("anyTagSelectionMatch", false);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void setAnyTagSelectionMatch(boolean value) {
+ settings.beginGroup("General");
+ settings.setValue("anyTagSelectionMatch", value);
+ settings.endGroup();
+ }
+
+ //*****************************************************************************
+ // Control if a user receives a warning when trying to create a note-to-note link
+ // when the DB is not synchronized.
+ //*****************************************************************************
+ public static boolean bypassSynchronizationWarning() {
+ settings.beginGroup("User");
+ try {
+ String value = (String)settings.value("bypassSynchronizationWarning", "false");
+ settings.endGroup();
+ if (value.equals("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("bypassSynchronizationWarning", false);
+ settings.endGroup();
+ return value;
+ }
+ }
+ public static void setBypassSynchronizationWarning(boolean value) {
+ settings.beginGroup("User");
+ settings.setValue("bypassSynchronizationWarning", value);
+ settings.endGroup();
+ }
+
+
+ //***********************
+ //* Database cache size
+ //***********************
+ public static String getDatabaseCacheSize() {
+ settings.beginGroup("Debug");
+ String text = (String)settings.value("databaseCache", "16384");
+ settings.endGroup();
+ return text;
+ }
+ public static void setDatabaseCache(String value) {
+ settings.beginGroup("Debug");
+ settings.setValue("databaseCache", value);
+ settings.endGroup();
+ databaseCache = value;
+ }
+
+
+ // This is used to copy a class since Java's normal deep copy is wacked
+ public static Object deepCopy(Object oldObj)
+ {
+ ObjectOutputStream oos = null;
+ ObjectInputStream ois = null;
+ try
+ {
+ ByteArrayOutputStream bos =
+ new ByteArrayOutputStream(); // A
+ oos = new ObjectOutputStream(bos); // B
+ // serialize and pass the object
+ oos.writeObject(oldObj); // C
+ oos.flush(); // D
+ ByteArrayInputStream bin =
+ new ByteArrayInputStream(bos.toByteArray()); // E
+ ois = new ObjectInputStream(bin); // F
+ // return the new object
+ return ois.readObject(); // G
+ }
+ catch(Exception e)
+ {
+ Global.logger.log(logger.LOW, "Exception in ObjectCloner = " + e);
+ }
+ try {
+ oos.close();
+ ois.close();
+ } catch (IOException e) {
+ Global.logger.log(logger.LOW, "Exception in ObjectCloner = " + e);
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+ // If we should automatically select the children of any tag
+ public static boolean includeTagChildren() {
+ settings.beginGroup("General");
+ try {
+ String value = (String)settings.value("includeTagChildren", "false");
+ settings.endGroup();
+ if (value.equals("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("includeTagChildren", false);
+ settings.endGroup();
+ return value;
+ }
+
+ }
+ public static void setIncludeTagChildren(boolean value) {
+ settings.beginGroup("General");
+ settings.setValue("includeTagChildren", value);
+ settings.endGroup();
+ }
+
+ // If we should automatically wildcard searches
+ public static boolean automaticWildcardSearches() {
+ settings.beginGroup("General");
+ try {
+ String value = (String)settings.value("automaticWildcard", "false");
+ settings.endGroup();
+ if (value.equals("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("automaticWildcard", false);
+ settings.endGroup();
+ return value;
+ }
+
+ }
+ public static void setAutomaticWildcardSearches(boolean value) {
+ settings.beginGroup("General");
+ settings.setValue("automaticWildcard", value);
+ settings.endGroup();
+ }
+
+ // If we should automatically select the children of any tag
+ public static boolean displayRightToLeft() {
+ settings.beginGroup("General");
+ try {
+ String value = (String)settings.value("displayRightToLeft", "false");
+ settings.endGroup();
+ if (value.equals("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("displayRightToLeft", false);
+ settings.endGroup();
+ return value;
+ }
+
+ }
+ public static void setDisplayRightToLeft(boolean value) {
+ settings.beginGroup("General");
+ settings.setValue("displayRightToLeft", value);
+ settings.endGroup();
+ }
+
+
+ //***********************
+ //* Startup Notebook
+ //***********************
+ public static String getStartupNotebook() {
+ settings.beginGroup("General");
+ String text = (String)settings.value("startupNotebook", "");
+ settings.endGroup();
+ return text;
+ }
+ public static void setStartupNotebook(String value) {
+ settings.beginGroup("General");
+ settings.setValue("startupNotebook", value);
+ settings.endGroup();
+ databaseCache = value;
+ }
+
+ // ICHANGED
+ // 複数ノート同時閲覧操作に対する重み付け
+ public static void setBrowseWeight(int weight) {
+ settings.beginGroup("RensoNoteList");
+ settings.setValue("browseWeight", weight);
+ settings.endGroup();
+ }
+ public static int getBrowseWeight() {
+ settings.beginGroup("RensoNoteList");
+ Integer value;
+ try {
+ String val = (String)settings.value("browseWeight", 1);
+ value = new Integer(val.trim());
+ } catch (Exception e) {
+ try {
+ value = (Integer)settings.value("browseWeight", 1);
+ } catch (Exception e1) {
+ value = 1;
+ }
+ }
+ settings.endGroup();
+ return value;
+ }
+
+ // ICHANGED
+ // ノート内容のコピー&ペースト操作に対する重み付け
+ public static void setCopyPasteWeight(int weight) {
+ settings.beginGroup("RensoNoteList");
+ settings.setValue("copyPasteWeight", weight);
+ settings.endGroup();
+ }
+ public static int getCopyPasteWeight() {
+ settings.beginGroup("RensoNoteList");
+ Integer value;
+ try {
+ String val = (String)settings.value("copyPasteWeight", 3);
+ value = new Integer(val.trim());
+ } catch (Exception e) {
+ try {
+ value = (Integer)settings.value("copyPasteWeight", 3);
+ } catch (Exception e1) {
+ value = 3;
+ }
+ }
+ settings.endGroup();
+ return value;
+ }
+
+ // ICHANGED
+ // 新規ノート追加操作に対する重み付け
+ public static void setAddNewNoteWeight(int weight) {
+ settings.beginGroup("RensoNoteList");
+ settings.setValue("addNewNoteWeight", weight);
+ settings.endGroup();
+ }
+ public static int getAddNewNoteWeight() {
+ settings.beginGroup("RensoNoteList");
+ Integer value;
+ try {
+ String val = (String)settings.value("addNewNoteWeight", 1);
+ value = new Integer(val.trim());
+ } catch (Exception e) {
+ try {
+ value = (Integer)settings.value("addNewNoteWeight", 1);
+ } catch (Exception e1) {
+ value = 1;
+ }
+ }
+ settings.endGroup();
+ return value;
+ }
+
+ // ICHANGED
+ // 連想ノートクリック操作に対する重み付け
+ public static void setRensoItemClickWeight(int weight) {
+ settings.beginGroup("RensoNoteList");
+ settings.setValue("rensoItemClickWeight", weight);
+ settings.endGroup();
+ }
+ public static int getRensoItemClickWeight() {
+ settings.beginGroup("RensoNoteList");
+ Integer value;
+ try {
+ String val = (String)settings.value("rensoItemClickWeight", 10);
+ value = new Integer(val.trim());
+ } catch (Exception e) {
+ try {
+ value = (Integer)settings.value("rensoItemClickWeight", 10);
+ } catch (Exception e1) {
+ value = 10;
+ }
+ }
+ settings.endGroup();
+ return value;
+ }
+
+ // ICHANGED
+ // タグ付け操作に対する重み付け
+ public static void setSameTagWeight(int weight) {
+ settings.beginGroup("RensoNoteList");
+ settings.setValue("sameTagWeight", weight);
+ settings.endGroup();
+ }
+ public static int getSameTagWeight() {
+ settings.beginGroup("RensoNoteList");
+ Integer value;
+ try {
+ String val = (String)settings.value("sameTagWeight", 2);
+ value = new Integer(val.trim());
+ } catch (Exception e) {
+ try {
+ value = (Integer)settings.value("sameTagWeight", 2);
+ } catch (Exception e1) {
+ value = 2;
+ }
+ }
+ settings.endGroup();
+ return value;
+ }
+
+ // ICHANGED
+ // ノートブック変更操作に対する重み付け
+ public static void setSameNotebookWeight(int weight) {
+ settings.beginGroup("RensoNoteList");
+ settings.setValue("sameNotebookWeight", weight);
+ settings.endGroup();
+ }
+ public static int getSameNotebookWeight() {
+ settings.beginGroup("RensoNoteList");
+ Integer value;
+ try {
+ String val = (String)settings.value("sameNotebookWeight", 2);
+ value = new Integer(val.trim());
+ } catch (Exception e) {
+ try {
+ value = (Integer)settings.value("sameNotebookWeight", 2);
+ } catch (Exception e1) {
+ value = 2;
+ }
+ }
+ settings.endGroup();
+ return value;
+ }
+
+ //*******************
+ // ノートのマージ・複製の関連ノートリストへの適用
+ //*******************
+ // ICHANGED
+ public static void setMergeRensoNote(boolean value) {
+ settings.beginGroup("RensoNoteList");
+ settings.setValue("mergeRensoNoteList", value);
+ settings.endGroup();
+ }
+ // ICHANGED
+ public static boolean getMergeRensoNote() {
+ settings.beginGroup("RensoNoteList");
+ try {
+ String value = (String)settings.value("mergeRensoNoteList", "true");
+ settings.endGroup();
+ if (value.equals("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("mergeRensoNoteList", true);
+ settings.endGroup();
+ return value;
+ }
+ }
+ // ICHANGED
+ public static void setDuplicateRensoNote(boolean value) {
+ settings.beginGroup("RensoNoteList");
+ settings.setValue("duplicateRensoNoteList", value);
+ settings.endGroup();
+ }
+ // ICHANGED
+ public static boolean getDuplicateRensoNote() {
+ settings.beginGroup("RensoNoteList");
+ try {
+ String value = (String)settings.value("duplicateRensoNoteList", "true");
+ settings.endGroup();
+ if (value.equals("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("duplicateRensoNoteList", true);
+ settings.endGroup();
+ return value;
+ }
+ }
+
+ // ICHANGED
+ // 連想ノートリストからノートを除外するときに確認メッセージを表示するかどうか
+ public static boolean verifyExclude() {
+ settings.beginGroup("RensoNoteList");
+ try {
+ String text = (String)settings.value("verifyExclude", "true");
+ settings.endGroup();
+ if (text.equalsIgnoreCase("true"))
+ return true;
+ else
+ return false;
+ } catch (java.lang.ClassCastException e) {
+ Boolean value = (Boolean) settings.value("verifyExclude", true);
+ settings.endGroup();
+ return value;
+ }
+ }
+ // ICHANGED
+ public static void setVerifyExclude(boolean val) {
+ settings.beginGroup("RensoNoteList");
+ if (val)
+ settings.setValue("verifyExclude", "true");
+ else
+ settings.setValue("verifyExclude", "false");
+ settings.endGroup();
+ }
+
+ // ICHANGED
+ // 連想ノートリスト最大表示アイテム数
+ public static void setRensoListItemMaximum(int maximum) {
+ settings.beginGroup("RensoNoteList");
+ settings.setValue("rensoListMaximum", maximum);
+ settings.endGroup();
+ }
+ public static int getRensoListItemMaximum() {
+ settings.beginGroup("RensoNoteList");
+ Integer value;
+ try {
+ String val = (String)settings.value("rensoListMaximum", 20);
+ value = new Integer(val.trim());
+ } catch (Exception e) {
+ try {
+ value = (Integer)settings.value("rensoListMaximum", 20);
+ } catch (Exception e1) {
+ value = 20;
+ }
+ }
+ settings.endGroup();
+ return value;
+ }
+}
+
import com.trolltech.qt.core.QUrl;
import com.trolltech.qt.core.Qt;
import com.trolltech.qt.core.Qt.BGMode;
+import com.trolltech.qt.core.Qt.DockWidgetArea;
import com.trolltech.qt.core.Qt.ItemDataRole;
import com.trolltech.qt.core.Qt.KeyboardModifier;
import com.trolltech.qt.core.Qt.MouseButton;
import com.trolltech.qt.gui.QCursor;
import com.trolltech.qt.gui.QDesktopServices;
import com.trolltech.qt.gui.QDialog;
+import com.trolltech.qt.gui.QDockWidget;
import com.trolltech.qt.gui.QFileDialog;
import com.trolltech.qt.gui.QFileDialog.AcceptMode;
import com.trolltech.qt.gui.QFileDialog.FileMode;
import com.trolltech.qt.gui.QImage;
import com.trolltech.qt.gui.QKeySequence;
import com.trolltech.qt.gui.QLabel;
+import com.trolltech.qt.gui.QListWidgetItem;
import com.trolltech.qt.gui.QMainWindow;
import com.trolltech.qt.gui.QMenu;
import com.trolltech.qt.gui.QMessageBox;
import cx.fbn.nevernote.gui.ExternalBrowse;
import cx.fbn.nevernote.gui.MainMenuBar;
import cx.fbn.nevernote.gui.NotebookTreeWidget;
+import cx.fbn.nevernote.gui.RensoNoteList;
import cx.fbn.nevernote.gui.SavedSearchTreeWidget;
import cx.fbn.nevernote.gui.SearchPanel;
+import cx.fbn.nevernote.gui.TabBrowse;
+import cx.fbn.nevernote.gui.TabBrowserWidget;
import cx.fbn.nevernote.gui.TableView;
import cx.fbn.nevernote.gui.TagTreeWidget;
import cx.fbn.nevernote.gui.Thumbnailer;
import cx.fbn.nevernote.gui.TrashTreeWidget;
import cx.fbn.nevernote.gui.controls.QuotaProgressBar;
+import cx.fbn.nevernote.neighbornote.ClipBoardObserver;
import cx.fbn.nevernote.oauth.OAuthTokenizer;
import cx.fbn.nevernote.oauth.OAuthWindow;
import cx.fbn.nevernote.sql.DatabaseConnection;
HashMap<String, String> noteCache; // Cash of note content
HashMap<String, Boolean> readOnlyCache; // List of cashe notes that are read-only
HashMap<String, Boolean> inkNoteCache; // List of cache notes that are ink notes
- List<String> historyGuids; // GUIDs of previously viewed items
- int historyPosition; // Position within the viewed items
- boolean fromHistory; // Is this from the history queue?
+ // ICHANGED
+ HashMap<Integer, ArrayList<String>> historyGuids; // タブごとの以前見たノートのGUID
+ HashMap<Integer, Integer> historyPosition; // Position within the viewed items
+ HashMap<Integer, Boolean> fromHistory; // Is this from the history queue?
+
String trashNoteGuid; // Guid to restore / set into or out of trash to save position
List<Thumbnailer> thumbGenerators; // generate preview image
ThumbnailViewer thumbnailViewer; // View preview thumbnail;
private QTimer blockTimer;
BrowserWindow blockingWindow;
+ // ICHANGED
+ private final TabBrowserWidget tabBrowser; // ブラウザウィンドウをタブ化
+ private final HashMap<Integer, TabBrowse> tabWindows; // タブウィンドウ
+ private final RensoNoteList rensoNoteList; // 連想ノートリスト
+ private final QDockWidget rensoNoteListDock; // 連想ノートリストドックウィジェット
+
+ // ICHANGED
+ ClipBoardObserver cbObserver;
+
+ // ICHANGED
+ String rensoNotePressedItemGuid;
+
String iconPath = new String("classpath:cx/fbn/nevernote/icons/");
// Application Constructor
@SuppressWarnings("static-access")
public NeverNote(DatabaseConnection dbConn) {
+ // ICHANGED
+ cbObserver = new ClipBoardObserver();
+
conn = dbConn;
if (conn.getConnection() == null) {
String msg = new String(tr("Unable to connect to the database.\n\nThe most probable reason is that some other process\n" +
- "is accessing the database or NixNote is already running.\n\n" +
- "Please end any other process or shutdown the other NixNote before starting.\n\nExiting program."));
+ "is accessing the database or NeighborNote is already running.\n\n" +
+ "Please end any other process or shutdown the other NeighborNote before starting.\n\nExiting program."));
QMessageBox.critical(null, tr("Database Connection Error") ,msg);
System.exit(16);
QApplication.setStyle(Global.getStyle());
if (Global.useStandardPalette())
QApplication.setPalette(QApplication.style().standardPalette());
- setWindowTitle(tr("NixNote"));
+ setWindowTitle(tr("NeighborNote"));
mainLeftRightSplitter = new QSplitter();
+ // ICHANGED
+ mainLeftRightSplitter.setOrientation(Qt.Orientation.Horizontal);
+
setCentralWidget(mainLeftRightSplitter);
leftSplitter1 = new QSplitter();
leftSplitter1.setOrientation(Qt.Orientation.Vertical);
listManager = new ListManager(conn, logger);
logger.log(logger.EXTREME, "Building index runners & timers");
- indexRunner = new IndexRunner("indexRunner.log",
- Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(),
- Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);
+ // ICHANGED Global.getBehaviorDatabaseUrl()を追加
+ indexRunner = new IndexRunner("indexRunner.log",
+ Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(),
+ Global.getResourceDatabaseUrl(),
+ Global.getBehaviorDatabaseUrl(), Global.getDatabaseUserid(),
+ Global.getDatabaseUserPassword(), Global.cipherPassword);
+
indexThread = new QThread(indexRunner, "Index Thread");
indexRunner.indexAttachmentsLocally = Global.indexAttachmentsLocally();
indexRunner.indexImageRecognition = Global.indexImageRecognition();
logger.log(logger.EXTREME, "Setting sync thread & timers");
syncThreadsReady=1;
- syncRunner = new SyncRunner("syncRunner.log",
- Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(),
- Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);
+ // ICHANGED Global.getBehaviorDatabaseUrl()を追加
+ syncRunner = new SyncRunner("syncRunner.log", Global.getDatabaseUrl(),
+ Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(),
+ Global.getBehaviorDatabaseUrl(), Global.getDatabaseUserid(),
+ Global.getDatabaseUserPassword(), Global.cipherPassword);
+
syncTime = new SyncTimes().timeValue(Global.getSyncInterval());
syncTimer = new QTimer();
syncTimer.timeout.connect(this, "syncTimer()");
logger.log(logger.EXTREME, "Starting thumnail thread");
pdfReadyQueue = new ArrayList<String>();
- thumbnailRunner = new ThumbnailRunner("thumbnailRunner.log",
- Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(),
- Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);
+ // ICHANGED Global.getBehaviorDatabaseUrl()を追加
+ thumbnailRunner = new ThumbnailRunner("thumbnailRunner.log",
+ Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(),
+ Global.getResourceDatabaseUrl(),
+ Global.getBehaviorDatabaseUrl(), Global.getDatabaseUserid(),
+ Global.getDatabaseUserPassword(), Global.cipherPassword);
+
thumbnailThread = new QThread(thumbnailRunner, "Thumbnail Thread");
thumbnailRunner.noteSignal.thumbnailPageReady.connect(this, "thumbnailHTMLReady(String,QByteArray,Integer)");
thumbnailThread.start();
tagTree = new TagTreeWidget(conn);
savedSearchTree = new SavedSearchTreeWidget();
trashTree = new TrashTreeWidget();
- noteTableView = new TableView(logger, listManager);
+ // ICHANGED
+ noteTableView = new TableView(logger, listManager, this);
searchField = new QComboBox();
searchField.setObjectName("searchField");
noteCache = new HashMap<String,String>();
readOnlyCache = new HashMap<String, Boolean>();
inkNoteCache = new HashMap<String, Boolean>();
- browserWindow = new BrowserWindow(conn);
-
+ // ICHANGED
+ browserWindow = new BrowserWindow(conn, cbObserver);
+
+ // ICHANGED 下から移動してきた。
+ historyGuids = new HashMap<Integer, ArrayList<String>>();
+ historyPosition = new HashMap<Integer, Integer>();
+ fromHistory = new HashMap<Integer, Boolean>();
+
+ // ICHANGED タブブラウザ作成
+ tabWindows = new HashMap<Integer, TabBrowse>();
+ tabBrowser = new TabBrowserWidget(this);
+ tabBrowser.setStyleSheet("QTabBar::tab{width:150px;}");
+ TabBrowse tab = new TabBrowse(conn, tabBrowser, cbObserver);
+ browserWindow = tab.getBrowserWindow();
+ int index = tabBrowser.addNewTab(tab, "");
+ tabWindows.put(index, tab);
+ tabBrowser.setTabsClosable(true);
+ tabBrowser.currentChanged.connect(this, "tabWindowChanged(int)");
+ tabBrowser.tabCloseRequested.connect(this, "tabWindowClosing(int)");
+
+ // ICHANGED
+ // 履歴記録のハッシュマップを初期化
+ historyGuids.put(index, new ArrayList<String>());
+ historyPosition.put(index, 0);
+ fromHistory.put(index, false);
+
mainLeftRightSplitter.addWidget(leftSplitter1);
mainLeftRightSplitter.addWidget(browserIndexSplitter);
- if (Global.getListView() == Global.View_List_Wide) {
- browserIndexSplitter.addWidget(noteTableView);
- browserIndexSplitter.addWidget(browserWindow);
- } else {
- mainLeftRightSplitter.addWidget(noteTableView);
- mainLeftRightSplitter.addWidget(browserWindow);
- }
+ // ICHANGED
+ // 連想ノートリストをセットアップ
+ rensoNoteList = new RensoNoteList(conn, this);
+ rensoNoteList.itemPressed.connect(this,
+ "rensoNoteItemPressed(QListWidgetItem)");
+ rensoNoteListDock = new QDockWidget(tr("Renso Note List"), this);
+ rensoNoteListDock.setWidget(rensoNoteList);
+ addDockWidget(DockWidgetArea.RightDockWidgetArea, rensoNoteListDock);
+
+ if (Global.getListView() == Global.View_List_Wide) {
+ browserIndexSplitter.addWidget(noteTableView);
+ // ICHANGED
+ browserIndexSplitter.addWidget(tabBrowser);
+ // browserIndexSplitter.addWidget(browserWindow);
+ } else {
+ mainLeftRightSplitter.addWidget(noteTableView);
+ // ICHANGED
+ mainLeftRightSplitter.addWidget(tabBrowser);
+ // mainLeftRightSplitter.addWidget(browserWindow);
+ }
// Setup the thumbnail viewer
thumbnailViewer = new ThumbnailViewer();
savedSearchTree.itemSelectionChanged.connect(this, "updateSavedSearchSelection()");
savedSearchTree.setVisible(Global.isWindowVisible("savedSearchTree"));
menuBar.hideSavedSearches.setChecked(Global.isWindowVisible("savedSearchTree"));
+
+ // ICHANGED noteTableViewに新しいタブで開くを追加
+ noteTableView.setOpenNewTabAction(menuBar.noteOpenNewTab);
noteTableView.setAddAction(menuBar.noteAdd);
+
+ // ICHANGED noteTableViewに新しいタブでノート追加を追加
+ noteTableView.setAddNoteNewTabAction(menuBar.noteAddNewTab);
+
noteTableView.setDeleteAction(menuBar.noteDelete);
noteTableView.setRestoreAction(menuBar.noteRestoreAction);
noteTableView.setNoteDuplicateAction(menuBar.noteDuplicateAction);
if (!Global.isWindowVisible("editorButtonBar"))
toggleEditorButtonBar();
+
if (!Global.isWindowVisible("leftPanel"))
menuBar.hideLeftSide.setChecked(true);
if (Global.isWindowVisible("noteInformation"))
toggleNoteInformation();
quotaBar.setVisible(Global.isWindowVisible("quota"));
- if (!quotaBar.isVisible())
+ // IFIXED quotaBar.isVisible() → Global.isWindowVisible("quota")
+ // なぜかquotaBar.isVisible()が常にfalseを返すようなので修正
+ if (!Global.isWindowVisible("quota"))
menuBar.hideQuota.setChecked(false);
+
searchField.setVisible(Global.isWindowVisible("searchField"));
- if (!searchField.isVisible())
+ // IFIXED !searchField.isVisible() → !Global.isWindowVisible("searchField")
+ // なぜかsearchField.isVisible()が常にfalseを返すようなので修正
+ if (!Global.isWindowVisible("searchField"))
menuBar.hideSearch.setChecked(false);
if (searchField.isHidden() && quotaBar.isHidden() && zoomSpinner.isHidden() && notebookTree.isHidden())
trayIcon = new QSystemTrayIcon(this);
- trayIcon.setToolTip(tr("NixNote"));
+ trayIcon.setToolTip(tr("NeighborNote"));
trayIcon.setContextMenu(trayMenu);
trayIcon.activated.connect(this, "trayActivated(com.trolltech.qt.gui.QSystemTrayIcon$ActivationReason)");
currentNoteGuid = Global.getLastViewedNoteGuid();
if (currentNoteGuid.equals(""))
currentNote = new Note();
- historyGuids = new ArrayList<String>();
- historyPosition = 0;
- fromHistory = false;
+
+ // ICHANGED
+ /* 上に移動したので要らない
+ historyGuids = new ArrayList<String>();
+ historyPosition = 0;
+ fromHistory = false;
+ */
+
noteDirty = false;
if (!currentNoteGuid.trim().equals("")) {
currentNote = conn.getNoteTable().getNote(currentNoteGuid, true,true,false,false,true);
threadMonitorTimer.timeout.connect(this, "threadMonitorCheck()");
threadMonitorTimer.start(1000*10); // Check for threads every 10 seconds;
- historyGuids.add(currentNoteGuid);
- historyPosition = 1;
+ // ICHANGED たぶんこれはいらない
+ // IFIXED ?
+ /*
+ historyGuids.add(currentNoteGuid);
+ historyPosition = 1;
+ */
menuBar.blockSignals(true);
menuBar.narrowListView.blockSignals(true);
menuBar.blockSignals(false);
menuBar.narrowListView.blockSignals(false);
menuBar.wideListView.blockSignals(false);
-
- if (Global.getListView() == Global.View_List_Wide) {
- browserIndexSplitter.addWidget(noteTableView);
- browserIndexSplitter.addWidget(browserWindow);
- } else {
- mainLeftRightSplitter.addWidget(noteTableView);
- mainLeftRightSplitter.addWidget(browserWindow);
- }
+
+ // IFIXED
+ // 上に同じコードがあるよね? とりあえずコメントアウト
+ /*
+ * if (Global.getListView() == Global.View_List_Wide) {
+ * browserIndexSplitter.addWidget(noteTableView); // ICHANGED //
+ * browserIndexSplitter.addWidget(tabBrowser);
+ * browserIndexSplitter.addWidget(browserWindow); } else {
+ * mainLeftRightSplitter.addWidget(noteTableView); // ICHANGED //
+ * mainLeftRightSplitter.addWidget(tabBrowser);
+ * mainLeftRightSplitter.addWidget(browserWindow); }
+ */
messageTimer = new QTimer();
messageTimer.timeout.connect(this, "clearMessage()");
}
}
-
-
-
- if (Global.checkVersionUpgrade())
- checkForUpdates();
+ if (Global.checkVersionUpgrade()) {
+ // ICHANGED TODO とりあえず封印
+ // checkForUpdates();
+ }
}
File f = Global.getFileManager().getDbDirFile(Global.databaseName + ".h2.db");
File fr = Global.getFileManager().getDbDirFile(Global.resourceDatabaseName + ".h2.db");
- File fi = Global.getFileManager().getDbDirFile(Global.resourceDatabaseName + ".h2.db");
+ // IFIXED resourceDatabaseNameになっていたので修正
+ File fi = Global.getFileManager().getDbDirFile(Global.indexDatabaseName + ".h2.db");
+ // ICHANGED
+ File fb = Global.getFileManager().getDbDirFile(Global.behaviorDatabaseName + ".h2.db");
+
if (!f.exists())
Global.setDatabaseUrl("");
if (!fr.exists())
Global.setResourceDatabaseUrl("");
if (!fi.exists())
Global.setIndexDatabaseUrl("");
+ // ICHANGED
+ if (!fb.exists())
+ Global.setBehaviorDatabaseUrl("");
if (Global.getDatabaseUrl().toUpperCase().indexOf("CIPHER=") > -1) {
boolean goodCheck = false;
Global.getDatabaseUserPassword(), Global.cipherPassword);
}
}
+ // ICHANGED Global.getBehaviorDatabaserUrl()を追加
DatabaseConnection dbConn = new DatabaseConnection(logger,Global.getDatabaseUrl(),
- Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(),
+ Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(), Global.getBehaviorDatabaseUrl(),
Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword, 0);
return dbConn;
}
st.execute("shutdown");
st = conn.getIndexConnection().createStatement();
st.execute("shutdown");
+ // ICHANGED
+ st = conn.getBehaviorConnection().createStatement();
+ st.execute("shutdown");
+
if (QMessageBox.question(this, tr("Are you sure"),
tr("Are you sure you wish to encrypt the database?"),
QMessageBox.StandardButton.Yes,
ChangeFileEncryption.execute(dbPath, "NeverNote", encryptCipher, null, Global.cipherPassword.toCharArray(), true);
ChangeFileEncryption.execute(dbPath, "Resources", encryptCipher, null, Global.cipherPassword.toCharArray(), true);
ChangeFileEncryption.execute(dbPath, "Index", encryptCipher, null, Global.cipherPassword.toCharArray(), true);
+ // ICHANGED
+ ChangeFileEncryption.execute(dbPath, "Behavior", encryptCipher, null, Global.cipherPassword.toCharArray(), true);
+
Global.setDatabaseUrl(Global.getDatabaseUrl() + ";CIPHER="+encryptCipher);
Global.setResourceDatabaseUrl(Global.getResourceDatabaseUrl() + ";CIPHER="+encryptCipher);
Global.setIndexDatabaseUrl(Global.getIndexDatabaseUrl() + ";CIPHER="+encryptCipher);
+ // ICHANGED
+ Global.setBehaviorDatabaseUrl(Global.getBehaviorDatabaseUrl() + ";CIPHER=" + encryptCipher);
QMessageBox.information(this, tr("Encryption Complete"), tr("Encryption is complete"));
}
logger.log(logger.HIGH, "Entering NeverNote.closeEvent");
waitCursor(true);
- if (currentNote!= null & browserWindow!=null) {
- if (currentNote.getTitle() != null && browserWindow != null
+ if (currentNote != null & browserWindow != null) {
+ if (currentNote.getTitle() != null && browserWindow != null
&& !currentNote.getTitle().equals(browserWindow.getTitle()))
- conn.getNoteTable().updateNoteTitle(currentNote.getGuid(), browserWindow.getTitle());
+ conn.getNoteTable().updateNoteTitle(currentNote.getGuid(),
+ browserWindow.getTitle());
}
+
saveNote();
setMessage(tr("Beginning shutdown."));
browser.close();
}
+ // ICHANGED タブブラウザに対してクローズ処理を行う
+ Collection<TabBrowse> win = tabWindows.values();
+ Iterator<TabBrowse> it = win.iterator();
+ tabBrowser.currentChanged.disconnect();
+ tabBrowser.tabCloseRequested.disconnect();
+ while (it.hasNext()) {
+ TabBrowse browser = it.next();
+ browser.close();
+ }
externalFileEditedSaver();
if (Global.isConnected && Global.synchronizeOnClose()) {
@SuppressWarnings("unused")
private void settings() {
logger.log(logger.HIGH, "Entering NeverNote.settings");
+
saveNoteColumnPositions();
saveNoteIndexWidth();
showColumns();
else
trayIcon.hide();
showColumns();
- if (menuBar.showEditorBar.isChecked())
- showEditorButtons(browserWindow);
+ if (menuBar.showEditorBar.isChecked()){
+ // ICHANGED
+ for(int i = 0; i < tabBrowser.count(); i++){
+ BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
+ showEditorButtons(browser);
+ }
+
+ }
// Reset the save timer
if (Global.getAutoSaveInterval() > 0)
restoreState(Global.restoreState(objectName()));
mainLeftRightSplitter.setObjectName("mainLeftRightSplitter");
browserIndexSplitter.setObjectName("browserIndexSplitter");
- leftSplitter1.setObjectName("leftSplitter1");
+ leftSplitter1.setObjectName("leftSplitter1");
+ // ICHANGED
+ rensoNoteListDock.setObjectName("rensoNoteListDock");
// Restore the actual positions.
if (mainWindow)
mainLeftRightSplitter.restoreState(Global.restoreState(mainLeftRightSplitter.objectName()));
browserIndexSplitter.restoreState(Global.restoreState(browserIndexSplitter.objectName()));
leftSplitter1.restoreState(Global.restoreState(leftSplitter1.objectName()));
+ // ICHANGED
+ rensoNoteListDock.restoreGeometry(Global.restoreGeometry(rensoNoteListDock.objectName()));
}
// Save window positions for the next start
Global.saveState(browserIndexSplitter.objectName(), browserIndexSplitter.saveState());
Global.saveState(leftSplitter1.objectName(), leftSplitter1.saveState());
Global.saveState(objectName(), saveState());
+ // ICHANGED
+ Global.saveGeometry(rensoNoteListDock.objectName(), rensoNoteListDock.saveGeometry());
}
// Load the style sheet
private void loadStyleSheet() {
menuBar.notebookShareAction.setEnabled(true);
menuBar.notebookIconAction.setEnabled(true);
menuBar.notebookStackAction.setEnabled(true);
+
+ // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
+ if (!rensoNoteListDock.isEnabled()) {
+ rensoNoteListDock.setEnabled(true);
+ }
+
List<QTreeWidgetItem> selections = notebookTree.selectedItems();
selectedNotebookGUIDs.clear();
String guid = "";
Iterator<String> set = externalWindows.keySet().iterator();
while(set.hasNext())
externalWindows.get(set.next()).getBrowserWindow().setNotebookList(filteredBooks);
+
+ // ICHANGED
+ Iterator<Integer>it = tabWindows.keySet().iterator();
+ while (it.hasNext()) {
+ tabWindows.get(it.next()).getBrowserWindow()
+ .setNotebookList(filteredBooks);
+ }
+
logger.log(logger.HIGH, "Leaving NeverNote.editNotebook");
}
// Publish a notebook
// A note's notebook has been updated
@SuppressWarnings("unused")
private void updateNoteNotebook(String guid, String notebookGuid) {
+ // ICHANGED 同じノートブックに入れられたノート間の履歴を登録
+ conn.getHistoryTable().addSameNotebookHistory(guid, notebookGuid);
// Update the list manager
listManager.updateNoteNotebook(guid, notebookGuid);
while(set.hasNext())
externalWindows.get(set.next()).getBrowserWindow().setNotebookList(filteredBooks);
+ // ICHANGED
+ // 全てのタブウィンドウを更新
+ Iterator<Integer> it = tabWindows.keySet().iterator();
+ while (it.hasNext()) {
+ tabWindows.get(it.next()).getBrowserWindow()
+ .setNotebookList(filteredBooks);
+ }
+
waitCursor(false);
}
// Change the notebook's icon
menuBar.noteRestoreAction.setVisible(false);
+ // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
+ if (!rensoNoteListDock.isEnabled()) {
+ rensoNoteListDock.setEnabled(true);
+ }
+
List<QTreeWidgetItem> selections = tagTree.selectedItems();
QTreeWidgetItem currentSelection;
selectedTagGUIDs.clear();
menuBar.savedSearchEditAction.setEnabled(true);
menuBar.savedSearchDeleteAction.setEnabled(true);
menuBar.savedSearchIconAction.setEnabled(true);
+
+ // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
+ if (!rensoNoteListDock.isEnabled()) {
+ rensoNoteListDock.setEnabled(true);
+ }
+
List<QTreeWidgetItem> selections = savedSearchTree.selectedItems();
QTreeWidgetItem currentSelection;
selectedSavedSearchGUID = "";
logger.log(logger.HIGH, "Entering NeverNote.compactDatabase");
if (QMessageBox.question(this, tr("Confirmation"), tr("This will free unused space in the database, "+
"but please be aware that depending upon the size of your database this can be time consuming " +
- "and NixNote will be unresponsive until it is complete. Do you wish to continue?"),
+ "and NeighborNote will be unresponsive until it is complete. Do you wish to continue?"),
QMessageBox.StandardButton.Yes,
QMessageBox.StandardButton.No)==StandardButton.No.value() && Global.verifyDelete() == true) {
return;
@SuppressWarnings("unused")
private void about() {
logger.log(logger.HIGH, "Entering NeverNote.about");
+ // ICHANGED based on...の記述を付加
QMessageBox.about(this,
- tr("About NixNote"),
- tr("<h4><center><b>NixNote</b></center></h4><hr><center>Version ")
- +Global.version
+ tr("About NeighborNote"),
+ tr("<h4><center><b>NeighborNote</b></center></h4><hr><center>Version ")
+ +Global.version + "(based on NixNote 1.5)"
//+"1.2.120724"
+tr("<hr>"
+"Open Source Evernote Client.<br><br>"
attributeButton = toolBar.addAction(tr("Attributes"));
QIcon attributeIcon = new QIcon(iconPath+"attribute.png");
attributeButton.setIcon(attributeIcon);
- attributeButton.triggered.connect(this, "toggleNoteInformation()");
+ attributeButton.triggered.connect(this, "toggleNoteAttributes()");
toggleAttributeButton(Global.isToolbarButtonVisible("attribute"));
emailButton = toolBar.addAction(tr("Email"));
Global.showDeleted = false;
menuBar.noteRestoreAction.setEnabled(false);
menuBar.noteRestoreAction.setVisible(false);
+ // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
+ rensoNoteListDock.setEnabled(true);
}
else {
trashNoteGuid = tempGuid;
currentNoteGuid = trashNoteGuid;
menuBar.noteRestoreAction.setEnabled(true);
menuBar.noteRestoreAction.setVisible(true);
+ // ICHANGED ゴミ箱を開く。連想ノートリストをOFFに。
+ rensoNoteListDock.setEnabled(false);
+
Global.showDeleted = true;
}
listManager.loadNotesIndex();
listManager.loadNotesIndex();
noteIndexUpdated(false);
+
+ // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
+ if (!rensoNoteListDock.isEnabled()) {
+ rensoNoteListDock.setEnabled(true);
+ }
}
}
// Show/Hide trash window
// clearNotebookFilter();
clearTrashFilter();
// clearSavedSearchFilter();
+
+ // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
+ if (!rensoNoteListDock.isEnabled()) {
+ rensoNoteListDock.setEnabled(true);
+ }
if (attributeTreeSelected == null || item.nativeId() != attributeTreeSelected.nativeId()) {
if (item.childCount() > 0) {
saveNote();
+ // ICHANGED
+ // Ctrlを押しながらノートテーブルを選択した時に選択ノート数0になってしまうのを止める
+ if (noteTableView.selectionModel().selectedRows().size() == 0) {
+ scrollToGuid(currentNoteGuid);
+ return;
+ }
+
+ // ICHANGED
+ // 右クリックだったときの処理
+ if (QApplication.mouseButtons().isSet(MouseButton.RightButton)) {
+ // 選択されたノート(current)のguidをcurrentnoteguidにセット
+ List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
+ if(selections.size() > 0){
+ selectedNoteGUIDs.clear();
+ for(int i = 0; i < selections.size(); i++){
+ int row = selections.get(i).row();
+ QModelIndex index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
+ SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
+ currentNoteGuid = (String) ix.values().toArray()[0];
+ selectedNoteGUIDs.add(currentNoteGuid);
+ }
+ }
+ return;
+ }
+
// If we have more than one selection, then set the merge note action to true.
List<QModelIndex> selections = noteTableView.selectionModel().selectedRows();
if (selections.size() > 1)
// If the ctrl key is pressed, then they are selecting multiple
// entries and we don't want to change the currently viewed note.
+ // ICHANGED
if (QApplication.keyboardModifiers().isSet(KeyboardModifier.ControlModifier) &&
- QApplication.mouseButtons().isSet(MouseButton.LeftButton))
+ QApplication.mouseButtons().isSet(MouseButton.LeftButton)){
+ selectedNoteGUIDs.clear();
+ for (int i=0; i<selections.size(); i++) {
+ int row = selections.get(i).row();
+ QModelIndex index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
+ SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
+ selectedNoteGUIDs.add((String)ix.values().toArray()[0]);
+ }
return;
-
- if (historyGuids.size() == 0) {
+ }
+
+ // ICHANGED たぶんこれは不要
+ // IFIXED ?
+ /*if (historyGuids.size() == 0) {
historyGuids.add(currentNoteGuid);
historyPosition = 1;
- }
+ }*/
+
noteTableView.showColumn(Global.noteTableGuidPosition);
if (!Global.isColumnVisible("guid"))
downButton.setEnabled(false);
index = noteTableView.proxyModel.index(row, Global.noteTableGuidPosition);
SortedMap<Integer, Object> ix = noteTableView.proxyModel.itemData(index);
+
currentNoteGuid = (String)ix.values().toArray()[0];
selectedNoteGUIDs.add(currentNoteGuid);
}
nextButton.setEnabled(true);
prevButton.setEnabled(true);
- if (!fromHistory) {
- int endPosition = historyGuids.size()-1;
- for (int j=historyPosition; j<=endPosition; j++) {
- historyGuids.remove(historyGuids.size()-1);
- }
- historyGuids.add(currentNoteGuid);
- historyPosition = historyGuids.size();
- }
- if (historyPosition <= 1)
- prevButton.setEnabled(false);
- if (historyPosition == historyGuids.size())
- nextButton.setEnabled(false);
-
- fromHistory = false;
+
+ // ICHANGED
+ int currentIndex = tabBrowser.currentIndex();
+ ArrayList<String> histGuids = historyGuids.get(currentIndex);
+ int histPosition = historyPosition.get(currentIndex);
+ boolean fromHist = fromHistory.get(currentIndex);
+
+ // ICHANGED
+ if (!fromHist) {
+ int endPosition = histGuids.size() - 1;
+
+ for (int j = histPosition; j <= endPosition; j++) {
+ histGuids.remove(histGuids.size() - 1);
+ }
+ histGuids.add(currentNoteGuid);
+ historyPosition.put(currentIndex, histGuids.size());
+ histPosition = histGuids.size();
+ }
+ if (histPosition <= 1){
+ prevButton.setEnabled(false);
+ }
+ if (histPosition == histGuids.size())
+ nextButton.setEnabled(false);
+ fromHistory.put(currentIndex, false);
+ fromHist = false;
+
scrollToGuid(currentNoteGuid);
refreshEvernoteNote(true);
- waitCursor(false);
+
+ // ICHANGED
+ if (currentNoteGuid != null && !currentNoteGuid.equals("")) {
+ if (!Global.showDeleted) { // ゴミ箱じゃなければ
+ addBrowseHistory();
+ }
+ }
+
+ // ICHANGED
+ // 連想ノートリストを更新
+ rensoNoteList.refreshRensoNoteList(currentNoteGuid);
+
+ waitCursor(false);
logger.log(logger.HIGH, "Leaving NeverNote.noteTableSelection");
- }
+ }
+
+
+ // ICHANGED
+ // 複数ノートの同時閲覧履歴をデータベースに保存
+ private void addBrowseHistory() {
+ // このノートと他のタブウィンドウノートの関連性を内部データベースのHistoryテーブルに登録
+ if (tabWindows.size() >= 2) {
+ Iterator<Integer> it = tabWindows.keySet().iterator();
+ while (it.hasNext()) {
+ int tabIndex = it.next();
+ String nextGuid = ((TabBrowse) tabBrowser.widget(tabIndex)).getBrowserWindow().getNote().getGuid();
+ // guid1=guid2のデータは登録しない
+ if (!currentNoteGuid.equals(nextGuid)) {
+ conn.getHistoryTable().addHistory("browse", currentNoteGuid, nextGuid);
+ }
+ }
+ }
+ // このノートと他の外部ウィンドウノートの関連性を内部データベースのHistoryテーブルに登録
+ if (externalWindows.size() >= 1) {
+ Iterator<String> it = externalWindows.keySet().iterator();
+ while (it.hasNext()) {
+ String nextGuid = it.next();
+ // guid1=guid2のデータは登録しない
+ if (!currentNoteGuid.equals(nextGuid)) {
+ conn.getHistoryTable().addHistory("browse", currentNoteGuid, nextGuid);
+ }
+ }
+ }
+ }
+
// Trigger a refresh when the note db has been updated
private void noteIndexUpdated(boolean reload) {
logger.log(logger.HIGH, "Entering NeverNote.noteIndexUpdated");
String saveCurrentNoteGuid = new String();
String tempNoteGuid = new String();
-
- historyGuids.clear();
- historyPosition = 0;
+
+ // ICHANGED
+ int currentIndex = tabBrowser.currentIndex();
+ ArrayList<String> histGuids = historyGuids.get(currentIndex);
+ histGuids.clear();
+ historyPosition.put(currentIndex, 0);
+
prevButton.setEnabled(false);
nextButton.setEnabled(false);
logger.log(logger.HIGH, "Leaving NeverNote.refreshEvernoteNoteList");
}
- // Called when the previous arrow button is clicked
- @SuppressWarnings("unused")
+
+ // ICHANGED
+ // Called when the previous arrow button is clicked
+ @SuppressWarnings("unused")
private void previousViewedAction() {
- if (!prevButton.isEnabled())
- return;
- if (historyPosition == 0)
- return;
- historyPosition--;
- if (historyPosition <= 0)
- return;
- String historyGuid = historyGuids.get(historyPosition-1);
- fromHistory = true;
- for (int i=0; i<noteTableView.model().rowCount(); i++) {
- QModelIndex modelIndex = noteTableView.model().index(i, Global.noteTableGuidPosition);
- if (modelIndex != null) {
- SortedMap<Integer, Object> ix = noteTableView.model().itemData(modelIndex);
- String tableGuid = (String)ix.values().toArray()[0];
- if (tableGuid.equals(historyGuid)) {
- noteTableView.selectRow(i);
- return;
- }
- }
- }
- }
+ int currentIndex = tabBrowser.currentIndex();
+ ArrayList<String> histGuids = historyGuids.get(currentIndex);
+ int histPosition = historyPosition.get(currentIndex);
+ boolean fromHist = fromHistory.get(currentIndex);
+ if (!prevButton.isEnabled())
+ return;
+ if (histPosition == 0)
+ return;
+ histPosition--;
+ historyPosition.put(currentIndex, histPosition);
+ if (histPosition <= 0)
+ return;
+ String historyGuid = histGuids.get(histPosition - 1);
+ fromHistory.put(currentIndex, true);
+ fromHist = true;
+ for (int i = 0; i < noteTableView.model().rowCount(); i++) {
+ QModelIndex modelIndex = noteTableView.model().index(i,
+ Global.noteTableGuidPosition);
+ if (modelIndex != null) {
+ SortedMap<Integer, Object> ix = noteTableView.model().itemData(
+ modelIndex);
+ String tableGuid = (String) ix.values().toArray()[0];
+ if (tableGuid.equals(historyGuid)) {
+ noteTableView.selectRow(i);
+ return;
+ }
+ }
+ }
+ }
+
@SuppressWarnings("unused")
private void nextViewedAction() {
if (!nextButton.isEnabled())
return;
- String historyGuid = historyGuids.get(historyPosition);
- historyPosition++;
- fromHistory = true;
- for (int i=0; i<noteTableView.model().rowCount(); i++) {
- QModelIndex modelIndex = noteTableView.model().index(i, Global.noteTableGuidPosition);
- if (modelIndex != null) {
- SortedMap<Integer, Object> ix = noteTableView.model().itemData(modelIndex);
- String tableGuid = (String)ix.values().toArray()[0];
- if (tableGuid.equals(historyGuid)) {
- noteTableView.selectRow(i);
- return;
- }
- }
- }
+ // ICHANGED
+ int currentIndex = tabBrowser.currentIndex();
+ ArrayList<String> histGuids = historyGuids.get(currentIndex);
+ int histPosition = historyPosition.get(currentIndex);
+ boolean fromHist = fromHistory.get(currentIndex);
+ String historyGuid = histGuids.get(histPosition);
+ histPosition++;
+ historyPosition.put(currentIndex, histPosition);
+ fromHistory.put(currentIndex, true);
+ fromHist = true;
+ for (int i = 0; i < noteTableView.model().rowCount(); i++) {
+ QModelIndex modelIndex = noteTableView.model().index(i,
+ Global.noteTableGuidPosition);
+ if (modelIndex != null) {
+ SortedMap<Integer, Object> ix = noteTableView.model().itemData(
+ modelIndex);
+ String tableGuid = (String) ix.values().toArray()[0];
+ if (tableGuid.equals(historyGuid)) {
+ noteTableView.selectRow(i);
+ return;
+ }
+ }
+ }
}
// Called when the up arrow is clicked
@SuppressWarnings("unused")
}
}
}
+
+ // ICHANGED
+ restoreSelectedNoteInfo();
+
logger.log(logger.HIGH, "Leaving NeverNote.titleColorChanged");
}
// A note has been pinned or unpinned
noteTableView.proxyModel.addGuid(selectedNoteGUIDs.get(j), meta);
}
- logger.log(logger.EXTREME, "Leaving NeverNote.setNoteDirty()");
+ // ICHANGED
+ restoreSelectedNoteInfo();
+
+ logger.log(logger.EXTREME, "Leaving NeverNote.notePinned()");
}
// Wide list was chosen
public void narrowListView() {
menuBar.narrowListView.blockSignals(false);
mainLeftRightSplitter.addWidget(noteTableView);
- mainLeftRightSplitter.addWidget(browserWindow);
+ // ICHANGED browserWindow → tabBrowser
+ mainLeftRightSplitter.addWidget(tabBrowser);
+
restoreWindowState(false);
noteTableView.repositionColumns();
noteTableView.resizeColumnWidths();
menuBar.narrowListView.blockSignals(false);
browserIndexSplitter.setVisible(true);
browserIndexSplitter.addWidget(noteTableView);
- browserIndexSplitter.addWidget(browserWindow);
+ // ICHANGED browserWindow → tabBrowser
+ browserIndexSplitter.addWidget(tabBrowser);
+
restoreWindowState(false);
noteTableView.repositionColumns();
noteTableView.resizeColumnWidths();
externalWindows.get(guid).raise();
return;
}
+
Note note = conn.getNoteTable().getNote(guid, true, true, false, true, true);
// We have a new external editor to create
QIcon appIcon = new QIcon(iconPath+"nevernote.png");
- ExternalBrowse newBrowser = new ExternalBrowse(conn);
+ // ICHANGED
+ ExternalBrowse newBrowser = new ExternalBrowse(conn, cbObserver);
+
newBrowser.setWindowIcon(appIcon);
externalWindows.put(guid, newBrowser);
showEditorButtons(newBrowser.getBrowserWindow());
private void externalWindowClosing(String guid) {
externalWindows.remove(guid);
}
-
-
+ // ***************************************************************
+ // ***************************************************************
+ // ** タブウィンドウの機能
+ // ***************************************************************
+ // ***************************************************************
+ @SuppressWarnings("unused")
+ private void openNewTab() {
+ saveNote();
+
+ // selectedNoteGUIDsをディープコピー
+ List<String> copySelected = new ArrayList<String>(selectedNoteGUIDs);
+
+ for (int i=0; i < copySelected.size() ; i++) {
+ openTabEditor(copySelected.get(i));
+ }
+ }
+
+ // ICHANGED 連想ノートリストから新しいタブで開く
+ @SuppressWarnings("unused")
+ private void openNewTabFromRNL(){
+ if(rensoNotePressedItemGuid != null){
+ String prevCurrentNoteGuid = new String(currentNoteGuid);
+
+ saveNote();
+ openTabEditor(rensoNotePressedItemGuid);
+
+ // 連想ノートリストアイテムクリック操作を記録
+ conn.getHistoryTable().addHistory("rensoItemClick", prevCurrentNoteGuid, rensoNotePressedItemGuid);
+ }
+ }
+
+ // ICHANGED
+ private void openTabEditor(String guid) {
+
+ Note note = conn.getNoteTable().getNote(guid, true, true, false, true, true);
+ // 新しいタブエディタを作成
+ TabBrowse newBrowser = new TabBrowse(conn, tabBrowser, cbObserver);
+ showEditorButtons(newBrowser.getBrowserWindow());
+
+ // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断
+ noteTableView.selectionModel().selectionChanged.disconnect(this, "noteTableSelection()");
+ loadNoteBrowserInformation(newBrowser.getBrowserWindow(), guid, note);
+ // 再接続
+ noteTableView.selectionModel().selectionChanged.connect(this, "noteTableSelection()");
+
+ setupBrowserWindowListeners(newBrowser.getBrowserWindow(), false);
+
+ String noteTitle = note.getTitle();
+ int index = tabBrowser.addNewTab(newBrowser, noteTitle);
+ tabWindows.put(index, newBrowser);
+
+ // ExtendedInformationを必要があれば表示する
+ toggleNoteInformation();
+ // Sourceを必要があれば表示する
+ viewSource();
+ // EditorButtonsBarを必要があれば表示する
+ toggleEditorButtonBar();
+
+ // 履歴記録のハッシュマップを初期化
+ ArrayList<String> histGuids = new ArrayList<String>();
+ historyGuids.put(index, histGuids);
+ historyPosition.put(index, 0);
+ fromHistory.put(index, false);
+
+ // 履歴に今開いたノートを追加
+ histGuids.add(guid);
+ historyPosition.put(index, histGuids.size());
+
+ tabBrowser.setCurrentIndex(index);
+
+ if (guid != null && !guid.equals("")) {
+ if (!Global.showDeleted) { // ゴミ箱じゃなければ
+ addBrowseHistory();
+ }
+ }
+ }
+
+ // ICHANGED タブが閉じられた
+ private void tabWindowClosing(int index) {
+ // タブが1つしかなかったら閉じない
+ if (tabBrowser.count() <= 1) {
+ return;
+ }
+
+ TabBrowse t = (TabBrowse) tabBrowser.widget(index);
+ String guid = t.getBrowserWindow().getNote().getGuid();
+ String content = t.getBrowserWindow().getContent();
+ BrowserWindow browser = t.getBrowserWindow();
+ // ノートが変更されていたら保存
+ if (t.getNoteDirty()) {
+ saveNoteTabBrowser(guid, content, true, browser);
+ }
+
+ // シグナル切断
+ browser.noteSignal.tagsChanged.disconnect();
+ browser.noteSignal.titleChanged.disconnect();
+ browser.noteSignal.noteChanged.disconnect();
+ browser.noteSignal.notebookChanged.disconnect();
+ browser.noteSignal.createdDateChanged.disconnect();
+ browser.noteSignal.alteredDateChanged.disconnect();
+
+ // ノートを削除
+ tabWindows.remove(index);
+ tabBrowser.removeTab(index);
+
+ // 履歴記録のハッシュマップを削除
+ historyGuids.remove(index);
+ historyPosition.remove(index);
+ fromHistory.remove(index);
+
+ // タブのインデックスを更新(削除によって空いた部分を詰める)
+ for(int i = index ; tabWindows.containsKey(i + 1) ; i++){
+ // tabWindows
+ TabBrowse tab = tabWindows.get(i + 1);
+ tabWindows.put(i, tab);
+ tabWindows.remove(i + 1);
+ // historyGuids
+ ArrayList<String> histGuids = historyGuids.get(i + 1);
+ historyGuids.put(i, histGuids);
+ historyGuids.remove(i + 1);
+ // historyPosition
+ int histPosition = historyPosition.get(i + 1);
+ historyPosition.put(i, histPosition);
+ historyPosition.remove(i + 1);
+ // fromHistory
+ boolean fromHist = fromHistory.get(i + 1);
+ fromHistory.put(i, fromHist);
+ fromHistory.remove(i + 1);
+ }
+
+ // タブの閉じるボタンを押すと、tabWindowClosingより先にtabWindowChangedが呼ばれてしまうので、手動で呼びなおす
+ tabWindowChanged(tabBrowser.currentIndex());
+ }
+
+ @SuppressWarnings("unused")
+ private void noteAddNewTab() {
+ saveNote();
+
+ // ノート追加前に開いていたノートとの関連性を記録するためにguidをとっておく
+ TabBrowse prevTab = (TabBrowse)tabBrowser.currentWidget();
+ String prevTabGuid = prevTab.getBrowserWindow().getNote().getGuid();
+
+ openEmptyTabEditor();
+ addNote();
+
+ // 追加されたノートのguidを取得し、ノート追加操作履歴としてデータベースに登録
+ TabBrowse addedTab = (TabBrowse)tabBrowser.currentWidget();
+ String addedTabGuid = addedTab.getBrowserWindow().getNote().getGuid();
+ if (prevTabGuid != null && !prevTabGuid.equals("")) {
+ if (addedTabGuid != null && !addedTabGuid.equals("")) {
+ if (!prevTabGuid.equals(addedTabGuid)) {
+ conn.getHistoryTable().addHistory("addNewNote", prevTabGuid, addedTabGuid);
+ }
+ }
+ }
+ }
+
+ // ICHANGED
+ private void openEmptyTabEditor() {
+ // 新しいタブエディタを作成
+ TabBrowse newBrowser = new TabBrowse(conn, tabBrowser, cbObserver);
+ showEditorButtons(newBrowser.getBrowserWindow());
+
+ setupBrowserWindowListeners(newBrowser.getBrowserWindow(), false);
+
+ int index = tabBrowser.addNewTab(newBrowser, "");
+ tabWindows.put(index, newBrowser);
+
+ // ExtendedInformationを必要があれば表示する
+ toggleNoteInformation();
+ // Sourceを必要があれば表示する
+ viewSource();
+ // EditorButtonsBarを必要があれば表示する
+ toggleEditorButtonBar();
+
+ // 履歴記録のハッシュマップを初期化
+ ArrayList<String> histGuids = new ArrayList<String>();
+ historyGuids.put(index, histGuids);
+ historyPosition.put(index, 0);
+ fromHistory.put(index, false);
+
+ tabBrowser.setCurrentIndex(index);
+ }
+
//***************************************************************
//***************************************************************
//** These functions deal with Note specific things
window.getBrowserWindow().setContent(unicode);
}
+ // ICHANGED ↓↓↓ここから↓↓↓
+ // 他のタブで同じノートを開いていないか探す。もしあったら、内容を更新する。
+ Collection<TabBrowse> tabBrowsers = tabWindows.values();
+ Iterator<TabBrowse> tabIterator = tabBrowsers.iterator();
+ Collection<Integer> tabIndexes = tabWindows.keySet();
+ Iterator<Integer> indexIterator = tabIndexes.iterator();
+
+ while (tabIterator.hasNext()) {
+ TabBrowse tab = tabIterator.next();
+ int index = indexIterator.next();
+ String guid = tab.getBrowserWindow().getNote().getGuid();
+
+ QTextCodec codec = QTextCodec.codecForName("UTF-8");
+ QByteArray unicode = codec.fromUnicode(browserWindow.getContent());
+
+ if (guid.equals(currentNoteGuid)) {
+ if (index != tabBrowser.currentIndex()) {
+ TabBrowse window = tabWindows.get(index);
+ window.getBrowserWindow().setContent(unicode);
+ }
+ }
+ }
+ // ICHANGED ↑↑↑ここまで↑↑↑
+
// If the note is dirty, then it is unsynchronized by default.
if (noteDirty)
return;
}
}
+
+ // ICHANGED
+ private void saveNoteTabBrowser(String guid, String content, Boolean save,
+ BrowserWindow browser) {
+ QTextCodec codec = QTextCodec.codecForName("UTF-8");
+ QByteArray unicode = codec.fromUnicode(content);
+ noteCache.remove(guid);
+ noteCache.put(guid, unicode.toString());
+ if (save) {
+ thumbnailRunner.addWork("GENERATE " + guid);
+ saveNote(guid, browser);
+ }
+ }
+
private void saveNote() {
if (noteDirty) {
saveNote(currentNoteGuid, browserWindow);
waitCursor(false);
return;
}
+
+ // ICHANGED
+ tabBrowser.setTabTitle(tabBrowser.currentIndex(), currentNote.getTitle());
+
loadNoteBrowserInformation(browserWindow, currentNoteGuid, currentNote);
}
if (formatter.formatError) {
waitCursor(false);
QMessageBox.information(this, tr("Error"),
- tr("NixNote had issues formatting this note." +
+ tr("NeighborNote had issues formatting this note." +
" To protect your data this note is being marked as read-only."));
waitCursor(true);
}
waitCursor(false);
logger.log(logger.HIGH, "Leaving NeverNote.refreshEvernoteNote");
}
+
+ // ICHANGED
+ @SuppressWarnings("unused")
+ private void toggleNoteAttributes() {
+ menuBar.noteAttributes.setChecked(!menuBar.noteAttributes.isChecked());
+ toggleNoteInformation();
+ }
+
// Save a generated thumbnail
private void toggleNoteInformation() {
logger.log(logger.HIGH, "Entering NeverNote.toggleNoteInformation");
- browserWindow.toggleInformation();
+
+ // ICHANGED
+ boolean isChecked = menuBar.noteAttributes.isChecked();
+
+ for(int i = 0; i < tabBrowser.count(); i++){
+ BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
+ boolean isExtended = browser.isExtended();
+ if((isChecked && !isExtended) || (!isChecked && isExtended)){
+ browser.toggleInformation();
+ }
+ }
+
menuBar.noteAttributes.setChecked(browserWindow.isExtended());
Global.saveWindowVisible("noteInformation", browserWindow.isExtended());
logger.log(logger.HIGH, "Leaving NeverNote.toggleNoteInformation");
}
+
// Listener triggered when a print button is pressed
@SuppressWarnings("unused")
private void printNote() {
if (QMessageBox.question(this, tr("Confirmation"), msg,
QMessageBox.StandardButton.Yes,
QMessageBox.StandardButton.No)==StandardButton.No.value() && Global.verifyDelete() == true) {
+ // ICHANGED
+ restoreSelectedNoteInfo();
+
return;
}
}
if (QMessageBox.question(this, "Confirmation", msg,
QMessageBox.StandardButton.Yes,
QMessageBox.StandardButton.No)==StandardButton.No.value()) {
+ // ICHANGED
+ restoreSelectedNoteInfo();
+
return;
}
}
}
}
listManager.expungeNote(selectedNoteGUIDs.get(i));
+
+ // ICHANGED
+ conn.getHistoryTable().expungeHistory(selectedNoteGUIDs.get(i));
+ conn.getExcludedTable().expungeExcludedNote(selectedNoteGUIDs.get(i));
+ conn.getStaredTable().expungeStaredNote(selectedNoteGUIDs.get(i));
+
}
}
currentNoteGuid = "";
+
+ // ICHANGED ↓↓↓ここから↓↓↓
+ // 削除したノートを外部ウィンドウで開いていたら、閉じる
+ Collection<ExternalBrowse> windows = externalWindows.values();
+ Iterator<ExternalBrowse> windowIterator = windows.iterator();
+ Collection<String> guids = externalWindows.keySet();
+ Iterator<String> guidIterator = guids.iterator();
+ List<ExternalBrowse> closeWindows = new ArrayList<ExternalBrowse>(); // イテレータ操作中に中身をいじっちゃダメなので
+
+ while (windowIterator.hasNext()) {
+ ExternalBrowse browser = windowIterator.next();
+ String guid = guidIterator.next();
+
+ for (int i = 0; i < selectedNoteGUIDs.size(); i++) {
+ if (guid.equals(selectedNoteGUIDs.get(i))) {
+ closeWindows.add(browser);
+ }
+ }
+ }
+
+ for (int i = closeWindows.size() - 1; i >= 0; i--) {
+ closeWindows.get(i).close();
+ }
+ // ICHANGED ↑↑↑ここまで↑↑↑
+
+ // ICHANGED ↓↓↓ここから↓↓↓
+ // 削除したノートをタブで開いていたら、閉じる
+ Collection<TabBrowse> tabBrowsers = tabWindows.values();
+ Iterator<TabBrowse> tabIterator = tabBrowsers.iterator();
+ Collection<Integer> tabIndexes = tabWindows.keySet();
+ Iterator<Integer> indexIterator = tabIndexes.iterator();
+ List<Integer> closeIndexes = new ArrayList<Integer>(); //イテレータ操作中に中身をいじっちゃダメなので
+
+ while (tabIterator.hasNext()) {
+ TabBrowse tab = tabIterator.next();
+ int index = indexIterator.next();
+ String guid = tab.getBrowserWindow().getNote().getGuid();
+
+ for(int i = 0; i < selectedNoteGUIDs.size(); i++){
+ if(guid.equals(selectedNoteGUIDs.get(i))){
+ closeIndexes.add(index);
+ }
+ }
+ }
+
+ for(int i = closeIndexes.size() - 1; i >= 0; i--){
+ tabWindowClosing(closeIndexes.get(i));
+ }
+ // ICHANGED ↑↑↑ここまで↑↑↑
+
+ // ICHANGED
+ restoreSelectedNoteInfo();
+
listManager.loadNotesIndex();
noteIndexUpdated(false);
refreshEvernoteNote(true);
logger.log(logger.HIGH, "Leaving NeverNote.deleteNote");
}
// Add a new note
- @SuppressWarnings("unused")
+ // ICHANGED @SuppressWarnings("unused") を削除
private void addNote() {
logger.log(logger.HIGH, "Inside NeverNote.addNote");
// browserWindow.setEnabled(true);
listManager.addNote(newNote, metadata);
// noteTableView.insertRow(newNote, true, -1);
+ // ICHANGED
+ String prevCurrentNoteGuid = new String(currentNoteGuid);
+
currentNote = newNote;
currentNoteGuid = currentNote.getGuid();
- noteTableView.clearSelection();
+ // IFIXED こいつのせいで、ノート追加時にcurrentNoteGuidが更新されないので消す
+ // noteTableView.clearSelection();
+
refreshEvernoteNote(true);
listManager.countNotebookResults(listManager.getNoteIndex());
browserWindow.titleLabel.setFocus();
browserWindow.titleLabel.selectAll();
// notebookTree.updateCounts(listManager.getNotebookIndex(), listManager.getNotebookCounter());
+ // ICHANGED 新規に作成したノートとそれまで開いていたノートの関連性を追加
+ if (prevCurrentNoteGuid != null && !prevCurrentNoteGuid.equals("")) {
+ if (currentNoteGuid != null && !currentNoteGuid.equals("")) {
+ conn.getHistoryTable().addHistory("addNewNote", prevCurrentNoteGuid, currentNoteGuid);
+ }
+ }
+
// If the window is hidden, then we want to popup this in an external window &
if (!isVisible())
listDoubleClick();
b.getBrowserWindow().getNote().setGuid(newGuid);
externalWindows.put(newGuid, b);
}
+
+ // ICHANGED
+ for(int i = 0; i < tabBrowser.count(); i++){
+ TabBrowse b = (TabBrowse)tabBrowser.widget(i);
+ b.getBrowserWindow().getNote().setGuid(newGuid);
+ }
for (int i=0; i<listManager.getNoteIndex().size(); i++) {
if (listManager.getNoteIndex().get(i).getGuid().equals(newGuid)) {
}
}
+
// Toggle the note editor button bar
+ // ICHANGED すべてのタブに
private void toggleEditorButtonBar() {
- if (browserWindow.buttonsVisible) {
- browserWindow.hideButtons();
- menuBar.showEditorBar.setChecked(browserWindow.buttonsVisible);
-// Global.saveWindowVisible("editorButtonBar", browserWindow.buttonsVisible);
- } else {
- browserWindow.buttonsVisible = true;
- showEditorButtons(browserWindow);
+ boolean isChecked = menuBar.showEditorBar.isChecked();
+
+ for(int i = 0; i < tabBrowser.count(); i++){
+ BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
+ boolean isVisible = browser.buttonsVisible;
+
+ if (isChecked && !isVisible) {
+ browser.buttonsVisible = true;
+ showEditorButtons(browser);
+ } else if(!isChecked && isVisible) {
+ browser.hideButtons();
+ }
}
+
Global.saveWindowVisible("editorButtonBar", browserWindow.buttonsVisible);
}
+
// Show editor buttons
private void showEditorButtons(BrowserWindow browser) {
browser.buttonLayout.setVisible(true);
}
newNote.setResources(resList);
+ // ICHANGED
+ // 操作履歴と除外ノートとスター付きノートも複製する
+ if(Global.getDuplicateRensoNote()) {
+ conn.getHistoryTable().duplicateHistory(newGuid, oldNote.getGuid());
+ conn.getExcludedTable().duplicateExcludedNotes(newGuid, oldNote.getGuid());
+ conn.getStaredTable().duplicateStaredNotes(newGuid, oldNote.getGuid());
+ }
+
// Add note to the database
conn.getNoteTable().addNote(newNote, true);
NoteMetadata metaData = new NoteMetadata();
refreshEvernoteNote(true);
listManager.countNotebookResults(listManager.getNoteIndex());
waitCursor(false);
+
}
// View all notes
@SuppressWarnings("unused")
}
notebookTreeSelection();
refreshEvernoteNote(true);
+
+ // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
+ if (!rensoNoteListDock.isEnabled()) {
+ rensoNoteListDock.setEnabled(true);
+ }
}
// Merge notes
@SuppressWarnings("unused")
logger.log(logger.EXTREME, "Children count: "+sources.size());
mergeNoteContents(masterGuid, sources);
currentNoteGuid = masterGuid;
+
+ // ICHANGED 操作履歴と除外ノートとスター付きノートをマージ
+ if(Global.getMergeRensoNote()) {
+ for (int i = 0; i < sources.size(); i++) {
+ String childGuid = sources.get(i);
+ if(masterGuid != null && childGuid != null) {
+ if(!masterGuid.equals(childGuid)) {
+ conn.getHistoryTable().mergeHistoryGuid(masterGuid, childGuid);
+ conn.getExcludedTable().mergeHistoryGuid(masterGuid, childGuid);
+ conn.getStaredTable().mergeHistoryGuid(masterGuid, childGuid);
+ }
+ }
+ }
+ }
+
+ // ICHANGED ↓↓↓ここから↓↓↓
+ // マージしたノート(child)を外部ウィンドウで開いていたら、閉じる
+ Collection<ExternalBrowse> windows = externalWindows.values();
+ Iterator<ExternalBrowse> windowIterator = windows.iterator();
+ Collection<String> guids = externalWindows.keySet();
+ Iterator<String> guidIterator = guids.iterator();
+ List<ExternalBrowse> closeWindows = new ArrayList<ExternalBrowse>(); // イテレータ操作中に中身をいじっちゃダメなので
+
+ while (windowIterator.hasNext()) {
+ ExternalBrowse browser = windowIterator.next();
+ String guid = guidIterator.next();
+
+ for (int i = 0; i < sources.size(); i++) {
+ if (guid.equals(sources.get(i))) {
+ closeWindows.add(browser);
+ }
+ }
+ }
+
+ for (int i = closeWindows.size() - 1; i >= 0; i--) {
+ closeWindows.get(i).close();
+ }
+ // ICHANGED ↑↑↑ここまで↑↑↑
+
+ // ICHANGED ↓↓↓ここから↓↓↓
+ // マージしたノート(child)をタブで開いていたら、閉じる
+ Collection<TabBrowse> tabBrowsers = tabWindows.values();
+ Iterator<TabBrowse> tabIterator = tabBrowsers.iterator();
+ Collection<Integer> tabIndexes = tabWindows.keySet();
+ Iterator<Integer> indexIterator = tabIndexes.iterator();
+ List<Integer> closeIndexes = new ArrayList<Integer>(); //イテレータ操作中に中身をいじっちゃダメなので
+
+ while (tabIterator.hasNext()) {
+ TabBrowse tab = tabIterator.next();
+ int tabIndex = indexIterator.next();
+ String guid = tab.getBrowserWindow().getNote().getGuid();
+
+ for(int i = 0; i < sources.size(); i++){
+ if(guid.equals(sources.get(i))){
+ closeIndexes.add(tabIndex);
+ }
+ }
+ }
+
+ for(int i = closeIndexes.size() - 1; i >= 0; i--){
+ tabWindowClosing(closeIndexes.get(i));
+ }
+ // ICHANGED ↑↑↑ここまで↑↑↑
+
noteIndexUpdated(false);
+ // IFIXED
+ // ICHANGED マージ後の新しいノートコンテンツを表示するためキャッシュを削除
+ noteCache.remove(masterGuid);
+
refreshEvernoteNote(true);
waitCursor(false);
}
}
}
msg = tr("An error has happened while saving the note \"") +title+
- tr("\".\n\nThis is probably due to a document that is too complex for NixNote to process. "+
+ tr("\".\n\nThis is probably due to a document that is too complex for NeighborNote to process. "+
"As a result, changes to the note may not be saved properly in the database."+
"\n\nA cached copy is being preserved so you can recover any data, but data may" +
"\nbe lost. Please review the note to recover any critical data before restarting.");
// If we've gotten this far, we have a good note.
if (historyWindow == null) {
- historyWindow = new OnlineNoteHistory(logger, conn);
+ // ICHANGED
+ historyWindow = new OnlineNoteHistory(logger, conn, cbObserver);
+
historyWindow.historyCombo.activated.connect(this, "reloadHistoryWindow(String)");
historyWindow.restoreAsNew.clicked.connect(this, "restoreHistoryNoteAsNew()");
historyWindow.restore.clicked.connect(this, "restoreHistoryNote()");
thumbnailRunner.interrupt = true;
indexRunner.addWork("SCAN");
}
- logger.log(logger.EXTREME, "Leaving NixNote index timer");
+ logger.log(logger.EXTREME, "Leaving NeighborNote index timer");
}
@SuppressWarnings("unused")
tagDeadCount++;
if (tagDeadCount > MAX && !disableTagThreadCheck) {
QMessageBox.information(this, tr("A thread has died."), tr("It appears as the tag counter thread has died. I recommend "+
- "checking stopping NixNote, saving the logs for later viewing, and restarting. Sorry."));
+ "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
disableTagThreadCheck = true;
}
} else
notebookThreadDeadCount++;
if (notebookThreadDeadCount > MAX && !disableNotebookThreadCheck) {
QMessageBox.information(this, tr("A thread has died."), tr("It appears as the notebook counter thread has died. I recommend "+
- "checking stopping NixNote, saving the logs for later viewing, and restarting. Sorry."));
+ "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
disableNotebookThreadCheck=true;
}
} else
trashDeadCount++;
if (trashDeadCount > MAX && !disableTrashThreadCheck) {
QMessageBox.information(this, tr("A thread has died."), ("It appears as the trash counter thread has died. I recommend "+
- "checking stopping NixNote, saving the logs for later viewing, and restarting. Sorry."));
+ "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
disableTrashThreadCheck = true;
}
} else
saveThreadDeadCount++;
if (saveThreadDeadCount > MAX && !disableSaveThreadCheck) {
QMessageBox.information(this, tr("A thread has died."), tr("It appears as the note saver thread has died. I recommend "+
- "checking stopping NixNote, saving the logs for later viewing, and restarting. Sorry."));
+ "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
disableSaveThreadCheck = true;
}
} else
syncThreadDeadCount++;
if (syncThreadDeadCount > MAX && !disableSyncThreadCheck) {
QMessageBox.information(this, tr("A thread has died."), tr("It appears as the synchronization thread has died. I recommend "+
- "checking stopping NixNote, saving the logs for later viewing, and restarting. Sorry."));
+ "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
disableSyncThreadCheck = true;
}
} else
indexThreadDeadCount++;
if (indexThreadDeadCount > MAX && !disableIndexThreadCheck) {
QMessageBox.information(this, tr("A thread has died."), tr("It appears as the index thread has died. I recommend "+
- "checking stopping NixNote, saving the logs for later viewing, and restarting. Sorry."));
+ "checking stopping NeighborNote, saving the logs for later viewing, and restarting. Sorry."));
disableIndexThreadCheck = true;
}
} else
//* View / Hide source HTML for a note
//*************************************************
public void viewSource() {
- browserWindow.showSource(menuBar.viewSource.isChecked());
+ // ICHANGED すべてのタブに対して
+ for(int i = 0; i < tabBrowser.count(); i++){
+ BrowserWindow browser = ((TabBrowse) tabBrowser.widget(i)).getBrowserWindow();
+ browser.showSource(menuBar.viewSource.isChecked());
+ }
}
//*************************************************
// Block the program. This is used for things
blockingWindow = null;
blockSignals(false);
}
+
+ // ICHANGED
+ // タブが変更された
+ private void tabWindowChanged(int index) {
+ if (index < 0 || index >= tabBrowser.count()) {
+ return;
+ }
+
+ saveNote();
+
+ TabBrowse tab = (TabBrowse) tabBrowser.widget(index);
+ if (tab.getBrowserWindow().getNote() != null) {
+ currentNoteGuid = tab.getBrowserWindow().getNote().getGuid();
+ currentNote = tab.getBrowserWindow().getNote();
+ } else {
+ currentNoteGuid = "";
+ currentNote = null;
+ }
+
+ // 選択ノートを更新
+ selectedNoteGUIDs.clear();
+ if (currentNoteGuid != null && !currentNoteGuid.equals("")) {
+ selectedNoteGUIDs.add(currentNoteGuid);
+ }
+
+ // browserWindowを更新
+ browserWindow.noteSignal.noteChanged.disconnect(this,"setNoteDirty()");
+ browserWindow.focusLost.disconnect(this, "saveNote()");
+ browserWindow = tab.getBrowserWindow();
+ browserWindow.noteSignal.noteChanged.connect(this, "setNoteDirty()");
+ browserWindow.focusLost.connect(this, "saveNote()");
+ // メニューバーのボタンを新しいbrowserWindowに合わせる
+ menuBar.refreshTargetWindow();
+
+ // 現在ゴミ箱かつ移るタブがアクティブなら通常テーブルに、現在通常テーブルかつこれから非アクティブのタブに移るならゴミ箱を表示させる
+ boolean nextIsActive;
+ if (tab.getBrowserWindow().getNote() != null) {
+ nextIsActive = tab.getBrowserWindow().getNote().isActive();
+ } else {
+ nextIsActive = true;
+ }
+ if (Global.showDeleted && nextIsActive) {
+ switchNoteTable(false);
+ } else if (!Global.showDeleted && !nextIsActive) {
+ switchNoteTable(true);
+ }
+
+ // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断
+ noteTableView.selectionModel().selectionChanged.disconnect(this,"noteTableSelection()");
+ scrollToGuid(currentNoteGuid);
+ // 再接続
+ noteTableView.selectionModel().selectionChanged.connect(this,"noteTableSelection()");
+
+ menuBar.noteDuplicateAction.setEnabled(true);
+ menuBar.noteOnlineHistoryAction.setEnabled(true);
+ menuBar.noteMergeAction.setEnabled(true);
+
+ if (Global.showDeleted) {
+ menuBar.noteDuplicateAction.setEnabled(false);
+ }
+ if (!Global.isConnected) {
+ menuBar.noteOnlineHistoryAction.setEnabled(false);
+ }
+ menuBar.noteMergeAction.setEnabled(false);
+ try {
+ int row = noteTableView.selectionModel().selectedRows().get(0).row();
+ if (row == 0)
+ upButton.setEnabled(false);
+ else
+ upButton.setEnabled(true);
+ if (row < listManager.getNoteTableModel().rowCount() - 1)
+ downButton.setEnabled(true);
+ else
+ downButton.setEnabled(false);
+ } catch (Exception e) {
+ upButton.setEnabled(false);
+ downButton.setEnabled(false);
+ }
+
+ int currentIndex = tabBrowser.currentIndex();
+ ArrayList<String> histGuids = historyGuids.get(currentIndex);
+ int histPosition = historyPosition.get(currentIndex);
+
+ // prev, nextボタンの有効・無効化
+ nextButton.setEnabled(true);
+ prevButton.setEnabled(true);
+
+ if (histPosition <= 1){
+ prevButton.setEnabled(false);
+ }
+ if (histPosition == histGuids.size()){
+ nextButton.setEnabled(false);
+ }
+
+ refreshEvernoteNote(true);
+
+ // 連想ノートリストを更新
+ rensoNoteList.refreshRensoNoteList(currentNoteGuid);
+ }
+
+ // ICHANGD
+ // 生存ノートテーブル→ゴミ箱(またはその逆)に切り替える
+ private void switchNoteTable(boolean toDeleted) {
+ clearNotebookFilter();
+ clearTagFilter();
+ clearAttributeFilter();
+ clearSavedSearchFilter();
+
+ listManager.getSelectedNotebooks().clear();
+ listManager.getSelectedTags().clear();
+ listManager.setSelectedSavedSearch("");
+
+ // toggle the add buttons
+ newButton.setEnabled(!newButton.isEnabled());
+ menuBar.noteAdd.setEnabled(newButton.isEnabled());
+ menuBar.noteAdd.setVisible(true);
+
+ if (!toDeleted) { // 生存ノートテーブルへ
+ trashTree.itemSelectionChanged.disconnect(this, "trashTreeSelection()");
+ trashTree.clearSelection();
+ trashTree.itemSelectionChanged.connect(this, "trashTreeSelection()");
+ Global.showDeleted = false;
+ menuBar.noteRestoreAction.setEnabled(false);
+ menuBar.noteRestoreAction.setVisible(false);
+ // ICHANGED ゴミ箱から元の画面に戻す。連想ノートリストをONに。
+ rensoNoteListDock.setEnabled(true);
+ } else { // ゴミ箱へ
+ trashTree.itemSelectionChanged.disconnect(this, "trashTreeSelection()");
+ trashTree.setCurrentItem(trashTree.getTrashItem());
+ trashTree.itemSelectionChanged.connect(this, "trashTreeSelection()");
+ Global.showDeleted = true;
+ menuBar.noteRestoreAction.setEnabled(true);
+ menuBar.noteRestoreAction.setVisible(true);
+ // ICHANGED ゴミ箱を開く。連想ノートリストをOFFに。
+ rensoNoteListDock.setEnabled(false);
+ }
+
+ listManager.loadNotesIndex();
+ // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断
+ noteTableView.selectionModel().selectionChanged.disconnect(this,"noteTableSelection()");
+ noteIndexUpdated(false);
+ // 再接続
+ noteTableView.selectionModel().selectionChanged.connect(this,"noteTableSelection()");
+
+ browserWindow.setReadOnly(!newButton.isEnabled());
+ }
+
+ // ICHANGED
+ // ユーザが連想ノートリストのアイテムを選択した時の処理
+ @SuppressWarnings("unused")
+ private void rensoNoteItemPressed(QListWidgetItem current) {
+ logger.log(logger.HIGH, "Nevernote.rensoNoteSelectionChangeに入った");
+
+ rensoNotePressedItemGuid = null;
+ // 右クリックだったときの処理
+ if (QApplication.mouseButtons().isSet(MouseButton.RightButton)) {
+ rensoNotePressedItemGuid = rensoNoteList.getNoteGuid(current);
+ return;
+ }
+
+ saveNote();
+
+ String prevCurrentNoteGuid = new String(currentNoteGuid);
+
+ // 選択されたノート(current)のguidをcurrentnoteguidにセット
+ currentNoteGuid = rensoNoteList.getNoteGuid(current);
+
+ // 選択ノートを更新
+ selectedNoteGUIDs.clear();
+ selectedNoteGUIDs.add(currentNoteGuid);
+
+ nextButton.setEnabled(true);
+ prevButton.setEnabled(true);
+
+ int currentIndex = tabBrowser.currentIndex();
+ ArrayList<String> histGuids = historyGuids.get(currentIndex);
+ int histPosition = historyPosition.get(currentIndex);
+ boolean fromHist = fromHistory.get(currentIndex);
+
+ int endPosition = histGuids.size() - 1;
+ for (int j = histPosition; j <= endPosition; j++) {
+ histGuids.remove(histGuids.size() - 1);
+ }
+
+ histGuids.add(currentNoteGuid);
+ historyPosition.put(currentIndex, histGuids.size());
+ histPosition = histGuids.size();
+
+ if (histPosition <= 1)
+ prevButton.setEnabled(false);
+ if (histPosition == histGuids.size())
+ nextButton.setEnabled(false);
+
+ // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断
+ noteTableView.selectionModel().selectionChanged.disconnect(this, "noteTableSelection()");
+ scrollToGuid(currentNoteGuid);
+ // 再接続
+ noteTableView.selectionModel().selectionChanged.connect(this, "noteTableSelection()");
+
+ refreshEvernoteNote(true); // Evernoteからノートをゲット(そしてブラウザに表示)
+
+ // upButton, downButton, 選択リストア用のprevRowを設定
+ int row = noteTableView.selectionModel().selectedRows().get(0).row();
+ if (row == 0)
+ upButton.setEnabled(false);
+ else
+ upButton.setEnabled(true);
+ if (row < listManager.getNoteTableModel().rowCount() - 1)
+ downButton.setEnabled(true);
+ else
+ downButton.setEnabled(false);
+
+ // 連想ノートリストアイテムクリック操作を記録
+ conn.getHistoryTable().addHistory("rensoItemClick", prevCurrentNoteGuid, currentNoteGuid);
+
+ // 連想ノートリストを更新
+ rensoNoteList.refreshRensoNoteList(currentNoteGuid);
+
+ logger.log(logger.HIGH, "Nevernote.rensoNoteSelectionChangeを出た");
+ }
+
+ // ICHANGED
+ public void restoreSelectedNoteInfo(){
+ // 現在のタブからguid取得
+ // currentNoteGuid = browserWindow.getNote().getGuid(); ↓と同じはずだけど敢えて使わない
+ int currentTabIndex = tabBrowser.currentIndex();
+ TabBrowse currentTab = tabWindows.get(currentTabIndex);
+ currentNoteGuid = currentTab.getBrowserWindow().getNote().getGuid();
+
+ selectedNoteGUIDs.clear();
+ selectedNoteGUIDs.add(currentNoteGuid);
+
+ // noteTableViewの選択を変更するとselectionChangedが発生してしまうので一度切断
+ noteTableView.selectionModel().selectionChanged.disconnect(this, "noteTableSelection()");
+ scrollToGuid(currentNoteGuid);
+ // 再接続
+ noteTableView.selectionModel().selectionChanged.connect(this, "noteTableSelection()");
+ }
+
+ // ICHANGED
+ // 関連ノートリストからノートを除外する
+ @SuppressWarnings("unused")
+ private void excludeNote() {
+ if (rensoNotePressedItemGuid != null) {
+ saveNote();
+ excludeNote(rensoNotePressedItemGuid);
+ }
+ }
+
+ // ICHANGED
+ // 関連ノートリストからノートを除外する
+ private void excludeNote(String guid) {
+ if (Global.verifyExclude()) {
+ String msg;
+ Note note = conn.getNoteTable().getNote(guid, false, false, false, false, false);
+ String title = note.getTitle();
+ if (title != null) {
+ msg = new String(tr("Exclude note \"") +title +"\"?");
+ } else {
+ msg = new String(tr("Exclude note selected note?"));
+ }
+
+ if (QMessageBox.question(this, tr("Confirmation"), msg,
+ QMessageBox.StandardButton.Yes,
+ QMessageBox.StandardButton.No)==StandardButton.No.value() && Global.verifyDelete() == true) {
+ return;
+ }
+ }
+
+ // Historyデータベースから除外するノートのデータを削除
+ conn.getHistoryTable().expungeHistory(guid, currentNoteGuid);
+
+ // 除外ノートテーブルに追加
+ conn.getExcludedTable().addExclusion(guid, currentNoteGuid);
+
+ rensoNoteList.refreshRensoNoteList(currentNoteGuid);
+ }
+
+ // ICHANGED
+ // 関連ノートリストのノートにスターを付ける
+ @SuppressWarnings("unused")
+ private void starNote() {
+ if (rensoNotePressedItemGuid != null) {
+ saveNote();
+ starNote(rensoNotePressedItemGuid);
+ }
+ }
+
+ // ICHANGED
+ // 関連ノートリストのノートにスターを付ける
+ private void starNote(String guid) {
+ // スター付きノートテーブルに追加
+ conn.getStaredTable().addStaredItem(currentNoteGuid, guid);
+
+ rensoNoteList.refreshRensoNoteList(currentNoteGuid);
+ }
+
+ // ICHANGED
+ // 関連ノートリストのノートからスターを外す
+ @SuppressWarnings("unused")
+ private void unstarNote() {
+ if (rensoNotePressedItemGuid != null) {
+ saveNote();
+ unstarNote(rensoNotePressedItemGuid);
+ }
+ }
+
+ // ICHANGED
+ // 関連ノートリストのノートからスターを外す
+ private void unstarNote(String guid) {
+ // スター付きノートテーブルから削除
+ conn.getStaredTable().removeStaredItem(currentNoteGuid, guid);
+
+ rensoNoteList.refreshRensoNoteList(currentNoteGuid);
+ }
+
+ // ICHANGED
+ // currentNoteGuidを返す
+ public String getCurrentNoteGuid() {
+ return currentNoteGuid;
+ }
}
private final ConfigAppearancePage appearancePage;\r
private final ConfigSpellPage spellPage;\r
private final ConfigIndexPage indexPage;\r
+ // ICHANGED\r
+ private final ConfigRensoNoteListPage rensoNoteListPage;\r
+ \r
private final String iconPath = new String("classpath:cx/fbn/nevernote/icons/");\r
\r
public ConfigDialog(QWidget parent) {\r
indexPage = new ConfigIndexPage(this);\r
debugPage = new ConfigDebugPage(this);\r
spellPage = new ConfigSpellPage(this);\r
+ // ICHANGED\r
+ rensoNoteListPage = new ConfigRensoNoteListPage(this);\r
+ \r
pagesWidget.addWidget(appearancePage);\r
pagesWidget.addWidget(fontPage);\r
pagesWidget.addWidget(indexPage);\r
pagesWidget.addWidget(spellPage);\r
pagesWidget.addWidget(connectionPage);\r
pagesWidget.addWidget(debugPage);\r
+ // ICHANGED\r
+ pagesWidget.addWidget(rensoNoteListPage);\r
\r
QPushButton cancelButton = new QPushButton(tr("Cancel"));\r
QPushButton okButton = new QPushButton(tr("OK"));\r
Global.setDefaultFont(fontPage.getFont());\r
Global.setDefaultFontSize(fontPage.getFontSize());\r
Global.setDatabaseCache(debugPage.getDatabaseCacheSize());\r
- \r
+ \r
+ // ICHANGED\r
+ Global.setBrowseWeight(rensoNoteListPage.getBrowseWeight());\r
+ Global.setCopyPasteWeight(rensoNoteListPage.getCopyPasteWeight());\r
+ Global.setAddNewNoteWeight(rensoNoteListPage.getAddNewNoteWeight());\r
+ Global.setRensoItemClickWeight(rensoNoteListPage.getRensoItemClickWeight());
+ Global.setSameTagWeight(rensoNoteListPage.getSameTagWeight());
+ Global.setSameNotebookWeight(rensoNoteListPage.getSameNotebookWeight());\r
+ \r
+ // ICHANGED\r
+ Global.setMergeRensoNote(rensoNoteListPage.getMergeChecked());\r
+ Global.setDuplicateRensoNote(rensoNoteListPage.getDuplicateChecked());\r
+ Global.setVerifyExclude(rensoNoteListPage.getVerifyExcludeChecked());\r
+ Global.setRensoListItemMaximum(rensoNoteListPage.getRensoListItemMaximum());\r
+ \r
close();\r
}\r
\r
formatsButton.setText(tr("Appearance"));\r
formatsButton.setTextAlignment(AlignmentFlag.AlignHCenter.value());\r
formatsButton.setFlags(ItemFlag.ItemIsSelectable, ItemFlag.ItemIsEnabled);\r
- formatsButton.setIcon(new QIcon(iconPath+"appearance.jpg"));\r
+ formatsButton.setIcon(new QIcon(iconPath+"appearance.png"));\r
\r
QListWidgetItem fontButton = new QListWidgetItem(contentsWidget);\r
fontButton.setText(tr("Fonts"));\r
debugButton.setFlags(ItemFlag.ItemIsSelectable, ItemFlag.ItemIsEnabled);\r
debugButton.setIcon(new QIcon(iconPath+"debug.jpg"));\r
\r
+ // ICHANGED\r
+ QListWidgetItem rensoListButton = new QListWidgetItem(contentsWidget);\r
+ rensoListButton.setText(tr("Renso Note List"));\r
+ rensoListButton.setTextAlignment(AlignmentFlag.AlignCenter.value());\r
+ rensoListButton.setFlags(ItemFlag.ItemIsSelectable, ItemFlag.ItemIsEnabled);\r
+ rensoListButton.setIcon(new QIcon(iconPath+"rensoNoteList.png"));\r
+ \r
contentsWidget.currentItemChanged.connect(this, "changePage(QListWidgetItem, QListWidgetItem)");\r
}\r
\r
debugPage.setDisableUploads(Global.disableUploads);\r
debugPage.setEnableThumbnails(Global.enableThumbnails());\r
// if (Global.getUpdateSequenceNumber() > 0)\r
- debugPage.serverCombo.setEnabled(false);\r
+ \r
+ // ICHANGED\r
+ // TODO ↓のコメントアウトは最終的に外す(設定のデバッグページのサーバー選択を使用不可にする)\r
+ // debugPage.serverCombo.setEnabled(false);\r
\r
appearancePage.setAutoSaveInterval(Global.getAutoSaveInterval());\r
connectionPage.setAutomaticLogin(Global.automaticLogin());\r
--- /dev/null
+// ICHANGED
+package cx.fbn.nevernote.dialog;
+
+import com.trolltech.qt.core.Qt;
+import com.trolltech.qt.gui.QCheckBox;
+import com.trolltech.qt.gui.QFormLayout;
+import com.trolltech.qt.gui.QGroupBox;
+import com.trolltech.qt.gui.QHBoxLayout;
+import com.trolltech.qt.gui.QSlider;
+import com.trolltech.qt.gui.QSpinBox;
+import com.trolltech.qt.gui.QVBoxLayout;
+import com.trolltech.qt.gui.QWidget;
+
+import cx.fbn.nevernote.Global;
+
+public class ConfigRensoNoteListPage extends QWidget {
+ private final QSlider browseSlider;
+ private final QSlider copyPasteSlider;
+ private final QSlider addNewNoteSlider;
+ private final QSlider rensoItemClickSlider;
+ private final QSlider sameTagSlider;
+ private final QSlider sameNotebookSlider;
+
+ private final QSpinBox browseSpinner;
+ private final QSpinBox copyPasteSpinner;
+ private final QSpinBox addNewNoteSpinner;
+ private final QSpinBox rensoItemClickSpinner;
+ private final QSpinBox sameTagSpinner;
+ private final QSpinBox sameNotebookSpinner;
+ private final QSpinBox rensoListItemMaximumSpinner;
+
+ private final QCheckBox mergeCheck;
+ private final QCheckBox duplicateCheck;
+ private final QCheckBox verifyExclude;
+
+ public ConfigRensoNoteListPage(QWidget parent) {
+ // 操作履歴への重み付け
+ // browseHistory
+ browseSlider = new QSlider();
+ browseSlider.setOrientation(Qt.Orientation.Horizontal);
+ browseSlider.setRange(0, 10);
+ browseSlider.setSingleStep(1);
+ browseSlider.setTickPosition(QSlider.TickPosition.TicksAbove);
+ browseSlider.setTickInterval(1);
+ browseSlider.setFocusPolicy(Qt.FocusPolicy.StrongFocus);
+
+ browseSpinner = new QSpinBox();
+ browseSpinner.setRange(0,10);
+ browseSpinner.setSingleStep(1);
+
+ browseSlider.valueChanged.connect(browseSpinner, "setValue(int)");
+ browseSpinner.valueChanged.connect(browseSlider, "setValue(int)");
+ browseSlider.setValue(Global.getBrowseWeight());
+
+ QHBoxLayout browseLayout = new QHBoxLayout();
+ browseLayout.addWidget(browseSlider);
+ browseLayout.addWidget(browseSpinner);
+
+
+ // copyPasteHistory
+ copyPasteSlider = new QSlider();
+ copyPasteSlider.setOrientation(Qt.Orientation.Horizontal);
+ copyPasteSlider.setRange(0, 10);
+ copyPasteSlider.setSingleStep(1);
+ copyPasteSlider.setTickPosition(QSlider.TickPosition.TicksAbove);
+ copyPasteSlider.setTickInterval(1);
+ copyPasteSlider.setFocusPolicy(Qt.FocusPolicy.StrongFocus);
+
+ copyPasteSpinner = new QSpinBox();
+ copyPasteSpinner.setRange(0,10);
+ copyPasteSpinner.setSingleStep(1);
+
+ copyPasteSlider.valueChanged.connect(copyPasteSpinner, "setValue(int)");
+ copyPasteSpinner.valueChanged.connect(copyPasteSlider, "setValue(int)");
+ copyPasteSlider.setValue(Global.getCopyPasteWeight());
+
+
+ QHBoxLayout copyPasteLayout = new QHBoxLayout();
+ copyPasteLayout.addWidget(copyPasteSlider);
+ copyPasteLayout.addWidget(copyPasteSpinner);
+
+
+ // addNewNoteHistory
+ addNewNoteSlider = new QSlider();
+ addNewNoteSlider.setOrientation(Qt.Orientation.Horizontal);
+ addNewNoteSlider.setRange(0, 10);
+ addNewNoteSlider.setSingleStep(1);
+ addNewNoteSlider.setTickPosition(QSlider.TickPosition.TicksAbove);
+ addNewNoteSlider.setTickInterval(1);
+ addNewNoteSlider.setFocusPolicy(Qt.FocusPolicy.StrongFocus);
+
+ addNewNoteSpinner = new QSpinBox();
+ addNewNoteSpinner.setRange(0,10);
+ addNewNoteSpinner.setSingleStep(1);
+
+ addNewNoteSlider.valueChanged.connect(addNewNoteSpinner, "setValue(int)");
+ addNewNoteSpinner.valueChanged.connect(addNewNoteSlider, "setValue(int)");
+ addNewNoteSlider.setValue(Global.getAddNewNoteWeight());
+
+ QHBoxLayout addNewNoteLayout = new QHBoxLayout();
+ addNewNoteLayout.addWidget(addNewNoteSlider);
+ addNewNoteLayout.addWidget(addNewNoteSpinner);
+
+
+ // rensoItemClickHistory
+ rensoItemClickSlider = new QSlider();
+ rensoItemClickSlider.setOrientation(Qt.Orientation.Horizontal);
+ rensoItemClickSlider.setRange(0, 10);
+ rensoItemClickSlider.setSingleStep(1);
+ rensoItemClickSlider.setTickPosition(QSlider.TickPosition.TicksAbove);
+ rensoItemClickSlider.setTickInterval(1);
+ rensoItemClickSlider.setFocusPolicy(Qt.FocusPolicy.StrongFocus);
+
+ rensoItemClickSpinner = new QSpinBox();
+ rensoItemClickSpinner.setRange(0,10);
+ rensoItemClickSpinner.setSingleStep(1);
+
+ rensoItemClickSlider.valueChanged.connect(rensoItemClickSpinner, "setValue(int)");
+ rensoItemClickSpinner.valueChanged.connect(rensoItemClickSlider, "setValue(int)");
+ rensoItemClickSlider.setValue(Global.getRensoItemClickWeight());
+
+ QHBoxLayout rensoItemClickLayout = new QHBoxLayout();
+ rensoItemClickLayout.addWidget(rensoItemClickSlider);
+ rensoItemClickLayout.addWidget(rensoItemClickSpinner);
+
+ // sameTagHistory
+ sameTagSlider = new QSlider();
+ sameTagSlider.setOrientation(Qt.Orientation.Horizontal);
+ sameTagSlider.setRange(0, 10);
+ sameTagSlider.setSingleStep(1);
+ sameTagSlider.setTickPosition(QSlider.TickPosition.TicksAbove);
+ sameTagSlider.setTickInterval(1);
+ sameTagSlider.setFocusPolicy(Qt.FocusPolicy.StrongFocus);
+
+ sameTagSpinner = new QSpinBox();
+ sameTagSpinner.setRange(0,10);
+ sameTagSpinner.setSingleStep(1);
+
+ sameTagSlider.valueChanged.connect(sameTagSpinner, "setValue(int)");
+ sameTagSpinner.valueChanged.connect(sameTagSlider, "setValue(int)");
+ sameTagSlider.setValue(Global.getSameTagWeight());
+
+ QHBoxLayout sameTagLayout = new QHBoxLayout();
+ sameTagLayout.addWidget(sameTagSlider);
+ sameTagLayout.addWidget(sameTagSpinner);
+
+ // sameNotebookHistory
+ sameNotebookSlider = new QSlider();
+ sameNotebookSlider.setOrientation(Qt.Orientation.Horizontal);
+ sameNotebookSlider.setRange(0, 10);
+ sameNotebookSlider.setSingleStep(1);
+ sameNotebookSlider.setTickPosition(QSlider.TickPosition.TicksAbove);
+ sameNotebookSlider.setTickInterval(1);
+ sameNotebookSlider.setFocusPolicy(Qt.FocusPolicy.StrongFocus);
+
+ sameNotebookSpinner = new QSpinBox();
+ sameNotebookSpinner.setRange(0,10);
+ sameNotebookSpinner.setSingleStep(1);
+
+ sameNotebookSlider.valueChanged.connect(sameNotebookSpinner, "setValue(int)");
+ sameNotebookSpinner.valueChanged.connect(sameNotebookSlider, "setValue(int)");
+ sameNotebookSlider.setValue(Global.getSameNotebookWeight());
+
+ QHBoxLayout sameNotebookLayout = new QHBoxLayout();
+ sameNotebookLayout.addWidget(sameNotebookSlider);
+ sameNotebookLayout.addWidget(sameNotebookSpinner);
+
+ QFormLayout styleLayout = new QFormLayout();
+ styleLayout.setHorizontalSpacing(10);
+ styleLayout.setVerticalSpacing(30);
+ styleLayout.addRow(tr("Browse Weight"), browseLayout);
+ styleLayout.addRow(tr("Copy&Paste Weight"), copyPasteLayout);
+ styleLayout.addRow(tr("Add New Note Weight"), addNewNoteLayout);
+ styleLayout.addRow(tr("Renso Item Click Weight"), rensoItemClickLayout);
+ styleLayout.addRow(tr("Same Tag Weight"), sameTagLayout);
+ styleLayout.addRow(tr("Same Notebook Weight"), sameNotebookLayout);
+
+ QGroupBox weightingGroup = new QGroupBox(tr("Weighting"));
+ weightingGroup.setLayout(styleLayout);
+
+ // ノートのマージ・複製の関連ノートリストへの適用
+ mergeCheck = new QCheckBox(tr("When you merge the notes, also merge RensoNoteList"));
+ mergeCheck.setChecked(Global.getMergeRensoNote());
+ duplicateCheck = new QCheckBox(tr("When you duplicate the notes, also duplicate RensoNoteList"));
+ duplicateCheck.setChecked(Global.getDuplicateRensoNote());
+ verifyExclude = new QCheckBox(tr("Verify when you exclude the note"));
+ verifyExclude.setChecked(Global.verifyExclude());
+
+ // 連想ノートリスト最大アイテム表示数
+ rensoListItemMaximumSpinner = new QSpinBox();
+ rensoListItemMaximumSpinner.setRange(1,100);
+ rensoListItemMaximumSpinner.setSingleStep(1);
+ rensoListItemMaximumSpinner.setValue(Global.getRensoListItemMaximum());
+ QFormLayout fLayout = new QFormLayout();
+ fLayout.setHorizontalSpacing(100);
+ fLayout.addRow(tr("Renso Note List Item Maximum"), rensoListItemMaximumSpinner);
+
+ // その他のレイアウト
+ QVBoxLayout othersLayout = new QVBoxLayout();
+ othersLayout.addWidget(mergeCheck);
+ othersLayout.addWidget(duplicateCheck);
+ othersLayout.addWidget(verifyExclude);
+ othersLayout.addLayout(fLayout);
+
+ QGroupBox othersGroup = new QGroupBox(tr("Others"));
+ othersGroup.setLayout(othersLayout);
+
+ QVBoxLayout mainLayout = new QVBoxLayout();
+ mainLayout.addWidget(weightingGroup);
+ mainLayout.addWidget(othersGroup);
+ mainLayout.addStretch(1);
+ setLayout(mainLayout);
+
+ }
+
+ //*****************************************
+ //* Browse Weight
+ //*****************************************
+ public int getBrowseWeight() {
+ return browseSpinner.value();
+ }
+
+ //*****************************************
+ //* Copy & Paste Weight
+ //*****************************************
+ public int getCopyPasteWeight() {
+ return copyPasteSpinner.value();
+ }
+
+ //*****************************************
+ //* Add New Note Weight
+ //*****************************************
+ public int getAddNewNoteWeight() {
+ return addNewNoteSpinner.value();
+ }
+
+ //*****************************************
+ //* Renso Item Click Weight
+ //*****************************************
+ public int getRensoItemClickWeight() {
+ return rensoItemClickSpinner.value();
+ }
+
+ //*****************************************
+ //* Same Tag Weight
+ //*****************************************
+ public int getSameTagWeight() {
+ return sameTagSpinner.value();
+ }
+
+ //*****************************************
+ //* Same Notebook Weight
+ //*****************************************
+ public int getSameNotebookWeight() {
+ return sameNotebookSpinner.value();
+ }
+
+ //*****************************************
+ //* Merge Check
+ //*****************************************
+ public boolean getMergeChecked() {
+ return mergeCheck.isChecked();
+ }
+
+ //*****************************************
+ //* DuplicateCheck
+ //*****************************************
+ public boolean getDuplicateChecked() {
+ return duplicateCheck.isChecked();
+ }
+
+ //*****************************************
+ //* VerifyExcludeCheck
+ //*****************************************
+ public boolean getVerifyExcludeChecked() {
+ return verifyExclude.isChecked();
+ }
+
+ //*****************************************
+ //* RensoNoteListItemMaximum
+ //*****************************************
+ public int getRensoListItemMaximum() {
+ return rensoListItemMaximumSpinner.value();
+ }
+}
fileCombo.addItem(tr("Index Log"), "IndexLog");\r
fileCombo.addItem(tr("Database Connection Log"), "DatabaseLog");\r
fileCombo.addItem(tr("Thumbnail Generator Log"), "ThumbnailLog");\r
- fileCombo.addItem(tr("NixNote Database SQL Trace File"), "NeverNoteDBLog");\r
+ fileCombo.addItem(tr("NeighborNote Database SQL Trace File"), "NeverNoteDBLog");\r
fileCombo.addItem(tr("Index Database SQL Trace File"), "IndexDBLog");\r
fileCombo.addItem(tr("Resource Database SQL Trace File"), "ResourceDBLog");\r
\r
-/*\r
- * This file is part of NixNote \r
- * Copyright 2011 Randy Baumgarte\r
- * \r
- * This file may be licensed under the terms of of the\r
- * GNU General Public License Version 2 (the ``GPL'').\r
- *\r
- * Software distributed under the License is distributed\r
- * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either\r
- * express or implied. See the GPL for the specific language\r
- * governing rights and limitations.\r
- *\r
- * You should have received a copy of the GPL along with this\r
- * program. If not, go to http://www.gnu.org/licenses/gpl.html\r
- * or write to the Free Software Foundation, Inc.,\r
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
- *\r
-*/\r
-\r
-package cx.fbn.nevernote.dialog;\r
-\r
-//**********************************************\r
-//**********************************************\r
-//* This is the dialog that shows a user\r
-//* a quick popup of a note based upon its title.\r
-//* It is used in the Quick Link function.\r
-//**********************************************\r
-//**********************************************\r
-\r
-import java.util.List;\r
-\r
-import com.evernote.edam.type.Note;\r
-import com.trolltech.qt.core.QByteArray;\r
-import com.trolltech.qt.core.QTemporaryFile;\r
-import com.trolltech.qt.core.Qt.ContextMenuPolicy;\r
-import com.trolltech.qt.gui.QComboBox;\r
-import com.trolltech.qt.gui.QDialog;\r
-import com.trolltech.qt.gui.QHBoxLayout;\r
-import com.trolltech.qt.gui.QIcon;\r
-import com.trolltech.qt.gui.QLabel;\r
-import com.trolltech.qt.gui.QPushButton;\r
-import com.trolltech.qt.gui.QVBoxLayout;\r
-\r
-import cx.fbn.nevernote.gui.BrowserWindow;\r
-import cx.fbn.nevernote.sql.DatabaseConnection;\r
-import cx.fbn.nevernote.utilities.ApplicationLogger;\r
-import cx.fbn.nevernote.utilities.Pair;\r
-import cx.fbn.nevernote.xml.NoteFormatter;\r
-\r
-public class NoteQuickLinkDialog extends QDialog {\r
- public final QPushButton ok;\r
- public final QPushButton cancel;\r
- private final DatabaseConnection conn;\r
- public final QComboBox titleCombo; \r
- private final BrowserWindow browser;\r
- private final ApplicationLogger logger;\r
- List<Pair<String,String>> results;\r
- public boolean okPressed;\r
- private List<QTemporaryFile> tempFiles;\r
- private final String iconPath = new String("classpath:cx/fbn/nevernote/icons/");\r
- \r
- // Constructor\r
- public NoteQuickLinkDialog(ApplicationLogger l, DatabaseConnection c, String text) {\r
- okPressed = false;\r
- setWindowTitle(tr("Quick Link Notes"));\r
- setWindowIcon(new QIcon(iconPath+"notebook-green.png"));\r
- QVBoxLayout main = new QVBoxLayout();\r
- setLayout(main);\r
- titleCombo = new QComboBox(this);\r
- \r
- QHBoxLayout comboLayout = new QHBoxLayout();\r
- comboLayout.addWidget(new QLabel(tr("Matching Notes:")));\r
- comboLayout.addWidget(titleCombo);\r
- comboLayout.addStretch(100);\r
- \r
- main.addLayout(comboLayout);\r
- \r
- conn = c;\r
- browser = new BrowserWindow(conn);\r
- main.addWidget(browser);\r
- browser.titleLabel.setVisible(false);\r
- browser.notebookBox.setVisible(false);\r
- browser.hideButtons();\r
- browser.tagEdit.setVisible(false);\r
- browser.tagLabel.setVisible(false);\r
- \r
- QHBoxLayout buttonLayout = new QHBoxLayout();\r
- buttonLayout.addStretch(100);\r
- ok = new QPushButton(tr("OK"));\r
- ok.clicked.connect(this, "okPressed()");\r
- \r
- cancel = new QPushButton(tr("Cancel"));\r
- cancel.clicked.connect(this, "cancelPressed()");\r
- \r
- buttonLayout.addWidget(ok);\r
- buttonLayout.addWidget(cancel);\r
- main.addLayout(buttonLayout);\r
- \r
- browser.getBrowser().setContextMenuPolicy(ContextMenuPolicy.NoContextMenu);\r
- logger = l;\r
- \r
- // Search for matching notes\r
- results = conn.getNoteTable().findNotesByTitle(text);\r
- \r
- // Add the results to the combo box\r
- for (int i=0; i<results.size(); i++) {\r
- titleCombo.addItem(results.get(i).getSecond(), results.get(i).getFirst());\r
- }\r
- titleCombo.activated.connect(this, "selectionChanged(String)");\r
- \r
- // Load the results into the combo box\r
- if (results.size() > 0) {\r
- Note currentNote = conn.getNoteTable().getNote(results.get(0).getFirst(), true, true, false, true, true);\r
- setContent(currentNote);\r
- }\r
- }\r
-\r
- // Cancel button pressed\r
- @SuppressWarnings("unused")\r
- private void cancelPressed() {\r
- this.close();\r
- }\r
- \r
- // OK button pressed\r
- @SuppressWarnings("unused")\r
- private void okPressed() {\r
- okPressed = true;\r
- close();\r
- }\r
-\r
- // When the selection changes, we refresh the browser window with the new content\r
- @SuppressWarnings("unused")\r
- private void selectionChanged(String text) {\r
- int pos = titleCombo.currentIndex();\r
- String guid = results.get(pos).getFirst();\r
- Note note = conn.getNoteTable().getNote(guid, true, true, false, true, true);\r
- setContent(note);\r
- }\r
- \r
- // Return the note the user is currently viewing\r
- public String getSelectedNote() {\r
- int pos = titleCombo.currentIndex();\r
- return results.get(pos).getFirst();\r
- }\r
- \r
- \r
- // Load the content of the note into the viewing window.\r
- public void setContent(Note currentNote) { \r
- NoteFormatter formatter = new NoteFormatter(logger, conn, tempFiles);\r
- formatter.setNote(currentNote, false);\r
- formatter.setHighlight(null);\r
- formatter.setNoteHistory(true);\r
- \r
- StringBuffer js = new StringBuffer();\r
- \r
- // We need to prepend the note with <HEAD></HEAD> or encoded characters are ugly \r
- js.append("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">"); \r
- js.append("<style type=\"text/css\">en-crypt-temp { border-style:solid; border-color:blue; padding:1mm 1mm 1mm 1mm; }</style>");\r
- js.append("</head>");\r
- js.append(formatter.rebuildNoteHTML());\r
- js.append("</HTML>");\r
- \r
- browser.setNote(currentNote);\r
- browser.setContent(new QByteArray(js.toString()));\r
- }\r
- \r
- // give the results from the DB search back to the caller.\r
- public List<Pair<String,String>> getResults() {\r
- return results;\r
- }\r
- \r
- \r
-}\r
- \r
-\r
-\r
- \r
- \r
- \r
- \r
-\r
+/*
+ * This file is part of NixNote
+ * Copyright 2011 Randy Baumgarte
+ *
+ * This file may be licensed under the terms of of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+*/
+
+package cx.fbn.nevernote.dialog;
+
+//**********************************************
+//**********************************************
+//* This is the dialog that shows a user
+//* a quick popup of a note based upon its title.
+//* It is used in the Quick Link function.
+//**********************************************
+//**********************************************
+
+import java.util.List;
+
+import com.evernote.edam.type.Note;
+import com.trolltech.qt.core.QByteArray;
+import com.trolltech.qt.core.QTemporaryFile;
+import com.trolltech.qt.core.Qt.ContextMenuPolicy;
+import com.trolltech.qt.gui.QComboBox;
+import com.trolltech.qt.gui.QDialog;
+import com.trolltech.qt.gui.QHBoxLayout;
+import com.trolltech.qt.gui.QIcon;
+import com.trolltech.qt.gui.QLabel;
+import com.trolltech.qt.gui.QPushButton;
+import com.trolltech.qt.gui.QVBoxLayout;
+
+import cx.fbn.nevernote.gui.BrowserWindow;
+import cx.fbn.nevernote.neighbornote.ClipBoardObserver;
+import cx.fbn.nevernote.sql.DatabaseConnection;
+import cx.fbn.nevernote.utilities.ApplicationLogger;
+import cx.fbn.nevernote.utilities.Pair;
+import cx.fbn.nevernote.xml.NoteFormatter;
+
+public class NoteQuickLinkDialog extends QDialog {
+ public final QPushButton ok;
+ public final QPushButton cancel;
+ private final DatabaseConnection conn;
+ public final QComboBox titleCombo;
+ private final BrowserWindow browser;
+ private final ApplicationLogger logger;
+ List<Pair<String,String>> results;
+ public boolean okPressed;
+ private List<QTemporaryFile> tempFiles;
+ private final String iconPath = new String("classpath:cx/fbn/nevernote/icons/");
+ // ICHANGED
+ private final ClipBoardObserver cbObserver;
+
+ // ICHANGED 引数にcbObserver追加
+ // Constructor
+ public NoteQuickLinkDialog(ApplicationLogger l, DatabaseConnection c, String text, ClipBoardObserver cbObserver) {
+ okPressed = false;
+ setWindowTitle(tr("Quick Link Notes"));
+ setWindowIcon(new QIcon(iconPath+"notebook-green.png"));
+ QVBoxLayout main = new QVBoxLayout();
+ setLayout(main);
+ titleCombo = new QComboBox(this);
+
+ QHBoxLayout comboLayout = new QHBoxLayout();
+ comboLayout.addWidget(new QLabel(tr("Matching Notes:")));
+ comboLayout.addWidget(titleCombo);
+ comboLayout.addStretch(100);
+
+ main.addLayout(comboLayout);
+
+ conn = c;
+
+ // ICHANGED
+ this.cbObserver = cbObserver;
+ browser = new BrowserWindow(conn, this.cbObserver);
+
+ main.addWidget(browser);
+ browser.titleLabel.setVisible(false);
+ browser.notebookBox.setVisible(false);
+ browser.hideButtons();
+ browser.tagEdit.setVisible(false);
+ browser.tagLabel.setVisible(false);
+
+ QHBoxLayout buttonLayout = new QHBoxLayout();
+ buttonLayout.addStretch(100);
+ ok = new QPushButton(tr("OK"));
+ ok.clicked.connect(this, "okPressed()");
+
+ cancel = new QPushButton(tr("Cancel"));
+ cancel.clicked.connect(this, "cancelPressed()");
+
+ buttonLayout.addWidget(ok);
+ buttonLayout.addWidget(cancel);
+ main.addLayout(buttonLayout);
+
+ browser.getBrowser().setContextMenuPolicy(ContextMenuPolicy.NoContextMenu);
+ logger = l;
+
+ // Search for matching notes
+ results = conn.getNoteTable().findNotesByTitle(text);
+
+ // Add the results to the combo box
+ for (int i=0; i<results.size(); i++) {
+ titleCombo.addItem(results.get(i).getSecond(), results.get(i).getFirst());
+ }
+ titleCombo.activated.connect(this, "selectionChanged(String)");
+
+ // Load the results into the combo box
+ if (results.size() > 0) {
+ Note currentNote = conn.getNoteTable().getNote(results.get(0).getFirst(), true, true, false, true, true);
+ setContent(currentNote);
+ }
+ }
+
+ // Cancel button pressed
+ @SuppressWarnings("unused")
+ private void cancelPressed() {
+ this.close();
+ }
+
+ // OK button pressed
+ @SuppressWarnings("unused")
+ private void okPressed() {
+ okPressed = true;
+ close();
+ }
+
+ // When the selection changes, we refresh the browser window with the new content
+ @SuppressWarnings("unused")
+ private void selectionChanged(String text) {
+ int pos = titleCombo.currentIndex();
+ String guid = results.get(pos).getFirst();
+ Note note = conn.getNoteTable().getNote(guid, true, true, false, true, true);
+ setContent(note);
+ }
+
+ // Return the note the user is currently viewing
+ public String getSelectedNote() {
+ int pos = titleCombo.currentIndex();
+ return results.get(pos).getFirst();
+ }
+
+
+ // Load the content of the note into the viewing window.
+ public void setContent(Note currentNote) {
+ NoteFormatter formatter = new NoteFormatter(logger, conn, tempFiles);
+ formatter.setNote(currentNote, false);
+ formatter.setHighlight(null);
+ formatter.setNoteHistory(true);
+
+ StringBuffer js = new StringBuffer();
+
+ // We need to prepend the note with <HEAD></HEAD> or encoded characters are ugly
+ js.append("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
+ js.append("<style type=\"text/css\">en-crypt-temp { border-style:solid; border-color:blue; padding:1mm 1mm 1mm 1mm; }</style>");
+ js.append("</head>");
+ js.append(formatter.rebuildNoteHTML());
+ js.append("</HTML>");
+
+ browser.setNote(currentNote);
+ browser.setContent(new QByteArray(js.toString()));
+ }
+
+ // give the results from the DB search back to the caller.
+ public List<Pair<String,String>> getResults() {
+ return results;
+ }
+
+
+}
+
+
+
+
+
+
+
+
-/*\r
- * This file is part of NixNote \r
- * Copyright 2009 Randy Baumgarte\r
- * \r
- * This file may be licensed under the terms of of the\r
- * GNU General Public License Version 2 (the ``GPL'').\r
- *\r
- * Software distributed under the License is distributed\r
- * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either\r
- * express or implied. See the GPL for the specific language\r
- * governing rights and limitations.\r
- *\r
- * You should have received a copy of the GPL along with this\r
- * program. If not, go to http://www.gnu.org/licenses/gpl.html\r
- * or write to the Free Software Foundation, Inc.,\r
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
- *\r
-*/\r
-\r
-package cx.fbn.nevernote.dialog;\r
-\r
-//**********************************************\r
-//**********************************************\r
-//* This is the dialog that shows a user\r
-//* the note's history from Evernote.\r
-//**********************************************\r
-//**********************************************\r
-\r
-import java.text.SimpleDateFormat;\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-import com.evernote.edam.notestore.NoteVersionId;\r
-import com.evernote.edam.type.Note;\r
-import com.trolltech.qt.core.QTemporaryFile;\r
-import com.trolltech.qt.core.Qt.ContextMenuPolicy;\r
-import com.trolltech.qt.gui.QComboBox;\r
-import com.trolltech.qt.gui.QDialog;\r
-import com.trolltech.qt.gui.QHBoxLayout;\r
-import com.trolltech.qt.gui.QIcon;\r
-import com.trolltech.qt.gui.QLabel;\r
-import com.trolltech.qt.gui.QPushButton;\r
-import com.trolltech.qt.gui.QVBoxLayout;\r
-\r
-import cx.fbn.nevernote.Global;\r
-import cx.fbn.nevernote.gui.BrowserWindow;\r
-import cx.fbn.nevernote.sql.DatabaseConnection;\r
-import cx.fbn.nevernote.utilities.ApplicationLogger;\r
-import cx.fbn.nevernote.xml.NoteFormatter;\r
-\r
-public class OnlineNoteHistory extends QDialog {\r
- public final QPushButton restoreAsNew;\r
- public final QPushButton restore;\r
- private final DatabaseConnection conn;\r
- public final QComboBox historyCombo; \r
- private final BrowserWindow browser;\r
- private final ApplicationLogger logger;\r
- List<QTemporaryFile> tempFiles;\r
- private final String iconPath = new String("classpath:cx/fbn/nevernote/icons/");\r
- \r
- // Constructor\r
- public OnlineNoteHistory(ApplicationLogger l, DatabaseConnection c) {\r
- setWindowTitle(tr("Online Note History"));\r
- setWindowIcon(new QIcon(iconPath+"notebook-green.png"));\r
- QVBoxLayout main = new QVBoxLayout();\r
- setLayout(main);\r
- historyCombo = new QComboBox(this);\r
- \r
- QHBoxLayout comboLayout = new QHBoxLayout();\r
- comboLayout.addWidget(new QLabel(tr("History Date:")));\r
- comboLayout.addWidget(historyCombo);\r
- comboLayout.addStretch(100);\r
- \r
- main.addLayout(comboLayout);\r
- \r
- conn = c;\r
- browser = new BrowserWindow(conn);\r
- main.addWidget(browser);\r
- browser.titleLabel.setVisible(false);\r
- browser.notebookBox.setVisible(false);\r
- browser.hideButtons();\r
- browser.tagEdit.setVisible(false);\r
- browser.tagLabel.setVisible(false);\r
- \r
- QHBoxLayout buttonLayout = new QHBoxLayout();\r
- buttonLayout.addStretch(100);\r
- restore = new QPushButton(tr("Restore Note"));\r
- restore.clicked.connect(this, "restorePushed()");\r
- \r
- restoreAsNew = new QPushButton(tr("Restore As New Note"));\r
- restoreAsNew.clicked.connect(this, "restoreAsNewPushed()");\r
- QPushButton cancel = new QPushButton(tr("Cancel"));\r
- cancel.clicked.connect(this, "cancelPressed()");\r
- \r
- buttonLayout.addWidget(restore);\r
- buttonLayout.addWidget(restoreAsNew);\r
- buttonLayout.addWidget(cancel);\r
- main.addLayout(buttonLayout);\r
- \r
- browser.getBrowser().setContextMenuPolicy(ContextMenuPolicy.NoContextMenu);\r
- tempFiles = new ArrayList<QTemporaryFile>();\r
- logger = l;\r
- }\r
- \r
- @SuppressWarnings("unused")\r
- private void restoreAsNewPushed() {\r
- this.close();\r
- }\r
- @SuppressWarnings("unused")\r
- private void restorePushed() {\r
- this.close();\r
- }\r
- @SuppressWarnings("unused")\r
- private void cancelPressed() {\r
- this.close();\r
- }\r
- \r
- public void setCurrent(boolean isDirty) {\r
- if (isDirty) \r
- historyCombo.addItem(new String(tr("Current (Non Synchronized)")));\r
- else\r
- historyCombo.addItem(new String(tr("Current (Synchronized)")));\r
- \r
- }\r
- \r
- public void load(List<NoteVersionId> versions) {\r
- String fmt = Global.getDateFormat() + " " + Global.getTimeFormat();\r
- String dateTimeFormat = new String(fmt);\r
- SimpleDateFormat simple = new SimpleDateFormat(dateTimeFormat);\r
- \r
- for (int i=0; i<versions.size(); i++) {\r
- StringBuilder versionDate = new StringBuilder(simple.format(versions.get(i).getSaved()));\r
- historyCombo.addItem(versionDate.toString());\r
- }\r
- }\r
- \r
- public void setContent(Note currentNote) {\r
- \r
- \r
- NoteFormatter formatter = new NoteFormatter(logger, conn, tempFiles);\r
- formatter.setNote(currentNote, false);\r
- formatter.setHighlight(null);\r
- formatter.setNoteHistory(true);\r
- \r
- StringBuffer js = new StringBuffer();\r
- \r
- // We need to prepend the note with <HEAD></HEAD> or encoded characters are ugly \r
- js.append("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">"); \r
- js.append("<style type=\"text/css\">en-crypt-temp { border-style:solid; border-color:blue; padding:1mm 1mm 1mm 1mm; }</style>");\r
- js.append("</head>");\r
- js.append(formatter.rebuildNoteHTML());\r
- js.append("</HTML>");\r
- \r
- browser.setNote(currentNote);\r
- browser.getBrowser().page().mainFrame().setHtml(js.toString());\r
- }\r
-}\r
- \r
-\r
-\r
- \r
- \r
- \r
- \r
-\r
+/*
+ * This file is part of NixNote
+ * Copyright 2009 Randy Baumgarte
+ *
+ * This file may be licensed under the terms of of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+*/
+
+package cx.fbn.nevernote.dialog;
+
+//**********************************************
+//**********************************************
+//* This is the dialog that shows a user
+//* the note's history from Evernote.
+//**********************************************
+//**********************************************
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.evernote.edam.notestore.NoteVersionId;
+import com.evernote.edam.type.Note;
+import com.trolltech.qt.core.QTemporaryFile;
+import com.trolltech.qt.core.Qt.ContextMenuPolicy;
+import com.trolltech.qt.gui.QComboBox;
+import com.trolltech.qt.gui.QDialog;
+import com.trolltech.qt.gui.QHBoxLayout;
+import com.trolltech.qt.gui.QIcon;
+import com.trolltech.qt.gui.QLabel;
+import com.trolltech.qt.gui.QPushButton;
+import com.trolltech.qt.gui.QVBoxLayout;
+
+import cx.fbn.nevernote.Global;
+import cx.fbn.nevernote.gui.BrowserWindow;
+import cx.fbn.nevernote.neighbornote.ClipBoardObserver;
+import cx.fbn.nevernote.sql.DatabaseConnection;
+import cx.fbn.nevernote.utilities.ApplicationLogger;
+import cx.fbn.nevernote.xml.NoteFormatter;
+
+public class OnlineNoteHistory extends QDialog {
+ public final QPushButton restoreAsNew;
+ public final QPushButton restore;
+ private final DatabaseConnection conn;
+ public final QComboBox historyCombo;
+ private final BrowserWindow browser;
+ private final ApplicationLogger logger;
+ List<QTemporaryFile> tempFiles;
+ private final String iconPath = new String("classpath:cx/fbn/nevernote/icons/");
+ // ICHANGED
+ private final ClipBoardObserver cbObserver;
+
+ // ICHANGED 引数にcbObserver追加
+ // Constructor
+ public OnlineNoteHistory(ApplicationLogger l, DatabaseConnection c, ClipBoardObserver cbObserver) {
+ setWindowTitle(tr("Online Note History"));
+ setWindowIcon(new QIcon(iconPath+"notebook-green.png"));
+ QVBoxLayout main = new QVBoxLayout();
+ setLayout(main);
+ historyCombo = new QComboBox(this);
+
+ QHBoxLayout comboLayout = new QHBoxLayout();
+ comboLayout.addWidget(new QLabel(tr("History Date:")));
+ comboLayout.addWidget(historyCombo);
+ comboLayout.addStretch(100);
+
+ main.addLayout(comboLayout);
+
+ conn = c;
+ // ICHANGED
+ this.cbObserver = cbObserver;
+ browser = new BrowserWindow(conn, this.cbObserver);
+
+ main.addWidget(browser);
+ browser.titleLabel.setVisible(false);
+ browser.notebookBox.setVisible(false);
+ browser.hideButtons();
+ browser.tagEdit.setVisible(false);
+ browser.tagLabel.setVisible(false);
+
+ QHBoxLayout buttonLayout = new QHBoxLayout();
+ buttonLayout.addStretch(100);
+ restore = new QPushButton(tr("Restore Note"));
+ restore.clicked.connect(this, "restorePushed()");
+
+ restoreAsNew = new QPushButton(tr("Restore As New Note"));
+ restoreAsNew.clicked.connect(this, "restoreAsNewPushed()");
+ QPushButton cancel = new QPushButton(tr("Cancel"));
+ cancel.clicked.connect(this, "cancelPressed()");
+
+ buttonLayout.addWidget(restore);
+ buttonLayout.addWidget(restoreAsNew);
+ buttonLayout.addWidget(cancel);
+ main.addLayout(buttonLayout);
+
+ browser.getBrowser().setContextMenuPolicy(ContextMenuPolicy.NoContextMenu);
+ tempFiles = new ArrayList<QTemporaryFile>();
+ logger = l;
+ }
+
+ @SuppressWarnings("unused")
+ private void restoreAsNewPushed() {
+ this.close();
+ }
+ @SuppressWarnings("unused")
+ private void restorePushed() {
+ this.close();
+ }
+ @SuppressWarnings("unused")
+ private void cancelPressed() {
+ this.close();
+ }
+
+ public void setCurrent(boolean isDirty) {
+ if (isDirty)
+ historyCombo.addItem(new String(tr("Current (Non Synchronized)")));
+ else
+ historyCombo.addItem(new String(tr("Current (Synchronized)")));
+
+ }
+
+ public void load(List<NoteVersionId> versions) {
+ String fmt = Global.getDateFormat() + " " + Global.getTimeFormat();
+ String dateTimeFormat = new String(fmt);
+ SimpleDateFormat simple = new SimpleDateFormat(dateTimeFormat);
+
+ for (int i=0; i<versions.size(); i++) {
+ StringBuilder versionDate = new StringBuilder(simple.format(versions.get(i).getSaved()));
+ historyCombo.addItem(versionDate.toString());
+ }
+ }
+
+ public void setContent(Note currentNote) {
+
+
+ NoteFormatter formatter = new NoteFormatter(logger, conn, tempFiles);
+ formatter.setNote(currentNote, false);
+ formatter.setHighlight(null);
+ formatter.setNoteHistory(true);
+
+ StringBuffer js = new StringBuffer();
+
+ // We need to prepend the note with <HEAD></HEAD> or encoded characters are ugly
+ js.append("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
+ js.append("<style type=\"text/css\">en-crypt-temp { border-style:solid; border-color:blue; padding:1mm 1mm 1mm 1mm; }</style>");
+ js.append("</head>");
+ js.append(formatter.rebuildNoteHTML());
+ js.append("</HTML>");
+
+ browser.setNote(currentNote);
+ browser.getBrowser().page().mainFrame().setHtml(js.toString());
+ }
+}
+
+
+
+
+
+
+
+
-/*\r
- * This file is part of NixNote \r
- * Copyright 2009 Randy Baumgarte\r
- * \r
- * This file may be licensed under the terms of of the\r
- * GNU General Public License Version 2 (the ``GPL'').\r
- *\r
- * Software distributed under the License is distributed\r
- * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either\r
- * express or implied. See the GPL for the specific language\r
- * governing rights and limitations.\r
- *\r
- * You should have received a copy of the GPL along with this\r
- * program. If not, go to http://www.gnu.org/licenses/gpl.html\r
- * or write to the Free Software Foundation, Inc.,\r
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
- *\r
- */\r
-\r
-package cx.fbn.nevernote.gui;\r
-\r
-import java.io.File;\r
-import java.io.FileNotFoundException;\r
-import java.io.IOException;\r
-import java.net.FileNameMap;\r
-import java.net.URI;\r
-import java.net.URLConnection;\r
-import java.security.MessageDigest;\r
-import java.security.NoSuchAlgorithmException;\r
-import java.text.SimpleDateFormat;\r
-import java.util.ArrayList;\r
-import java.util.Calendar;\r
-import java.util.Collections;\r
-import java.util.Date;\r
-import java.util.GregorianCalendar;\r
-import java.util.HashMap;\r
-import java.util.List;\r
-import java.util.Locale;\r
-import java.util.StringTokenizer;\r
-\r
-import org.apache.commons.lang3.StringEscapeUtils;\r
-import org.apache.commons.lang3.StringUtils;\r
-\r
-import com.evernote.edam.limits.Constants;\r
-import com.evernote.edam.type.Data;\r
-import com.evernote.edam.type.Note;\r
-import com.evernote.edam.type.Notebook;\r
-import com.evernote.edam.type.Resource;\r
-import com.evernote.edam.type.ResourceAttributes;\r
-import com.evernote.edam.type.Tag;\r
-import com.evernote.edam.type.User;\r
-import com.swabunga.spell.engine.Configuration;\r
-import com.swabunga.spell.engine.SpellDictionary;\r
-import com.swabunga.spell.engine.SpellDictionaryHashMap;\r
-import com.swabunga.spell.engine.Word;\r
-import com.swabunga.spell.event.SpellCheckEvent;\r
-import com.swabunga.spell.event.SpellCheckListener;\r
-import com.swabunga.spell.event.SpellChecker;\r
-import com.swabunga.spell.event.StringWordTokenizer;\r
-import com.trolltech.qt.core.QByteArray;\r
-import com.trolltech.qt.core.QCoreApplication;\r
-import com.trolltech.qt.core.QDataStream;\r
-import com.trolltech.qt.core.QDateTime;\r
-import com.trolltech.qt.core.QEvent;\r
-import com.trolltech.qt.core.QEvent.Type;\r
-import com.trolltech.qt.core.QFile;\r
-import com.trolltech.qt.core.QFileSystemWatcher;\r
-import com.trolltech.qt.core.QIODevice;\r
-import com.trolltech.qt.core.QMimeData;\r
-import com.trolltech.qt.core.QTextCodec;\r
-import com.trolltech.qt.core.QTimer;\r
-import com.trolltech.qt.core.QUrl;\r
-import com.trolltech.qt.core.Qt;\r
-import com.trolltech.qt.core.Qt.Key;\r
-import com.trolltech.qt.core.Qt.KeyboardModifier;\r
-import com.trolltech.qt.core.Qt.KeyboardModifiers;\r
-import com.trolltech.qt.gui.QAction;\r
-import com.trolltech.qt.gui.QApplication;\r
-import com.trolltech.qt.gui.QCalendarWidget;\r
-import com.trolltech.qt.gui.QClipboard;\r
-import com.trolltech.qt.gui.QClipboard.Mode;\r
-import com.trolltech.qt.gui.QColor;\r
-import com.trolltech.qt.gui.QComboBox;\r
-import com.trolltech.qt.gui.QDateEdit;\r
-import com.trolltech.qt.gui.QDesktopServices;\r
-import com.trolltech.qt.gui.QFileDialog;\r
-import com.trolltech.qt.gui.QFileDialog.AcceptMode;\r
-import com.trolltech.qt.gui.QFileDialog.FileMode;\r
-import com.trolltech.qt.gui.QFont;\r
-import com.trolltech.qt.gui.QFontDatabase;\r
-import com.trolltech.qt.gui.QFormLayout;\r
-import com.trolltech.qt.gui.QGridLayout;\r
-import com.trolltech.qt.gui.QHBoxLayout;\r
-import com.trolltech.qt.gui.QIcon;\r
-import com.trolltech.qt.gui.QImage;\r
-import com.trolltech.qt.gui.QKeyEvent;\r
-import com.trolltech.qt.gui.QKeySequence;\r
-import com.trolltech.qt.gui.QLabel;\r
-import com.trolltech.qt.gui.QLineEdit;\r
-import com.trolltech.qt.gui.QListWidgetItem;\r
-import com.trolltech.qt.gui.QMatrix;\r
-import com.trolltech.qt.gui.QMessageBox;\r
-import com.trolltech.qt.gui.QPalette;\r
-import com.trolltech.qt.gui.QPalette.ColorRole;\r
-import com.trolltech.qt.gui.QPushButton;\r
-import com.trolltech.qt.gui.QShortcut;\r
-import com.trolltech.qt.gui.QSplitter;\r
-import com.trolltech.qt.gui.QTextEdit;\r
-import com.trolltech.qt.gui.QTextEdit.LineWrapMode;\r
-import com.trolltech.qt.gui.QTimeEdit;\r
-import com.trolltech.qt.gui.QToolButton;\r
-import com.trolltech.qt.gui.QToolButton.ToolButtonPopupMode;\r
-import com.trolltech.qt.gui.QVBoxLayout;\r
-import com.trolltech.qt.gui.QWidget;\r
-import com.trolltech.qt.network.QNetworkAccessManager;\r
-import com.trolltech.qt.network.QNetworkReply;\r
-import com.trolltech.qt.network.QNetworkReply.NetworkError;\r
-import com.trolltech.qt.network.QNetworkRequest;\r
-import com.trolltech.qt.webkit.QWebPage;\r
-import com.trolltech.qt.webkit.QWebPage.WebAction;\r
-import com.trolltech.qt.webkit.QWebSettings;\r
-import com.trolltech.qt.webkit.QWebView;\r
-\r
-import cx.fbn.nevernote.Global;\r
-import cx.fbn.nevernote.dialog.EnCryptDialog;\r
-import cx.fbn.nevernote.dialog.EnDecryptDialog;\r
-import cx.fbn.nevernote.dialog.GeoDialog;\r
-import cx.fbn.nevernote.dialog.InsertLatexImage;\r
-import cx.fbn.nevernote.dialog.InsertLinkDialog;\r
-import cx.fbn.nevernote.dialog.NoteQuickLinkDialog;\r
-import cx.fbn.nevernote.dialog.SpellCheck;\r
-import cx.fbn.nevernote.dialog.TableDialog;\r
-import cx.fbn.nevernote.dialog.TagAssign;\r
-import cx.fbn.nevernote.evernote.EnCrypt;\r
-import cx.fbn.nevernote.filters.FilterEditorTags;\r
-import cx.fbn.nevernote.signals.NoteResourceSignal;\r
-import cx.fbn.nevernote.signals.NoteSignal;\r
-import cx.fbn.nevernote.sql.DatabaseConnection;\r
-import cx.fbn.nevernote.utilities.ApplicationLogger;\r
-import cx.fbn.nevernote.utilities.FileUtils;\r
-import cx.fbn.nevernote.utilities.Pair;\r
-import cx.fbn.nevernote.xml.HtmlTagModifier;\r
-\r
-public class BrowserWindow extends QWidget {\r
-\r
- public final QLineEdit titleLabel;\r
- private final QLineEdit urlText;\r
- private final QLabel authorLabel;\r
- private final QLineEdit authorText;\r
- private final QComboBox geoBox;\r
- public final TagLineEdit tagEdit;\r
- public final QLabel tagLabel;\r
- private final QPushButton urlLabel;\r
- private final QLabel alteredLabel;\r
- private final QDateEdit alteredDate;\r
- private final QTimeEdit alteredTime;\r
- private final QDateEdit createdDate;\r
- private final QTimeEdit createdTime;\r
- private final QLabel subjectLabel;\r
- private final QDateEdit subjectDate;\r
- private final QTimeEdit subjectTime;\r
- public final QComboBox notebookBox;\r
- private final QLabel notebookLabel;\r
- private final QLabel createdLabel;\r
- public final QComboBox fontSize;\r
- public final QAction fontSizeAction;\r
- private boolean extendedOn;\r
- public boolean buttonsVisible;\r
- private final String iconPath;\r
- public final ContentView browser;\r
- private final QTextEdit sourceEdit;\r
- private String sourceEditHeader;\r
- Highlighter syntaxHighlighter;\r
- private List<Tag> allTags;\r
- private List<String> currentTags;\r
- public NoteSignal noteSignal;\r
- public Signal2<String,String> evernoteLinkClicked;\r
- private List<Notebook> notebookList;\r
- private Note currentNote;\r
- private String saveNoteTitle;\r
- private String saveTagList;\r
- private boolean insideList;\r
- private final DatabaseConnection conn;\r
- private final QCalendarWidget createdCalendarWidget;\r
- private final QCalendarWidget alteredCalendarWidget;\r
- private final QCalendarWidget subjectCalendarWidget;\r
-\r
- public final QPushButton undoButton;\r
- public final QAction undoAction;\r
- public final QPushButton redoButton;\r
- public final QAction redoAction;\r
- public final QPushButton cutButton;\r
- public final QAction cutAction;\r
- public final QPushButton copyButton;\r
- public final QAction copyAction;\r
- public final QPushButton pasteButton;\r
- public final QAction pasteAction;\r
- public final QPushButton boldButton;\r
- public final QAction boldAction;\r
- public final QPushButton underlineButton;\r
- public final QAction underlineAction;\r
- public final QPushButton italicButton;\r
- public final QAction italicAction;\r
- public final Signal0 focusLost;\r
- public final NoteResourceSignal resourceSignal;\r
-\r
- public QPushButton rightAlignButton;\r
- public final QAction rightAlignAction;\r
- public QPushButton leftAlignButton;\r
- public final QAction leftAlignAction;\r
- public QPushButton centerAlignButton;\r
- public final QAction centerAlignAction;\r
-\r
- public final QPushButton strikethroughButton;\r
- public final QAction strikethroughAction;\r
- public final QPushButton hlineButton;\r
- public final QAction hlineAction;\r
- public final QPushButton indentButton;\r
- public final QAction indentAction;\r
- public final QPushButton outdentButton;\r
- public final QAction outdentAction;\r
- public final QPushButton bulletListButton;\r
- public final QAction bulletListAction;\r
- public final QPushButton numberListButton;\r
- public final QAction numberListAction;\r
- public final QPushButton spellCheckButton;\r
- public final QAction spellCheckAction;\r
- public final QPushButton todoButton;\r
- public final QAction todoAction;\r
-\r
- public final QShortcut focusTitleShortcut;\r
- public final QShortcut focusTagShortcut;\r
- public final QShortcut focusNoteShortcut;\r
- public final QShortcut focusUrlShortcut;\r
- public final QShortcut focusAuthorShortcut;\r
- \r
- public EditorButtonBar buttonLayout;\r
- public final QComboBox fontList;\r
- public final QAction fontListAction;\r
- public final QToolButton fontColor;\r
- public final QAction fontColorAction;\r
- private final ColorMenu fontColorMenu;\r
- public final QToolButton fontHilight;\r
- public final QAction fontHilightAction;\r
- private final ColorMenu fontHilightColorMenu;\r
- public final QFileSystemWatcher fileWatcher;\r
- public int cursorPosition;\r
- private boolean forceTextPaste;\r
- private String selectedFile;\r
- private String currentHyperlink;\r
- public boolean keepPDFNavigationHidden;\r
- private final ApplicationLogger logger;\r
- SpellDictionary dictionary;\r
- SpellDictionary userDictionary;\r
- SpellChecker spellChecker;\r
- SuggestionListener spellListener;\r
- private final HashMap<String,Integer> previewPageList; \r
- boolean insertHyperlink;\r
- boolean insideTable;\r
- boolean insideEncryption;\r
- public Signal1<BrowserWindow> blockApplication;\r
- public Signal0 unblockApplication;\r
- public boolean awaitingHttpResponse;\r
- public long unblockTime;\r
- private final QTimer setSourceTimer;\r
- String latexGuid; // This is set if we are editing an existing LaTeX formula. Useful to track guid.\r
-\r
- \r
- public static class SuggestionListener implements SpellCheckListener {\r
- public boolean abortSpellCheck = false;\r
- public boolean errorsFound = false;\r
- private final SpellCheck spellCheckDialog;\r
- \r
- \r
- private final BrowserWindow parent;\r
- public SuggestionListener(BrowserWindow parent, SpellChecker checker) {\r
- this.parent = parent;\r
- spellCheckDialog = new SpellCheck(checker);\r
- }\r
- public void spellingError(SpellCheckEvent event) {\r
- errorsFound = true;\r
- spellCheckDialog.setWord(event.getInvalidWord());\r
-\r
- @SuppressWarnings("unchecked")\r
- List<Word> suggestions = event.getSuggestions();\r
- spellCheckDialog.clearSuggestions();\r
- if (!suggestions.isEmpty()) {\r
-// spellCheckDialog.setCurrentSuggestion(suggestions.get(0).getWord());\r
- for (int i=0; i<suggestions.size(); i++) {\r
- spellCheckDialog.addSuggestion(suggestions.get(i).getWord());\r
- }\r
- spellCheckDialog.setSelectedSuggestion(0);\r
- }\r
- spellCheckDialog.exec();\r
- if (spellCheckDialog.cancelPressed()) {\r
- abortSpellCheck = true;\r
- event.cancel();\r
- return;\r
- }\r
- if (spellCheckDialog.replacePressed()) {\r
- QClipboard clipboard = QApplication.clipboard();\r
- clipboard.setText(spellCheckDialog.getReplacementWord()); \r
- parent.pasteClicked();\r
- }\r
- event.cancel();\r
- }\r
- }\r
-\r
- \r
- \r
- public BrowserWindow(DatabaseConnection c) {\r
- logger = new ApplicationLogger("browser.log");\r
- logger.log(logger.HIGH, "Setting up browser");\r
- iconPath = new String("classpath:cx/fbn/nevernote/icons/");\r
- forceTextPaste = false;\r
- insertHyperlink = true;\r
- insideTable = false;\r
- insideEncryption = false;\r
- \r
- fileWatcher = new QFileSystemWatcher();\r
-// fileWatcher.fileChanged.connect(this, "fileChanged(String)");\r
- noteSignal = new NoteSignal();\r
- titleLabel = new QLineEdit();\r
- evernoteLinkClicked = new Signal2<String,String>();\r
- titleLabel.setMaxLength(Constants.EDAM_NOTE_TITLE_LEN_MAX);\r
- urlText = new QLineEdit();\r
- authorText = new QLineEdit();\r
- geoBox = new QComboBox();\r
- urlLabel = new QPushButton();\r
- urlLabel.clicked.connect(this, "sourceUrlClicked()");\r
- authorLabel = new QLabel();\r
- conn = c;\r
- \r
- focusLost = new Signal0();\r
-\r
- tagEdit = new TagLineEdit(allTags);\r
- tagLabel = new QLabel(tr("Tags:"));\r
- tagEdit.focusLost.connect(this, "modifyTagsTyping()");\r
-\r
- createdCalendarWidget = new QCalendarWidget();\r
- createdDate = new QDateEdit();\r
- createdDate.setDisplayFormat(Global.getDateFormat());\r
- createdDate.setCalendarPopup(true);\r
- createdDate.setCalendarWidget(createdCalendarWidget);\r
- createdTime = new QTimeEdit();\r
- createdDate.dateChanged.connect(this, "createdChanged()");\r
- createdTime.timeChanged.connect(this, "createdChanged()");\r
-\r
- alteredCalendarWidget = new QCalendarWidget();\r
- alteredDate = new QDateEdit();\r
- alteredDate.setDisplayFormat(Global.getDateFormat());\r
- alteredDate.setCalendarPopup(true);\r
- alteredDate.setCalendarWidget(alteredCalendarWidget);\r
- alteredTime = new QTimeEdit();\r
- alteredLabel = new QLabel(tr("Altered:"));\r
- alteredDate.dateChanged.connect(this, "alteredChanged()");\r
- alteredTime.timeChanged.connect(this, "alteredChanged()");\r
-\r
- subjectCalendarWidget = new QCalendarWidget();\r
- subjectDate = new QDateEdit();\r
- subjectDate.setDisplayFormat(Global.getDateFormat());\r
- subjectDate.setCalendarPopup(true);\r
- subjectDate.setCalendarWidget(subjectCalendarWidget);\r
- subjectTime = new QTimeEdit();\r
- subjectLabel = new QLabel(tr("Subject Date:"));\r
- subjectDate.dateChanged.connect(this, "subjectDateTimeChanged()");\r
- subjectTime.timeChanged.connect(this, "subjectDateTimeChanged()");\r
- authorText.textChanged.connect(this, "authorChanged()");\r
- urlText.textChanged.connect(this, "sourceUrlChanged()");\r
-\r
- notebookBox = new QComboBox();\r
- notebookLabel = new QLabel(tr("Notebook"));\r
- createdLabel = new QLabel(tr("Created:"));\r
- // selectedText = new String();\r
-\r
- urlLabel.setVisible(false);\r
- urlText.setVisible(false);\r
- authorLabel.setVisible(false);\r
- \r
- geoBox.setVisible(false);\r
- geoBox.addItem(new QIcon(iconPath+"globe.png"), "");\r
- geoBox.addItem(new String(tr("Set")));\r
- geoBox.addItem(new String(tr("Clear")));\r
- geoBox.addItem(new String(tr("View On Map")));\r
- geoBox.activated.connect(this, "geoBoxChanged()");\r
- \r
- authorText.setVisible(false);\r
- createdDate.setVisible(false);\r
- alteredLabel.setVisible(false);\r
- //notebookBox.setVisible(false);\r
- notebookLabel.setVisible(false);\r
- createdLabel.setVisible(false);\r
- createdTime.setVisible(false);\r
- alteredDate.setVisible(false);\r
- alteredTime.setVisible(false);\r
- subjectLabel.setVisible(false);\r
- subjectDate.setVisible(false);\r
- subjectTime.setVisible(false);\r
- extendedOn = false;\r
- buttonsVisible = true;\r
- setAcceptDrops(true);\r
-\r
- browser = new ContentView(this);\r
- \r
- browser.page().setLinkDelegationPolicy(\r
- QWebPage.LinkDelegationPolicy.DelegateAllLinks);\r
- browser.linkClicked.connect(this, "linkClicked(QUrl)");\r
- currentHyperlink = "";\r
- \r
- //Setup the source editor\r
- sourceEdit = new QTextEdit(this);\r
- sourceEdit.setVisible(false);\r
- sourceEdit.setTabChangesFocus(true);\r
- sourceEdit.setLineWrapMode(LineWrapMode.NoWrap);\r
- QFont font = new QFont();\r
- font.setFamily("Courier");\r
- font.setFixedPitch(true);\r
- font.setPointSize(10);\r
- sourceEdit.setFont(font);\r
- syntaxHighlighter = new Highlighter(sourceEdit.document());\r
- sourceEdit.textChanged.connect(this, "sourceEdited()");\r
-\r
- QVBoxLayout v = new QVBoxLayout();\r
- QFormLayout notebookLayout = new QFormLayout();\r
- QGridLayout dateLayout = new QGridLayout();\r
- titleLabel.setReadOnly(false);\r
- titleLabel.editingFinished.connect(this, "titleEdited()");\r
- browser.page().contentsChanged.connect(this, "contentChanged()");\r
- browser.page().selectionChanged.connect(this, "selectionChanged()");\r
- browser.page().mainFrame().javaScriptWindowObjectCleared.connect(this,\r
- "exposeToJavascript()");\r
-\r
- notebookBox.activated.connect(this, "notebookChanged()");\r
- resourceSignal = new NoteResourceSignal();\r
- \r
- QHBoxLayout tagLayout = new QHBoxLayout();\r
- v.addWidget(titleLabel, 0);\r
- notebookLayout.addRow(notebookLabel, notebookBox);\r
- tagLayout.addLayout(notebookLayout, 0);\r
- tagLayout.stretch(4);\r
- tagLayout.addWidget(tagLabel, 0);\r
- tagLayout.addWidget(tagEdit, 1);\r
- v.addLayout(tagLayout);\r
-\r
- QHBoxLayout urlLayout = new QHBoxLayout();\r
- urlLayout.addWidget(urlLabel, 0);\r
- urlLayout.addWidget(urlText, 0);\r
- v.addLayout(urlLayout);\r
-\r
- QHBoxLayout authorLayout = new QHBoxLayout();\r
- authorLayout.addWidget(authorLabel, 0);\r
- authorLayout.addWidget(authorText, 0);\r
- authorLayout.addWidget(geoBox);\r
- v.addLayout(authorLayout);\r
-\r
- dateLayout.addWidget(createdLabel, 0, 0);\r
- dateLayout.addWidget(createdDate, 0, 1);\r
- dateLayout.addWidget(createdTime, 0, 2);\r
- dateLayout.setColumnStretch(9, 100);\r
- dateLayout.addWidget(alteredLabel, 0, 3);\r
- dateLayout.addWidget(alteredDate, 0, 4);\r
- dateLayout.addWidget(alteredTime, 0, 5);\r
- dateLayout.addWidget(subjectLabel, 0, 6);\r
- dateLayout.addWidget(subjectDate, 0, 7);\r
- dateLayout.addWidget(subjectTime, 0, 8);\r
- v.addLayout(dateLayout, 0);\r
-\r
- undoButton = newEditorButton("undo", tr("Undo Change"));\r
- redoButton = newEditorButton("redo", tr("Redo Change"));\r
- cutButton = newEditorButton("cut", tr("Cut"));\r
- copyButton = newEditorButton("copy", tr("Copy"));\r
- pasteButton = newEditorButton("paste", tr("Paste"));\r
- boldButton = newEditorButton("bold", tr("Bold"));\r
- underlineButton = newEditorButton("underline", tr("Underline"));\r
- italicButton = newEditorButton("italic", tr("Italic"));\r
-\r
- rightAlignButton = newEditorButton("justifyRight", tr("Right Align"));\r
- leftAlignButton = newEditorButton("justifyLeft", tr("Left Align"));\r
- centerAlignButton = newEditorButton("justifyCenter", tr("Center Align"));\r
-\r
- strikethroughButton = newEditorButton("strikethrough", tr("Strikethrough"));\r
- hlineButton = newEditorButton("hline", tr("Insert Horizontal Line"));\r
- indentButton = newEditorButton("indent", tr("Shift Right"));\r
- outdentButton = newEditorButton("outdent", tr("Shift Left"));\r
- bulletListButton = newEditorButton("bulletList", tr("Bullet List"));\r
- numberListButton = newEditorButton("numberList", tr("Number List"));\r
- spellCheckButton = newEditorButton("spellCheck", tr("Spell Check"));\r
- todoButton = newEditorButton("todo", tr("To-do"));\r
-\r
- \r
- buttonLayout = new EditorButtonBar();\r
- v.addWidget(buttonLayout);\r
- \r
- undoAction = buttonLayout.addWidget(undoButton);\r
- buttonLayout.toggleUndoVisible.triggered.connect(this, "toggleUndoVisible(Boolean)");\r
- redoAction = buttonLayout.addWidget(redoButton);\r
- buttonLayout.toggleRedoVisible.triggered.connect(this, "toggleRedoVisible(Boolean)");\r
- \r
- buttonLayout.addWidget(newSeparator());\r
- cutAction = buttonLayout.addWidget(cutButton);\r
- buttonLayout.toggleCutVisible.triggered.connect(this, "toggleCutVisible(Boolean)");\r
- copyAction = buttonLayout.addWidget(copyButton);\r
- buttonLayout.toggleCopyVisible.triggered.connect(this, "toggleCopyVisible(Boolean)");\r
- pasteAction = buttonLayout.addWidget(pasteButton);\r
- buttonLayout.togglePasteVisible.triggered.connect(this, "togglePasteVisible(Boolean)");\r
-\r
- buttonLayout.addWidget(newSeparator());\r
- boldAction = buttonLayout.addWidget(boldButton);\r
- buttonLayout.toggleBoldVisible.triggered.connect(this, "toggleBoldVisible(Boolean)");\r
- italicAction = buttonLayout.addWidget(italicButton);\r
- buttonLayout.toggleItalicVisible.triggered.connect(this, "toggleItalicVisible(Boolean)");\r
- underlineAction = buttonLayout.addWidget(underlineButton);\r
- buttonLayout.toggleUnderlineVisible.triggered.connect(this, "toggleUnderlineVisible(Boolean)");\r
- strikethroughAction = buttonLayout.addWidget(strikethroughButton);\r
- buttonLayout.toggleStrikethroughVisible.triggered.connect(this, "toggleStrikethroughVisible(Boolean)");\r
-\r
- \r
- buttonLayout.addWidget(newSeparator());\r
- leftAlignAction = buttonLayout.addWidget(leftAlignButton);\r
- buttonLayout.toggleLeftAlignVisible.triggered.connect(this, "toggleLeftAlignVisible(Boolean)");\r
- centerAlignAction = buttonLayout.addWidget(centerAlignButton);\r
- buttonLayout.toggleCenterAlignVisible.triggered.connect(this, "toggleCenterAlignVisible(Boolean)");\r
- rightAlignAction = buttonLayout.addWidget(rightAlignButton);\r
- buttonLayout.toggleRightAlignVisible.triggered.connect(this, "toggleRightAlignVisible(Boolean)");\r
-\r
- buttonLayout.addWidget(newSeparator());\r
- hlineAction = buttonLayout.addWidget(hlineButton);\r
- buttonLayout.toggleHLineVisible.triggered.connect(this, "toggleHLineVisible(Boolean)");\r
-\r
- indentAction = buttonLayout.addWidget(indentButton);\r
- buttonLayout.toggleIndentVisible.triggered.connect(this, "toggleIndentVisible(Boolean)");\r
- outdentAction = buttonLayout.addWidget(outdentButton);\r
- buttonLayout.toggleOutdentVisible.triggered.connect(this, "toggleOutdentVisible(Boolean)");\r
- bulletListAction = buttonLayout.addWidget(bulletListButton);\r
- buttonLayout.toggleBulletListVisible.triggered.connect(this, "toggleBulletListVisible(Boolean)");\r
- numberListAction = buttonLayout.addWidget(numberListButton);\r
- buttonLayout.toggleNumberListVisible.triggered.connect(this, "toggleNumberListVisible(Boolean)");\r
-\r
- // Setup the font & font size combo boxes\r
- buttonLayout.addWidget(newSeparator());\r
- fontList = new QComboBox();\r
- fontSize = new QComboBox();\r
- fontList.setToolTip("Font");\r
- fontSize.setToolTip("Font Size");\r
- fontList.activated.connect(this, "fontChanged(String)");\r
- fontSize.activated.connect(this, "fontSizeChanged(String)");\r
- fontListAction = buttonLayout.addWidget(fontList);\r
- buttonLayout.toggleFontVisible.triggered.connect(this, "toggleFontListVisible(Boolean)");\r
- fontSizeAction = buttonLayout.addWidget(fontSize);\r
- buttonLayout.toggleFontSizeVisible.triggered.connect(this, "toggleFontSizeVisible(Boolean)");\r
- QFontDatabase fonts = new QFontDatabase();\r
- List<String> fontFamilies = fonts.families();\r
- for (int i = 0; i < fontFamilies.size(); i++) {\r
- fontList.addItem(fontFamilies.get(i));\r
- if (i == 0) {\r
- loadFontSize(fontFamilies.get(i));\r
- }\r
- }\r
-\r
-// buttonLayout.addWidget(newSeparator(), 0);\r
- fontColor = newToolButton("fontColor", tr("Font Color"));\r
- fontColorMenu = new ColorMenu(this);\r
- fontColor.setMenu(fontColorMenu.getMenu());\r
- fontColor.setPopupMode(ToolButtonPopupMode.MenuButtonPopup);\r
- fontColor.setAutoRaise(false);\r
- fontColorMenu.getMenu().triggered.connect(this, "fontColorClicked()");\r
- fontColorAction = buttonLayout.addWidget(fontColor);\r
- buttonLayout.toggleFontColorVisible.triggered.connect(this, "toggleFontColorVisible(Boolean)");\r
- fontHilight = newToolButton("fontHilight", tr("Font Hilight Color"));\r
- fontHilight.setPopupMode(ToolButtonPopupMode.MenuButtonPopup);\r
- fontHilight.setAutoRaise(false);\r
- fontHilightColorMenu = new ColorMenu(this);\r
- fontHilightColorMenu.setDefault(QColor.yellow);\r
- fontHilight.setMenu(fontHilightColorMenu.getMenu());\r
- fontHilightColorMenu.getMenu().triggered.connect(this, "fontHilightClicked()");\r
- fontHilightAction = buttonLayout.addWidget(fontHilight);\r
- fontHilightColorMenu.setDefault(QColor.yellow);\r
- buttonLayout.toggleFontHilight.triggered.connect(this, "toggleFontHilightVisible(Boolean)");\r
- \r
- spellCheckAction = buttonLayout.addWidget(spellCheckButton);\r
- buttonLayout.toggleNumberListVisible.triggered.connect(this, "spellCheckClicked()");\r
- buttonLayout.toggleSpellCheck.triggered.connect(this, "toggleSpellCheckVisible(Boolean)");\r
- \r
- todoAction = buttonLayout.addWidget(todoButton);\r
- buttonLayout.toggleNumberListVisible.triggered.connect(this, "todoClicked()");\r
- buttonLayout.toggleTodo.triggered.connect(this, "toggleTodoVisible(Boolean)");\r
-\r
- // Setup the source browser);\r
-\r
-// buttonLayout.addWidget(new QLabel(), 1);\r
- QSplitter editSplitter = new QSplitter(this);\r
- editSplitter.addWidget(browser);\r
- editSplitter.setOrientation(Qt.Orientation.Vertical);\r
- editSplitter.addWidget(sourceEdit);\r
-\r
- \r
-\r
-// v.addWidget(browser, 1);\r
-// v.addWidget(sourceEdit);\r
- v.addWidget(editSplitter);\r
- setLayout(v);\r
-\r
- browser.downloadAttachmentRequested.connect(this,\r
- "downloadAttachment(QNetworkRequest)");\r
- browser.downloadImageRequested.connect(this,\r
- "downloadImage(QNetworkRequest)");\r
- setTabOrder(notebookBox, tagEdit);\r
- setTabOrder(tagEdit, browser);\r
- \r
- focusNoteShortcut = new QShortcut(this);\r
- setupShortcut(focusNoteShortcut, "Focus_Note");\r
- focusNoteShortcut.activated.connect(this, "focusNote()");\r
- focusTitleShortcut = new QShortcut(this);\r
- setupShortcut(focusTitleShortcut, "Focus_Title");\r
- focusTitleShortcut.activated.connect(this, "focusTitle()");\r
- focusTagShortcut = new QShortcut(this);\r
- setupShortcut(focusTagShortcut, "Focus_Tag");\r
- focusTagShortcut.activated.connect(this, "focusTag()");\r
- focusAuthorShortcut = new QShortcut(this);\r
- setupShortcut(focusAuthorShortcut, "Focus_Author");\r
- focusAuthorShortcut.activated.connect(this, "focusAuthor()");\r
- focusUrlShortcut = new QShortcut(this);\r
- setupShortcut(focusUrlShortcut, "Focus_Url");\r
- focusUrlShortcut.activated.connect(this, "focusUrl()");\r
- \r
- browser.page().mainFrame().setTextSizeMultiplier(Global.getTextSizeMultiplier());\r
- browser.page().mainFrame().setZoomFactor(Global.getZoomFactor());\r
- \r
- previewPageList = new HashMap<String,Integer>();\r
- \r
- browser.page().microFocusChanged.connect(this, "microFocusChanged()");\r
- \r
- //Setup colors\r
- \r
- QPalette pal = new QPalette();\r
- pal.setColor(ColorRole.Text, QColor.black);\r
- titleLabel.setPalette(pal);\r
- authorText.setPalette(pal);\r
- authorLabel.setPalette(pal);\r
- urlLabel.setPalette(pal);\r
- urlText.setPalette(pal);\r
- createdDate.setPalette(pal);\r
- createdTime.setPalette(pal);\r
- alteredDate.setPalette(pal);\r
- alteredTime.setPalette(pal);\r
- subjectDate.setPalette(pal);\r
- subjectTime.setPalette(pal);\r
- tagEdit.setPalette(pal);\r
- notebookBox.setPalette(pal);\r
- \r
- blockApplication = new Signal1<BrowserWindow>();\r
- unblockApplication = new Signal0();\r
- \r
- setSourceTimer = new QTimer();\r
- setSourceTimer.timeout.connect(this, "setSource()");\r
- \r
- logger.log(logger.HIGH, "Browser setup complete");\r
- }\r
-\r
- \r
- \r
- private void setupShortcut(QShortcut action, String text) {\r
- if (!Global.shortcutKeys.containsAction(text))\r
- return;\r
- action.setKey(new QKeySequence(Global.shortcutKeys.getShortcut(text)));\r
- }\r
- \r
- \r
-\r
- \r
- // Getter for the QWebView\r
- public QWebView getBrowser() {\r
- return browser;\r
- }\r
-\r
- // Block signals while loading data or things are flagged as dirty by\r
- // mistake\r
- public void loadingData(boolean val) {\r
- logger.log(logger.EXTREME, "Entering BrowserWindow.loadingData() " +val);\r
- notebookBox.blockSignals(val);\r
- browser.page().blockSignals(val);\r
- browser.page().mainFrame().blockSignals(val);\r
- titleLabel.blockSignals(val);\r
- alteredDate.blockSignals(val);\r
- alteredTime.blockSignals(val);\r
- createdTime.blockSignals(val);\r
- createdDate.blockSignals(val);\r
- subjectDate.blockSignals(val);\r
- subjectTime.blockSignals(val);\r
- urlText.blockSignals(val);\r
- authorText.blockSignals(val);\r
- if (!val)\r
- exposeToJavascript();\r
- logger.log(logger.EXTREME, "Exiting BrowserWindow.loadingData() " +val);\r
- }\r
-\r
- // Enable/disable\r
- public void setReadOnly(boolean v) {\r
- setEnabled(true);\r
- titleLabel.setEnabled(!v);\r
- notebookBox.setEnabled(!v);\r
- tagEdit.setEnabled(!v);\r
- authorLabel.setEnabled(!v);\r
- geoBox.setEnabled(!v);\r
- urlText.setEnabled(!v);\r
- createdDate.setEnabled(!v);\r
- subjectDate.setEnabled(!v);\r
- alteredDate.setEnabled(!v);\r
- authorText.setEnabled(!v);\r
- createdTime.setEnabled(!v);\r
- alteredTime.setEnabled(!v);\r
- subjectTime.setEnabled(!v);\r
- getBrowser().setEnabled(true);\r
- getBrowser().page().setContentEditable(!v);\r
-// getBrowser().setEnabled(!v);\r
- }\r
- \r
- // expose this class to Javascript on the web page\r
- private void exposeToJavascript() {\r
- browser.page().mainFrame().addToJavaScriptWindowObject("jambi", this);\r
- }\r
-\r
- // Custom event queue\r
- @Override\r
- public boolean event(QEvent e) {\r
- if (e.type().equals(QEvent.Type.FocusOut)) {\r
- logger.log(logger.EXTREME, "Focus lost");\r
- focusLost.emit();\r
- }\r
- return super.event(e);\r
- }\r
-\r
- // clear out browser\r
- public void clear() {\r
- logger.log(logger.EXTREME, "Entering BrowserWindow.clear()");\r
- setNote(null);\r
- setContent(new QByteArray());\r
- tagEdit.setText("");\r
- tagEdit.tagCompleter.reset();\r
- urlLabel.setText(tr("Source URL:"));\r
- titleLabel.setText("");\r
- logger.log(logger.EXTREME, "Exiting BrowserWindow.clear()");\r
- }\r
-\r
- public void setContent(QByteArray data) {\r
- sourceEdit.blockSignals(true);\r
- browser.setContent(data);\r
- setSource();\r
- }\r
- // get/set current note\r
- public void setNote(Note n) {\r
- currentNote = n;\r
- if (n == null)\r
- n = new Note();\r
- saveNoteTitle = n.getTitle();\r
-\r
- }\r
-\r
- public Note getNote() {\r
- return currentNote;\r
- }\r
-\r
- // New Editor Button\r
- private QPushButton newEditorButton(String name, String toolTip) {\r
- QPushButton button = new QPushButton();\r
-// QIcon icon = new QIcon(iconPath + name + ".gif");\r
- QIcon icon = new QIcon(iconPath + name + ".png");\r
- button.setIcon(icon);\r
- button.setToolTip(toolTip);\r
- button.clicked.connect(this, name + "Clicked()");\r
- return button;\r
- }\r
- // New Editor Button\r
- private QToolButton newToolButton(String name, String toolTip) {\r
- QToolButton button = new QToolButton();\r
-// QIcon icon = new QIcon(iconPath + name + ".gif");\r
- QIcon icon = new QIcon(iconPath + name + ".png");\r
- button.setIcon(icon);\r
- button.setToolTip(toolTip);\r
- button.clicked.connect(this, name + "Clicked()");\r
- return button;\r
- }\r
-\r
- // New Separator\r
- private QLabel newSeparator() {\r
- return new QLabel(" ");\r
- }\r
-\r
- // Set the title in the window\r
- public void setTitle(String t) {\r
- titleLabel.setText(t);\r
- saveNoteTitle = t;\r
- checkNoteTitle();\r
- }\r
-\r
- // Return the current text title\r
- public String getTitle() {\r
- return titleLabel.text();\r
- }\r
-\r
- // Set the tag name string\r
- public void setTag(String t) {\r
- saveTagList = t;\r
- tagEdit.setText(t);\r
- tagEdit.tagCompleter.reset();\r
- }\r
-\r
- // Set the source URL\r
- public void setUrl(String t) {\r
- urlLabel.setText(tr("Source URL:\t"));\r
- urlText.setText(t);\r
- }\r
-\r
- // The user want's to launch a web browser on the source of the URL\r
- public void sourceUrlClicked() {\r
- // Make sure we have a valid URL\r
- if (urlText.text().trim().equals(""))\r
- return;\r
- \r
- String url = urlText.text();\r
- if (!url.toLowerCase().startsWith(tr("http://")))\r
- url = tr("http://") +url;\r
- \r
- if (!QDesktopServices.openUrl(new QUrl(url))) {\r
- logger.log(logger.LOW, "Error opening file :" +url);\r
- }\r
- }\r
- \r
- public void setAuthor(String t) {\r
- authorLabel.setText(tr("Author:\t"));\r
- authorText.setText(t);\r
- }\r
-\r
- // Set the creation date\r
- public void setCreation(long date) {\r
- QDateTime dt = new QDateTime();\r
- dt.setTime_t((int) (date / 1000));\r
- createdDate.setDateTime(dt);\r
- createdTime.setDateTime(dt);\r
- createdDate.setDisplayFormat(Global.getDateFormat());\r
- createdTime.setDisplayFormat(Global.getTimeFormat());\r
- }\r
-\r
- // Set the creation date\r
- public void setAltered(long date) {\r
- QDateTime dt = new QDateTime();\r
- dt.setTime_t((int) (date / 1000));\r
- alteredDate.setDateTime(dt);\r
- alteredTime.setDateTime(dt);\r
- alteredDate.setDisplayFormat(Global.getDateFormat());\r
- alteredTime.setDisplayFormat(Global.getTimeFormat());\r
- }\r
-\r
- // Set the subject date\r
- public void setSubjectDate(long date) {\r
- QDateTime dt = new QDateTime();\r
- dt.setTime_t((int) (date / 1000));\r
- subjectDate.setDateTime(dt);\r
- subjectTime.setDateTime(dt);\r
- subjectDate.setDisplayFormat(Global.getDateFormat());\r
- subjectTime.setDisplayFormat(Global.getTimeFormat());\r
- }\r
-\r
- // Toggle the extended attribute information\r
- public void toggleInformation() {\r
- if (extendedOn) {\r
- extendedOn = false;\r
- } else {\r
- extendedOn = true;\r
- }\r
- urlLabel.setVisible(extendedOn);\r
- urlText.setVisible(extendedOn);\r
- authorText.setVisible(extendedOn);\r
- geoBox.setVisible(extendedOn);\r
- authorLabel.setVisible(extendedOn);\r
- createdDate.setVisible(extendedOn);\r
- createdTime.setVisible(extendedOn);\r
- createdLabel.setVisible(extendedOn);\r
- alteredLabel.setVisible(extendedOn);\r
- alteredDate.setVisible(extendedOn);\r
- alteredTime.setVisible(extendedOn);\r
- //notebookBox.setVisible(extendedOn);\r
- notebookLabel.setVisible(extendedOn);\r
- subjectLabel.setVisible(extendedOn);\r
- subjectDate.setVisible(extendedOn);\r
- subjectTime.setVisible(extendedOn);\r
- }\r
-\r
- public void hideButtons() {\r
-\r
- undoButton.parentWidget().setVisible(false);\r
- buttonsVisible = false;\r
- }\r
-\r
-\r
- // Is the extended view on?\r
- public boolean isExtended() {\r
- return extendedOn;\r
- }\r
-\r
- // Listener for when a link is clicked\r
- @SuppressWarnings("unused")\r
- private void openFile() {\r
- logger.log(logger.EXTREME, "Starting openFile()");\r
- File fileHandle = new File(selectedFile);\r
- URI fileURL = fileHandle.toURI();\r
- String localURL = fileURL.toString();\r
- QUrl url = new QUrl(localURL);\r
- QFile file = new QFile(selectedFile);\r
- \r
- logger.log(logger.EXTREME, "Adding to fileWatcher:"+file.fileName());\r
- fileWatcher.addPath(file.fileName());\r
- \r
- if (!QDesktopServices.openUrl(url)) {\r
- logger.log(logger.LOW, "Error opening file :" +url);\r
- }\r
- }\r
- \r
- \r
- // Listener for when a link is clicked\r
- @SuppressWarnings("unused")\r
- private void linkClicked(QUrl url) {\r
- logger.log(logger.EXTREME, "URL Clicked: " +url.toString());\r
- if (url.toString().startsWith("latex:")) {\r
- int position = url.toString().lastIndexOf(".");\r
- String guid = url.toString().substring(0,position);\r
- position = guid.lastIndexOf("/");\r
- guid = guid.substring(position+1);\r
- editLatex(guid);\r
- return;\r
- }\r
- if (url.toString().startsWith("evernote:/view/")) {\r
- StringTokenizer tokens = new StringTokenizer(url.toString().replace("evernote:/view/", ""), "/");\r
- tokens.nextToken();\r
- tokens.nextToken();\r
- String sid = tokens.nextToken();\r
- String lid = tokens.nextToken();\r
- \r
- // Emit that we want to switch to a new note\r
- evernoteLinkClicked.emit(sid, lid);\r
-\r
- return;\r
- }\r
- if (url.toString().startsWith("nnres://")) {\r
- logger.log(logger.EXTREME, "URL is NN resource");\r
- if (url.toString().endsWith("/vnd.evernote.ink")) {\r
- logger.log(logger.EXTREME, "Unable to open ink note");\r
- QMessageBox.information(this, tr("Unable Open"), tr("This is an ink note.\n"+\r
- "Ink notes are not supported since Evernote has not\n published any specifications on them\n" +\r
- "and I'm too lazy to figure them out by myself."));\r
- return;\r
- }\r
- String fullName = url.toString().substring(8);\r
- int index = fullName.indexOf(".");\r
- String guid = "";\r
- String type = "";\r
- if (index >-1) {\r
- type = fullName.substring(index+1);\r
- guid = fullName.substring(0,index);\r
- }\r
- index = guid.indexOf(Global.attachmentNameDelimeter);\r
- if (index > -1) {\r
- guid = guid.substring(0,index);\r
- }\r
- List<Resource> resList = currentNote.getResources();\r
- Resource res = null;\r
- for (int i=0; i<resList.size(); i++) {\r
- if (resList.get(i).getGuid().equals(guid)) {\r
- res = resList.get(i);\r
- i=resList.size();\r
- }\r
- }\r
- if (res == null) {\r
- String resGuid = Global.resourceMap.get(guid);\r
- if (resGuid != null) \r
- res = conn.getNoteTable().noteResourceTable.getNoteResource(resGuid, true);\r
- }\r
- if (res != null) {\r
- String fileName;\r
- if (res.getAttributes() != null && \r
- res.getAttributes().getFileName() != null && \r
- !res.getAttributes().getFileName().trim().equals(""))\r
- fileName = res.getGuid()+Global.attachmentNameDelimeter+res.getAttributes().getFileName();\r
- else\r
- fileName = res.getGuid()+"."+type;\r
- QFile file = new QFile(Global.getFileManager().getResDirPath(fileName));\r
- QFile.OpenMode mode = new QFile.OpenMode();\r
- mode.set(QFile.OpenModeFlag.WriteOnly);\r
- boolean openResult = file.open(mode);\r
- logger.log(logger.EXTREME, "File opened:" +openResult);\r
- QDataStream out = new QDataStream(file);\r
- Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(res.getGuid(), true);\r
- QByteArray binData = new QByteArray(resBinary.getData().getBody());\r
- resBinary = null;\r
- logger.log(logger.EXTREME, "Writing resource");\r
- out.writeBytes(binData.toByteArray());\r
- file.close();\r
- \r
- String whichOS = System.getProperty("os.name");\r
- if (whichOS.contains("Windows")) \r
- url.setUrl("file:///"+file.fileName());\r
- else\r
- url.setUrl("file://"+file.fileName());\r
- // fileWatcher.removePath(file.fileName());\r
- logger.log(logger.EXTREME, "Adding file watcher " +file.fileName());\r
- fileWatcher.addPath(file.fileName());\r
- \r
- // If we can't open it, then prompt the user to save it.\r
- if (!QDesktopServices.openUrl(url)) {\r
- logger.log(logger.EXTREME, "We can't handle this. Where do we put it?");\r
- QFileDialog dialog = new QFileDialog();\r
- dialog.show();\r
- if (dialog.exec()!=0) {\r
- List<String> fileNames = dialog.selectedFiles(); //gets all selected filenames\r
- if (fileNames.size() == 0) \r
- return;\r
- String sf = fileNames.get(0);\r
- QFile saveFile = new QFile(sf);\r
- mode.set(QFile.OpenModeFlag.WriteOnly);\r
- saveFile.open(mode);\r
- QDataStream saveOut = new QDataStream(saveFile);\r
- saveOut.writeBytes(binData.toByteArray());\r
- saveFile.close();\r
- return;\r
- }\r
- }\r
- }\r
- return;\r
- }\r
- logger.log(logger.EXTREME, "Launching URL");\r
- QDesktopServices.openUrl(url);\r
- }\r
-\r
- // Listener for when BOLD is clicked\r
- @SuppressWarnings("unused")\r
- private void undoClicked() {\r
- browser.page().triggerAction(WebAction.Undo);\r
- browser.setFocus();\r
- }\r
-\r
- // Listener for when BOLD is clicked\r
- @SuppressWarnings("unused")\r
- private void redoClicked() {\r
- browser.page().triggerAction(WebAction.Redo);\r
- browser.setFocus();\r
- }\r
-\r
- // Listener for when BOLD is clicked\r
- @SuppressWarnings("unused")\r
- private void boldClicked() {\r
- browser.page().triggerAction(WebAction.ToggleBold);\r
- microFocusChanged();\r
- browser.setFocus();\r
- }\r
-\r
- // Listener for when Italics is clicked\r
- @SuppressWarnings("unused")\r
- private void italicClicked() {\r
- browser.page().triggerAction(WebAction.ToggleItalic);\r
- microFocusChanged();\r
- browser.setFocus();\r
- }\r
-\r
- // Listener for when UNDERLINE is clicked\r
- @SuppressWarnings("unused")\r
- private void underlineClicked() {\r
- browser.page().triggerAction(WebAction.ToggleUnderline);\r
- microFocusChanged();\r
- browser.setFocus();\r
- }\r
-\r
- // Listener for when Strikethrough is clicked\r
- @SuppressWarnings("unused")\r
- private void strikethroughClicked() {\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('strikeThrough', false, '');");\r
- browser.setFocus();\r
- }\r
-\r
- // Listener for when cut is clicked\r
- @SuppressWarnings("unused")\r
- private void cutClicked() {\r
- browser.page().triggerAction(WebAction.Cut);\r
- browser.setFocus();\r
- }\r
-\r
- // Listener when COPY is clicked\r
- @SuppressWarnings("unused")\r
- private void copyClicked() {\r
- browser.page().triggerAction(WebAction.Copy);\r
- browser.setFocus();\r
- }\r
-\r
- // Listener when PASTE is clicked\r
- public void pasteClicked() {\r
- logger.log(logger.EXTREME, "Paste Clicked");\r
- if (forceTextPaste) {\r
- pasteWithoutFormattingClicked();\r
- return;\r
- }\r
- QClipboard clipboard = QApplication.clipboard();\r
- QMimeData mime = clipboard.mimeData();\r
-\r
- if (mime.hasImage()) {\r
- logger.log(logger.EXTREME, "Image paste found");\r
- browser.setFocus();\r
- insertImage(mime);\r
- browser.setFocus();\r
- return;\r
- }\r
-\r
- if (mime.hasUrls()) {\r
- logger.log(logger.EXTREME, "URL paste found");\r
- if (mime.text().startsWith("evernote:")) {\r
- handleNoteLink(mime);\r
- } else {\r
- handleUrls(mime);\r
- browser.setFocus();\r
- }\r
- return;\r
- }\r
- \r
- String text = mime.html();\r
- if (text.contains("en-tag") && mime.hasHtml()) {\r
- logger.log(logger.EXTREME, "Intra-note paste found");\r
- text = fixInternotePaste(text);\r
- mime.setHtml(text);\r
- clipboard.setMimeData(mime);\r
- }\r
-\r
- logger.log(logger.EXTREME, "Final paste choice encountered");\r
- browser.page().triggerAction(WebAction.Paste);\r
- browser.setFocus();\r
-\r
- }\r
-\r
- // Paste text without formatting\r
- private void pasteWithoutFormattingClicked() {\r
- logger.log(logger.EXTREME, "Paste without format clipped");\r
- QClipboard clipboard = QApplication.clipboard();\r
- QMimeData mime = clipboard.mimeData();\r
- if (!mime.hasText())\r
- return;\r
- String text = mime.text();\r
- clipboard.clear();\r
- clipboard.setText(text, Mode.Clipboard);\r
- browser.page().triggerAction(WebAction.Paste);\r
-\r
- // This is done because pasting into an encryption block\r
- // can cause multiple cells (which can't happen). It \r
- // just goes through the table, extracts the data, & \r
- // puts it back as one table cell.\r
- if (insideEncryption) {\r
- String js = new String( "function fixEncryption() { "\r
- +" var selObj = window.getSelection();"\r
- +" var selRange = selObj.getRangeAt(0);"\r
- +" var workingNode = window.getSelection().anchorNode;"\r
- +" while(workingNode != null && workingNode.nodeName.toLowerCase() != 'table') { " \r
- +" workingNode = workingNode.parentNode;"\r
- +" } "\r
- +" workingNode.innerHTML = window.jambi.fixEncryptionPaste(workingNode.innerHTML);"\r
- +"} fixEncryption();");\r
- browser.page().mainFrame().evaluateJavaScript(js);\r
- }\r
- }\r
- \r
- // This basically removes all the table tags and returns just the contents.\r
- // This is called by JavaScript to fix encryption pastes.\r
- public String fixEncryptionPaste(String data) {\r
- data = data.replace("<tbody>", "");\r
- data = data.replace("</tbody>", "");\r
- data = data.replace("<tr>", "");\r
- data = data.replace("</tr>", "");\r
- data = data.replace("<td>", "");\r
- data = data.replace("</td>", "<br>");\r
- data = data.replace("<br><br>", "<br>");\r
-\r
- return "<tbody><tr><td>"+data+"</td></tr></tbody>";\r
- }\r
- \r
- // insert date/time\r
- @SuppressWarnings("unused")\r
- private void insertDateTime() {\r
- String fmt = Global.getDateFormat() + " " + Global.getTimeFormat();\r
- String dateTimeFormat = new String(fmt);\r
- SimpleDateFormat simple = new SimpleDateFormat(dateTimeFormat);\r
- Calendar cal = Calendar.getInstance();\r
- \r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('insertHtml', false, '"+simple.format(cal.getTime())+"');");\r
- \r
- browser.setFocus();\r
-\r
- }\r
-\r
- // Listener when Left is clicked\r
- @SuppressWarnings("unused")\r
- private void justifyLeftClicked() {\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('JustifyLeft', false, '');");\r
- browser.setFocus();\r
- }\r
-\r
- // Listener when Center is clicked\r
- @SuppressWarnings("unused")\r
- private void justifyCenterClicked() {\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('JustifyCenter', false, '');");\r
- browser.setFocus();\r
- }\r
-\r
- // Listener when Left is clicked\r
- @SuppressWarnings("unused")\r
- private void justifyRightClicked() {\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('JustifyRight', false, '');");\r
- browser.setFocus();\r
- }\r
-\r
- // Listener when HLINE is clicked\r
- @SuppressWarnings("unused")\r
- private void hlineClicked() {\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('insertHorizontalRule', false, '');");\r
- browser.setFocus();\r
- }\r
-\r
- // Listener when outdent is clicked\r
- private void outdentClicked() {\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('outdent', false, '');");\r
- browser.setFocus();\r
- }\r
-\r
- // Listener when a bullet list is clicked\r
- @SuppressWarnings("unused")\r
- private void bulletListClicked() {\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('InsertUnorderedList', false, '');");\r
- browser.setFocus();\r
- }\r
-\r
- // Listener when a bullet list is clicked\r
- @SuppressWarnings("unused")\r
- private void numberListClicked() {\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('InsertOrderedList', false, '');");\r
- browser.setFocus();\r
- }\r
-\r
- // Listener when indent is clicked\r
- private void indentClicked() {\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('indent', false, '');");\r
- browser.setFocus();\r
- }\r
-\r
- // Listener when the font name is changed\r
- @SuppressWarnings("unused")\r
- private void fontChanged(String font) {\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('fontName',false,'" + font + "');");\r
- browser.setFocus();\r
- }\r
-\r
- // Listener when a font size is changed\r
- @SuppressWarnings("unused")\r
- private void fontSizeChanged(String font) {\r
- String text = browser.selectedText();\r
- if (text.trim().equalsIgnoreCase(""))\r
- return;\r
-\r
- String selectedText = browser.selectedText();\r
- String url = "<span style=\"font-size:" +font +"pt; \">"+selectedText +"</a>";\r
- String script = "document.execCommand('insertHtml', false, '"+url+"');";\r
- browser.page().mainFrame().evaluateJavaScript(script);\r
-/* browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('fontSize',false,'"\r
- + font + "');");\r
-*/\r
- browser.setFocus();\r
- }\r
-\r
- // Load the font combo box based upon the font selected\r
- private void loadFontSize(String name) { \r
- QFontDatabase db = new QFontDatabase(); \r
- fontSize.clear();\r
- List<Integer> points = db.pointSizes(name); \r
- for (int i=0; i<points.size(); i++) { \r
- fontSize.addItem(points.get(i).toString()); \r
- }\r
- /*\r
- fontSize.addItem("x-small");\r
- fontSize.addItem("small");\r
- fontSize.addItem("medium");\r
- fontSize.addItem("large");\r
- fontSize.addItem("x-large");\r
- fontSize.addItem("xx-large");\r
- fontSize.addItem("xxx-large");\r
- */\r
- }\r
-\r
- // Listener when a font size is changed\r
- @SuppressWarnings("unused")\r
- private void fontColorClicked() {\r
-// QColorDialog dialog = new QColorDialog();\r
-// QColor color = QColorDialog.getColor();\r
- QColor color = fontColorMenu.getColor();\r
- if (color.isValid())\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('foreColor',false,'" + color.name()\r
- + "');");\r
- browser.setFocus();\r
- }\r
-\r
- // Listener for when a background color change is requested\r
- @SuppressWarnings("unused")\r
- private void fontHilightClicked() {\r
-// QColorDialog dialog = new QColorDialog();\r
-// QColor color = QColorDialog.getColor();\r
- QColor color = fontHilightColorMenu.getColor();\r
- if (color.isValid())\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('backColor',false,'" + color.name()\r
- + "');");\r
- browser.setFocus();\r
- }\r
- \r
- // Listener for when a background color change is requested\r
- @SuppressWarnings("unused")\r
- private void superscriptClicked() {\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('superscript');");\r
- browser.setFocus();\r
- }\r
- \r
- // Listener for when a background color change is requested\r
- @SuppressWarnings("unused")\r
- private void subscriptClicked() {\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('subscript');");\r
- browser.setFocus();\r
- }\r
- // Insert a to-do checkbox\r
- @SuppressWarnings("unused")\r
- private void todoClicked() {\r
- FileNameMap fileNameMap = URLConnection.getFileNameMap();\r
- String script_start = new String(\r
- "document.execCommand('insertHtml', false, '");\r
- String script_end = new String("');");\r
- String todo = new String(\r
- "<input TYPE=\"CHECKBOX\" value=\"false\" " +\r
- "onMouseOver=\"style.cursor=\\'hand\\'\" " +\r
- "onClick=\"value=checked; window.jambi.contentChanged(); \" />");\r
- browser.page().mainFrame().evaluateJavaScript(\r
- script_start + todo + script_end);\r
- browser.setFocus();\r
- }\r
-\r
- // Encrypt the selected text\r
- @SuppressWarnings("unused")\r
- private void encryptText() {\r
- String text = browser.selectedText();\r
- if (text.trim().equalsIgnoreCase(""))\r
- return;\r
- text = new String(text.replaceAll("\n", "<br/>"));\r
-\r
- EnCryptDialog dialog = new EnCryptDialog();\r
- dialog.exec();\r
- if (!dialog.okPressed()) {\r
- return;\r
- }\r
-\r
- EnCrypt crypt = new EnCrypt();\r
- String encrypted = crypt.encrypt(text, dialog.getPassword().trim(), 64);\r
- String decrypted = crypt.decrypt(encrypted, dialog.getPassword().trim(), 64);\r
-\r
- if (encrypted.trim().equals("")) {\r
- QMessageBox.information(this, tr("Error"), tr("Error Encrypting String"));\r
- return;\r
- }\r
- StringBuffer buffer = new StringBuffer(encrypted.length() + 100);\r
- buffer.append("<img en-tag=\"en-crypt\" cipher=\"RC2\" hint=\""\r
- + dialog.getHint().replace("'","\\'") + "\" length=\"64\" ");\r
- buffer.append("contentEditable=\"false\" alt=\"");\r
- buffer.append(encrypted);\r
- buffer.append("\" src=\"").append(FileUtils.toForwardSlashedPath(Global.getFileManager().getImageDirPath("encrypt.png") +"\""));\r
- Global.cryptCounter++;\r
- buffer.append(" id=\"crypt"+Global.cryptCounter.toString() +"\"");\r
- buffer.append(" onMouseOver=\"style.cursor=\\'hand\\'\"");\r
- buffer.append(" onClick=\"window.jambi.decryptText(\\'crypt"+Global.cryptCounter.toString() \r
- +"\\', \\'"+encrypted+"\\', \\'"+dialog.getHint().replace("'", "\\&apos;")+"\\');\"");\r
- buffer.append("style=\"display:block\" />");\r
-\r
- String script_start = new String(\r
- "document.execCommand('insertHtml', false, '");\r
- String script_end = new String("');");\r
- browser.page().mainFrame().evaluateJavaScript(\r
- script_start + buffer.toString() + script_end);\r
- }\r
-\r
-\r
- // Insert a Quick hyperlink\r
- public void insertQuickLink() {\r
- logger.log(logger.EXTREME, "Inserting link");\r
- String text = browser.selectedText();\r
- if (text.trim().equalsIgnoreCase(""))\r
- return;\r
-\r
- NoteQuickLinkDialog dialog = new NoteQuickLinkDialog(logger, conn, text);\r
- if (dialog.getResults().size() == 0) {\r
- QMessageBox.critical(null, tr("No Matches Found") ,tr("No matching notes found."));\r
- return;\r
- }\r
- if (dialog.getResults().size() > 1) {\r
- dialog.exec();\r
- if (!dialog.okPressed) {\r
- logger.log(logger.EXTREME, "Insert link canceled");\r
- return;\r
- }\r
- }\r
-\r
- User user = Global.getUserInformation();\r
- String dUrl = new String("evernote:///view/") + new String(user.getId() + "/" +user.getShardId() +"/"\r
- +dialog.getSelectedNote()+"/"+dialog.getSelectedNote() +"/ " +"style=\"color:#69aa35\"");\r
- \r
- String url = "<a title=\"" +dUrl\r
- +"\" href=" +dUrl \r
- +" >"+text +"</a>";\r
- String script = "document.execCommand('insertHtml', false, '"+url+"');";\r
- browser.page().mainFrame().evaluateJavaScript(script); \r
- contentChanged();\r
- }\r
-\r
- // Insert a hyperlink\r
- public void insertLink() {\r
- logger.log(logger.EXTREME, "Inserting link");\r
- String text = browser.selectedText();\r
- if (text.trim().equalsIgnoreCase(""))\r
- return;\r
-\r
- InsertLinkDialog dialog = new InsertLinkDialog(insertHyperlink);\r
- if (currentHyperlink != null && currentHyperlink != "") {\r
- dialog.setUrl(currentHyperlink);\r
- }\r
- dialog.exec();\r
- if (!dialog.okPressed()) {\r
- logger.log(logger.EXTREME, "Insert link canceled");\r
- return;\r
- }\r
- \r
- // Take care of inserting new links\r
- if (insertHyperlink) {\r
- String selectedText = browser.selectedText();\r
- if (dialog.getUrl().trim().equals(""))\r
- return;\r
- logger.log(logger.EXTREME, "Inserting link on text "+selectedText);\r
- logger.log(logger.EXTREME, "URL Link " +dialog.getUrl().trim());\r
- String dUrl = StringUtils.replace(dialog.getUrl().trim(), "'", "\\'");\r
- String url = "<a href=\"" +dUrl\r
- +"\" title=" +dUrl \r
- +" >"+selectedText +"</a>";\r
- String script = "document.execCommand('insertHtml', false, '"+url+"');";\r
- browser.page().mainFrame().evaluateJavaScript(script);\r
- return;\r
- }\r
- \r
- // Edit existing links\r
- String js = new String( "function getCursorPos() {"\r
- +"var cursorPos;"\r
- +"if (window.getSelection) {"\r
- +" var selObj = window.getSelection();"\r
- +" var selRange = selObj.getRangeAt(0);"\r
- +" var workingNode = window.getSelection().anchorNode.parentNode;"\r
- +" while(workingNode != null) { " \r
- +" if (workingNode.nodeName.toLowerCase()=='a') workingNode.setAttribute('href','" +dialog.getUrl() +"');"\r
- +" workingNode = workingNode.parentNode;"\r
- +" }"\r
- +"}"\r
- +"} getCursorPos();");\r
- browser.page().mainFrame().evaluateJavaScript(js);\r
- \r
- if (!dialog.getUrl().trim().equals("")) {\r
- contentChanged();\r
- return;\r
- }\r
- \r
- // Remove URL\r
- js = new String( "function getCursorPos() {"\r
- +"var cursorPos;"\r
- +"if (window.getSelection) {"\r
- +" var selObj = window.getSelection();"\r
- +" var selRange = selObj.getRangeAt(0);"\r
- +" var workingNode = window.getSelection().anchorNode.parentNode;"\r
- +" while(workingNode != null) { " \r
- +" if (workingNode.nodeName.toLowerCase()=='a') { "\r
- +" workingNode.removeAttribute('href');"\r
- +" workingNode.removeAttribute('title');"\r
- +" var text = document.createTextNode(workingNode.innerText);"\r
- +" workingNode.parentNode.insertBefore(text, workingNode);"\r
- +" workingNode.parentNode.removeChild(workingNode);"\r
- +" }"\r
- +" workingNode = workingNode.parentNode;"\r
- +" }"\r
- +"}"\r
- +"} getCursorPos();");\r
- browser.page().mainFrame().evaluateJavaScript(js);\r
- \r
- contentChanged();\r
-\r
- \r
- }\r
- \r
- \r
- // Insert a hyperlink\r
- public void insertLatex() {\r
- editLatex(null);\r
- }\r
- public void editLatex(String guid) {\r
- logger.log(logger.EXTREME, "Inserting latex");\r
- String text = browser.selectedText();\r
- if (text.trim().equalsIgnoreCase("\n") || text.trim().equalsIgnoreCase("")) {\r
- InsertLatexImage dialog = new InsertLatexImage();\r
- if (guid != null) {\r
- String formula = conn.getNoteTable().noteResourceTable.getNoteSourceUrl(guid).replace("http://latex.codecogs.com/gif.latex?", "");\r
- dialog.setFormula(formula);\r
- }\r
- dialog.exec();\r
- if (!dialog.okPressed()) {\r
- logger.log(logger.EXTREME, "Edit LaTex canceled");\r
- return;\r
- }\r
- text = dialog.getFormula().trim();\r
- }\r
- blockApplication.emit(this);\r
- logger.log(logger.EXTREME, "Inserting LaTeX formula:" +text);\r
- latexGuid = guid;\r
- text = StringUtils.replace(text, "'", "\\'");\r
- String url = "http://latex.codecogs.com/gif.latex?" +text;\r
- logger.log(logger.EXTREME, "Sending request to codecogs --> " + url);\r
- QNetworkAccessManager manager = new QNetworkAccessManager(this);\r
- manager.finished.connect(this, "insertLatexImageReady(QNetworkReply)");\r
- unblockTime = new GregorianCalendar().getTimeInMillis()+5000;\r
- awaitingHttpResponse = true;\r
- manager.get(new QNetworkRequest(new QUrl(url)));\r
- }\r
- \r
- public void insertLatexImageReady(QNetworkReply reply) {\r
- logger.log(logger.EXTREME, "Response received from CodeCogs");\r
- if (reply.error() != NetworkError.NoError) \r
- return;\r
-\r
- unblockTime = -1;\r
- if (!awaitingHttpResponse)\r
- return;\r
- \r
- awaitingHttpResponse = false;\r
- QUrl replyUrl = reply.url(); \r
- QByteArray image = reply.readAll();\r
- reply.close();\r
- logger.log(logger.EXTREME, "New image size: " +image.size());\r
-\r
- Resource newRes = null;\r
- QFile tfile;\r
- String path;\r
- if (latexGuid == null) {\r
- logger.log(logger.EXTREME, "Creating temporary gif"); \r
- path = Global.getFileManager().getResDirPath("latex-temp.gif");\r
- tfile = new QFile(path);\r
- tfile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.WriteOnly));\r
- logger.log(logger.EXTREME, "File Open: " +tfile.errorString());\r
- tfile.write(image);\r
- logger.log(logger.EXTREME, "Bytes writtes: "+tfile.size());\r
- tfile.close();\r
- logger.log(logger.EXTREME, "Creating resource");\r
- int sequence = 0;\r
- if (currentNote.getResources() != null || currentNote.getResources().size() > 0)\r
- sequence = currentNote.getResources().size();\r
- newRes = createResource(path,sequence ,"image/gif", false);\r
- QImage pix = new QImage();\r
- pix.loadFromData(image);\r
- newRes.setHeight(new Integer(pix.height()).shortValue());\r
- newRes.setWidth(new Integer(pix.width()).shortValue());\r
- logger.log(logger.EXTREME, "Renaming temporary file to " +newRes.getGuid()+".gif");\r
- path = Global.getFileManager().getResDirPath(newRes.getGuid()+".gif");\r
- tfile.rename(path);\r
- } else {\r
- newRes = conn.getNoteTable().noteResourceTable.getNoteResource(latexGuid, false);\r
- path = Global.getFileManager().getResDirPath(newRes.getGuid()+".gif");\r
- tfile = new QFile(path);\r
- tfile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.WriteOnly));\r
- tfile.write(image);\r
- tfile.close();\r
- newRes.getData().setBody(image.toByteArray());\r
- // Calculate the new hash value\r
- MessageDigest md;\r
-\r
- logger.log(logger.EXTREME, "Generating MD5");\r
- try {\r
- md = MessageDigest.getInstance("MD5");\r
- md.update(image.toByteArray());\r
- byte[] hash = md.digest();\r
- newRes.getData().setBodyHash(hash);\r
- } catch (NoSuchAlgorithmException e) {\r
- e.printStackTrace();\r
- }\r
- QImage pix = new QImage();\r
- pix.loadFromData(image);\r
- newRes.setHeight(new Integer(pix.height()).shortValue());\r
- newRes.setWidth(new Integer(pix.width()).shortValue());\r
- conn.getNoteTable().noteResourceTable.updateNoteResource(newRes, true);\r
- }\r
-\r
- logger.log(logger.EXTREME, "Setting source: " +replyUrl.toString());\r
- newRes.getAttributes().setSourceURL(replyUrl.toString());\r
- conn.getNoteTable().noteResourceTable.updateNoteSourceUrl(newRes.getGuid(), replyUrl.toString(), true);\r
- \r
- for(int i=0; i<currentNote.getResourcesSize(); i++) {\r
- if (currentNote.getResources().get(i).getGuid().equals(newRes.getGuid())) {\r
- currentNote.getResources().remove(i);\r
- i=currentNote.getResourcesSize();\r
- }\r
- }\r
- currentNote.getResources().add(newRes);\r
- \r
-\r
- // do the actual insert into the note. We only do this on new formulas. \r
- if (latexGuid == null) {\r
- StringBuffer buffer = new StringBuffer(100);\r
- String formula = replyUrl.toString().toLowerCase().replace("http://latex.codecogs.com/gif.latex?", "");\r
- buffer.append("<a href=\"latex://"+path.replace("\\", "/")+"\" title=\""+formula+"\""\r
- +"><img src=\"");\r
- buffer.append(path.replace("\\", "/"));\r
- buffer.append("\" en-tag=\"en-latex\" type=\"image/gif\""\r
- +" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\""\r
- +" guid=\"" +newRes.getGuid() +"\""\r
- + " /></a>");\r
- \r
- String script_start = new String("document.execCommand('insertHTML', false, '");\r
- String script_end = new String("');");\r
- browser.page().mainFrame().evaluateJavaScript(\r
- script_start + buffer + script_end);\r
- } else {\r
- HtmlTagModifier modifier = new HtmlTagModifier(getContent());\r
- modifier.modifyLatexTagHash(newRes);\r
- String newContent = modifier.getHtml();\r
- setContent(new QByteArray(newContent));\r
- }\r
-\r
- logger.log(logger.EXTREME, "New HTML set\n" +browser.page().currentFrame().toHtml());\r
- QWebSettings.setMaximumPagesInCache(0);\r
- QWebSettings.setObjectCacheCapacities(0, 0, 0);\r
- \r
- browser.page().mainFrame().setHtml(browser.page().mainFrame().toHtml());\r
- browser.reload();\r
- contentChanged();\r
-// resourceSignal.contentChanged.emit(path);\r
- unblockTime = -1;\r
- unblockApplication.emit();\r
- return;\r
- \r
- }\r
-\r
- \r
- \r
- // Insert a table\r
- public void insertTable() {\r
- TableDialog dialog = new TableDialog();\r
- dialog.exec();\r
- if (!dialog.okPressed()) {\r
- return;\r
- }\r
- \r
- int cols = dialog.getCols();\r
- int rows = dialog.getRows();\r
- int width = dialog.getWidth();\r
- boolean percent = dialog.isPercent();\r
- \r
- String newHTML = "<table border=\"1\" width=\"" +new Integer(width).toString();\r
- if (percent)\r
- newHTML = newHTML +"%";\r
- newHTML = newHTML + "\"><tbody>";\r
-\r
- for (int i=0; i<rows; i++) {\r
- newHTML = newHTML +"<tr>";\r
- for (int j=0; j<cols; j++) {\r
- newHTML = newHTML +"<td> </td>";\r
- }\r
- newHTML = newHTML +"</tr>";\r
- }\r
- newHTML = newHTML+"</tbody></table>"; \r
- \r
- String script = "document.execCommand('insertHtml', false, '"+newHTML+"');";\r
- browser.page().mainFrame().evaluateJavaScript(script);\r
- }\r
- \r
- \r
- // Text content changed\r
- @SuppressWarnings("unused")\r
- private void selectionChanged() {\r
- browser.encryptAction.setEnabled(true);\r
- browser.insertLinkAction.setEnabled(true);\r
- browser.insertQuickLinkAction.setEnabled(true);\r
- String scriptStart = "var selection_text = (window.getSelection()).toString();"\r
- + "var range = (window.getSelection()).getRangeAt(0);"\r
- + "var parent_html = range.commonAncestorContainer.innerHTML;"\r
- + "if (parent_html == undefined) {window.jambi.saveSelectedText(selection_text); return;}"\r
- + "var first_text = range.startContainer.nodeValue.substr(range.startOffset);"\r
- + "var last_text = (range.endContainer.nodeValue).substring(0,range.endOffset);"\r
- + "var start = parent_html.indexOf(first_text);"\r
- + "var end = parent_html.indexOf(last_text,start+1)+last_text.length;"\r
- + "var value = parent_html.substring(start,end);"\r
- + "window.jambi.saveSelectedText(value);" ;\r
- browser.page().mainFrame().evaluateJavaScript(scriptStart);\r
-\r
- }\r
-\r
- public void saveSelectedText(String text) {\r
- boolean enabled = true;\r
- if (text.trim().length() == 0)\r
- enabled=false;\r
- if (text.indexOf("en-tag=\"en-crypt\"") >= 0)\r
- enabled=false;\r
- if (text.indexOf("<img en-tag=\"en-media\"") >= 0)\r
- enabled=false;\r
- if (text.indexOf("<a en-tag=\"en-media\"") >= 0)\r
- enabled=false;\r
- if (text.indexOf("<input ") >= 0)\r
- enabled=false;\r
- \r
- browser.encryptAction.setEnabled(enabled);\r
- browser.insertLinkAction.setEnabled(enabled);\r
- browser.insertQuickLinkAction.setEnabled(enabled);\r
-// selectedText = text;\r
- }\r
-\r
- // Decrypt clicked text\r
- public void decryptText(String id, String text, String hint) {\r
- EnCrypt crypt = new EnCrypt();\r
- String plainText = null;\r
- Calendar currentTime = new GregorianCalendar();\r
- Long l = new Long(currentTime.getTimeInMillis());\r
- String slot = new String(Long.toString(l));\r
- \r
- // First, try to decrypt with any keys we already have\r
- for (int i=0; i<Global.passwordRemember.size(); i++) {\r
- plainText = crypt.decrypt(text, Global.passwordRemember.get(i).getFirst(), 64);\r
- if (plainText != null) {\r
- slot = new String(Long.toString(l));\r
- Global.passwordSafe.put(slot, Global.passwordRemember.get(i));\r
- removeEncryption(id, plainText, false, slot); \r
- return;\r
- }\r
- }\r
- \r
- \r
- EnDecryptDialog dialog = new EnDecryptDialog();\r
- dialog.setHint(hint);\r
- while (plainText == null || !dialog.okPressed()) {\r
- dialog.exec();\r
- if (!dialog.okPressed()) {\r
- return;\r
- }\r
- plainText = crypt.decrypt(text, dialog.getPassword().trim(), 64);\r
- if (plainText == null) {\r
- QMessageBox.warning(this, tr("Incorrect Password"), tr("The password entered is not correct"));\r
- }\r
- }\r
- Pair<String,String> passwordPair = new Pair<String,String>();\r
- passwordPair.setFirst(dialog.getPassword());\r
- passwordPair.setSecond(dialog.getHint());\r
- Global.passwordSafe.put(slot, passwordPair);\r
-// removeEncryption(id, plainText.replaceAll("\n", "<br/>"), dialog.permanentlyDecrypt(), slot);\r
- removeEncryption(id, plainText, dialog.permanentlyDecrypt(), slot);\r
- if (dialog.rememberPassword()) {\r
- Pair<String, String> pair = new Pair<String,String>();\r
- pair.setFirst(dialog.getPassword());\r
- pair.setSecond(dialog.getHint());\r
- Global.passwordRemember.add(pair);\r
- }\r
-\r
- }\r
-\r
- // Get the editor tag line\r
- public TagLineEdit getTagLine() {\r
- return tagEdit;\r
- }\r
-\r
- // Modify a note's tags\r
- @SuppressWarnings("unused")\r
- private void modifyTags() {\r
- TagAssign tagWindow = new TagAssign(allTags, currentTags, !conn.getNotebookTable().isLinked(currentNote.getNotebookGuid()));\r
- tagWindow.exec();\r
- if (tagWindow.okClicked()) {\r
- currentTags.clear();\r
- StringBuffer tagDisplay = new StringBuffer();\r
-\r
- List<QListWidgetItem> newTags = tagWindow.getTagList()\r
- .selectedItems();\r
- for (int i = 0; i < newTags.size(); i++) {\r
- currentTags.add(newTags.get(i).text());\r
- tagDisplay.append(newTags.get(i).text());\r
- if (i < newTags.size() - 1) {\r
- tagDisplay.append(Global.tagDelimeter + " ");\r
- }\r
- }\r
- tagEdit.setText(tagDisplay.toString());\r
- noteSignal.tagsChanged.emit(currentNote.getGuid(), currentTags);\r
- }\r
- }\r
-\r
- // Tag line has been modified by typing text\r
- @SuppressWarnings("unused")\r
- private void modifyTagsTyping() {\r
- String completionText = "";\r
- if (tagEdit.currentCompleterSelection != null && !tagEdit.currentCompleterSelection.equals("")) {\r
- completionText = tagEdit.currentCompleterSelection;\r
- tagEdit.currentCompleterSelection = "";\r
- }\r
- \r
- if (tagEdit.text().equalsIgnoreCase(saveTagList))\r
- return;\r
-\r
- // We know something has changed...\r
- String oldTagArray[] = saveTagList.split(Global.tagDelimeter);\r
- String newTagArray[];\r
- if (!completionText.equals("")) {\r
- String before = tagEdit.text().substring(0,tagEdit.cursorPosition());\r
- int lastDelimiter = before.lastIndexOf(Global.tagDelimeter);\r
- if (lastDelimiter > 0)\r
- before = before.substring(0,before.lastIndexOf(Global.tagDelimeter));\r
- else \r
- before = "";\r
- String after = tagEdit.text().substring(tagEdit.cursorPosition());\r
- newTagArray = (before+Global.tagDelimeter+completionText+Global.tagDelimeter+after).split(Global.tagDelimeter);\r
- }\r
- else {\r
- newTagArray = tagEdit.text().split(Global.tagDelimeter);\r
- }\r
- \r
- // Remove any traling or leading blanks\r
- for (int i=0; i<newTagArray.length; i++)\r
- newTagArray[i] = newTagArray[i].trim().replaceAll("^\\s+", "");;\r
- \r
- // Remove any potential duplicates from the new list\r
- for (int i=0; i<newTagArray.length; i++) {\r
- boolean foundOnce = false;\r
- for (int j=0; j<newTagArray.length; j++) {\r
- if (newTagArray[j].equalsIgnoreCase(newTagArray[i])) {\r
- if (!foundOnce) {\r
- foundOnce = true;\r
- } else\r
- newTagArray[j] = "";\r
- }\r
- }\r
- }\r
-\r
- List<String> newTagList = new ArrayList<String>();\r
- List<String> oldTagList = new ArrayList<String>();\r
-\r
- for (int i = 0; i < oldTagArray.length; i++)\r
- if (!oldTagArray[i].trim().equals(""))\r
- oldTagList.add(oldTagArray[i]);\r
- for (int i = 0; i < newTagArray.length; i++)\r
- if (!newTagArray[i].trim().equals(""))\r
- newTagList.add(newTagArray[i]);\r
-\r
- if (conn.getNotebookTable().isLinked(currentNote.getNotebookGuid())) {\r
- for (int i=newTagList.size()-1; i>=0; i--) {\r
- boolean found = false;\r
- for (int j=0; j<allTags.size(); j++) {\r
- if (allTags.get(j).getName().equalsIgnoreCase(newTagList.get(i))) {\r
- found = true;\r
- j=allTags.size();\r
- }\r
- }\r
- if (!found)\r
- newTagList.remove(i);\r
- }\r
- }\r
-\r
- // Let's cleanup the appearance of the tag list\r
- Collections.sort(newTagList);\r
- String newDisplay = "";\r
- for (int i=0; i<newTagList.size(); i++) {\r
- newDisplay = newDisplay+newTagList.get(i);\r
- if (i<newTagList.size()-1)\r
- newDisplay = newDisplay+Global.tagDelimeter +" ";\r
- }\r
- tagEdit.blockSignals(true);\r
- tagEdit.setText(newDisplay);\r
- tagEdit.blockSignals(false);\r
- \r
- // We now have lists of the new & old. Remove duplicates. If all\r
- // are removed from both then nothing has really changed\r
- for (int i = newTagList.size() - 1; i >= 0; i--) {\r
- String nTag = newTagList.get(i);\r
- for (int j = oldTagList.size() - 1; j >= 0; j--) {\r
- String oTag = oldTagList.get(j);\r
- if (oTag.equalsIgnoreCase(nTag)) {\r
- oldTagList.remove(j);\r
- newTagList.remove(i);\r
- j = -1;\r
- }\r
- }\r
- }\r
-\r
- if (oldTagList.size() != 0 || newTagList.size() != 0) {\r
- currentTags.clear();\r
- newTagArray = tagEdit.text().split(Global.tagDelimeter);\r
- for (int i = 0; i < newTagArray.length; i++)\r
- if (!newTagArray[i].trim().equals(""))\r
- currentTags.add(newTagArray[i].trim());\r
-\r
- noteSignal.tagsChanged.emit(currentNote.getGuid(), currentTags);\r
- }\r
- \r
- }\r
-\r
- // Tab button was pressed\r
- public void tabPressed() {\r
- if (insideEncryption)\r
- return;\r
- if (!insideList && !insideTable) {\r
- String script_start = new String(\r
- "document.execCommand('insertHtml', false, ' ');");\r
- browser.page().mainFrame().evaluateJavaScript(script_start);\r
- return;\r
- }\r
- if (insideList) {\r
- indentClicked();\r
- }\r
- if (insideTable) {\r
- String js = new String( "function getCursorPosition() { "\r
- +" var selObj = window.getSelection();"\r
- +" var selRange = selObj.getRangeAt(0);"\r
- +" var workingNode = window.getSelection().anchorNode;"\r
- +" var rowCount = 0;"\r
- +" var colCount = 0;"\r
- +" while(workingNode != null && workingNode.nodeName.toLowerCase() != 'table') { " \r
- +" if (workingNode.nodeName.toLowerCase()=='tr') {"\r
- +" rowCount = rowCount+1;"\r
- +" }"\r
- +" if (workingNode.nodeName.toLowerCase() == 'td') {"\r
- +" colCount = colCount+1;"\r
- +" }"\r
- +" if (workingNode.previousSibling != null)"\r
- +" workingNode = workingNode.previousSibling;"\r
- +" else "\r
- +" workingNode = workingNode.parentNode;"\r
- +" }"\r
- +" var nodes = workingNode.getElementsByTagName('tr');"\r
- +" var tableRows = nodes.length;"\r
- +" nodes = nodes[0].getElementsByTagName('td');"\r
- +" var tableColumns = nodes.length;"\r
- +" window.jambi.setTableCursorPositionTab(rowCount, colCount, tableRows, tableColumns);"\r
- +"} getCursorPosition();");\r
- browser.page().mainFrame().evaluateJavaScript(js);\r
- }\r
- }\r
- \r
- // If a user presses tab from within a table\r
- public void setTableCursorPositionTab(int currentRow, int currentCol, int tableRows, int tableColumns) {\r
- if (tableRows == currentRow && currentCol == tableColumns) {\r
- insertTableRow();\r
- }\r
- KeyboardModifiers modifiers = new KeyboardModifiers(KeyboardModifier.NoModifier);\r
- QKeyEvent right = new QKeyEvent(Type.KeyPress, Qt.Key.Key_Right.value(), modifiers);\r
- QKeyEvent end = new QKeyEvent(Type.KeyPress, Qt.Key.Key_End.value(), modifiers);\r
- QKeyEvent end2 = new QKeyEvent(Type.KeyPress, Qt.Key.Key_End.value(), modifiers);\r
- getBrowser().focusWidget();\r
- QCoreApplication.postEvent(getBrowser(), end);\r
- QCoreApplication.postEvent(getBrowser(), right);\r
- QCoreApplication.postEvent(getBrowser(), end2);\r
- }\r
- \r
- public void backtabPressed() {\r
- if (insideEncryption) \r
- return;\r
- if (insideList)\r
- outdentClicked();\r
- if (insideTable) {\r
- String js = new String( "function getCursorPosition() { "\r
- +" var selObj = window.getSelection();"\r
- +" var selRange = selObj.getRangeAt(0);"\r
- +" var workingNode = window.getSelection().anchorNode;"\r
- +" var rowCount = 0;"\r
- +" var colCount = 0;"\r
- +" while(workingNode != null && workingNode.nodeName.toLowerCase() != 'table') { " \r
- +" if (workingNode.nodeName.toLowerCase()=='tr') {"\r
- +" rowCount = rowCount+1;"\r
- +" }"\r
- +" if (workingNode.nodeName.toLowerCase() == 'td') {"\r
- +" colCount = colCount+1;"\r
- +" }"\r
- +" if (workingNode.previousSibling != null)"\r
- +" workingNode = workingNode.previousSibling;"\r
- +" else "\r
- +" workingNode = workingNode.parentNode;"\r
- +" }"\r
- +" var nodes = workingNode.getElementsByTagName('tr');"\r
- +" var tableRows = nodes.length;"\r
- +" nodes = nodes[0].getElementsByTagName('td');"\r
- +" var tableColumns = nodes.length;"\r
- +" window.jambi.setTableCursorPositionBackTab(rowCount, colCount, tableRows, tableColumns);"\r
- +"} getCursorPosition();");\r
- browser.page().mainFrame().evaluateJavaScript(js);\r
- \r
- }\r
- }\r
- \r
- // If a user presses backtab from within a table\r
- public void setTableCursorPositionBackTab(int currentRow, int currentCol, int tableRows, int tableColumns) {\r
- if (currentRow == 1 && currentCol == 1) {\r
- return;\r
- }\r
- KeyboardModifiers modifiers = new KeyboardModifiers(KeyboardModifier.NoModifier);\r
- QKeyEvent left = new QKeyEvent(Type.KeyPress, Qt.Key.Key_Left.value(), modifiers);\r
- QKeyEvent home = new QKeyEvent(Type.KeyPress, Qt.Key.Key_Home.value(), modifiers);\r
- getBrowser().focusWidget();\r
- QCoreApplication.postEvent(getBrowser(), home);\r
- QCoreApplication.postEvent(getBrowser(), left);\r
- }\r
- \r
- \r
- public void setInsideList() {\r
- insideList = true;\r
- }\r
- \r
- // The title has been edited\r
- @SuppressWarnings("unused")\r
- private void titleEdited() {\r
- // If we don't have a good note, or if the current title\r
- // matches the old title then we don't need to do anything\r
- if (currentNote == null)\r
- return;\r
- if (currentNote.getTitle().trim().equals(titleLabel.text().trim()))\r
- return;\r
- \r
- // If we have a real change, we need to save it.\r
- String text = titleLabel.text().trim();\r
- if (text.equals("")) \r
- text = tr("Untitled Note");\r
- noteSignal.titleChanged.emit(currentNote.getGuid(), text);\r
- currentNote.setTitle(text);\r
- saveNoteTitle = text;\r
- checkNoteTitle();\r
- }\r
-\r
- // Set the list of note tags\r
- public void setAllTags(List<Tag> l) {\r
- allTags = l;\r
- tagEdit.setTagList(l);\r
- }\r
-\r
- // Setter for the current tags\r
- public void setCurrentTags(List<String> s) {\r
- currentTags = s;\r
- }\r
-\r
- // Save the list of notebooks\r
- public void setNotebookList(List<Notebook> n) {\r
- notebookList = n;\r
- loadNotebookList();\r
- }\r
-\r
- // Load the notebook list and select the current notebook\r
- private void loadNotebookList() {\r
- if (notebookBox.count() != 0)\r
- notebookBox.clear();\r
- if (notebookList == null)\r
- return;\r
-\r
- for (int i = 0; i < notebookList.size(); i++) {\r
- notebookBox.addItem(notebookList.get(i).getName());\r
- if (currentNote != null) {\r
- if (currentNote.getNotebookGuid().equals(\r
- notebookList.get(i).getGuid())) {\r
- notebookBox.setCurrentIndex(i);\r
- }\r
- }\r
- }\r
- }\r
- \r
- \r
- // Set the notebook for a note\r
- public void setNotebook(String notebook) {\r
- currentNote.setNotebookGuid(notebook);\r
- loadNotebookList();\r
- }\r
-\r
- // Get the contents of the editor\r
- public String getContent() {\r
- return browser.page().currentFrame().toHtml();\r
- }\r
-\r
- // The note contents have changed\r
- public void contentChanged() {\r
- String content = getContent();\r
- \r
- // This puts in a 1/2 second delay\r
- // before updating the source editor.\r
- // It improves response when someone is doing\r
- // frequent updates on a large note.\r
- // If the source editor isn't visible, then there\r
- // is no point to doing any of this.\r
- if (sourceEdit.isVisible()) {\r
- setSourceTimer.stop();\r
- setSourceTimer.setInterval(500);\r
- setSourceTimer.setSingleShot(true);\r
- setSourceTimer.start();\r
- }\r
- \r
- checkNoteTitle();\r
- noteSignal.noteChanged.emit(currentNote.getGuid(), content); \r
- }\r
-\r
- // The notebook selection has changed\r
- @SuppressWarnings("unused")\r
- private void notebookChanged() {\r
- boolean changed = false;\r
- String n = notebookBox.currentText();\r
- for (int i = 0; i < notebookList.size(); i++) {\r
- if (n.equals(notebookList.get(i).getName())) {\r
- if (!notebookList.get(i).getGuid().equals(currentNote.getNotebookGuid())) {\r
- String guid = conn.getNotebookTable().findNotebookByName(n);\r
- if (conn.getNotebookTable().isLinked(guid)) {\r
- tagEdit.setText("");\r
- noteSignal.tagsChanged.emit(currentNote.getGuid(), new ArrayList<String>());\r
- FilterEditorTags t = new FilterEditorTags(conn, logger);\r
- setAllTags(t.getValidTags(currentNote));\r
- }\r
- currentNote.setNotebookGuid(notebookList.get(i).getGuid());\r
- changed = true;\r
- }\r
- i = notebookList.size();\r
- }\r
- }\r
- \r
- // If the notebook changed, signal the update\r
- if (changed)\r
- noteSignal.notebookChanged.emit(currentNote.getGuid(), currentNote\r
- .getNotebookGuid());\r
- }\r
-\r
- // Check the note title\r
- private void checkNoteTitle() {\r
- String text = browser.page().currentFrame().toPlainText();\r
- if (saveNoteTitle == null)\r
- saveNoteTitle = new String();\r
- text = text.trim();\r
- if (!saveNoteTitle.trim().equals("") && !saveNoteTitle.trim().equals("Untitled Note"))\r
- text = saveNoteTitle.trim();\r
- int newLine = text.indexOf("\n");\r
- if (newLine > 0)\r
- text = text.substring(0,newLine);\r
- if (saveNoteTitle.trim().equals("") || saveNoteTitle.trim().equals("Untitled Note")) {\r
- if (text.trim().equals(""))\r
- text = tr("Untitled Note");\r
- titleLabel.setText(text);\r
- } else {\r
- if (text.length() > Constants.EDAM_NOTE_TITLE_LEN_MAX)\r
- titleLabel.setText(text.substring(0, Constants.EDAM_NOTE_TITLE_LEN_MAX));\r
- else {\r
- titleLabel.blockSignals(true);\r
- if (text.trim().equals(""))\r
- titleLabel.setText(tr("Untitled Note"));\r
- else\r
- titleLabel.setText(text);\r
- titleLabel.blockSignals(false);\r
- }\r
- }\r
- if (currentNote != null && titleLabel != null && !currentNote.getTitle().equals(text))\r
- noteSignal.titleChanged.emit(currentNote.getGuid(), text);\r
- }\r
-\r
- // Return the note contents so we can email them\r
- public String getContentsToEmail() {\r
- return browser.page().currentFrame().toPlainText().trim();\r
- /*\r
- * int body = browser.page().currentFrame().toHtml().indexOf("<body>");\r
- * String temp = browser.page().currentFrame().toHtml(); if (body == -1)\r
- * temp = "<html><body><b>Test</b></body></html>"; else temp =\r
- * "<html>"+temp.substring(body); return temp; // return\r
- * urlEncode(browser.page().currentFrame().toHtml());\r
- */\r
- }\r
-\r
- // Insert an image into the editor\r
- private void insertImage(QMimeData mime) {\r
- logger.log(logger.EXTREME, "Entering insertImage");\r
- QImage img = (QImage) mime.imageData();\r
- String script_start = new String(\r
- "document.execCommand('insertHTML', false, '");\r
- String script_end = new String("');");\r
-\r
- long now = new Date().getTime();\r
- String path = Global.getFileManager().getResDirPath(\r
- (new Long(now).toString()) + ".jpg");\r
-\r
- // This block is just a hack to make sure we wait at least 1ms so we\r
- // don't\r
- // have collisions on image names\r
- long i = new Date().getTime();\r
- while (now == i)\r
- i = new Date().getTime();\r
-\r
- // Open the file & write the data\r
- QFile tfile = new QFile(path);\r
- tfile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.WriteOnly));\r
- if (!img.save(tfile)) {\r
- tfile.close();\r
- return;\r
- }\r
- tfile.close();\r
- \r
- Resource newRes = createResource(QUrl.fromLocalFile(path).toString(), 0, "image/jpeg", false);\r
- if (newRes == null)\r
- return;\r
- currentNote.getResources().add(newRes);\r
-\r
- // do the actual insert into the note\r
- StringBuffer buffer = new StringBuffer(100);\r
- buffer.append("<img src=\"");\r
- buffer.append(tfile.fileName());\r
- buffer.append("\" en-tag=en-media type=\"image/jpeg\""\r
- +" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\""\r
- +" guid=\"" +newRes.getGuid() +"\""\r
- +" onContextMenu=\"window.jambi.imageContextMenu(&." +tfile.fileName() +"&.);\""\r
- + " />");\r
- \r
- browser.page().mainFrame().evaluateJavaScript(\r
- script_start + buffer + script_end);\r
-\r
- return;\r
- }\r
-\r
- // Handle pasting of a note-to-note link\r
- private void handleNoteLink(QMimeData mime) {\r
- for (int i=0; i<mime.urls().size(); i++) {\r
- StringTokenizer tokens = new StringTokenizer(mime.urls().get(i).toString().replace("evernote:///view/", ""), "/");\r
- tokens.nextToken();\r
- tokens.nextToken();\r
- String sid = tokens.nextToken();\r
- String lid = tokens.nextToken();\r
- \r
- if (!sid.equals(currentNote.getGuid()) && !lid.equals(currentNote.getGuid())) {\r
- \r
- Note note = conn.getNoteTable().getNote(sid, false, false, false, false, false);\r
- if (note == null)\r
- note = conn.getNoteTable().getNote(lid, false, false, false, false, false);\r
- \r
- if (note == null)\r
- return;\r
-\r
- // If we've gotten this far, we have a bunch of values. We need to build the link.\r
- StringBuffer url = new StringBuffer(100);\r
- String script_start = new String(\r
- "document.execCommand('insertHtml', false, '");\r
- String script_end = new String("');");\r
- \r
- url.append("<a href=\""+mime.urls().get(i).toString() +"\" style=\"color:#69aa35\">");\r
- url.append(note.getTitle());\r
- url.append("</a>");\r
- if (mime.urls().size() > 1)\r
- url.append(" ");\r
- browser.page().mainFrame().evaluateJavaScript(\r
- script_start + url + script_end);\r
- }\r
- }\r
- }\r
- \r
- // Handle URLs that are trying to be pasted\r
- public void handleUrls(QMimeData mime) {\r
- logger.log(logger.EXTREME, "Starting handleUrls");\r
- FileNameMap fileNameMap = URLConnection.getFileNameMap();\r
-\r
- List<QUrl> urlList = mime.urls();\r
- String url = new String();\r
- String script_start = new String(\r
- "document.execCommand('createLink', false, '");\r
- String script_end = new String("');");\r
-\r
- for (int i = 0; i < urlList.size(); i++) {\r
- url = urlList.get(i).toString();\r
- // Find out what type of file we have\r
- String mimeType = fileNameMap.getContentTypeFor(url);\r
-\r
- // If null returned, we need to guess at the file type\r
- if (mimeType == null)\r
- mimeType = "application/"\r
- + url.substring(url.lastIndexOf(".") + 1);\r
-\r
- // Check if we have an image or some other type of file\r
- if (url.substring(0, 5).equalsIgnoreCase("file:")\r
- && mimeType.substring(0, 5).equalsIgnoreCase("image")) {\r
- handleLocalImageURLPaste(mime, mimeType);\r
- return;\r
- }\r
-\r
- boolean smallEnough = checkFileAttachmentSize(url);\r
- if (smallEnough \r
- && url.substring(0, 5).equalsIgnoreCase("file:")\r
- && !mimeType.substring(0, 5).equalsIgnoreCase("image")) {\r
- handleLocalAttachment(mime, mimeType);\r
- return;\r
- }\r
- browser.page().mainFrame().evaluateJavaScript(\r
- script_start + url + script_end);\r
- }\r
- return;\r
- }\r
-\r
- // If a URL being pasted is an image URL, then attach the image\r
- private void handleLocalImageURLPaste(QMimeData mime, String mimeType) {\r
- List<QUrl> urlList = mime.urls();\r
- String url = new String();\r
- String script_start_image = new String(\r
- "document.execCommand('insertHtml', false, '");\r
- String script_end = new String("');");\r
- StringBuffer buffer;\r
-\r
- // Copy the image over into the resource directory and create a new resource \r
- // record for each url pasted\r
- for (int i = 0; i < urlList.size(); i++) {\r
- url = urlList.get(i).toString();\r
-\r
- Resource newRes = createResource(url, i, mimeType, false);\r
- if (newRes == null)\r
- return;\r
- currentNote.getResources().add(newRes);\r
- buffer = new StringBuffer(100);\r
- \r
- // Open the file & write the data\r
- String fileName = Global.getFileManager().getResDirPath(newRes.getGuid());\r
- QFile tfile = new QFile(fileName);\r
- tfile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.WriteOnly));\r
- tfile.write(newRes.getData().getBody());\r
- tfile.close();\r
- buffer.append(script_start_image);\r
- buffer.append("<img src=\"" + FileUtils.toForwardSlashedPath(fileName));\r
-// if (mimeType.equalsIgnoreCase("image/jpg"))\r
-// mimeType = "image/jpeg";\r
- buffer.append("\" en-tag=\"en-media\" type=\"" + mimeType +"\""\r
- +" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\""\r
- +" guid=\"" +newRes.getGuid() +"\""\r
- +" onContextMenu=\"window.jambi.imageContextMenu('" +tfile.fileName() +"');\""\r
- + " />");\r
- buffer.append(script_end);\r
- browser.page().mainFrame().evaluateJavaScript(buffer.toString());\r
- }\r
- return;\r
- }\r
- \r
-\r
- // If a URL being pasted is a local file URL, then attach the file\r
- private void handleLocalAttachment(QMimeData mime, String mimeType) {\r
- logger.log(logger.EXTREME, "Attaching local file");\r
- List<QUrl> urlList = mime.urls();\r
- String script_start = new String(\r
- "document.execCommand('insertHtml', false, '");\r
- String script_end = new String("');");\r
- StringBuffer buffer;\r
-\r
- String[] type = mimeType.split("/");\r
- String icon = findIcon(type[1]);\r
- if (icon.equals("attachment.png"))\r
- icon = findIcon(type[0]);\r
- buffer = new StringBuffer(100);\r
-\r
- for (int i = 0; i < urlList.size(); i++) {\r
- String url = urlList.get(i).toString();\r
-\r
- // Start building the HTML\r
- if (icon.equals("attachment.png"))\r
- icon = findIcon(url.substring(url.lastIndexOf(".")+1));\r
- String imageURL = FileUtils.toFileURLString(Global.getFileManager().getImageDirFile(icon));\r
-\r
- logger.log(logger.EXTREME, "Creating resource ");\r
- Resource newRes = createResource(url, i, mimeType, true);\r
- if (newRes == null)\r
- return;\r
- logger.log(logger.EXTREME, "New resource size: " +newRes.getData().getSize());\r
- currentNote.getResources().add(newRes);\r
- \r
- String fileName = newRes.getGuid() + Global.attachmentNameDelimeter+newRes.getAttributes().getFileName();\r
- // If we have a PDF, we need to setup the preview.\r
- if (icon.equalsIgnoreCase("pdf.png") && Global.pdfPreview()) {\r
- logger.log(logger.EXTREME, "Setting up PDF preview");\r
- if (newRes.getAttributes() != null && \r
- newRes.getAttributes().getFileName() != null && \r
- !newRes.getAttributes().getFileName().trim().equals(""))\r
- fileName = newRes.getGuid()+Global.attachmentNameDelimeter+\r
- newRes.getAttributes().getFileName();\r
- else\r
- fileName = newRes.getGuid()+".pdf";\r
- QFile file = new QFile(Global.getFileManager().getResDirPath(fileName));\r
- QFile.OpenMode mode = new QFile.OpenMode();\r
- mode.set(QFile.OpenModeFlag.WriteOnly);\r
- file.open(mode);\r
- QDataStream out = new QDataStream(file);\r
-// Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(newRes.getGuid(), true);\r
- QByteArray binData = new QByteArray(newRes.getData().getBody());\r
-// resBinary = null;\r
- out.writeBytes(binData.toByteArray());\r
- file.close();\r
-\r
- PDFPreview pdfPreview = new PDFPreview();\r
- if (pdfPreview.setupPreview(Global.getFileManager().getResDirPath(fileName), "pdf",0)) {\r
- imageURL = file.fileName() + ".png";\r
- }\r
- }\r
- \r
- logger.log(logger.EXTREME, "Generating link tags");\r
- buffer.delete(0, buffer.length());\r
- buffer.append("<a en-tag=\"en-media\" guid=\"" +newRes.getGuid()+"\" ");\r
- buffer.append(" onContextMenu=\"window.jambi.imageContextMenu('")\r
- .append(Global.getFileManager().getResDirPath(fileName))\r
- .append("');\" "); \r
- buffer.append("type=\"" + mimeType + "\" href=\"nnres://" + fileName +"\" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\" >");\r
- buffer.append("<img src=\"" + imageURL + "\" title=\"" +newRes.getAttributes().getFileName());\r
- buffer.append("\"></img>");\r
- buffer.append("</a>");\r
- browser.page().mainFrame().evaluateJavaScript(\r
- script_start + buffer.toString() + script_end);\r
- }\r
- return;\r
- }\r
-\r
- private Resource createResource(String url, int sequence, String mime, boolean attachment) {\r
- logger.log(logger.EXTREME, "Inside create resource");\r
- QFile resourceFile; \r
- //These two lines are added to handle odd characters in the name like #. Without it\r
- // toLocalFile() chokes and returns the wrong name.\r
- logger.log(logger.EXTREME, "File URL:" +url);\r
- String whichOS = System.getProperty("os.name");\r
- if (whichOS.contains("Windows")) \r
- url = url.replace("file:///", "");\r
- else\r
- url = url.replace("file://", "");\r
- String urlTest = new QUrl(url).toLocalFile();\r
- logger.log(logger.EXTREME, "File URL toLocalFile():" +urlTest);\r
- urlTest = url;\r
- if (!urlTest.equals(""))\r
- url = urlTest;\r
-// url = url.replace("/", File.separator);\r
- logger.log(logger.EXTREME, "Reading from file to create resource:" +url);\r
- resourceFile = new QFile(url); \r
- resourceFile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly));\r
- logger.log(logger.EXTREME, "Error opening file "+url.toString() +": "+resourceFile.errorString());\r
- byte[] fileData = resourceFile.readAll().toByteArray();\r
- resourceFile.close();\r
- logger.log(logger.EXTREME, "File Length: " +fileData.length);\r
- if (fileData.length == 0)\r
- return null;\r
- MessageDigest md;\r
- try {\r
- logger.log(logger.EXTREME, "Generating MD5");\r
- md = MessageDigest.getInstance("MD5");\r
- md.update(fileData);\r
- byte[] hash = md.digest();\r
- \r
- Resource r = new Resource();\r
- Calendar time = new GregorianCalendar();\r
- long prevTime = time.getTimeInMillis();\r
- while (prevTime == time.getTimeInMillis()) {\r
- time = new GregorianCalendar();\r
- }\r
- r.setGuid(time.getTimeInMillis()+new Integer(sequence).toString());\r
- r.setNoteGuid(currentNote.getGuid());\r
- r.setMime(mime);\r
- r.setActive(true);\r
- r.setUpdateSequenceNum(0);\r
- r.setWidth((short) 0);\r
- r.setHeight((short) 0);\r
- r.setDuration((short) 0);\r
- \r
- Data d = new Data();\r
- d.setBody(fileData);\r
- d.setBodyIsSet(true);\r
- d.setBodyHash(hash);\r
- d.setBodyHashIsSet(true);\r
- r.setData(d);\r
- d.setSize(fileData.length);\r
- \r
- int fileNamePos = url.lastIndexOf(File.separator);\r
- if (fileNamePos == -1)\r
- fileNamePos = url.lastIndexOf("/");\r
- String fileName = url.substring(fileNamePos+1);\r
- ResourceAttributes a = new ResourceAttributes();\r
- a.setAltitude(0);\r
- a.setAltitudeIsSet(false);\r
- a.setLongitude(0);\r
- a.setLongitudeIsSet(false);\r
- a.setLatitude(0);\r
- a.setLatitudeIsSet(false);\r
- a.setCameraMake("");\r
- a.setCameraMakeIsSet(false);\r
- a.setCameraModel("");\r
- a.setCameraModelIsSet(false);\r
- a.setAttachment(attachment);\r
- a.setAttachmentIsSet(true);\r
- a.setClientWillIndex(false);\r
- a.setClientWillIndexIsSet(true);\r
- a.setRecoType("");\r
- a.setRecoTypeIsSet(false);\r
- a.setSourceURL(url);\r
- a.setSourceURLIsSet(true);\r
- a.setTimestamp(0);\r
- a.setTimestampIsSet(false);\r
- a.setFileName(fileName);\r
- a.setFileNameIsSet(true);\r
- r.setAttributes(a);\r
- \r
- conn.getNoteTable().noteResourceTable.saveNoteResource(r, true);\r
- logger.log(logger.EXTREME, "Resource created");\r
- return r;\r
- } catch (NoSuchAlgorithmException e1) {\r
- e1.printStackTrace();\r
- }\r
- return null;\r
- }\r
- \r
-\r
- // find the appropriate icon for an attachment\r
- private String findIcon(String appl) {\r
- appl = appl.toLowerCase();\r
- File f = Global.getFileManager().getImageDirFile(appl + ".png");\r
- if (f.exists())\r
- return appl+".png";\r
- return "attachment.png";\r
- }\r
-\r
-\r
-\r
- // Check the file attachment to be sure it isn't over 25 mb\r
- private boolean checkFileAttachmentSize(String url) {\r
- String fileName = url.substring(8);\r
- QFile resourceFile = new QFile(fileName);\r
- resourceFile.open(new QIODevice.OpenMode(\r
- QIODevice.OpenModeFlag.ReadOnly));\r
- long size = resourceFile.size();\r
- resourceFile.close();\r
- size = size / 1024 / 1024;\r
- if (size < 50 && Global.isPremium())\r
- return true;\r
- if (size < 25)\r
- return true;\r
-\r
- String error = tr("A file attachment may not exceed 25MB.");\r
- QMessageBox.information(this, tr("Attachment Size"), error);\r
- return false;\r
- }\r
-\r
-\r
- @SuppressWarnings("unused")\r
- private void createdChanged() {\r
- QDateTime dt = new QDateTime();\r
- dt.setDate(createdDate.date());\r
- dt.setTime(createdTime.time());\r
- noteSignal.createdDateChanged.emit(currentNote.getGuid(), dt);\r
-\r
- }\r
-\r
- @SuppressWarnings("unused")\r
- private void alteredChanged() {\r
- QDateTime dt = new QDateTime();\r
- dt.setDate(alteredDate.date());\r
- dt.setTime(alteredTime.time());\r
- noteSignal.alteredDateChanged.emit(currentNote.getGuid(), dt);\r
- }\r
-\r
- @SuppressWarnings("unused")\r
- private void subjectDateTimeChanged() {\r
- QDateTime dt = new QDateTime();\r
- dt.setDate(subjectDate.date());\r
- dt.setTime(subjectTime.time());\r
- noteSignal.subjectDateChanged.emit(currentNote.getGuid(), dt);\r
-\r
- }\r
-\r
- @SuppressWarnings("unused")\r
- private void sourceUrlChanged() {\r
- noteSignal.sourceUrlChanged.emit(currentNote.getGuid(), urlText.text());\r
- }\r
-\r
- @SuppressWarnings("unused")\r
- private void authorChanged() {\r
- noteSignal.authorChanged.emit(currentNote.getGuid(), authorText.text());\r
- }\r
- \r
- @SuppressWarnings("unused")\r
- private void geoBoxChanged() {\r
- int index = geoBox.currentIndex();\r
- geoBox.setCurrentIndex(0);\r
- if (index == 1) {\r
- GeoDialog box = new GeoDialog();\r
- box.setLongitude(currentNote.getAttributes().getLongitude());\r
- box.setLatitude(currentNote.getAttributes().getLatitude());\r
- box.setAltitude(currentNote.getAttributes().getAltitude());\r
- box.exec();\r
- if (!box.okPressed())\r
- return;\r
- double alt = box.getAltitude();\r
- double lat = box.getLatitude();\r
- double lon = box.getLongitude();\r
- if (alt != currentNote.getAttributes().getAltitude() ||\r
- lon != currentNote.getAttributes().getLongitude() ||\r
- lat != currentNote.getAttributes().getLatitude()) {\r
- noteSignal.geoChanged.emit(currentNote.getGuid(), lon, lat, alt);\r
- currentNote.getAttributes().setAltitude(alt);\r
- currentNote.getAttributes().setLongitude(lon);\r
- currentNote.getAttributes().setLatitude(lat);\r
- }\r
- }\r
- \r
- if (index == 2) {\r
- noteSignal.geoChanged.emit(currentNote.getGuid(), 0.0, 0.0, 0.0);\r
- currentNote.getAttributes().setAltitude(0.0);\r
- currentNote.getAttributes().setLongitude(0.0);\r
- currentNote.getAttributes().setLatitude(0.0);\r
- }\r
- \r
- if (index == 3 || index == 0) {\r
- QDesktopServices.openUrl(new QUrl("http://maps.google.com/maps?z=6&q="+currentNote.getAttributes().getLatitude() +"," +currentNote.getAttributes().getLongitude()));\r
- }\r
- }\r
-\r
- // ************************************************************\r
- // * User chose to save an attachment. Pares out the request *\r
- // * into a guid & file. Save the result. *\r
- // ************************************************************\r
- public void downloadAttachment(QNetworkRequest request) {\r
- String guid;\r
- QFileDialog fd = new QFileDialog(this);\r
- fd.setFileMode(FileMode.AnyFile);\r
- fd.setConfirmOverwrite(true);\r
- fd.setWindowTitle(tr("Save File"));\r
- fd.setAcceptMode(AcceptMode.AcceptSave);\r
- fd.setDirectory(System.getProperty("user.home"));\r
- String name = request.url().toString();\r
-\r
- int pos = name.lastIndexOf(Global.attachmentNameDelimeter);\r
- if (pos > -1) {\r
- guid = name.substring(0, pos).replace("nnres://", "");\r
- name = name.substring(pos +Global.attachmentNameDelimeter.length());\r
- fd.selectFile(name);\r
- pos = name.lastIndexOf('.');\r
- if (pos > -1) {\r
- String mimeType = "(*." + name.substring(pos + 1)\r
- + ");; All Files (*)";\r
- fd.setFilter(tr(mimeType));\r
- }\r
- } else {\r
- guid = name;\r
- }\r
-\r
- // Strip URL prefix and base dir\r
- guid = guid.replace("nnres://", "")\r
- .replace(FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath()), "");\r
- guid = guid.replace("file://", "").replace("/", "")\r
- .replace(FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath()), "");\r
-\r
- pos = guid.lastIndexOf('.');\r
- if (pos > 0)\r
- guid = guid.substring(0,pos);\r
- if (fd.exec() != 0 && fd.selectedFiles().size() > 0) {\r
- name = name.replace('\\', '/');\r
- Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);\r
- QFile saveFile = new QFile(fd.selectedFiles().get(0));\r
- QFile.OpenMode mode = new QFile.OpenMode();\r
- mode.set(QFile.OpenModeFlag.WriteOnly);\r
- saveFile.open(mode);\r
- QDataStream saveOut = new QDataStream(saveFile);\r
- QByteArray binData = new QByteArray(resBinary.getData().getBody());\r
- saveOut.writeBytes(binData.toByteArray());\r
- saveFile.close();\r
-\r
- }\r
- }\r
-\r
- \r
- // ************************************************************\r
- // * User chose to save an attachment. Pares out the request *\r
- // * into a guid & file. Save the result. --- DONE FROM downloadAttachment now!!!!! \r
- // ************************************************************\r
- public void downloadImage(QNetworkRequest request) {\r
- QFileDialog fd = new QFileDialog(this);\r
- fd.setFileMode(FileMode.AnyFile);\r
- fd.setConfirmOverwrite(true);\r
- fd.setWindowTitle(tr("Save File"));\r
- fd.setAcceptMode(AcceptMode.AcceptSave);\r
- fd.setDirectory(System.getProperty("user.home"));\r
- String name = request.url().toString();\r
- name = name.replace("nnres://", "");\r
- String dPath = FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath());\r
- name = name.replace(dPath, "");\r
- int pos = name.lastIndexOf('.');\r
- String guid = name;\r
- if (pos > -1) {\r
- String mimeType = "(*." + name.substring(pos + 1)\r
- + ");; All Files (*)";\r
- fd.setFilter(tr(mimeType));\r
- guid = guid.substring(0,pos);\r
- }\r
- pos = name.lastIndexOf(Global.attachmentNameDelimeter);\r
- if (pos > -1) {\r
- guid = name.substring(0, pos);\r
- fd.selectFile(name.substring(pos+Global.attachmentNameDelimeter.length())); \r
- }\r
- if (fd.exec() != 0 && fd.selectedFiles().size() > 0) {\r
- Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);\r
- String fileName = fd.selectedFiles().get(0);\r
- QFile saveFile = new QFile(fileName);\r
- QFile.OpenMode mode = new QFile.OpenMode();\r
- mode.set(QFile.OpenModeFlag.WriteOnly);\r
- saveFile.open(mode);\r
- QDataStream saveOut = new QDataStream(saveFile);\r
- QByteArray binData = new QByteArray(resBinary.getData().getBody());\r
- saveOut.writeBytes(binData.toByteArray());\r
- saveFile.close();\r
- }\r
- }\r
-\r
- \r
- // *************************************************************\r
- // * decrypt any hidden text. We could do an XML parse, but \r
- // * it is quicker here just to scan for an <img tag & do the fix\r
- // * the manual way\r
- // *************************************************************\r
- private void removeEncryption(String id, String plainText, boolean permanent, String slot) {\r
- if (!permanent) {\r
- plainText = " <table class=\"en-crypt-temp\" slot=\""\r
- +slot \r
- +"\""\r
- +"border=1 width=100%><tbody><tr><td>"\r
- +plainText+"</td></tr></tbody></table>";\r
- }\r
- \r
- String html = browser.page().mainFrame().toHtml();\r
- String text = html;\r
- int imagePos = html.indexOf("<img");\r
- int endPos;\r
- for ( ;imagePos>0; ) {\r
- // Find the end tag\r
- endPos = text.indexOf(">", imagePos);\r
- String tag = text.substring(imagePos-1,endPos);\r
- if (tag.indexOf("id=\""+id+"\"") > -1) {\r
- text = text.substring(0,imagePos) +plainText+text.substring(endPos+1); \r
- QTextCodec codec = QTextCodec.codecForName("UTF-8");\r
- QByteArray unicode = codec.fromUnicode(text);\r
- setContent(unicode);\r
- if (permanent)\r
- contentChanged();\r
- }\r
- imagePos = text.indexOf("<img", imagePos+1);\r
- }\r
- }\r
- \r
- \r
- //****************************************************************\r
- //* Focus shortcuts\r
- //****************************************************************\r
- @SuppressWarnings("unused")\r
- private void focusTitle() {\r
- titleLabel.setFocus();\r
- }\r
- @SuppressWarnings("unused")\r
- private void focusTag() {\r
- tagEdit.setFocus();\r
- }\r
- @SuppressWarnings("unused")\r
- private void focusNote() {\r
- browser.setFocus();\r
- }\r
- @SuppressWarnings("unused")\r
- private void focusAuthor() {\r
- authorLabel.setFocus();\r
- }\r
- @SuppressWarnings("unused")\r
- private void focusUrl() {\r
- urlLabel.setFocus();\r
- }\r
- \r
-\r
- //*****************************************************************\r
- //* Set the document background color\r
- //*****************************************************************\r
- public void setBackgroundColor(String color) {\r
- String js = "function changeBackground(color) {"\r
- +"document.body.style.background = color;"\r
- +"}" \r
- +"changeBackground('" +color+"');";\r
- browser.page().mainFrame().evaluateJavaScript(js);\r
- contentChanged();\r
- }\r
- \r
- \r
- //****************************************************************\r
- //* MicroFocus changed\r
- //****************************************************************\r
- private void microFocusChanged() {\r
- boldButton.setDown(false);\r
- italicButton.setDown(false);\r
- underlineButton.setDown(false);\r
- browser.openAction.setEnabled(false);\r
- browser.downloadAttachment.setEnabled(false);\r
- browser.downloadImage.setEnabled(false);\r
- browser.rotateImageLeft.setEnabled(false);\r
- browser.rotateImageRight.setEnabled(false);\r
- browser.insertTableAction.setEnabled(true);\r
- browser.deleteTableColumnAction.setEnabled(false);\r
- browser.insertTableRowAction.setEnabled(false);\r
- browser.insertTableColumnAction.setEnabled(false);\r
- browser.deleteTableRowAction.setEnabled(false);\r
- browser.insertLinkAction.setText(tr("Insert Hyperlink"));\r
- insertHyperlink = true;\r
- browser.insertQuickLinkAction.setEnabled(true);\r
- currentHyperlink ="";\r
- insideList = false;\r
- insideTable = false;\r
- insideEncryption = false;\r
- forceTextPaste = false;\r
- \r
- String js = new String( "function getCursorPos() {"\r
- +"var cursorPos;"\r
- +"if (window.getSelection) {"\r
- +" var selObj = window.getSelection();"\r
- +" var selRange = selObj.getRangeAt(0);"\r
- +" var workingNode = window.getSelection().anchorNode.parentNode;"\r
- +" while(workingNode != null) { " \r
-// +" window.jambi.printNode(workingNode.nodeName);"\r
- +" if (workingNode.nodeName=='TABLE') { if (workingNode.getAttribute('class').toLowerCase() == 'en-crypt-temp') window.jambi.insideEncryption(); }"\r
- +" if (workingNode.nodeName=='B') window.jambi.boldActive();"\r
- +" if (workingNode.nodeName=='I') window.jambi.italicActive();"\r
- +" if (workingNode.nodeName=='U') window.jambi.underlineActive();"\r
- +" if (workingNode.nodeName=='UL') window.jambi.setInsideList();"\r
- +" if (workingNode.nodeName=='OL') window.jambi.setInsideList();"\r
- +" if (workingNode.nodeName=='LI') window.jambi.setInsideList();"\r
- +" if (workingNode.nodeName=='TBODY') window.jambi.setInsideTable();"\r
- +" if (workingNode.nodeName=='A') {for(var x = 0; x < workingNode.attributes.length; x++ ) {if (workingNode.attributes[x].nodeName.toLowerCase() == 'href') window.jambi.setInsideLink(workingNode.attributes[x].nodeValue);}}"\r
- +" if (workingNode.nodeName=='SPAN') {"\r
- +" if (workingNode.getAttribute('style') == 'text-decoration: underline;') window.jambi.underlineActive();"\r
- +" }"\r
- +" workingNode = workingNode.parentNode;"\r
- +" }"\r
- +"}"\r
- +"} getCursorPos();");\r
- browser.page().mainFrame().evaluateJavaScript(js);\r
- }\r
- \r
- public void printNode(String n) {\r
- System.out.println("Node Vaule: " +n);\r
- }\r
- \r
- public void insideEncryption() {\r
- insideEncryption = true;\r
- forceTextPaste();\r
- }\r
- \r
- //****************************************************************\r
- //* Insert a table row\r
- //****************************************************************\r
- public void insertTableRow() {\r
- \r
- String js = new String( "function insertTableRow() {"\r
- +" var selObj = window.getSelection();"\r
- +" var selRange = selObj.getRangeAt(0);"\r
- +" var workingNode = window.getSelection().anchorNode.parentNode;"\r
- +" var cellCount = 0;"\r
- +" while(workingNode != null) { " \r
- +" if (workingNode.nodeName.toLowerCase()=='tr') {"\r
- +" row = document.createElement('TR');"\r
- +" var nodes = workingNode.getElementsByTagName('td');"\r
- +" for (j=0; j<nodes.length; j=j+1) {"\r
- +" cell = document.createElement('TD');"\r
- +" cell.innerHTML=' ';"\r
- +" row.appendChild(cell);"\r
- +" }" \r
- +" workingNode.parentNode.insertBefore(row,workingNode.nextSibling);"\r
- +" return;"\r
- +" }"\r
- +" workingNode = workingNode.parentNode;"\r
- +" }"\r
- +"} insertTableRow();");\r
- browser.page().mainFrame().evaluateJavaScript(js);\r
- contentChanged();\r
- }\r
- \r
- public void insertTableColumn() {\r
- String js = new String( "function insertTableColumn() {"\r
- +" var selObj = window.getSelection();"\r
- +" var selRange = selObj.getRangeAt(0);"\r
- +" var workingNode = window.getSelection().anchorNode.parentNode;"\r
- +" var current = 0;"\r
- +" while (workingNode.nodeName.toLowerCase() != 'table' && workingNode != null) {"\r
- +" if (workingNode.nodeName.toLowerCase() == 'td') {"\r
- +" var td = workingNode;"\r
- +" while (td.previousSibling != null) { " \r
- +" current = current+1; td = td.previousSibling;"\r
- +" }"\r
- +" }"\r
- +" workingNode = workingNode.parentNode; "\r
- +" }"\r
- +" if (workingNode == null) return;"\r
- +" for (var i=0; i<workingNode.rows.length; i++) { " \r
- +" var cell = workingNode.rows[i].insertCell(current+1); " \r
- +" cell.innerHTML = ' '; "\r
- +" }"\r
- +"} insertTableColumn();");\r
- browser.page().mainFrame().evaluateJavaScript(js);\r
- contentChanged();\r
- }\r
- \r
- //****************************************************************\r
- //* Delete a table row\r
- //****************************************************************\r
- public void deleteTableRow() {\r
- \r
- String js = new String( "function deleteTableRow() {"\r
- +" var selObj = window.getSelection();"\r
- +" var selRange = selObj.getRangeAt(0);"\r
- +" var workingNode = window.getSelection().anchorNode.parentNode;"\r
- +" var cellCount = 0;"\r
- +" while(workingNode != null) { " \r
- +" if (workingNode.nodeName.toLowerCase()=='tr') {"\r
- +" workingNode.parentNode.removeChild(workingNode);"\r
- +" return;"\r
- +" }"\r
- +" workingNode = workingNode.parentNode;"\r
- +" }"\r
- +"} deleteTableRow();");\r
- browser.page().mainFrame().evaluateJavaScript(js);\r
- contentChanged();\r
- }\r
-\r
- public void deleteTableColumn() {\r
- String js = new String( "function deleteTableColumn() {"\r
- +" var selObj = window.getSelection();"\r
- +" var selRange = selObj.getRangeAt(0);"\r
- +" var workingNode = window.getSelection().anchorNode.parentNode;"\r
- +" var current = 0;"\r
- +" while (workingNode.nodeName.toLowerCase() != 'table' && workingNode != null) {"\r
- +" if (workingNode.nodeName.toLowerCase() == 'td') {"\r
- +" var td = workingNode;"\r
- +" while (td.previousSibling != null) { " \r
- +" current = current+1; td = td.previousSibling;"\r
- +" }"\r
- +" }"\r
- +" workingNode = workingNode.parentNode; "\r
- +" }"\r
- +" if (workingNode == null) return;"\r
- +" for (var i=0; i<workingNode.rows.length; i++) { " \r
- +" workingNode.rows[i].deleteCell(current); " \r
- +" }"\r
- +"} deleteTableColumn();");\r
- browser.page().mainFrame().evaluateJavaScript(js);\r
- contentChanged();\r
- }\r
- \r
- \r
- public void setInsideTable() {\r
- browser.insertTableRowAction.setEnabled(true);\r
- browser.insertTableColumnAction.setEnabled(true);\r
- browser.deleteTableRowAction.setEnabled(true);\r
- browser.deleteTableColumnAction.setEnabled(true);\r
- browser.insertTableAction.setEnabled(false);\r
- browser.encryptAction.setEnabled(false);\r
- insideTable = true;\r
- }\r
- \r
- public void setInsideLink(String link) {\r
- browser.insertLinkAction.setText(tr("Edit Hyperlink"));\r
- currentHyperlink = link;\r
- insertHyperlink = false;\r
- }\r
- \r
- public void italicActive() {\r
- italicButton.setDown(true);\r
- }\r
- public void boldActive() {\r
- boldButton.setDown(true);\r
- }\r
- public void underlineActive() {\r
- underlineButton.setDown(true);\r
- }\r
- public void forceTextPaste() {\r
- forceTextPaste = true;\r
- }\r
- public void imageContextMenu(String f) {\r
- browser.downloadImage.setEnabled(true);\r
- browser.rotateImageRight.setEnabled(true);\r
- browser.rotateImageLeft.setEnabled(true);\r
- browser.openAction.setEnabled(true);\r
- selectedFile = f;\r
- }\r
- public void rotateImageRight() {\r
- QWebSettings.setMaximumPagesInCache(0);\r
- QWebSettings.setObjectCacheCapacities(0, 0, 0);\r
- QImage image = new QImage(selectedFile);\r
- QMatrix matrix = new QMatrix();\r
- matrix.rotate( 90.0 );\r
- image = image.transformed(matrix);\r
- image.save(selectedFile);\r
- QWebSettings.setMaximumPagesInCache(0);\r
- QWebSettings.setObjectCacheCapacities(0, 0, 0);\r
- browser.setHtml(browser.page().mainFrame().toHtml());\r
- browser.reload();\r
- contentChanged();\r
- resourceSignal.contentChanged.emit(selectedFile);\r
-\r
- }\r
- public void rotateImageLeft() {\r
- QImage image = new QImage(selectedFile);\r
- QMatrix matrix = new QMatrix();\r
- matrix.rotate( -90.0 );\r
- image = image.transformed(matrix);\r
- image.save(selectedFile);\r
- browser.setHtml(browser.page().mainFrame().toHtml());\r
- browser.reload();\r
- contentChanged();\r
- resourceSignal.contentChanged.emit(selectedFile);\r
- }\r
- public void resourceContextMenu(String f) {\r
- browser.downloadAttachment.setEnabled(true);\r
- browser.openAction.setEnabled(true);\r
- selectedFile = f;\r
- }\r
- public void latexContextMenu(String f) {\r
- browser.downloadImage.setEnabled(true);\r
- browser.rotateImageRight.setEnabled(true);\r
- browser.rotateImageLeft.setEnabled(true);\r
- browser.openAction.setEnabled(true);\r
- selectedFile = f;\r
- }\r
-\r
- //****************************************************************\r
- //* Apply CSS style to specified word\r
- //****************************************************************\r
-/* public void applyStyleToWords(String word, String style) {\r
- QFile script = new QFile("D:\\NeverNote\\js\\hilight1.js");\r
- script.open(OpenModeFlag.ReadOnly);\r
- String s = script.readAll().toString();\r
- String js = new String(s +" findit('"+word+"', '"+style+"');");\r
- browser.page().mainFrame().evaluateJavaScript(js);\r
- System.out.println(getContent());\r
- }\r
-*/ \r
- //****************************************************************\r
- //* Someone tried to paste a resource between notes, so we need *\r
- //* to do some special handling. *\r
- //****************************************************************\r
- private String fixInternotePaste(String text) {\r
- logger.log(logger.EXTREME, "Fixing internote paste");\r
- String returnValue = fixInternotePasteSearch(text, "<img", "src=\"");\r
- return fixInternotePasteSearch(returnValue, "<a", "href=\"nnres://");\r
- }\r
- private String fixInternotePasteSearch(String text, String type, String locTag) {\r
- \r
- // First, let's fix the images.\r
- int startPos = text.indexOf(type);\r
- int endPos;\r
- for (; startPos>=0;) {\r
- endPos = text.indexOf(">", startPos+1);\r
- String segment = text.substring(startPos, endPos);\r
- if (segment.indexOf("en-tag") > -1) {\r
- String newSegment = segment;\r
- \r
- int guidStartPos = segment.indexOf("guid=\"");\r
- int guidEndPos = segment.indexOf("\"", guidStartPos+7);\r
- String guid = segment.substring(guidStartPos+6,guidEndPos);\r
- \r
- int mimeStartPos = segment.indexOf("type");\r
- int mimeEndPos = segment.indexOf("\"", mimeStartPos+7);\r
- String mime = segment.substring(mimeStartPos+6,mimeEndPos);\r
-\r
- int srcStartPos = segment.indexOf("src");\r
- int srcEndPos = segment.indexOf("\"", srcStartPos+6);\r
- String src = segment.substring(srcStartPos+5,srcEndPos);\r
- \r
- Calendar currentTime = new GregorianCalendar();\r
- Long l = new Long(currentTime.getTimeInMillis());\r
- long prevTime = l;\r
- while (l==prevTime) {\r
- currentTime = new GregorianCalendar();\r
- l= new Long(currentTime.getTimeInMillis());\r
- }\r
- \r
- Resource r = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);\r
- // if r==null, then the image doesn't exist (it was probably cut out of another note, so \r
- // we need to recereate it\r
- if (r==null) {\r
- r = createResource(src, 1, mime, false);\r
- if (r==null)\r
- return "";\r
- }\r
- String randint = new String(Long.toString(l));\r
- String extension = null;\r
- if (r.getMime()!= null) {\r
- extension = r.getMime().toLowerCase();\r
- if (extension.indexOf("/")>-1)\r
- extension = extension.substring(extension.indexOf("/")+1);\r
- }\r
- String newFile = randint;\r
- if (r.getAttributes().getFileName() != null && r.getAttributes().getFileName() != "")\r
- if (!locTag.startsWith("src"))\r
- newFile = newFile+Global.attachmentNameDelimeter+r.getAttributes().getFileName();\r
- r.setNoteGuid(currentNote.getGuid());\r
- \r
- r.setGuid(randint);\r
- conn.getNoteTable().noteResourceTable.saveNoteResource(r, true);\r
- QFile f = new QFile(Global.getFileManager().getResDirPath(newFile));\r
- QByteArray bin = new QByteArray(r.getData().getBody());\r
- f.open(QFile.OpenModeFlag.WriteOnly);\r
- f.write(bin);\r
- f.close();\r
- newSegment = newSegment.replace("guid=\""+guid, "guid=\""+randint);\r
- currentNote.getResources().add(r);\r
- \r
- int startSrcPos = newSegment.indexOf(locTag);\r
- int endSrcPos = newSegment.indexOf("\"",startSrcPos+locTag.length()+1);\r
- String source; \r
- if (locTag.startsWith("src")) {\r
- source = newSegment.substring(startSrcPos+locTag.length(),endSrcPos);\r
- newSegment = newSegment.replace(source,\r
- FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath(newFile)));\r
- } else {\r
- source = newSegment.substring(startSrcPos+locTag.length(),endSrcPos);\r
- newSegment = newSegment.replace(source, newFile);\r
- }\r
- \r
- text = text.substring(0,startPos) + newSegment + text.substring(endPos);\r
- }\r
- startPos = text.indexOf(type, startPos+1);\r
- }\r
- return text;\r
- }\r
-\r
-\r
- public void nextPage(String file) {\r
- logger.log(logger.EXTREME, "Starting nextPage()");\r
- \r
- Integer pageNumber;\r
- if (previewPageList.containsKey(file))\r
- pageNumber = previewPageList.get(file)+1;\r
- else\r
- pageNumber = 2;\r
- previewPageList.remove(file);\r
- previewPageList.put(file, pageNumber);\r
- PDFPreview pdfPreview = new PDFPreview();\r
- boolean goodPreview = pdfPreview.setupPreview(file, "pdf", pageNumber);\r
- if (goodPreview) {\r
-\r
-// String html = getContent();\r
- QWebSettings.setMaximumPagesInCache(0);\r
- QWebSettings.setObjectCacheCapacities(0, 0, 0);\r
-// browser.setContent(new QByteArray());\r
- browser.setHtml(browser.page().mainFrame().toHtml());\r
- browser.reload();\r
-// browser.setContent(new QByteArray(html));\r
-// browser.triggerPageAction(WebAction.Reload);\r
-// pdfMouseOver(selectedFile);\r
- }\r
- }\r
-\r
- public void previousPage(String file) {\r
- logger.log(logger.EXTREME, "Starting previousPage()");\r
- \r
- Integer pageNumber;\r
- if (previewPageList.containsKey(file))\r
- pageNumber = previewPageList.get(file)-1;\r
- else\r
- pageNumber = 1;\r
- previewPageList.remove(file);\r
- previewPageList.put(file, pageNumber);\r
- PDFPreview pdfPreview = new PDFPreview();\r
- boolean goodPreview = pdfPreview.setupPreview(file, "pdf", pageNumber);\r
- if (goodPreview) {\r
-\r
-// String html = getContent();\r
- QWebSettings.setMaximumPagesInCache(0);\r
- QWebSettings.setObjectCacheCapacities(0, 0, 0);\r
- browser.setHtml(browser.page().mainFrame().toHtml());\r
- browser.reload();\r
-// browser.setContent(new QByteArray(html));\r
-// browser.triggerPageAction(WebAction.Reload);\r
- }\r
- }\r
- \r
-/* public void pdfMouseOver(String name) { \r
- int pageNumber;\r
- if (previewPageList.containsKey(selectedFile))\r
- pageNumber = previewPageList.get(selectedFile)+1;\r
- else\r
- pageNumber = 1;\r
- \r
- if (pageNumber <= 1)\r
- browser.previousPageAction.setEnabled(false);\r
- else\r
- browser.previousPageAction.setEnabled(true);\r
- \r
- PDFPreview pdf = new PDFPreview();\r
- int totalPages = pdf.getPageCount(name);\r
- if (previewPageList.containsKey(selectedFile))\r
- pageNumber = previewPageList.get(selectedFile)+1;\r
- else\r
- pageNumber = 1;\r
- if (totalPages > pageNumber)\r
- browser.nextPageAction.setEnabled(true);\r
- else\r
- browser.nextPageAction.setEnabled(false);\r
- }\r
- \r
-\r
- public void pdfMouseOut() { \r
-// browser.nextPageAction.setVisible(false);\r
-// browser.previousPageAction.setVisible(false);\r
- }\r
-*/\r
- \r
- @SuppressWarnings("unused")\r
- private void toggleUndoVisible(Boolean toggle) {\r
- undoAction.setVisible(toggle);\r
- Global.saveEditorButtonsVisible("undo", toggle);\r
- }\r
- @SuppressWarnings("unused")\r
- private void toggleRedoVisible(Boolean toggle) {\r
- redoAction.setVisible(toggle);\r
- Global.saveEditorButtonsVisible("redo", toggle);\r
- }\r
- @SuppressWarnings("unused")\r
- private void toggleCutVisible(Boolean toggle) {\r
- cutAction.setVisible(toggle);\r
- Global.saveEditorButtonsVisible("cut", toggle);\r
- }\r
- @SuppressWarnings("unused")\r
- private void toggleCopyVisible(Boolean toggle) {\r
- copyAction.setVisible(toggle);\r
- Global.saveEditorButtonsVisible("copy", toggle);\r
- }\r
- @SuppressWarnings("unused")\r
- private void togglePasteVisible(Boolean toggle) {\r
- pasteAction.setVisible(toggle);\r
- Global.saveEditorButtonsVisible("paste", toggle);\r
- }\r
- @SuppressWarnings("unused")\r
- private void toggleBoldVisible(Boolean toggle) {\r
- boldAction.setVisible(toggle);\r
- Global.saveEditorButtonsVisible("bold", toggle);\r
- }\r
- @SuppressWarnings("unused")\r
- private void toggleItalicVisible(Boolean toggle) {\r
- italicAction.setVisible(toggle);\r
- Global.saveEditorButtonsVisible("italic", toggle);\r
- }\r
- @SuppressWarnings("unused")\r
- private void toggleUnderlineVisible(Boolean toggle) {\r
- underlineAction.setVisible(toggle);\r
- Global.saveEditorButtonsVisible("underline", toggle);\r
- }\r
- @SuppressWarnings("unused")\r
- private void toggleStrikethroughVisible(Boolean toggle) {\r
- strikethroughAction.setVisible(toggle);\r
- Global.saveEditorButtonsVisible("strikethrough", toggle);\r
- }\r
- @SuppressWarnings("unused")\r
- private void toggleLeftAlignVisible(Boolean toggle) {\r
- leftAlignAction.setVisible(toggle);\r
- Global.saveEditorButtonsVisible("alignLeft", toggle);\r
- }\r
- @SuppressWarnings("unused")\r
- private void toggleRightAlignVisible(Boolean toggle) {\r
- rightAlignAction.setVisible(toggle);\r
- Global.saveEditorButtonsVisible("alignRight", toggle);\r
- } \r
- @SuppressWarnings("unused")\r
- private void toggleCenterAlignVisible(Boolean toggle) {\r
- centerAlignAction.setVisible(toggle);\r
- Global.saveEditorButtonsVisible("alignCenter", toggle);\r
- }\r
- @SuppressWarnings("unused")\r
- private void toggleHLineVisible(Boolean toggle) {\r
- hlineAction.setVisible(toggle);\r
- Global.saveEditorButtonsVisible("hline", toggle);\r
- }\r
- @SuppressWarnings("unused")\r
- private void toggleIndentVisible(Boolean toggle) {\r
- indentAction.setVisible(toggle);\r
- Global.saveEditorButtonsVisible("indent", toggle);\r
- }\r
- @SuppressWarnings("unused")\r
- private void toggleTodoVisible(Boolean toggle) {\r
- todoAction.setVisible(toggle);\r
- Global.saveEditorButtonsVisible("todo", toggle);\r
- }\r
- @SuppressWarnings("unused")\r
- private void toggleOutdentVisible(Boolean toggle) {\r
- outdentAction.setVisible(toggle);\r
- Global.saveEditorButtonsVisible("outdent", toggle);\r
- }\r
- @SuppressWarnings("unused")\r
- private void toggleBulletListVisible(Boolean toggle) {\r
- bulletListAction.setVisible(toggle);\r
- Global.saveEditorButtonsVisible("bulletList", toggle);\r
- }\r
- @SuppressWarnings("unused")\r
- private void toggleNumberListVisible(Boolean toggle) {\r
- numberListAction.setVisible(toggle);\r
- Global.saveEditorButtonsVisible("numberList", toggle);\r
- }\r
- @SuppressWarnings("unused")\r
- private void toggleFontListVisible(Boolean toggle) {\r
- fontListAction.setVisible(toggle);\r
- Global.saveEditorButtonsVisible("font", toggle);\r
- }\r
- @SuppressWarnings("unused")\r
- private void toggleFontColorVisible(Boolean toggle) {\r
- fontColorAction.setVisible(toggle);\r
- Global.saveEditorButtonsVisible("fontColor", toggle);\r
- }\r
- @SuppressWarnings("unused")\r
- private void toggleFontSizeVisible(Boolean toggle) {\r
- fontSizeAction.setVisible(toggle);\r
- Global.saveEditorButtonsVisible("fontSize", toggle);\r
- }\r
- @SuppressWarnings("unused")\r
- private void toggleFontHilightVisible(Boolean toggle) {\r
- fontHilightAction.setVisible(toggle);\r
- Global.saveEditorButtonsVisible("fontHilight", toggle);\r
- }\r
- @SuppressWarnings("unused")\r
- private void toggleSpellCheckVisible(Boolean toggle) {\r
- spellCheckAction.setVisible(toggle);\r
- Global.saveEditorButtonsVisible("spellCheck", toggle);\r
- }\r
-\r
-\r
- private void setupDictionary() {\r
- File wordList = new File(Global.getFileManager().getSpellDirPath()+Locale.getDefault()+".dic");\r
- try {\r
- dictionary = new SpellDictionaryHashMap(wordList);\r
- spellChecker = new SpellChecker(dictionary);\r
- \r
- File userWordList;\r
- userWordList = new File(Global.getFileManager().getSpellDirPathUser()+"user.dic");\r
- \r
- // Get the local user spell dictionary\r
- try {\r
- userDictionary = new SpellDictionaryHashMap(userWordList);\r
- } catch (FileNotFoundException e) {\r
- userWordList.createNewFile();\r
- userDictionary = new SpellDictionaryHashMap(userWordList);\r
- } catch (IOException e) {\r
- userWordList.createNewFile();\r
- userDictionary = new SpellDictionaryHashMap(userWordList);\r
- }\r
- \r
- spellListener = new SuggestionListener(this, spellChecker);\r
- \r
- // Add the user dictionary\r
- spellChecker.addSpellCheckListener(spellListener);\r
- spellChecker.setUserDictionary(userDictionary);\r
-\r
- } catch (FileNotFoundException e) {\r
- QMessageBox.critical(this, tr("Spell Check Error"), \r
- tr("Dictionary ")+ Global.getFileManager().getSpellDirPath()+Locale.getDefault()+\r
- tr(".dic was not found."));\r
- } catch (IOException e) {\r
- QMessageBox.critical(this, tr("Spell Check Error"), \r
- tr("Dictionary ")+ Global.getFileManager().getSpellDirPath()+Locale.getDefault()+\r
- tr(".dic is invalid."));\r
- }\r
-\r
- }\r
- \r
- // Invoke spell checker dialog\r
- @SuppressWarnings("unused")\r
- private void spellCheckClicked() {\r
-\r
- if (spellChecker == null) {\r
- setupDictionary(); \r
- }\r
- \r
- // Read user settings\r
- spellChecker.getConfiguration().setBoolean(Configuration.SPELL_IGNOREDIGITWORDS, \r
- Global.getSpellSetting(Configuration.SPELL_IGNOREDIGITWORDS));\r
- spellChecker.getConfiguration().setBoolean(Configuration.SPELL_IGNOREINTERNETADDRESSES, \r
- Global.getSpellSetting(Configuration.SPELL_IGNOREINTERNETADDRESSES));\r
- spellChecker.getConfiguration().setBoolean(Configuration.SPELL_IGNOREMIXEDCASE, \r
- Global.getSpellSetting(Configuration.SPELL_IGNOREMIXEDCASE));\r
- spellChecker.getConfiguration().setBoolean(Configuration.SPELL_IGNOREUPPERCASE, \r
- Global.getSpellSetting(Configuration.SPELL_IGNOREUPPERCASE));\r
- spellChecker.getConfiguration().setBoolean(Configuration.SPELL_IGNORESENTENCECAPITALIZATION, \r
- Global.getSpellSetting(Configuration.SPELL_IGNORESENTENCECAPITALIZATION));\r
-\r
- spellListener.abortSpellCheck = false;\r
- spellListener.errorsFound = false;\r
- String content = getBrowser().page().mainFrame().toPlainText();\r
- StringWordTokenizer tokenizer = new StringWordTokenizer(content);\r
- if (!tokenizer.hasMoreWords())\r
- return;\r
- getBrowser().page().action(WebAction.MoveToStartOfDocument);\r
-\r
- getBrowser().setFocus();\r
- boolean found;\r
- \r
- // Move to the start of page\r
- KeyboardModifiers ctrl = new KeyboardModifiers(KeyboardModifier.ControlModifier.value());\r
- QKeyEvent home = new QKeyEvent(Type.KeyPress, Key.Key_Home.value(), ctrl); \r
- browser.keyPressEvent(home);\r
- getBrowser().setFocus();\r
- \r
- tokenizer = new StringWordTokenizer(content);\r
- String word;\r
- \r
- while(tokenizer.hasMoreWords()) {\r
- word = tokenizer.nextWord();\r
- found = getBrowser().page().findText(word);\r
- if (found && !spellListener.abortSpellCheck) {\r
- spellChecker.checkSpelling(new StringWordTokenizer(word));\r
- getBrowser().setFocus();\r
- }\r
- }\r
-\r
- // Go to the end of the document & finish up.\r
- home = new QKeyEvent(Type.KeyPress, Key.Key_End.value(), ctrl); \r
- browser.keyPressEvent(home);\r
- if (!spellListener.errorsFound)\r
- QMessageBox.information(this, tr("Spell Check Complete"), \r
- tr("No Errors Found"));\r
-\r
- }\r
- \r
- // Source edited\r
- @SuppressWarnings("unused")\r
- private void sourceEdited() {\r
- QTextCodec codec = QTextCodec.codecForLocale();\r
- codec = QTextCodec.codecForName("UTF-8");\r
- String content = codec.fromUnicode(sourceEdit.toHtml()).toString();\r
- content = StringEscapeUtils.unescapeHtml4(removeTags(content));\r
- QByteArray data = new QByteArray(sourceEditHeader+content+"</body></html>");\r
- getBrowser().setContent(data);\r
- checkNoteTitle();\r
- if (currentNote != null && sourceEdit != null)\r
- noteSignal.noteChanged.emit(currentNote.getGuid(), sourceEdit.toPlainText()); \r
- }\r
- \r
- private void setSource() {\r
- String text = getContent();\r
- sourceEdit.blockSignals(true);\r
- int body = text.indexOf("<body");\r
- if (body > 0) {\r
- body = text.indexOf(">",body);\r
- if (body > 0) {\r
- sourceEditHeader =text.substring(0, body+1);\r
- text = text.substring(body+1);\r
- }\r
- }\r
- text = text.replace("</body></html>", "");\r
- sourceEdit.setPlainText(text);\r
- sourceEdit.setReadOnly(!getBrowser().page().isContentEditable());\r
- //syntaxHighlighter.rehighlight();\r
- sourceEdit.blockSignals(false);\r
- }\r
-\r
- // show/hide view source window\r
- public void showSource(boolean value) {\r
- setSource();\r
- sourceEdit.setVisible(value);\r
- }\r
-\r
- // Remove HTML tags\r
- private String removeTags(String text) {\r
- StringBuffer buffer = new StringBuffer(text);\r
- boolean inTag = false;\r
- int bodyPosition = text.indexOf("<body");\r
- for (int i=buffer.length()-1; i>=0; i--) {\r
- if (buffer.charAt(i) == '>')\r
- inTag = true;\r
- if (buffer.charAt(i) == '<')\r
- inTag = false;\r
- if (inTag || buffer.charAt(i) == '<' || i<bodyPosition)\r
- buffer.deleteCharAt(i);\r
- }\r
- \r
- return buffer.toString();\r
- }\r
-}\r
+/*
+ * This file is part of NixNote
+ * Copyright 2009 Randy Baumgarte
+ *
+ * This file may be licensed under the terms of of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+package cx.fbn.nevernote.gui;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.FileNameMap;
+import java.net.URI;
+import java.net.URLConnection;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import org.apache.commons.lang3.StringEscapeUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import com.evernote.edam.limits.Constants;
+import com.evernote.edam.type.Data;
+import com.evernote.edam.type.Note;
+import com.evernote.edam.type.Notebook;
+import com.evernote.edam.type.Resource;
+import com.evernote.edam.type.ResourceAttributes;
+import com.evernote.edam.type.Tag;
+import com.evernote.edam.type.User;
+import com.swabunga.spell.engine.Configuration;
+import com.swabunga.spell.engine.SpellDictionary;
+import com.swabunga.spell.engine.SpellDictionaryHashMap;
+import com.swabunga.spell.engine.Word;
+import com.swabunga.spell.event.SpellCheckEvent;
+import com.swabunga.spell.event.SpellCheckListener;
+import com.swabunga.spell.event.SpellChecker;
+import com.swabunga.spell.event.StringWordTokenizer;
+import com.trolltech.qt.core.QByteArray;
+import com.trolltech.qt.core.QCoreApplication;
+import com.trolltech.qt.core.QDataStream;
+import com.trolltech.qt.core.QDateTime;
+import com.trolltech.qt.core.QEvent;
+import com.trolltech.qt.core.QEvent.Type;
+import com.trolltech.qt.core.QFile;
+import com.trolltech.qt.core.QFileSystemWatcher;
+import com.trolltech.qt.core.QIODevice;
+import com.trolltech.qt.core.QMimeData;
+import com.trolltech.qt.core.QSize;
+import com.trolltech.qt.core.QTextCodec;
+import com.trolltech.qt.core.QTimer;
+import com.trolltech.qt.core.QUrl;
+import com.trolltech.qt.core.Qt;
+import com.trolltech.qt.core.Qt.Key;
+import com.trolltech.qt.core.Qt.KeyboardModifier;
+import com.trolltech.qt.core.Qt.KeyboardModifiers;
+import com.trolltech.qt.gui.QAction;
+import com.trolltech.qt.gui.QApplication;
+import com.trolltech.qt.gui.QCalendarWidget;
+import com.trolltech.qt.gui.QClipboard;
+import com.trolltech.qt.gui.QClipboard.Mode;
+import com.trolltech.qt.gui.QColor;
+import com.trolltech.qt.gui.QComboBox;
+import com.trolltech.qt.gui.QDateEdit;
+import com.trolltech.qt.gui.QDesktopServices;
+import com.trolltech.qt.gui.QFileDialog;
+import com.trolltech.qt.gui.QFileDialog.AcceptMode;
+import com.trolltech.qt.gui.QFileDialog.FileMode;
+import com.trolltech.qt.gui.QFont;
+import com.trolltech.qt.gui.QFontDatabase;
+import com.trolltech.qt.gui.QFormLayout;
+import com.trolltech.qt.gui.QGridLayout;
+import com.trolltech.qt.gui.QHBoxLayout;
+import com.trolltech.qt.gui.QIcon;
+import com.trolltech.qt.gui.QImage;
+import com.trolltech.qt.gui.QKeyEvent;
+import com.trolltech.qt.gui.QKeySequence;
+import com.trolltech.qt.gui.QLabel;
+import com.trolltech.qt.gui.QLineEdit;
+import com.trolltech.qt.gui.QListWidgetItem;
+import com.trolltech.qt.gui.QMatrix;
+import com.trolltech.qt.gui.QMessageBox;
+import com.trolltech.qt.gui.QPalette;
+import com.trolltech.qt.gui.QPalette.ColorRole;
+import com.trolltech.qt.gui.QPushButton;
+import com.trolltech.qt.gui.QShortcut;
+import com.trolltech.qt.gui.QSplitter;
+import com.trolltech.qt.gui.QTextEdit;
+import com.trolltech.qt.gui.QTextEdit.LineWrapMode;
+import com.trolltech.qt.gui.QTimeEdit;
+import com.trolltech.qt.gui.QToolButton;
+import com.trolltech.qt.gui.QToolButton.ToolButtonPopupMode;
+import com.trolltech.qt.gui.QVBoxLayout;
+import com.trolltech.qt.gui.QWidget;
+import com.trolltech.qt.network.QNetworkAccessManager;
+import com.trolltech.qt.network.QNetworkReply;
+import com.trolltech.qt.network.QNetworkReply.NetworkError;
+import com.trolltech.qt.network.QNetworkRequest;
+import com.trolltech.qt.webkit.QWebPage;
+import com.trolltech.qt.webkit.QWebPage.WebAction;
+import com.trolltech.qt.webkit.QWebSettings;
+import com.trolltech.qt.webkit.QWebView;
+
+import cx.fbn.nevernote.Global;
+import cx.fbn.nevernote.dialog.EnCryptDialog;
+import cx.fbn.nevernote.dialog.EnDecryptDialog;
+import cx.fbn.nevernote.dialog.GeoDialog;
+import cx.fbn.nevernote.dialog.InsertLatexImage;
+import cx.fbn.nevernote.dialog.InsertLinkDialog;
+import cx.fbn.nevernote.dialog.NoteQuickLinkDialog;
+import cx.fbn.nevernote.dialog.SpellCheck;
+import cx.fbn.nevernote.dialog.TableDialog;
+import cx.fbn.nevernote.dialog.TagAssign;
+import cx.fbn.nevernote.evernote.EnCrypt;
+import cx.fbn.nevernote.filters.FilterEditorTags;
+import cx.fbn.nevernote.neighbornote.ClipBoardObserver;
+import cx.fbn.nevernote.signals.NoteResourceSignal;
+import cx.fbn.nevernote.signals.NoteSignal;
+import cx.fbn.nevernote.sql.DatabaseConnection;
+import cx.fbn.nevernote.utilities.ApplicationLogger;
+import cx.fbn.nevernote.utilities.FileUtils;
+import cx.fbn.nevernote.utilities.Pair;
+import cx.fbn.nevernote.xml.HtmlTagModifier;
+
+public class BrowserWindow extends QWidget {
+
+ public final QLineEdit titleLabel;
+ private final QLineEdit urlText;
+ private final QLabel authorLabel;
+ private final QLineEdit authorText;
+ private final QComboBox geoBox;
+ public final TagLineEdit tagEdit;
+ public final QLabel tagLabel;
+ private final QPushButton urlLabel;
+ private final QLabel alteredLabel;
+ private final QDateEdit alteredDate;
+ private final QTimeEdit alteredTime;
+ private final QDateEdit createdDate;
+ private final QTimeEdit createdTime;
+ private final QLabel subjectLabel;
+ private final QDateEdit subjectDate;
+ private final QTimeEdit subjectTime;
+ public final QComboBox notebookBox;
+ private final QLabel notebookLabel;
+ private final QLabel createdLabel;
+ public final QComboBox fontSize;
+ public final QAction fontSizeAction;
+ private boolean extendedOn;
+ public boolean buttonsVisible;
+ private final String iconPath;
+ public final ContentView browser;
+ private final QTextEdit sourceEdit;
+ private String sourceEditHeader;
+ Highlighter syntaxHighlighter;
+ private List<Tag> allTags;
+ private List<String> currentTags;
+ public NoteSignal noteSignal;
+ public Signal2<String,String> evernoteLinkClicked;
+ private List<Notebook> notebookList;
+ private Note currentNote;
+ private String saveNoteTitle;
+ private String saveTagList;
+ private boolean insideList;
+ private final DatabaseConnection conn;
+ private final QCalendarWidget createdCalendarWidget;
+ private final QCalendarWidget alteredCalendarWidget;
+ private final QCalendarWidget subjectCalendarWidget;
+
+ public final QPushButton undoButton;
+ public final QAction undoAction;
+ public final QPushButton redoButton;
+ public final QAction redoAction;
+ public final QPushButton cutButton;
+ public final QAction cutAction;
+ public final QPushButton copyButton;
+ public final QAction copyAction;
+ public final QPushButton pasteButton;
+ public final QAction pasteAction;
+ public final QPushButton boldButton;
+ public final QAction boldAction;
+ public final QPushButton underlineButton;
+ public final QAction underlineAction;
+ public final QPushButton italicButton;
+ public final QAction italicAction;
+ public final Signal0 focusLost;
+ public final NoteResourceSignal resourceSignal;
+
+ public QPushButton rightAlignButton;
+ public final QAction rightAlignAction;
+ public QPushButton leftAlignButton;
+ public final QAction leftAlignAction;
+ public QPushButton centerAlignButton;
+ public final QAction centerAlignAction;
+
+ public final QPushButton strikethroughButton;
+ public final QAction strikethroughAction;
+ public final QPushButton hlineButton;
+ public final QAction hlineAction;
+ public final QPushButton indentButton;
+ public final QAction indentAction;
+ public final QPushButton outdentButton;
+ public final QAction outdentAction;
+ public final QPushButton bulletListButton;
+ public final QAction bulletListAction;
+ public final QPushButton numberListButton;
+ public final QAction numberListAction;
+ public final QPushButton spellCheckButton;
+ public final QAction spellCheckAction;
+ public final QPushButton todoButton;
+ public final QAction todoAction;
+
+ public final QShortcut focusTitleShortcut;
+ public final QShortcut focusTagShortcut;
+ public final QShortcut focusNoteShortcut;
+ public final QShortcut focusUrlShortcut;
+ public final QShortcut focusAuthorShortcut;
+
+ public EditorButtonBar buttonLayout;
+ public final QComboBox fontList;
+ public final QAction fontListAction;
+ public final QToolButton fontColor;
+ public final QAction fontColorAction;
+ private final ColorMenu fontColorMenu;
+ public final QToolButton fontHilight;
+ public final QAction fontHilightAction;
+ private final ColorMenu fontHilightColorMenu;
+ public final QFileSystemWatcher fileWatcher;
+ public int cursorPosition;
+ private boolean forceTextPaste;
+ private String selectedFile;
+ private String currentHyperlink;
+ public boolean keepPDFNavigationHidden;
+ private final ApplicationLogger logger;
+ SpellDictionary dictionary;
+ SpellDictionary userDictionary;
+ SpellChecker spellChecker;
+ SuggestionListener spellListener;
+ private final HashMap<String,Integer> previewPageList;
+ boolean insertHyperlink;
+ boolean insideTable;
+ boolean insideEncryption;
+ public Signal1<BrowserWindow> blockApplication;
+ public Signal0 unblockApplication;
+ public boolean awaitingHttpResponse;
+ public long unblockTime;
+ private final QTimer setSourceTimer;
+ String latexGuid; // This is set if we are editing an existing LaTeX formula. Useful to track guid.
+
+ // ICHANGED
+ private final ClipBoardObserver cbObserver;
+
+ public static class SuggestionListener implements SpellCheckListener {
+ public boolean abortSpellCheck = false;
+ public boolean errorsFound = false;
+ private final SpellCheck spellCheckDialog;
+
+
+ private final BrowserWindow parent;
+ public SuggestionListener(BrowserWindow parent, SpellChecker checker) {
+ this.parent = parent;
+ spellCheckDialog = new SpellCheck(checker);
+ }
+ public void spellingError(SpellCheckEvent event) {
+ errorsFound = true;
+ spellCheckDialog.setWord(event.getInvalidWord());
+
+ @SuppressWarnings("unchecked")
+ List<Word> suggestions = event.getSuggestions();
+ spellCheckDialog.clearSuggestions();
+ if (!suggestions.isEmpty()) {
+// spellCheckDialog.setCurrentSuggestion(suggestions.get(0).getWord());
+ for (int i=0; i<suggestions.size(); i++) {
+ spellCheckDialog.addSuggestion(suggestions.get(i).getWord());
+ }
+ spellCheckDialog.setSelectedSuggestion(0);
+ }
+ spellCheckDialog.exec();
+ if (spellCheckDialog.cancelPressed()) {
+ abortSpellCheck = true;
+ event.cancel();
+ return;
+ }
+ if (spellCheckDialog.replacePressed()) {
+ QClipboard clipboard = QApplication.clipboard();
+ clipboard.setText(spellCheckDialog.getReplacementWord());
+ parent.pasteClicked();
+ }
+ event.cancel();
+ }
+ }
+
+
+ // ICHANGED 引数にcbObserverを追加
+ public BrowserWindow(DatabaseConnection c, ClipBoardObserver cbObserver) {
+ logger = new ApplicationLogger("browser.log");
+ logger.log(logger.HIGH, "Setting up browser");
+ iconPath = new String("classpath:cx/fbn/nevernote/icons/");
+ forceTextPaste = false;
+ insertHyperlink = true;
+ insideTable = false;
+ insideEncryption = false;
+
+ fileWatcher = new QFileSystemWatcher();
+// fileWatcher.fileChanged.connect(this, "fileChanged(String)");
+ noteSignal = new NoteSignal();
+ titleLabel = new QLineEdit();
+ evernoteLinkClicked = new Signal2<String,String>();
+ titleLabel.setMaxLength(Constants.EDAM_NOTE_TITLE_LEN_MAX);
+ urlText = new QLineEdit();
+ authorText = new QLineEdit();
+ geoBox = new QComboBox();
+ urlLabel = new QPushButton();
+ urlLabel.clicked.connect(this, "sourceUrlClicked()");
+ authorLabel = new QLabel();
+ conn = c;
+
+ // ICHANGED
+ this.cbObserver = cbObserver;
+
+ focusLost = new Signal0();
+
+ tagEdit = new TagLineEdit(allTags);
+ tagLabel = new QLabel(tr("Tags:"));
+ tagEdit.focusLost.connect(this, "modifyTagsTyping()");
+
+ createdCalendarWidget = new QCalendarWidget();
+ createdDate = new QDateEdit();
+ createdDate.setDisplayFormat(Global.getDateFormat());
+ createdDate.setCalendarPopup(true);
+ createdDate.setCalendarWidget(createdCalendarWidget);
+ createdTime = new QTimeEdit();
+ createdDate.dateChanged.connect(this, "createdChanged()");
+ createdTime.timeChanged.connect(this, "createdChanged()");
+
+ alteredCalendarWidget = new QCalendarWidget();
+ alteredDate = new QDateEdit();
+ alteredDate.setDisplayFormat(Global.getDateFormat());
+ alteredDate.setCalendarPopup(true);
+ alteredDate.setCalendarWidget(alteredCalendarWidget);
+ alteredTime = new QTimeEdit();
+ alteredLabel = new QLabel(tr("Altered:"));
+ alteredDate.dateChanged.connect(this, "alteredChanged()");
+ alteredTime.timeChanged.connect(this, "alteredChanged()");
+
+ subjectCalendarWidget = new QCalendarWidget();
+ subjectDate = new QDateEdit();
+ subjectDate.setDisplayFormat(Global.getDateFormat());
+ subjectDate.setCalendarPopup(true);
+ subjectDate.setCalendarWidget(subjectCalendarWidget);
+ subjectTime = new QTimeEdit();
+ subjectLabel = new QLabel(tr("Subject Date:"));
+ subjectDate.dateChanged.connect(this, "subjectDateTimeChanged()");
+ subjectTime.timeChanged.connect(this, "subjectDateTimeChanged()");
+ authorText.textChanged.connect(this, "authorChanged()");
+ urlText.textChanged.connect(this, "sourceUrlChanged()");
+
+ notebookBox = new QComboBox();
+ notebookLabel = new QLabel(tr("Notebook"));
+ createdLabel = new QLabel(tr("Created:"));
+ // selectedText = new String();
+
+ urlLabel.setVisible(false);
+ urlText.setVisible(false);
+ authorLabel.setVisible(false);
+
+ geoBox.setVisible(false);
+ geoBox.addItem(new QIcon(iconPath+"globe.png"), "");
+ geoBox.addItem(new String(tr("Set")));
+ geoBox.addItem(new String(tr("Clear")));
+ geoBox.addItem(new String(tr("View On Map")));
+ geoBox.activated.connect(this, "geoBoxChanged()");
+
+ authorText.setVisible(false);
+ createdDate.setVisible(false);
+ alteredLabel.setVisible(false);
+ //notebookBox.setVisible(false);
+ notebookLabel.setVisible(false);
+ createdLabel.setVisible(false);
+ createdTime.setVisible(false);
+ alteredDate.setVisible(false);
+ alteredTime.setVisible(false);
+ subjectLabel.setVisible(false);
+ subjectDate.setVisible(false);
+ subjectTime.setVisible(false);
+ extendedOn = false;
+ buttonsVisible = true;
+ setAcceptDrops(true);
+
+ browser = new ContentView(this);
+
+ browser.page().setLinkDelegationPolicy(
+ QWebPage.LinkDelegationPolicy.DelegateAllLinks);
+ browser.linkClicked.connect(this, "linkClicked(QUrl)");
+ currentHyperlink = "";
+
+ //Setup the source editor
+ sourceEdit = new QTextEdit(this);
+ sourceEdit.setVisible(false);
+ sourceEdit.setTabChangesFocus(true);
+ sourceEdit.setLineWrapMode(LineWrapMode.NoWrap);
+ QFont font = new QFont();
+ font.setFamily("Courier");
+ font.setFixedPitch(true);
+ font.setPointSize(10);
+ sourceEdit.setFont(font);
+ syntaxHighlighter = new Highlighter(sourceEdit.document());
+ sourceEdit.textChanged.connect(this, "sourceEdited()");
+
+ QVBoxLayout v = new QVBoxLayout();
+ QFormLayout notebookLayout = new QFormLayout();
+ QGridLayout dateLayout = new QGridLayout();
+ titleLabel.setReadOnly(false);
+ titleLabel.editingFinished.connect(this, "titleEdited()");
+ browser.page().contentsChanged.connect(this, "contentChanged()");
+ browser.page().selectionChanged.connect(this, "selectionChanged()");
+ browser.page().mainFrame().javaScriptWindowObjectCleared.connect(this,
+ "exposeToJavascript()");
+
+ notebookBox.activated.connect(this, "notebookChanged()");
+ resourceSignal = new NoteResourceSignal();
+
+ QHBoxLayout tagLayout = new QHBoxLayout();
+ v.addWidget(titleLabel, 0);
+ notebookLayout.addRow(notebookLabel, notebookBox);
+ tagLayout.addLayout(notebookLayout, 0);
+ tagLayout.stretch(4);
+ tagLayout.addWidget(tagLabel, 0);
+ tagLayout.addWidget(tagEdit, 1);
+ v.addLayout(tagLayout);
+
+ QHBoxLayout urlLayout = new QHBoxLayout();
+ urlLayout.addWidget(urlLabel, 0);
+ urlLayout.addWidget(urlText, 0);
+ v.addLayout(urlLayout);
+
+ QHBoxLayout authorLayout = new QHBoxLayout();
+ authorLayout.addWidget(authorLabel, 0);
+ authorLayout.addWidget(authorText, 0);
+ authorLayout.addWidget(geoBox);
+ v.addLayout(authorLayout);
+
+ dateLayout.addWidget(createdLabel, 0, 0);
+ dateLayout.addWidget(createdDate, 0, 1);
+ dateLayout.addWidget(createdTime, 0, 2);
+ dateLayout.setColumnStretch(9, 100);
+ dateLayout.addWidget(alteredLabel, 0, 3);
+ dateLayout.addWidget(alteredDate, 0, 4);
+ dateLayout.addWidget(alteredTime, 0, 5);
+ dateLayout.addWidget(subjectLabel, 0, 6);
+ dateLayout.addWidget(subjectDate, 0, 7);
+ dateLayout.addWidget(subjectTime, 0, 8);
+ v.addLayout(dateLayout, 0);
+
+ undoButton = newEditorButton("undo", tr("Undo Change"));
+ redoButton = newEditorButton("redo", tr("Redo Change"));
+ cutButton = newEditorButton("cut", tr("Cut"));
+ copyButton = newEditorButton("copy", tr("Copy"));
+ pasteButton = newEditorButton("paste", tr("Paste"));
+ boldButton = newEditorButton("bold", tr("Bold"));
+ underlineButton = newEditorButton("underline", tr("Underline"));
+ italicButton = newEditorButton("italic", tr("Italic"));
+
+ rightAlignButton = newEditorButton("justifyRight", tr("Right Align"));
+ leftAlignButton = newEditorButton("justifyLeft", tr("Left Align"));
+ centerAlignButton = newEditorButton("justifyCenter", tr("Center Align"));
+
+ strikethroughButton = newEditorButton("strikethrough", tr("Strikethrough"));
+ hlineButton = newEditorButton("hline", tr("Insert Horizontal Line"));
+ indentButton = newEditorButton("indent", tr("Shift Right"));
+ outdentButton = newEditorButton("outdent", tr("Shift Left"));
+ bulletListButton = newEditorButton("bulletList", tr("Bullet List"));
+ numberListButton = newEditorButton("numberList", tr("Number List"));
+ spellCheckButton = newEditorButton("spellCheck", tr("Spell Check"));
+ todoButton = newEditorButton("todo", tr("To-do"));
+
+
+ buttonLayout = new EditorButtonBar();
+ v.addWidget(buttonLayout);
+
+ undoAction = buttonLayout.addWidget(undoButton);
+ buttonLayout.toggleUndoVisible.triggered.connect(this, "toggleUndoVisible(Boolean)");
+ redoAction = buttonLayout.addWidget(redoButton);
+ buttonLayout.toggleRedoVisible.triggered.connect(this, "toggleRedoVisible(Boolean)");
+
+ buttonLayout.addWidget(newSeparator());
+ cutAction = buttonLayout.addWidget(cutButton);
+ buttonLayout.toggleCutVisible.triggered.connect(this, "toggleCutVisible(Boolean)");
+ copyAction = buttonLayout.addWidget(copyButton);
+ buttonLayout.toggleCopyVisible.triggered.connect(this, "toggleCopyVisible(Boolean)");
+ pasteAction = buttonLayout.addWidget(pasteButton);
+ buttonLayout.togglePasteVisible.triggered.connect(this, "togglePasteVisible(Boolean)");
+
+ buttonLayout.addWidget(newSeparator());
+ boldAction = buttonLayout.addWidget(boldButton);
+ buttonLayout.toggleBoldVisible.triggered.connect(this, "toggleBoldVisible(Boolean)");
+ italicAction = buttonLayout.addWidget(italicButton);
+ buttonLayout.toggleItalicVisible.triggered.connect(this, "toggleItalicVisible(Boolean)");
+ underlineAction = buttonLayout.addWidget(underlineButton);
+ buttonLayout.toggleUnderlineVisible.triggered.connect(this, "toggleUnderlineVisible(Boolean)");
+ strikethroughAction = buttonLayout.addWidget(strikethroughButton);
+ buttonLayout.toggleStrikethroughVisible.triggered.connect(this, "toggleStrikethroughVisible(Boolean)");
+
+
+ buttonLayout.addWidget(newSeparator());
+ leftAlignAction = buttonLayout.addWidget(leftAlignButton);
+ buttonLayout.toggleLeftAlignVisible.triggered.connect(this, "toggleLeftAlignVisible(Boolean)");
+ centerAlignAction = buttonLayout.addWidget(centerAlignButton);
+ buttonLayout.toggleCenterAlignVisible.triggered.connect(this, "toggleCenterAlignVisible(Boolean)");
+ rightAlignAction = buttonLayout.addWidget(rightAlignButton);
+ buttonLayout.toggleRightAlignVisible.triggered.connect(this, "toggleRightAlignVisible(Boolean)");
+
+ buttonLayout.addWidget(newSeparator());
+ hlineAction = buttonLayout.addWidget(hlineButton);
+ buttonLayout.toggleHLineVisible.triggered.connect(this, "toggleHLineVisible(Boolean)");
+
+ indentAction = buttonLayout.addWidget(indentButton);
+ buttonLayout.toggleIndentVisible.triggered.connect(this, "toggleIndentVisible(Boolean)");
+ outdentAction = buttonLayout.addWidget(outdentButton);
+ buttonLayout.toggleOutdentVisible.triggered.connect(this, "toggleOutdentVisible(Boolean)");
+ bulletListAction = buttonLayout.addWidget(bulletListButton);
+ buttonLayout.toggleBulletListVisible.triggered.connect(this, "toggleBulletListVisible(Boolean)");
+ numberListAction = buttonLayout.addWidget(numberListButton);
+ buttonLayout.toggleNumberListVisible.triggered.connect(this, "toggleNumberListVisible(Boolean)");
+
+ // Setup the font & font size combo boxes
+ buttonLayout.addWidget(newSeparator());
+ fontList = new QComboBox();
+ fontSize = new QComboBox();
+ fontList.setToolTip("Font");
+ fontSize.setToolTip("Font Size");
+ fontList.activated.connect(this, "fontChanged(String)");
+ fontSize.activated.connect(this, "fontSizeChanged(String)");
+ fontListAction = buttonLayout.addWidget(fontList);
+ buttonLayout.toggleFontVisible.triggered.connect(this, "toggleFontListVisible(Boolean)");
+ fontSizeAction = buttonLayout.addWidget(fontSize);
+ buttonLayout.toggleFontSizeVisible.triggered.connect(this, "toggleFontSizeVisible(Boolean)");
+ QFontDatabase fonts = new QFontDatabase();
+ List<String> fontFamilies = fonts.families();
+ for (int i = 0; i < fontFamilies.size(); i++) {
+ fontList.addItem(fontFamilies.get(i));
+ if (i == 0) {
+ loadFontSize(fontFamilies.get(i));
+ }
+ }
+
+// buttonLayout.addWidget(newSeparator(), 0);
+ fontColor = newToolButton("fontColor", tr("Font Color"));
+ fontColorMenu = new ColorMenu(this);
+ fontColor.setMenu(fontColorMenu.getMenu());
+ fontColor.setPopupMode(ToolButtonPopupMode.MenuButtonPopup);
+ fontColor.setAutoRaise(false);
+ fontColorMenu.getMenu().triggered.connect(this, "fontColorClicked()");
+ fontColorAction = buttonLayout.addWidget(fontColor);
+ buttonLayout.toggleFontColorVisible.triggered.connect(this, "toggleFontColorVisible(Boolean)");
+ fontHilight = newToolButton("fontHilight", tr("Font Hilight Color"));
+ fontHilight.setPopupMode(ToolButtonPopupMode.MenuButtonPopup);
+ fontHilight.setAutoRaise(false);
+ fontHilightColorMenu = new ColorMenu(this);
+ fontHilightColorMenu.setDefault(QColor.yellow);
+ fontHilight.setMenu(fontHilightColorMenu.getMenu());
+ fontHilightColorMenu.getMenu().triggered.connect(this, "fontHilightClicked()");
+ fontHilightAction = buttonLayout.addWidget(fontHilight);
+ fontHilightColorMenu.setDefault(QColor.yellow);
+ buttonLayout.toggleFontHilight.triggered.connect(this, "toggleFontHilightVisible(Boolean)");
+
+ spellCheckAction = buttonLayout.addWidget(spellCheckButton);
+ buttonLayout.toggleNumberListVisible.triggered.connect(this, "spellCheckClicked()");
+ buttonLayout.toggleSpellCheck.triggered.connect(this, "toggleSpellCheckVisible(Boolean)");
+
+ todoAction = buttonLayout.addWidget(todoButton);
+ buttonLayout.toggleNumberListVisible.triggered.connect(this, "todoClicked()");
+ buttonLayout.toggleTodo.triggered.connect(this, "toggleTodoVisible(Boolean)");
+
+ // Setup the source browser);
+
+// buttonLayout.addWidget(new QLabel(), 1);
+ QSplitter editSplitter = new QSplitter(this);
+ editSplitter.addWidget(browser);
+ editSplitter.setOrientation(Qt.Orientation.Vertical);
+ editSplitter.addWidget(sourceEdit);
+
+
+
+// v.addWidget(browser, 1);
+// v.addWidget(sourceEdit);
+ v.addWidget(editSplitter);
+ setLayout(v);
+
+ browser.downloadAttachmentRequested.connect(this,
+ "downloadAttachment(QNetworkRequest)");
+ browser.downloadImageRequested.connect(this,
+ "downloadImage(QNetworkRequest)");
+ setTabOrder(notebookBox, tagEdit);
+ setTabOrder(tagEdit, browser);
+
+ focusNoteShortcut = new QShortcut(this);
+ setupShortcut(focusNoteShortcut, "Focus_Note");
+ focusNoteShortcut.activated.connect(this, "focusNote()");
+ focusTitleShortcut = new QShortcut(this);
+ setupShortcut(focusTitleShortcut, "Focus_Title");
+ focusTitleShortcut.activated.connect(this, "focusTitle()");
+ focusTagShortcut = new QShortcut(this);
+ setupShortcut(focusTagShortcut, "Focus_Tag");
+ focusTagShortcut.activated.connect(this, "focusTag()");
+ focusAuthorShortcut = new QShortcut(this);
+ setupShortcut(focusAuthorShortcut, "Focus_Author");
+ focusAuthorShortcut.activated.connect(this, "focusAuthor()");
+ focusUrlShortcut = new QShortcut(this);
+ setupShortcut(focusUrlShortcut, "Focus_Url");
+ focusUrlShortcut.activated.connect(this, "focusUrl()");
+
+ browser.page().mainFrame().setTextSizeMultiplier(Global.getTextSizeMultiplier());
+ browser.page().mainFrame().setZoomFactor(Global.getZoomFactor());
+
+ previewPageList = new HashMap<String,Integer>();
+
+ browser.page().microFocusChanged.connect(this, "microFocusChanged()");
+
+ //Setup colors
+
+ QPalette pal = new QPalette();
+ pal.setColor(ColorRole.Text, QColor.black);
+ titleLabel.setPalette(pal);
+ authorText.setPalette(pal);
+ authorLabel.setPalette(pal);
+ urlLabel.setPalette(pal);
+ urlText.setPalette(pal);
+ createdDate.setPalette(pal);
+ createdTime.setPalette(pal);
+ alteredDate.setPalette(pal);
+ alteredTime.setPalette(pal);
+ subjectDate.setPalette(pal);
+ subjectTime.setPalette(pal);
+ tagEdit.setPalette(pal);
+ notebookBox.setPalette(pal);
+
+ blockApplication = new Signal1<BrowserWindow>();
+ unblockApplication = new Signal0();
+
+ setSourceTimer = new QTimer();
+ setSourceTimer.timeout.connect(this, "setSource()");
+
+ logger.log(logger.HIGH, "Browser setup complete");
+ }
+
+
+
+ private void setupShortcut(QShortcut action, String text) {
+ if (!Global.shortcutKeys.containsAction(text))
+ return;
+ action.setKey(new QKeySequence(Global.shortcutKeys.getShortcut(text)));
+ }
+
+
+
+
+ // Getter for the QWebView
+ public QWebView getBrowser() {
+ return browser;
+ }
+
+ // Block signals while loading data or things are flagged as dirty by
+ // mistake
+ public void loadingData(boolean val) {
+ logger.log(logger.EXTREME, "Entering BrowserWindow.loadingData() " +val);
+ notebookBox.blockSignals(val);
+ browser.page().blockSignals(val);
+ browser.page().mainFrame().blockSignals(val);
+ titleLabel.blockSignals(val);
+ alteredDate.blockSignals(val);
+ alteredTime.blockSignals(val);
+ createdTime.blockSignals(val);
+ createdDate.blockSignals(val);
+ subjectDate.blockSignals(val);
+ subjectTime.blockSignals(val);
+ urlText.blockSignals(val);
+ authorText.blockSignals(val);
+ if (!val)
+ exposeToJavascript();
+ logger.log(logger.EXTREME, "Exiting BrowserWindow.loadingData() " +val);
+ }
+
+ // Enable/disable
+ public void setReadOnly(boolean v) {
+ setEnabled(true);
+ titleLabel.setEnabled(!v);
+ notebookBox.setEnabled(!v);
+ tagEdit.setEnabled(!v);
+ authorLabel.setEnabled(!v);
+ geoBox.setEnabled(!v);
+ urlText.setEnabled(!v);
+ createdDate.setEnabled(!v);
+ subjectDate.setEnabled(!v);
+ alteredDate.setEnabled(!v);
+ authorText.setEnabled(!v);
+ createdTime.setEnabled(!v);
+ alteredTime.setEnabled(!v);
+ subjectTime.setEnabled(!v);
+ getBrowser().setEnabled(true);
+ getBrowser().page().setContentEditable(!v);
+// getBrowser().setEnabled(!v);
+ }
+
+ // expose this class to Javascript on the web page
+ private void exposeToJavascript() {
+ browser.page().mainFrame().addToJavaScriptWindowObject("jambi", this);
+ }
+
+ // Custom event queue
+ @Override
+ public boolean event(QEvent e) {
+ if (e.type().equals(QEvent.Type.FocusOut)) {
+ logger.log(logger.EXTREME, "Focus lost");
+ focusLost.emit();
+ }
+ return super.event(e);
+ }
+
+ // clear out browser
+ public void clear() {
+ logger.log(logger.EXTREME, "Entering BrowserWindow.clear()");
+ setNote(null);
+ setContent(new QByteArray());
+ tagEdit.setText("");
+ tagEdit.tagCompleter.reset();
+ urlLabel.setText(tr("Source URL:"));
+ titleLabel.setText("");
+ logger.log(logger.EXTREME, "Exiting BrowserWindow.clear()");
+ }
+
+ public void setContent(QByteArray data) {
+ sourceEdit.blockSignals(true);
+ browser.setContent(data);
+ setSource();
+ }
+ // get/set current note
+ public void setNote(Note n) {
+ currentNote = n;
+ if (n == null)
+ n = new Note();
+ saveNoteTitle = n.getTitle();
+
+ }
+
+ public Note getNote() {
+ return currentNote;
+ }
+
+ // New Editor Button
+ private QPushButton newEditorButton(String name, String toolTip) {
+ QPushButton button = new QPushButton();
+// QIcon icon = new QIcon(iconPath + name + ".gif");
+ QIcon icon = new QIcon(iconPath + name + ".png");
+ button.setIcon(icon);
+ // ICHANGED
+ button.setIconSize(new QSize(16, 16));
+
+ button.setToolTip(toolTip);
+ button.clicked.connect(this, name + "Clicked()");
+ return button;
+ }
+ // New Editor Button
+ private QToolButton newToolButton(String name, String toolTip) {
+ QToolButton button = new QToolButton();
+// QIcon icon = new QIcon(iconPath + name + ".gif");
+ QIcon icon = new QIcon(iconPath + name + ".png");
+ button.setIcon(icon);
+ // ICHANGED
+ button.setIconSize(new QSize(16, 16));
+
+ button.setToolTip(toolTip);
+ button.clicked.connect(this, name + "Clicked()");
+ return button;
+ }
+
+ // New Separator
+ private QLabel newSeparator() {
+ return new QLabel(" ");
+ }
+
+ // Set the title in the window
+ public void setTitle(String t) {
+ titleLabel.setText(t);
+ saveNoteTitle = t;
+ checkNoteTitle();
+ }
+
+ // Return the current text title
+ public String getTitle() {
+ return titleLabel.text();
+ }
+
+ // Set the tag name string
+ public void setTag(String t) {
+ saveTagList = t;
+ tagEdit.setText(t);
+ tagEdit.tagCompleter.reset();
+ }
+
+ // Set the source URL
+ public void setUrl(String t) {
+ urlLabel.setText(tr("Source URL:\t"));
+ urlText.setText(t);
+ }
+
+ // The user want's to launch a web browser on the source of the URL
+ public void sourceUrlClicked() {
+ // Make sure we have a valid URL
+ if (urlText.text().trim().equals(""))
+ return;
+
+ String url = urlText.text();
+ if (!url.toLowerCase().startsWith(tr("http://")))
+ url = tr("http://") +url;
+
+ if (!QDesktopServices.openUrl(new QUrl(url))) {
+ logger.log(logger.LOW, "Error opening file :" +url);
+ }
+ }
+
+ public void setAuthor(String t) {
+ authorLabel.setText(tr("Author:\t"));
+ authorText.setText(t);
+ }
+
+ // Set the creation date
+ public void setCreation(long date) {
+ QDateTime dt = new QDateTime();
+ dt.setTime_t((int) (date / 1000));
+ createdDate.setDateTime(dt);
+ createdTime.setDateTime(dt);
+ createdDate.setDisplayFormat(Global.getDateFormat());
+ createdTime.setDisplayFormat(Global.getTimeFormat());
+ }
+
+ // Set the creation date
+ public void setAltered(long date) {
+ QDateTime dt = new QDateTime();
+ dt.setTime_t((int) (date / 1000));
+ alteredDate.setDateTime(dt);
+ alteredTime.setDateTime(dt);
+ alteredDate.setDisplayFormat(Global.getDateFormat());
+ alteredTime.setDisplayFormat(Global.getTimeFormat());
+ }
+
+ // Set the subject date
+ public void setSubjectDate(long date) {
+ QDateTime dt = new QDateTime();
+ dt.setTime_t((int) (date / 1000));
+ subjectDate.setDateTime(dt);
+ subjectTime.setDateTime(dt);
+ subjectDate.setDisplayFormat(Global.getDateFormat());
+ subjectTime.setDisplayFormat(Global.getTimeFormat());
+ }
+
+ // Toggle the extended attribute information
+ public void toggleInformation() {
+ if (extendedOn) {
+ extendedOn = false;
+ } else {
+ extendedOn = true;
+ }
+ urlLabel.setVisible(extendedOn);
+ urlText.setVisible(extendedOn);
+ authorText.setVisible(extendedOn);
+ geoBox.setVisible(extendedOn);
+ authorLabel.setVisible(extendedOn);
+ createdDate.setVisible(extendedOn);
+ createdTime.setVisible(extendedOn);
+ createdLabel.setVisible(extendedOn);
+ alteredLabel.setVisible(extendedOn);
+ alteredDate.setVisible(extendedOn);
+ alteredTime.setVisible(extendedOn);
+ //notebookBox.setVisible(extendedOn);
+ notebookLabel.setVisible(extendedOn);
+ subjectLabel.setVisible(extendedOn);
+ subjectDate.setVisible(extendedOn);
+ subjectTime.setVisible(extendedOn);
+ }
+
+ public void hideButtons() {
+
+ undoButton.parentWidget().setVisible(false);
+ buttonsVisible = false;
+ }
+
+
+ // Is the extended view on?
+ public boolean isExtended() {
+ return extendedOn;
+ }
+
+ // Listener for when a link is clicked
+ @SuppressWarnings("unused")
+ private void openFile() {
+ logger.log(logger.EXTREME, "Starting openFile()");
+ File fileHandle = new File(selectedFile);
+ URI fileURL = fileHandle.toURI();
+ String localURL = fileURL.toString();
+ QUrl url = new QUrl(localURL);
+ QFile file = new QFile(selectedFile);
+
+ logger.log(logger.EXTREME, "Adding to fileWatcher:"+file.fileName());
+ fileWatcher.addPath(file.fileName());
+
+ if (!QDesktopServices.openUrl(url)) {
+ logger.log(logger.LOW, "Error opening file :" +url);
+ }
+ }
+
+
+ // Listener for when a link is clicked
+ @SuppressWarnings("unused")
+ private void linkClicked(QUrl url) {
+ logger.log(logger.EXTREME, "URL Clicked: " +url.toString());
+ if (url.toString().startsWith("latex:")) {
+ int position = url.toString().lastIndexOf(".");
+ String guid = url.toString().substring(0,position);
+ position = guid.lastIndexOf("/");
+ guid = guid.substring(position+1);
+ editLatex(guid);
+ return;
+ }
+ if (url.toString().startsWith("evernote:/view/")) {
+ StringTokenizer tokens = new StringTokenizer(url.toString().replace("evernote:/view/", ""), "/");
+ tokens.nextToken();
+ tokens.nextToken();
+ String sid = tokens.nextToken();
+ String lid = tokens.nextToken();
+
+ // Emit that we want to switch to a new note
+ evernoteLinkClicked.emit(sid, lid);
+
+ return;
+ }
+ if (url.toString().startsWith("nnres://")) {
+ logger.log(logger.EXTREME, "URL is NN resource");
+ if (url.toString().endsWith("/vnd.evernote.ink")) {
+ logger.log(logger.EXTREME, "Unable to open ink note");
+ QMessageBox.information(this, tr("Unable Open"), tr("This is an ink note.\n"+
+ "Ink notes are not supported since Evernote has not\n published any specifications on them\n" +
+ "and I'm too lazy to figure them out by myself."));
+ return;
+ }
+ String fullName = url.toString().substring(8);
+ int index = fullName.indexOf(".");
+ String guid = "";
+ String type = "";
+ if (index >-1) {
+ type = fullName.substring(index+1);
+ guid = fullName.substring(0,index);
+ }
+ index = guid.indexOf(Global.attachmentNameDelimeter);
+ if (index > -1) {
+ guid = guid.substring(0,index);
+ }
+ List<Resource> resList = currentNote.getResources();
+ Resource res = null;
+ for (int i=0; i<resList.size(); i++) {
+ if (resList.get(i).getGuid().equals(guid)) {
+ res = resList.get(i);
+ i=resList.size();
+ }
+ }
+ if (res == null) {
+ String resGuid = Global.resourceMap.get(guid);
+ if (resGuid != null)
+ res = conn.getNoteTable().noteResourceTable.getNoteResource(resGuid, true);
+ }
+ if (res != null) {
+ String fileName;
+ if (res.getAttributes() != null &&
+ res.getAttributes().getFileName() != null &&
+ !res.getAttributes().getFileName().trim().equals(""))
+ fileName = res.getGuid()+Global.attachmentNameDelimeter+res.getAttributes().getFileName();
+ else
+ fileName = res.getGuid()+"."+type;
+ QFile file = new QFile(Global.getFileManager().getResDirPath(fileName));
+ QFile.OpenMode mode = new QFile.OpenMode();
+ mode.set(QFile.OpenModeFlag.WriteOnly);
+ boolean openResult = file.open(mode);
+ logger.log(logger.EXTREME, "File opened:" +openResult);
+ QDataStream out = new QDataStream(file);
+ Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(res.getGuid(), true);
+ QByteArray binData = new QByteArray(resBinary.getData().getBody());
+ resBinary = null;
+ logger.log(logger.EXTREME, "Writing resource");
+ out.writeBytes(binData.toByteArray());
+ file.close();
+
+ String whichOS = System.getProperty("os.name");
+ if (whichOS.contains("Windows"))
+ url.setUrl("file:///"+file.fileName());
+ else
+ url.setUrl("file://"+file.fileName());
+ // fileWatcher.removePath(file.fileName());
+ logger.log(logger.EXTREME, "Adding file watcher " +file.fileName());
+ fileWatcher.addPath(file.fileName());
+
+ // If we can't open it, then prompt the user to save it.
+ if (!QDesktopServices.openUrl(url)) {
+ logger.log(logger.EXTREME, "We can't handle this. Where do we put it?");
+ QFileDialog dialog = new QFileDialog();
+ dialog.show();
+ if (dialog.exec()!=0) {
+ List<String> fileNames = dialog.selectedFiles(); //gets all selected filenames
+ if (fileNames.size() == 0)
+ return;
+ String sf = fileNames.get(0);
+ QFile saveFile = new QFile(sf);
+ mode.set(QFile.OpenModeFlag.WriteOnly);
+ saveFile.open(mode);
+ QDataStream saveOut = new QDataStream(saveFile);
+ saveOut.writeBytes(binData.toByteArray());
+ saveFile.close();
+ return;
+ }
+ }
+ }
+ return;
+ }
+ logger.log(logger.EXTREME, "Launching URL");
+ QDesktopServices.openUrl(url);
+ }
+
+ // Listener for when BOLD is clicked
+ @SuppressWarnings("unused")
+ private void undoClicked() {
+ browser.page().triggerAction(WebAction.Undo);
+ browser.setFocus();
+ }
+
+ // Listener for when BOLD is clicked
+ @SuppressWarnings("unused")
+ private void redoClicked() {
+ browser.page().triggerAction(WebAction.Redo);
+ browser.setFocus();
+ }
+
+ // Listener for when BOLD is clicked
+ @SuppressWarnings("unused")
+ private void boldClicked() {
+ browser.page().triggerAction(WebAction.ToggleBold);
+ microFocusChanged();
+ browser.setFocus();
+ }
+
+ // Listener for when Italics is clicked
+ @SuppressWarnings("unused")
+ private void italicClicked() {
+ browser.page().triggerAction(WebAction.ToggleItalic);
+ microFocusChanged();
+ browser.setFocus();
+ }
+
+ // Listener for when UNDERLINE is clicked
+ @SuppressWarnings("unused")
+ private void underlineClicked() {
+ browser.page().triggerAction(WebAction.ToggleUnderline);
+ microFocusChanged();
+ browser.setFocus();
+ }
+
+ // Listener for when Strikethrough is clicked
+ @SuppressWarnings("unused")
+ private void strikethroughClicked() {
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('strikeThrough', false, '');");
+ browser.setFocus();
+ }
+
+ // Listener for when cut is clicked
+ @SuppressWarnings("unused")
+ private void cutClicked() {
+ // ICHANGED
+ cbObserver.setCopySourceGuid(currentNote.getGuid(), browser.page().selectedText());
+
+ browser.page().triggerAction(WebAction.Cut);
+ browser.setFocus();
+ }
+
+ // Listener when COPY is clicked
+ @SuppressWarnings("unused")
+ private void copyClicked() {
+ // ICHANGED
+ cbObserver.setCopySourceGuid(currentNote.getGuid(), browser.page().selectedText());
+
+ browser.page().triggerAction(WebAction.Copy);
+ browser.setFocus();
+ }
+
+ // Listener when PASTE is clicked
+ public void pasteClicked() {
+ logger.log(logger.EXTREME, "Paste Clicked");
+ if (forceTextPaste) {
+ pasteWithoutFormattingClicked();
+ return;
+ }
+
+ // ICHANGED コピー&ペーストの操作履歴をデータベースに登録
+ String srcGuid = cbObserver.getSourceGuid();
+ String dstGuid = currentNote.getGuid();
+ if(srcGuid != null && dstGuid != null){
+ if(!srcGuid.equals(dstGuid)){
+ conn.getHistoryTable().addHistory("copy & paste", srcGuid, dstGuid);
+ }
+ }
+
+ QClipboard clipboard = QApplication.clipboard();
+ QMimeData mime = clipboard.mimeData();
+
+ if (mime.hasImage()) {
+ logger.log(logger.EXTREME, "Image paste found");
+ browser.setFocus();
+ insertImage(mime);
+ browser.setFocus();
+ return;
+ }
+
+ if (mime.hasUrls()) {
+ logger.log(logger.EXTREME, "URL paste found");
+ if (mime.text().startsWith("evernote:")) {
+ handleNoteLink(mime);
+ } else {
+ handleUrls(mime);
+ browser.setFocus();
+ }
+ return;
+ }
+
+ String text = mime.html();
+ if (text.contains("en-tag") && mime.hasHtml()) {
+ logger.log(logger.EXTREME, "Intra-note paste found");
+ text = fixInternotePaste(text);
+ mime.setHtml(text);
+ clipboard.setMimeData(mime);
+ }
+
+ logger.log(logger.EXTREME, "Final paste choice encountered");
+ browser.page().triggerAction(WebAction.Paste);
+ browser.setFocus();
+
+ }
+
+ // Paste text without formatting
+ private void pasteWithoutFormattingClicked() {
+ logger.log(logger.EXTREME, "Paste without format clipped");
+ QClipboard clipboard = QApplication.clipboard();
+ QMimeData mime = clipboard.mimeData();
+ if (!mime.hasText())
+ return;
+
+ // ICHANGED コピー&ペーストの操作履歴をデータベースに登録
+ String srcGuid = cbObserver.getSourceGuid();
+ String dstGuid = currentNote.getGuid();
+ if(srcGuid != null && dstGuid != null){
+ if(!srcGuid.equals(dstGuid)){
+ conn.getHistoryTable().addHistory("copy & paste", srcGuid, dstGuid);
+ }
+ }
+
+ String text = mime.text();
+ clipboard.clear();
+ clipboard.setText(text, Mode.Clipboard);
+ browser.page().triggerAction(WebAction.Paste);
+
+ // This is done because pasting into an encryption block
+ // can cause multiple cells (which can't happen). It
+ // just goes through the table, extracts the data, &
+ // puts it back as one table cell.
+ if (insideEncryption) {
+ String js = new String( "function fixEncryption() { "
+ +" var selObj = window.getSelection();"
+ +" var selRange = selObj.getRangeAt(0);"
+ +" var workingNode = window.getSelection().anchorNode;"
+ +" while(workingNode != null && workingNode.nodeName.toLowerCase() != 'table') { "
+ +" workingNode = workingNode.parentNode;"
+ +" } "
+ +" workingNode.innerHTML = window.jambi.fixEncryptionPaste(workingNode.innerHTML);"
+ +"} fixEncryption();");
+ browser.page().mainFrame().evaluateJavaScript(js);
+ }
+ }
+
+ // This basically removes all the table tags and returns just the contents.
+ // This is called by JavaScript to fix encryption pastes.
+ public String fixEncryptionPaste(String data) {
+ data = data.replace("<tbody>", "");
+ data = data.replace("</tbody>", "");
+ data = data.replace("<tr>", "");
+ data = data.replace("</tr>", "");
+ data = data.replace("<td>", "");
+ data = data.replace("</td>", "<br>");
+ data = data.replace("<br><br>", "<br>");
+
+ return "<tbody><tr><td>"+data+"</td></tr></tbody>";
+ }
+
+ // insert date/time
+ @SuppressWarnings("unused")
+ private void insertDateTime() {
+ String fmt = Global.getDateFormat() + " " + Global.getTimeFormat();
+ String dateTimeFormat = new String(fmt);
+ SimpleDateFormat simple = new SimpleDateFormat(dateTimeFormat);
+ Calendar cal = Calendar.getInstance();
+
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('insertHtml', false, '"+simple.format(cal.getTime())+"');");
+
+ browser.setFocus();
+
+ }
+
+ // Listener when Left is clicked
+ @SuppressWarnings("unused")
+ private void justifyLeftClicked() {
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('JustifyLeft', false, '');");
+ browser.setFocus();
+ }
+
+ // Listener when Center is clicked
+ @SuppressWarnings("unused")
+ private void justifyCenterClicked() {
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('JustifyCenter', false, '');");
+ browser.setFocus();
+ }
+
+ // Listener when Left is clicked
+ @SuppressWarnings("unused")
+ private void justifyRightClicked() {
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('JustifyRight', false, '');");
+ browser.setFocus();
+ }
+
+ // Listener when HLINE is clicked
+ @SuppressWarnings("unused")
+ private void hlineClicked() {
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('insertHorizontalRule', false, '');");
+ browser.setFocus();
+ }
+
+ // Listener when outdent is clicked
+ private void outdentClicked() {
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('outdent', false, '');");
+ browser.setFocus();
+ }
+
+ // Listener when a bullet list is clicked
+ @SuppressWarnings("unused")
+ private void bulletListClicked() {
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('InsertUnorderedList', false, '');");
+ browser.setFocus();
+ }
+
+ // Listener when a bullet list is clicked
+ @SuppressWarnings("unused")
+ private void numberListClicked() {
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('InsertOrderedList', false, '');");
+ browser.setFocus();
+ }
+
+ // Listener when indent is clicked
+ private void indentClicked() {
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('indent', false, '');");
+ browser.setFocus();
+ }
+
+ // Listener when the font name is changed
+ @SuppressWarnings("unused")
+ private void fontChanged(String font) {
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('fontName',false,'" + font + "');");
+ browser.setFocus();
+ }
+
+ // Listener when a font size is changed
+ @SuppressWarnings("unused")
+ private void fontSizeChanged(String font) {
+ String text = browser.selectedText();
+ if (text.trim().equalsIgnoreCase(""))
+ return;
+
+ String selectedText = browser.selectedText();
+ String url = "<span style=\"font-size:" +font +"pt; \">"+selectedText +"</a>";
+ String script = "document.execCommand('insertHtml', false, '"+url+"');";
+ browser.page().mainFrame().evaluateJavaScript(script);
+/* browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('fontSize',false,'"
+ + font + "');");
+*/
+ browser.setFocus();
+ }
+
+ // Load the font combo box based upon the font selected
+ private void loadFontSize(String name) {
+ QFontDatabase db = new QFontDatabase();
+ fontSize.clear();
+ List<Integer> points = db.pointSizes(name);
+ for (int i=0; i<points.size(); i++) {
+ fontSize.addItem(points.get(i).toString());
+ }
+ /*
+ fontSize.addItem("x-small");
+ fontSize.addItem("small");
+ fontSize.addItem("medium");
+ fontSize.addItem("large");
+ fontSize.addItem("x-large");
+ fontSize.addItem("xx-large");
+ fontSize.addItem("xxx-large");
+ */
+ }
+
+ // Listener when a font size is changed
+ @SuppressWarnings("unused")
+ private void fontColorClicked() {
+// QColorDialog dialog = new QColorDialog();
+// QColor color = QColorDialog.getColor();
+ QColor color = fontColorMenu.getColor();
+ if (color.isValid())
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('foreColor',false,'" + color.name()
+ + "');");
+ browser.setFocus();
+ }
+
+ // Listener for when a background color change is requested
+ @SuppressWarnings("unused")
+ private void fontHilightClicked() {
+// QColorDialog dialog = new QColorDialog();
+// QColor color = QColorDialog.getColor();
+ QColor color = fontHilightColorMenu.getColor();
+ if (color.isValid())
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('backColor',false,'" + color.name()
+ + "');");
+ browser.setFocus();
+ }
+
+ // Listener for when a background color change is requested
+ @SuppressWarnings("unused")
+ private void superscriptClicked() {
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('superscript');");
+ browser.setFocus();
+ }
+
+ // Listener for when a background color change is requested
+ @SuppressWarnings("unused")
+ private void subscriptClicked() {
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('subscript');");
+ browser.setFocus();
+ }
+ // Insert a to-do checkbox
+ @SuppressWarnings("unused")
+ private void todoClicked() {
+ FileNameMap fileNameMap = URLConnection.getFileNameMap();
+ String script_start = new String(
+ "document.execCommand('insertHtml', false, '");
+ String script_end = new String("');");
+ String todo = new String(
+ "<input TYPE=\"CHECKBOX\" value=\"false\" " +
+ "onMouseOver=\"style.cursor=\\'hand\\'\" " +
+ "onClick=\"value=checked; window.jambi.contentChanged(); \" />");
+ browser.page().mainFrame().evaluateJavaScript(
+ script_start + todo + script_end);
+ browser.setFocus();
+ }
+
+ // Encrypt the selected text
+ @SuppressWarnings("unused")
+ private void encryptText() {
+ String text = browser.selectedText();
+ if (text.trim().equalsIgnoreCase(""))
+ return;
+ text = new String(text.replaceAll("\n", "<br/>"));
+
+ EnCryptDialog dialog = new EnCryptDialog();
+ dialog.exec();
+ if (!dialog.okPressed()) {
+ return;
+ }
+
+ EnCrypt crypt = new EnCrypt();
+ String encrypted = crypt.encrypt(text, dialog.getPassword().trim(), 64);
+ String decrypted = crypt.decrypt(encrypted, dialog.getPassword().trim(), 64);
+
+ if (encrypted.trim().equals("")) {
+ QMessageBox.information(this, tr("Error"), tr("Error Encrypting String"));
+ return;
+ }
+ StringBuffer buffer = new StringBuffer(encrypted.length() + 100);
+ buffer.append("<img en-tag=\"en-crypt\" cipher=\"RC2\" hint=\""
+ + dialog.getHint().replace("'","\\'") + "\" length=\"64\" ");
+ buffer.append("contentEditable=\"false\" alt=\"");
+ buffer.append(encrypted);
+ buffer.append("\" src=\"").append(FileUtils.toForwardSlashedPath(Global.getFileManager().getImageDirPath("encrypt.png") +"\""));
+ Global.cryptCounter++;
+ buffer.append(" id=\"crypt"+Global.cryptCounter.toString() +"\"");
+ buffer.append(" onMouseOver=\"style.cursor=\\'hand\\'\"");
+ buffer.append(" onClick=\"window.jambi.decryptText(\\'crypt"+Global.cryptCounter.toString()
+ +"\\', \\'"+encrypted+"\\', \\'"+dialog.getHint().replace("'", "\\&apos;")+"\\');\"");
+ buffer.append("style=\"display:block\" />");
+
+ String script_start = new String(
+ "document.execCommand('insertHtml', false, '");
+ String script_end = new String("');");
+ browser.page().mainFrame().evaluateJavaScript(
+ script_start + buffer.toString() + script_end);
+ }
+
+
+ // Insert a Quick hyperlink
+ public void insertQuickLink() {
+ logger.log(logger.EXTREME, "Inserting link");
+ String text = browser.selectedText();
+ if (text.trim().equalsIgnoreCase(""))
+ return;
+
+ // ICHANGED
+ NoteQuickLinkDialog dialog = new NoteQuickLinkDialog(logger, conn, text, cbObserver);
+
+ if (dialog.getResults().size() == 0) {
+ QMessageBox.critical(null, tr("No Matches Found") ,tr("No matching notes found."));
+ return;
+ }
+ if (dialog.getResults().size() > 1) {
+ dialog.exec();
+ if (!dialog.okPressed) {
+ logger.log(logger.EXTREME, "Insert link canceled");
+ return;
+ }
+ }
+
+ User user = Global.getUserInformation();
+ String dUrl = new String("evernote:///view/") + new String(user.getId() + "/" +user.getShardId() +"/"
+ +dialog.getSelectedNote()+"/"+dialog.getSelectedNote() +"/ " +"style=\"color:#69aa35\"");
+
+ String url = "<a title=\"" +dUrl
+ +"\" href=" +dUrl
+ +" >"+text +"</a>";
+ String script = "document.execCommand('insertHtml', false, '"+url+"');";
+ browser.page().mainFrame().evaluateJavaScript(script);
+ contentChanged();
+ }
+
+ // Insert a hyperlink
+ public void insertLink() {
+ logger.log(logger.EXTREME, "Inserting link");
+ String text = browser.selectedText();
+ if (text.trim().equalsIgnoreCase(""))
+ return;
+
+ InsertLinkDialog dialog = new InsertLinkDialog(insertHyperlink);
+ if (currentHyperlink != null && currentHyperlink != "") {
+ dialog.setUrl(currentHyperlink);
+ }
+ dialog.exec();
+ if (!dialog.okPressed()) {
+ logger.log(logger.EXTREME, "Insert link canceled");
+ return;
+ }
+
+ // Take care of inserting new links
+ if (insertHyperlink) {
+ String selectedText = browser.selectedText();
+ if (dialog.getUrl().trim().equals(""))
+ return;
+ logger.log(logger.EXTREME, "Inserting link on text "+selectedText);
+ logger.log(logger.EXTREME, "URL Link " +dialog.getUrl().trim());
+ String dUrl = StringUtils.replace(dialog.getUrl().trim(), "'", "\\'");
+ String url = "<a href=\"" +dUrl
+ +"\" title=" +dUrl
+ +" >"+selectedText +"</a>";
+ String script = "document.execCommand('insertHtml', false, '"+url+"');";
+ browser.page().mainFrame().evaluateJavaScript(script);
+ return;
+ }
+
+ // Edit existing links
+ String js = new String( "function getCursorPos() {"
+ +"var cursorPos;"
+ +"if (window.getSelection) {"
+ +" var selObj = window.getSelection();"
+ +" var selRange = selObj.getRangeAt(0);"
+ +" var workingNode = window.getSelection().anchorNode.parentNode;"
+ +" while(workingNode != null) { "
+ +" if (workingNode.nodeName.toLowerCase()=='a') workingNode.setAttribute('href','" +dialog.getUrl() +"');"
+ +" workingNode = workingNode.parentNode;"
+ +" }"
+ +"}"
+ +"} getCursorPos();");
+ browser.page().mainFrame().evaluateJavaScript(js);
+
+ if (!dialog.getUrl().trim().equals("")) {
+ contentChanged();
+ return;
+ }
+
+ // Remove URL
+ js = new String( "function getCursorPos() {"
+ +"var cursorPos;"
+ +"if (window.getSelection) {"
+ +" var selObj = window.getSelection();"
+ +" var selRange = selObj.getRangeAt(0);"
+ +" var workingNode = window.getSelection().anchorNode.parentNode;"
+ +" while(workingNode != null) { "
+ +" if (workingNode.nodeName.toLowerCase()=='a') { "
+ +" workingNode.removeAttribute('href');"
+ +" workingNode.removeAttribute('title');"
+ +" var text = document.createTextNode(workingNode.innerText);"
+ +" workingNode.parentNode.insertBefore(text, workingNode);"
+ +" workingNode.parentNode.removeChild(workingNode);"
+ +" }"
+ +" workingNode = workingNode.parentNode;"
+ +" }"
+ +"}"
+ +"} getCursorPos();");
+ browser.page().mainFrame().evaluateJavaScript(js);
+
+ contentChanged();
+
+
+ }
+
+
+ // Insert a hyperlink
+ public void insertLatex() {
+ editLatex(null);
+ }
+ public void editLatex(String guid) {
+ logger.log(logger.EXTREME, "Inserting latex");
+ String text = browser.selectedText();
+ if (text.trim().equalsIgnoreCase("\n") || text.trim().equalsIgnoreCase("")) {
+ InsertLatexImage dialog = new InsertLatexImage();
+ if (guid != null) {
+ String formula = conn.getNoteTable().noteResourceTable.getNoteSourceUrl(guid).replace("http://latex.codecogs.com/gif.latex?", "");
+ dialog.setFormula(formula);
+ }
+ dialog.exec();
+ if (!dialog.okPressed()) {
+ logger.log(logger.EXTREME, "Edit LaTex canceled");
+ return;
+ }
+ text = dialog.getFormula().trim();
+ }
+ blockApplication.emit(this);
+ logger.log(logger.EXTREME, "Inserting LaTeX formula:" +text);
+ latexGuid = guid;
+ text = StringUtils.replace(text, "'", "\\'");
+ String url = "http://latex.codecogs.com/gif.latex?" +text;
+ logger.log(logger.EXTREME, "Sending request to codecogs --> " + url);
+ QNetworkAccessManager manager = new QNetworkAccessManager(this);
+ manager.finished.connect(this, "insertLatexImageReady(QNetworkReply)");
+ unblockTime = new GregorianCalendar().getTimeInMillis()+5000;
+ awaitingHttpResponse = true;
+ manager.get(new QNetworkRequest(new QUrl(url)));
+ }
+
+ public void insertLatexImageReady(QNetworkReply reply) {
+ logger.log(logger.EXTREME, "Response received from CodeCogs");
+ if (reply.error() != NetworkError.NoError)
+ return;
+
+ unblockTime = -1;
+ if (!awaitingHttpResponse)
+ return;
+
+ awaitingHttpResponse = false;
+ QUrl replyUrl = reply.url();
+ QByteArray image = reply.readAll();
+ reply.close();
+ logger.log(logger.EXTREME, "New image size: " +image.size());
+
+ Resource newRes = null;
+ QFile tfile;
+ String path;
+ if (latexGuid == null) {
+ logger.log(logger.EXTREME, "Creating temporary gif");
+ path = Global.getFileManager().getResDirPath("latex-temp.gif");
+ tfile = new QFile(path);
+ tfile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.WriteOnly));
+ logger.log(logger.EXTREME, "File Open: " +tfile.errorString());
+ tfile.write(image);
+ logger.log(logger.EXTREME, "Bytes writtes: "+tfile.size());
+ tfile.close();
+ logger.log(logger.EXTREME, "Creating resource");
+ int sequence = 0;
+ if (currentNote.getResources() != null || currentNote.getResources().size() > 0)
+ sequence = currentNote.getResources().size();
+ newRes = createResource(path,sequence ,"image/gif", false);
+ QImage pix = new QImage();
+ pix.loadFromData(image);
+ newRes.setHeight(new Integer(pix.height()).shortValue());
+ newRes.setWidth(new Integer(pix.width()).shortValue());
+ logger.log(logger.EXTREME, "Renaming temporary file to " +newRes.getGuid()+".gif");
+ path = Global.getFileManager().getResDirPath(newRes.getGuid()+".gif");
+ tfile.rename(path);
+ } else {
+ newRes = conn.getNoteTable().noteResourceTable.getNoteResource(latexGuid, false);
+ path = Global.getFileManager().getResDirPath(newRes.getGuid()+".gif");
+ tfile = new QFile(path);
+ tfile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.WriteOnly));
+ tfile.write(image);
+ tfile.close();
+ newRes.getData().setBody(image.toByteArray());
+ // Calculate the new hash value
+ MessageDigest md;
+
+ logger.log(logger.EXTREME, "Generating MD5");
+ try {
+ md = MessageDigest.getInstance("MD5");
+ md.update(image.toByteArray());
+ byte[] hash = md.digest();
+ newRes.getData().setBodyHash(hash);
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ }
+ QImage pix = new QImage();
+ pix.loadFromData(image);
+ newRes.setHeight(new Integer(pix.height()).shortValue());
+ newRes.setWidth(new Integer(pix.width()).shortValue());
+ conn.getNoteTable().noteResourceTable.updateNoteResource(newRes, true);
+ }
+
+ logger.log(logger.EXTREME, "Setting source: " +replyUrl.toString());
+ newRes.getAttributes().setSourceURL(replyUrl.toString());
+ conn.getNoteTable().noteResourceTable.updateNoteSourceUrl(newRes.getGuid(), replyUrl.toString(), true);
+
+ for(int i=0; i<currentNote.getResourcesSize(); i++) {
+ if (currentNote.getResources().get(i).getGuid().equals(newRes.getGuid())) {
+ currentNote.getResources().remove(i);
+ i=currentNote.getResourcesSize();
+ }
+ }
+ currentNote.getResources().add(newRes);
+
+
+ // do the actual insert into the note. We only do this on new formulas.
+ if (latexGuid == null) {
+ StringBuffer buffer = new StringBuffer(100);
+ String formula = replyUrl.toString().toLowerCase().replace("http://latex.codecogs.com/gif.latex?", "");
+ buffer.append("<a href=\"latex://"+path.replace("\\", "/")+"\" title=\""+formula+"\""
+ +"><img src=\"");
+ buffer.append(path.replace("\\", "/"));
+ buffer.append("\" en-tag=\"en-latex\" type=\"image/gif\""
+ +" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\""
+ +" guid=\"" +newRes.getGuid() +"\""
+ + " /></a>");
+
+ String script_start = new String("document.execCommand('insertHTML', false, '");
+ String script_end = new String("');");
+ browser.page().mainFrame().evaluateJavaScript(
+ script_start + buffer + script_end);
+ } else {
+ HtmlTagModifier modifier = new HtmlTagModifier(getContent());
+ modifier.modifyLatexTagHash(newRes);
+ String newContent = modifier.getHtml();
+ setContent(new QByteArray(newContent));
+ }
+
+ logger.log(logger.EXTREME, "New HTML set\n" +browser.page().currentFrame().toHtml());
+ QWebSettings.setMaximumPagesInCache(0);
+ QWebSettings.setObjectCacheCapacities(0, 0, 0);
+
+ browser.page().mainFrame().setHtml(browser.page().mainFrame().toHtml());
+ browser.reload();
+ contentChanged();
+// resourceSignal.contentChanged.emit(path);
+ unblockTime = -1;
+ unblockApplication.emit();
+ return;
+
+ }
+
+
+
+ // Insert a table
+ public void insertTable() {
+ TableDialog dialog = new TableDialog();
+ dialog.exec();
+ if (!dialog.okPressed()) {
+ return;
+ }
+
+ int cols = dialog.getCols();
+ int rows = dialog.getRows();
+ int width = dialog.getWidth();
+ boolean percent = dialog.isPercent();
+
+ String newHTML = "<table border=\"1\" width=\"" +new Integer(width).toString();
+ if (percent)
+ newHTML = newHTML +"%";
+ newHTML = newHTML + "\"><tbody>";
+
+ for (int i=0; i<rows; i++) {
+ newHTML = newHTML +"<tr>";
+ for (int j=0; j<cols; j++) {
+ newHTML = newHTML +"<td> </td>";
+ }
+ newHTML = newHTML +"</tr>";
+ }
+ newHTML = newHTML+"</tbody></table>";
+
+ String script = "document.execCommand('insertHtml', false, '"+newHTML+"');";
+ browser.page().mainFrame().evaluateJavaScript(script);
+ }
+
+
+ // Text content changed
+ @SuppressWarnings("unused")
+ private void selectionChanged() {
+ browser.encryptAction.setEnabled(true);
+ browser.insertLinkAction.setEnabled(true);
+ browser.insertQuickLinkAction.setEnabled(true);
+ String scriptStart = "var selection_text = (window.getSelection()).toString();"
+ + "var range = (window.getSelection()).getRangeAt(0);"
+ + "var parent_html = range.commonAncestorContainer.innerHTML;"
+ + "if (parent_html == undefined) {window.jambi.saveSelectedText(selection_text); return;}"
+ + "var first_text = range.startContainer.nodeValue.substr(range.startOffset);"
+ + "var last_text = (range.endContainer.nodeValue).substring(0,range.endOffset);"
+ + "var start = parent_html.indexOf(first_text);"
+ + "var end = parent_html.indexOf(last_text,start+1)+last_text.length;"
+ + "var value = parent_html.substring(start,end);"
+ + "window.jambi.saveSelectedText(value);" ;
+ browser.page().mainFrame().evaluateJavaScript(scriptStart);
+
+ }
+
+ public void saveSelectedText(String text) {
+ boolean enabled = true;
+ if (text.trim().length() == 0)
+ enabled=false;
+ if (text.indexOf("en-tag=\"en-crypt\"") >= 0)
+ enabled=false;
+ if (text.indexOf("<img en-tag=\"en-media\"") >= 0)
+ enabled=false;
+ if (text.indexOf("<a en-tag=\"en-media\"") >= 0)
+ enabled=false;
+ if (text.indexOf("<input ") >= 0)
+ enabled=false;
+
+ browser.encryptAction.setEnabled(enabled);
+ browser.insertLinkAction.setEnabled(enabled);
+ browser.insertQuickLinkAction.setEnabled(enabled);
+// selectedText = text;
+ }
+
+ // Decrypt clicked text
+ public void decryptText(String id, String text, String hint) {
+ EnCrypt crypt = new EnCrypt();
+ String plainText = null;
+ Calendar currentTime = new GregorianCalendar();
+ Long l = new Long(currentTime.getTimeInMillis());
+ String slot = new String(Long.toString(l));
+
+ // First, try to decrypt with any keys we already have
+ for (int i=0; i<Global.passwordRemember.size(); i++) {
+ plainText = crypt.decrypt(text, Global.passwordRemember.get(i).getFirst(), 64);
+ if (plainText != null) {
+ slot = new String(Long.toString(l));
+ Global.passwordSafe.put(slot, Global.passwordRemember.get(i));
+ removeEncryption(id, plainText, false, slot);
+ return;
+ }
+ }
+
+
+ EnDecryptDialog dialog = new EnDecryptDialog();
+ dialog.setHint(hint);
+ while (plainText == null || !dialog.okPressed()) {
+ dialog.exec();
+ if (!dialog.okPressed()) {
+ return;
+ }
+ plainText = crypt.decrypt(text, dialog.getPassword().trim(), 64);
+ if (plainText == null) {
+ QMessageBox.warning(this, tr("Incorrect Password"), tr("The password entered is not correct"));
+ }
+ }
+ Pair<String,String> passwordPair = new Pair<String,String>();
+ passwordPair.setFirst(dialog.getPassword());
+ passwordPair.setSecond(dialog.getHint());
+ Global.passwordSafe.put(slot, passwordPair);
+// removeEncryption(id, plainText.replaceAll("\n", "<br/>"), dialog.permanentlyDecrypt(), slot);
+ removeEncryption(id, plainText, dialog.permanentlyDecrypt(), slot);
+ if (dialog.rememberPassword()) {
+ Pair<String, String> pair = new Pair<String,String>();
+ pair.setFirst(dialog.getPassword());
+ pair.setSecond(dialog.getHint());
+ Global.passwordRemember.add(pair);
+ }
+
+ }
+
+ // Get the editor tag line
+ public TagLineEdit getTagLine() {
+ return tagEdit;
+ }
+
+ // Modify a note's tags
+ @SuppressWarnings("unused")
+ private void modifyTags() {
+ TagAssign tagWindow = new TagAssign(allTags, currentTags, !conn.getNotebookTable().isLinked(currentNote.getNotebookGuid()));
+ tagWindow.exec();
+ if (tagWindow.okClicked()) {
+ currentTags.clear();
+ StringBuffer tagDisplay = new StringBuffer();
+
+ List<QListWidgetItem> newTags = tagWindow.getTagList()
+ .selectedItems();
+ for (int i = 0; i < newTags.size(); i++) {
+ currentTags.add(newTags.get(i).text());
+ tagDisplay.append(newTags.get(i).text());
+ if (i < newTags.size() - 1) {
+ tagDisplay.append(Global.tagDelimeter + " ");
+ }
+ }
+ tagEdit.setText(tagDisplay.toString());
+ noteSignal.tagsChanged.emit(currentNote.getGuid(), currentTags);
+ }
+ }
+
+ // Tag line has been modified by typing text
+ @SuppressWarnings("unused")
+ private void modifyTagsTyping() {
+ String completionText = "";
+ if (tagEdit.currentCompleterSelection != null && !tagEdit.currentCompleterSelection.equals("")) {
+ completionText = tagEdit.currentCompleterSelection;
+ tagEdit.currentCompleterSelection = "";
+ }
+
+ if (tagEdit.text().equalsIgnoreCase(saveTagList))
+ return;
+
+ // We know something has changed...
+ String oldTagArray[] = saveTagList.split(Global.tagDelimeter);
+ String newTagArray[];
+ if (!completionText.equals("")) {
+ String before = tagEdit.text().substring(0,tagEdit.cursorPosition());
+ int lastDelimiter = before.lastIndexOf(Global.tagDelimeter);
+ if (lastDelimiter > 0)
+ before = before.substring(0,before.lastIndexOf(Global.tagDelimeter));
+ else
+ before = "";
+ String after = tagEdit.text().substring(tagEdit.cursorPosition());
+ newTagArray = (before+Global.tagDelimeter+completionText+Global.tagDelimeter+after).split(Global.tagDelimeter);
+ }
+ else {
+ newTagArray = tagEdit.text().split(Global.tagDelimeter);
+ }
+
+ // Remove any traling or leading blanks
+ for (int i=0; i<newTagArray.length; i++)
+ newTagArray[i] = newTagArray[i].trim().replaceAll("^\\s+", "");;
+
+ // Remove any potential duplicates from the new list
+ for (int i=0; i<newTagArray.length; i++) {
+ boolean foundOnce = false;
+ for (int j=0; j<newTagArray.length; j++) {
+ if (newTagArray[j].equalsIgnoreCase(newTagArray[i])) {
+ if (!foundOnce) {
+ foundOnce = true;
+ } else
+ newTagArray[j] = "";
+ }
+ }
+ }
+
+ List<String> newTagList = new ArrayList<String>();
+ List<String> oldTagList = new ArrayList<String>();
+
+ for (int i = 0; i < oldTagArray.length; i++)
+ if (!oldTagArray[i].trim().equals(""))
+ oldTagList.add(oldTagArray[i]);
+ for (int i = 0; i < newTagArray.length; i++)
+ if (!newTagArray[i].trim().equals(""))
+ newTagList.add(newTagArray[i]);
+
+ if (conn.getNotebookTable().isLinked(currentNote.getNotebookGuid())) {
+ for (int i=newTagList.size()-1; i>=0; i--) {
+ boolean found = false;
+ for (int j=0; j<allTags.size(); j++) {
+ if (allTags.get(j).getName().equalsIgnoreCase(newTagList.get(i))) {
+ found = true;
+ j=allTags.size();
+ }
+ }
+ if (!found)
+ newTagList.remove(i);
+ }
+ }
+
+ // Let's cleanup the appearance of the tag list
+ Collections.sort(newTagList);
+ String newDisplay = "";
+ for (int i=0; i<newTagList.size(); i++) {
+ newDisplay = newDisplay+newTagList.get(i);
+ if (i<newTagList.size()-1)
+ newDisplay = newDisplay+Global.tagDelimeter +" ";
+ }
+ tagEdit.blockSignals(true);
+ tagEdit.setText(newDisplay);
+ tagEdit.blockSignals(false);
+
+ // We now have lists of the new & old. Remove duplicates. If all
+ // are removed from both then nothing has really changed
+ for (int i = newTagList.size() - 1; i >= 0; i--) {
+ String nTag = newTagList.get(i);
+ for (int j = oldTagList.size() - 1; j >= 0; j--) {
+ String oTag = oldTagList.get(j);
+ if (oTag.equalsIgnoreCase(nTag)) {
+ oldTagList.remove(j);
+ newTagList.remove(i);
+ j = -1;
+ }
+ }
+ }
+
+ if (oldTagList.size() != 0 || newTagList.size() != 0) {
+ currentTags.clear();
+ newTagArray = tagEdit.text().split(Global.tagDelimeter);
+ for (int i = 0; i < newTagArray.length; i++)
+ if (!newTagArray[i].trim().equals(""))
+ currentTags.add(newTagArray[i].trim());
+
+ noteSignal.tagsChanged.emit(currentNote.getGuid(), currentTags);
+ }
+
+ }
+
+ // Tab button was pressed
+ public void tabPressed() {
+ if (insideEncryption)
+ return;
+ if (!insideList && !insideTable) {
+ String script_start = new String(
+ "document.execCommand('insertHtml', false, ' ');");
+ browser.page().mainFrame().evaluateJavaScript(script_start);
+ return;
+ }
+ if (insideList) {
+ indentClicked();
+ }
+ if (insideTable) {
+ String js = new String( "function getCursorPosition() { "
+ +" var selObj = window.getSelection();"
+ +" var selRange = selObj.getRangeAt(0);"
+ +" var workingNode = window.getSelection().anchorNode;"
+ +" var rowCount = 0;"
+ +" var colCount = 0;"
+ +" while(workingNode != null && workingNode.nodeName.toLowerCase() != 'table') { "
+ +" if (workingNode.nodeName.toLowerCase()=='tr') {"
+ +" rowCount = rowCount+1;"
+ +" }"
+ +" if (workingNode.nodeName.toLowerCase() == 'td') {"
+ +" colCount = colCount+1;"
+ +" }"
+ +" if (workingNode.previousSibling != null)"
+ +" workingNode = workingNode.previousSibling;"
+ +" else "
+ +" workingNode = workingNode.parentNode;"
+ +" }"
+ +" var nodes = workingNode.getElementsByTagName('tr');"
+ +" var tableRows = nodes.length;"
+ +" nodes = nodes[0].getElementsByTagName('td');"
+ +" var tableColumns = nodes.length;"
+ +" window.jambi.setTableCursorPositionTab(rowCount, colCount, tableRows, tableColumns);"
+ +"} getCursorPosition();");
+ browser.page().mainFrame().evaluateJavaScript(js);
+ }
+ }
+
+ // If a user presses tab from within a table
+ public void setTableCursorPositionTab(int currentRow, int currentCol, int tableRows, int tableColumns) {
+ if (tableRows == currentRow && currentCol == tableColumns) {
+ insertTableRow();
+ }
+ KeyboardModifiers modifiers = new KeyboardModifiers(KeyboardModifier.NoModifier);
+ QKeyEvent right = new QKeyEvent(Type.KeyPress, Qt.Key.Key_Right.value(), modifiers);
+ QKeyEvent end = new QKeyEvent(Type.KeyPress, Qt.Key.Key_End.value(), modifiers);
+ QKeyEvent end2 = new QKeyEvent(Type.KeyPress, Qt.Key.Key_End.value(), modifiers);
+ getBrowser().focusWidget();
+ QCoreApplication.postEvent(getBrowser(), end);
+ QCoreApplication.postEvent(getBrowser(), right);
+ QCoreApplication.postEvent(getBrowser(), end2);
+ }
+
+ public void backtabPressed() {
+ if (insideEncryption)
+ return;
+ if (insideList)
+ outdentClicked();
+ if (insideTable) {
+ String js = new String( "function getCursorPosition() { "
+ +" var selObj = window.getSelection();"
+ +" var selRange = selObj.getRangeAt(0);"
+ +" var workingNode = window.getSelection().anchorNode;"
+ +" var rowCount = 0;"
+ +" var colCount = 0;"
+ +" while(workingNode != null && workingNode.nodeName.toLowerCase() != 'table') { "
+ +" if (workingNode.nodeName.toLowerCase()=='tr') {"
+ +" rowCount = rowCount+1;"
+ +" }"
+ +" if (workingNode.nodeName.toLowerCase() == 'td') {"
+ +" colCount = colCount+1;"
+ +" }"
+ +" if (workingNode.previousSibling != null)"
+ +" workingNode = workingNode.previousSibling;"
+ +" else "
+ +" workingNode = workingNode.parentNode;"
+ +" }"
+ +" var nodes = workingNode.getElementsByTagName('tr');"
+ +" var tableRows = nodes.length;"
+ +" nodes = nodes[0].getElementsByTagName('td');"
+ +" var tableColumns = nodes.length;"
+ +" window.jambi.setTableCursorPositionBackTab(rowCount, colCount, tableRows, tableColumns);"
+ +"} getCursorPosition();");
+ browser.page().mainFrame().evaluateJavaScript(js);
+
+ }
+ }
+
+ // If a user presses backtab from within a table
+ public void setTableCursorPositionBackTab(int currentRow, int currentCol, int tableRows, int tableColumns) {
+ if (currentRow == 1 && currentCol == 1) {
+ return;
+ }
+ KeyboardModifiers modifiers = new KeyboardModifiers(KeyboardModifier.NoModifier);
+ QKeyEvent left = new QKeyEvent(Type.KeyPress, Qt.Key.Key_Left.value(), modifiers);
+ QKeyEvent home = new QKeyEvent(Type.KeyPress, Qt.Key.Key_Home.value(), modifiers);
+ getBrowser().focusWidget();
+ QCoreApplication.postEvent(getBrowser(), home);
+ QCoreApplication.postEvent(getBrowser(), left);
+ }
+
+
+ public void setInsideList() {
+ insideList = true;
+ }
+
+ // The title has been edited
+ @SuppressWarnings("unused")
+ private void titleEdited() {
+ // If we don't have a good note, or if the current title
+ // matches the old title then we don't need to do anything
+ if (currentNote == null)
+ return;
+ if (currentNote.getTitle().trim().equals(titleLabel.text().trim()))
+ return;
+
+ // If we have a real change, we need to save it.
+ String text = titleLabel.text().trim();
+ if (text.equals(""))
+ text = tr("Untitled Note");
+ noteSignal.titleChanged.emit(currentNote.getGuid(), text);
+ currentNote.setTitle(text);
+ saveNoteTitle = text;
+ checkNoteTitle();
+ }
+
+ // Set the list of note tags
+ public void setAllTags(List<Tag> l) {
+ allTags = l;
+ tagEdit.setTagList(l);
+ }
+
+ // Setter for the current tags
+ public void setCurrentTags(List<String> s) {
+ currentTags = s;
+ }
+
+ // Save the list of notebooks
+ public void setNotebookList(List<Notebook> n) {
+ notebookList = n;
+ loadNotebookList();
+ }
+
+ // Load the notebook list and select the current notebook
+ private void loadNotebookList() {
+ if (notebookBox.count() != 0)
+ notebookBox.clear();
+ if (notebookList == null)
+ return;
+
+ for (int i = 0; i < notebookList.size(); i++) {
+ notebookBox.addItem(notebookList.get(i).getName());
+ if (currentNote != null) {
+ if (currentNote.getNotebookGuid().equals(
+ notebookList.get(i).getGuid())) {
+ notebookBox.setCurrentIndex(i);
+ }
+ }
+ }
+ }
+
+
+ // Set the notebook for a note
+ public void setNotebook(String notebook) {
+ currentNote.setNotebookGuid(notebook);
+ loadNotebookList();
+ }
+
+ // Get the contents of the editor
+ public String getContent() {
+ return browser.page().currentFrame().toHtml();
+ }
+
+ // The note contents have changed
+ public void contentChanged() {
+ String content = getContent();
+
+ // This puts in a 1/2 second delay
+ // before updating the source editor.
+ // It improves response when someone is doing
+ // frequent updates on a large note.
+ // If the source editor isn't visible, then there
+ // is no point to doing any of this.
+ if (sourceEdit.isVisible()) {
+ setSourceTimer.stop();
+ setSourceTimer.setInterval(500);
+ setSourceTimer.setSingleShot(true);
+ setSourceTimer.start();
+ }
+
+ checkNoteTitle();
+ noteSignal.noteChanged.emit(currentNote.getGuid(), content);
+ }
+
+ // The notebook selection has changed
+ @SuppressWarnings("unused")
+ private void notebookChanged() {
+ boolean changed = false;
+ String n = notebookBox.currentText();
+ for (int i = 0; i < notebookList.size(); i++) {
+ if (n.equals(notebookList.get(i).getName())) {
+ if (!notebookList.get(i).getGuid().equals(currentNote.getNotebookGuid())) {
+ String guid = conn.getNotebookTable().findNotebookByName(n);
+ if (conn.getNotebookTable().isLinked(guid)) {
+ tagEdit.setText("");
+ noteSignal.tagsChanged.emit(currentNote.getGuid(), new ArrayList<String>());
+ FilterEditorTags t = new FilterEditorTags(conn, logger);
+ setAllTags(t.getValidTags(currentNote));
+ }
+ currentNote.setNotebookGuid(notebookList.get(i).getGuid());
+ changed = true;
+ }
+ i = notebookList.size();
+ }
+ }
+
+ // If the notebook changed, signal the update
+ if (changed)
+ noteSignal.notebookChanged.emit(currentNote.getGuid(), currentNote
+ .getNotebookGuid());
+ }
+
+ // Check the note title
+ private void checkNoteTitle() {
+ String text = browser.page().currentFrame().toPlainText();
+ if (saveNoteTitle == null)
+ saveNoteTitle = new String();
+ text = text.trim();
+ if (!saveNoteTitle.trim().equals("") && !saveNoteTitle.trim().equals("Untitled Note"))
+ text = saveNoteTitle.trim();
+ int newLine = text.indexOf("\n");
+ if (newLine > 0)
+ text = text.substring(0,newLine);
+ if (saveNoteTitle.trim().equals("") || saveNoteTitle.trim().equals("Untitled Note")) {
+ if (text.trim().equals(""))
+ text = tr("Untitled Note");
+ titleLabel.setText(text);
+ } else {
+ if (text.length() > Constants.EDAM_NOTE_TITLE_LEN_MAX)
+ titleLabel.setText(text.substring(0, Constants.EDAM_NOTE_TITLE_LEN_MAX));
+ else {
+ titleLabel.blockSignals(true);
+ if (text.trim().equals(""))
+ titleLabel.setText(tr("Untitled Note"));
+ else
+ titleLabel.setText(text);
+ titleLabel.blockSignals(false);
+ }
+ }
+ if (currentNote != null && titleLabel != null && !currentNote.getTitle().equals(text))
+ noteSignal.titleChanged.emit(currentNote.getGuid(), text);
+ }
+
+ // Return the note contents so we can email them
+ public String getContentsToEmail() {
+ return browser.page().currentFrame().toPlainText().trim();
+ /*
+ * int body = browser.page().currentFrame().toHtml().indexOf("<body>");
+ * String temp = browser.page().currentFrame().toHtml(); if (body == -1)
+ * temp = "<html><body><b>Test</b></body></html>"; else temp =
+ * "<html>"+temp.substring(body); return temp; // return
+ * urlEncode(browser.page().currentFrame().toHtml());
+ */
+ }
+
+ // Insert an image into the editor
+ private void insertImage(QMimeData mime) {
+ logger.log(logger.EXTREME, "Entering insertImage");
+ QImage img = (QImage) mime.imageData();
+ String script_start = new String(
+ "document.execCommand('insertHTML', false, '");
+ String script_end = new String("');");
+
+ long now = new Date().getTime();
+ String path = Global.getFileManager().getResDirPath(
+ (new Long(now).toString()) + ".jpg");
+
+ // This block is just a hack to make sure we wait at least 1ms so we
+ // don't
+ // have collisions on image names
+ long i = new Date().getTime();
+ while (now == i)
+ i = new Date().getTime();
+
+ // Open the file & write the data
+ QFile tfile = new QFile(path);
+ tfile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.WriteOnly));
+ if (!img.save(tfile)) {
+ tfile.close();
+ return;
+ }
+ tfile.close();
+
+ Resource newRes = createResource(QUrl.fromLocalFile(path).toString(), 0, "image/jpeg", false);
+ if (newRes == null)
+ return;
+ currentNote.getResources().add(newRes);
+
+ // do the actual insert into the note
+ StringBuffer buffer = new StringBuffer(100);
+ buffer.append("<img src=\"");
+ buffer.append(tfile.fileName());
+ buffer.append("\" en-tag=en-media type=\"image/jpeg\""
+ +" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\""
+ +" guid=\"" +newRes.getGuid() +"\""
+ +" onContextMenu=\"window.jambi.imageContextMenu(&." +tfile.fileName() +"&.);\""
+ + " />");
+
+ browser.page().mainFrame().evaluateJavaScript(
+ script_start + buffer + script_end);
+
+ return;
+ }
+
+ // Handle pasting of a note-to-note link
+ private void handleNoteLink(QMimeData mime) {
+ for (int i=0; i<mime.urls().size(); i++) {
+ StringTokenizer tokens = new StringTokenizer(mime.urls().get(i).toString().replace("evernote:///view/", ""), "/");
+ tokens.nextToken();
+ tokens.nextToken();
+ String sid = tokens.nextToken();
+ String lid = tokens.nextToken();
+
+ if (!sid.equals(currentNote.getGuid()) && !lid.equals(currentNote.getGuid())) {
+
+ Note note = conn.getNoteTable().getNote(sid, false, false, false, false, false);
+ if (note == null)
+ note = conn.getNoteTable().getNote(lid, false, false, false, false, false);
+
+ if (note == null)
+ return;
+
+ // If we've gotten this far, we have a bunch of values. We need to build the link.
+ StringBuffer url = new StringBuffer(100);
+ String script_start = new String(
+ "document.execCommand('insertHtml', false, '");
+ String script_end = new String("');");
+
+ url.append("<a href=\""+mime.urls().get(i).toString() +"\" style=\"color:#69aa35\">");
+ url.append(note.getTitle());
+ url.append("</a>");
+ if (mime.urls().size() > 1)
+ url.append(" ");
+ browser.page().mainFrame().evaluateJavaScript(
+ script_start + url + script_end);
+ }
+ }
+ }
+
+ // Handle URLs that are trying to be pasted
+ public void handleUrls(QMimeData mime) {
+ logger.log(logger.EXTREME, "Starting handleUrls");
+ FileNameMap fileNameMap = URLConnection.getFileNameMap();
+
+ List<QUrl> urlList = mime.urls();
+ String url = new String();
+ String script_start = new String(
+ "document.execCommand('createLink', false, '");
+ String script_end = new String("');");
+
+ for (int i = 0; i < urlList.size(); i++) {
+ url = urlList.get(i).toString();
+ // Find out what type of file we have
+ String mimeType = fileNameMap.getContentTypeFor(url);
+
+ // If null returned, we need to guess at the file type
+ if (mimeType == null)
+ mimeType = "application/"
+ + url.substring(url.lastIndexOf(".") + 1);
+
+ // Check if we have an image or some other type of file
+ if (url.substring(0, 5).equalsIgnoreCase("file:")
+ && mimeType.substring(0, 5).equalsIgnoreCase("image")) {
+ handleLocalImageURLPaste(mime, mimeType);
+ return;
+ }
+
+ boolean smallEnough = checkFileAttachmentSize(url);
+ if (smallEnough
+ && url.substring(0, 5).equalsIgnoreCase("file:")
+ && !mimeType.substring(0, 5).equalsIgnoreCase("image")) {
+ handleLocalAttachment(mime, mimeType);
+ return;
+ }
+ browser.page().mainFrame().evaluateJavaScript(
+ script_start + url + script_end);
+ }
+ return;
+ }
+
+ // If a URL being pasted is an image URL, then attach the image
+ private void handleLocalImageURLPaste(QMimeData mime, String mimeType) {
+ List<QUrl> urlList = mime.urls();
+ String url = new String();
+ String script_start_image = new String(
+ "document.execCommand('insertHtml', false, '");
+ String script_end = new String("');");
+ StringBuffer buffer;
+
+ // Copy the image over into the resource directory and create a new resource
+ // record for each url pasted
+ for (int i = 0; i < urlList.size(); i++) {
+ url = urlList.get(i).toString();
+
+ Resource newRes = createResource(url, i, mimeType, false);
+ if (newRes == null)
+ return;
+ currentNote.getResources().add(newRes);
+ buffer = new StringBuffer(100);
+
+ // Open the file & write the data
+ String fileName = Global.getFileManager().getResDirPath(newRes.getGuid());
+ QFile tfile = new QFile(fileName);
+ tfile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.WriteOnly));
+ tfile.write(newRes.getData().getBody());
+ tfile.close();
+ buffer.append(script_start_image);
+ buffer.append("<img src=\"" + FileUtils.toForwardSlashedPath(fileName));
+// if (mimeType.equalsIgnoreCase("image/jpg"))
+// mimeType = "image/jpeg";
+ buffer.append("\" en-tag=\"en-media\" type=\"" + mimeType +"\""
+ +" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\""
+ +" guid=\"" +newRes.getGuid() +"\""
+ +" onContextMenu=\"window.jambi.imageContextMenu('" +tfile.fileName() +"');\""
+ + " />");
+ buffer.append(script_end);
+ browser.page().mainFrame().evaluateJavaScript(buffer.toString());
+ }
+ return;
+ }
+
+
+ // If a URL being pasted is a local file URL, then attach the file
+ private void handleLocalAttachment(QMimeData mime, String mimeType) {
+ logger.log(logger.EXTREME, "Attaching local file");
+ List<QUrl> urlList = mime.urls();
+ String script_start = new String(
+ "document.execCommand('insertHtml', false, '");
+ String script_end = new String("');");
+ StringBuffer buffer;
+
+ String[] type = mimeType.split("/");
+ String icon = findIcon(type[1]);
+ if (icon.equals("attachment.png"))
+ icon = findIcon(type[0]);
+ buffer = new StringBuffer(100);
+
+ for (int i = 0; i < urlList.size(); i++) {
+ String url = urlList.get(i).toString();
+
+ // Start building the HTML
+ if (icon.equals("attachment.png"))
+ icon = findIcon(url.substring(url.lastIndexOf(".")+1));
+ String imageURL = FileUtils.toFileURLString(Global.getFileManager().getImageDirFile(icon));
+
+ logger.log(logger.EXTREME, "Creating resource ");
+ Resource newRes = createResource(url, i, mimeType, true);
+ if (newRes == null)
+ return;
+ logger.log(logger.EXTREME, "New resource size: " +newRes.getData().getSize());
+ currentNote.getResources().add(newRes);
+
+ String fileName = newRes.getGuid() + Global.attachmentNameDelimeter+newRes.getAttributes().getFileName();
+ // If we have a PDF, we need to setup the preview.
+ if (icon.equalsIgnoreCase("pdf.png") && Global.pdfPreview()) {
+ logger.log(logger.EXTREME, "Setting up PDF preview");
+ if (newRes.getAttributes() != null &&
+ newRes.getAttributes().getFileName() != null &&
+ !newRes.getAttributes().getFileName().trim().equals(""))
+ fileName = newRes.getGuid()+Global.attachmentNameDelimeter+
+ newRes.getAttributes().getFileName();
+ else
+ fileName = newRes.getGuid()+".pdf";
+ QFile file = new QFile(Global.getFileManager().getResDirPath(fileName));
+ QFile.OpenMode mode = new QFile.OpenMode();
+ mode.set(QFile.OpenModeFlag.WriteOnly);
+ file.open(mode);
+ QDataStream out = new QDataStream(file);
+// Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(newRes.getGuid(), true);
+ QByteArray binData = new QByteArray(newRes.getData().getBody());
+// resBinary = null;
+ out.writeBytes(binData.toByteArray());
+ file.close();
+
+ PDFPreview pdfPreview = new PDFPreview();
+ if (pdfPreview.setupPreview(Global.getFileManager().getResDirPath(fileName), "pdf",0)) {
+ imageURL = file.fileName() + ".png";
+ }
+ }
+
+ logger.log(logger.EXTREME, "Generating link tags");
+ buffer.delete(0, buffer.length());
+ buffer.append("<a en-tag=\"en-media\" guid=\"" +newRes.getGuid()+"\" ");
+ buffer.append(" onContextMenu=\"window.jambi.imageContextMenu('")
+ .append(Global.getFileManager().getResDirPath(fileName))
+ .append("');\" ");
+ buffer.append("type=\"" + mimeType + "\" href=\"nnres://" + fileName +"\" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\" >");
+ buffer.append("<img src=\"" + imageURL + "\" title=\"" +newRes.getAttributes().getFileName());
+ buffer.append("\"></img>");
+ buffer.append("</a>");
+ browser.page().mainFrame().evaluateJavaScript(
+ script_start + buffer.toString() + script_end);
+ }
+ return;
+ }
+
+ private Resource createResource(String url, int sequence, String mime, boolean attachment) {
+ logger.log(logger.EXTREME, "Inside create resource");
+ QFile resourceFile;
+ //These two lines are added to handle odd characters in the name like #. Without it
+ // toLocalFile() chokes and returns the wrong name.
+ logger.log(logger.EXTREME, "File URL:" +url);
+ String whichOS = System.getProperty("os.name");
+ if (whichOS.contains("Windows"))
+ url = url.replace("file:///", "");
+ else
+ url = url.replace("file://", "");
+ String urlTest = new QUrl(url).toLocalFile();
+ logger.log(logger.EXTREME, "File URL toLocalFile():" +urlTest);
+ urlTest = url;
+ if (!urlTest.equals(""))
+ url = urlTest;
+// url = url.replace("/", File.separator);
+ logger.log(logger.EXTREME, "Reading from file to create resource:" +url);
+ resourceFile = new QFile(url);
+ resourceFile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly));
+ logger.log(logger.EXTREME, "Error opening file "+url.toString() +": "+resourceFile.errorString());
+ byte[] fileData = resourceFile.readAll().toByteArray();
+ resourceFile.close();
+ logger.log(logger.EXTREME, "File Length: " +fileData.length);
+ if (fileData.length == 0)
+ return null;
+ MessageDigest md;
+ try {
+ logger.log(logger.EXTREME, "Generating MD5");
+ md = MessageDigest.getInstance("MD5");
+ md.update(fileData);
+ byte[] hash = md.digest();
+
+ Resource r = new Resource();
+ Calendar time = new GregorianCalendar();
+ long prevTime = time.getTimeInMillis();
+ while (prevTime == time.getTimeInMillis()) {
+ time = new GregorianCalendar();
+ }
+ r.setGuid(time.getTimeInMillis()+new Integer(sequence).toString());
+ r.setNoteGuid(currentNote.getGuid());
+ r.setMime(mime);
+ r.setActive(true);
+ r.setUpdateSequenceNum(0);
+ r.setWidth((short) 0);
+ r.setHeight((short) 0);
+ r.setDuration((short) 0);
+
+ Data d = new Data();
+ d.setBody(fileData);
+ d.setBodyIsSet(true);
+ d.setBodyHash(hash);
+ d.setBodyHashIsSet(true);
+ r.setData(d);
+ d.setSize(fileData.length);
+
+ int fileNamePos = url.lastIndexOf(File.separator);
+ if (fileNamePos == -1)
+ fileNamePos = url.lastIndexOf("/");
+ String fileName = url.substring(fileNamePos+1);
+ ResourceAttributes a = new ResourceAttributes();
+ a.setAltitude(0);
+ a.setAltitudeIsSet(false);
+ a.setLongitude(0);
+ a.setLongitudeIsSet(false);
+ a.setLatitude(0);
+ a.setLatitudeIsSet(false);
+ a.setCameraMake("");
+ a.setCameraMakeIsSet(false);
+ a.setCameraModel("");
+ a.setCameraModelIsSet(false);
+ a.setAttachment(attachment);
+ a.setAttachmentIsSet(true);
+ a.setClientWillIndex(false);
+ a.setClientWillIndexIsSet(true);
+ a.setRecoType("");
+ a.setRecoTypeIsSet(false);
+ a.setSourceURL(url);
+ a.setSourceURLIsSet(true);
+ a.setTimestamp(0);
+ a.setTimestampIsSet(false);
+ a.setFileName(fileName);
+ a.setFileNameIsSet(true);
+ r.setAttributes(a);
+
+ conn.getNoteTable().noteResourceTable.saveNoteResource(r, true);
+ logger.log(logger.EXTREME, "Resource created");
+ return r;
+ } catch (NoSuchAlgorithmException e1) {
+ e1.printStackTrace();
+ }
+ return null;
+ }
+
+
+ // find the appropriate icon for an attachment
+ private String findIcon(String appl) {
+ appl = appl.toLowerCase();
+ File f = Global.getFileManager().getImageDirFile(appl + ".png");
+ if (f.exists())
+ return appl+".png";
+ return "attachment.png";
+ }
+
+
+
+ // Check the file attachment to be sure it isn't over 25 mb
+ private boolean checkFileAttachmentSize(String url) {
+ String fileName = url.substring(8);
+ QFile resourceFile = new QFile(fileName);
+ resourceFile.open(new QIODevice.OpenMode(
+ QIODevice.OpenModeFlag.ReadOnly));
+ long size = resourceFile.size();
+ resourceFile.close();
+ size = size / 1024 / 1024;
+ if (size < 50 && Global.isPremium())
+ return true;
+ if (size < 25)
+ return true;
+
+ String error = tr("A file attachment may not exceed 25MB.");
+ QMessageBox.information(this, tr("Attachment Size"), error);
+ return false;
+ }
+
+
+ @SuppressWarnings("unused")
+ private void createdChanged() {
+ QDateTime dt = new QDateTime();
+ dt.setDate(createdDate.date());
+ dt.setTime(createdTime.time());
+ noteSignal.createdDateChanged.emit(currentNote.getGuid(), dt);
+
+ }
+
+ @SuppressWarnings("unused")
+ private void alteredChanged() {
+ QDateTime dt = new QDateTime();
+ dt.setDate(alteredDate.date());
+ dt.setTime(alteredTime.time());
+ noteSignal.alteredDateChanged.emit(currentNote.getGuid(), dt);
+ }
+
+ @SuppressWarnings("unused")
+ private void subjectDateTimeChanged() {
+ QDateTime dt = new QDateTime();
+ dt.setDate(subjectDate.date());
+ dt.setTime(subjectTime.time());
+ noteSignal.subjectDateChanged.emit(currentNote.getGuid(), dt);
+
+ }
+
+ @SuppressWarnings("unused")
+ private void sourceUrlChanged() {
+ noteSignal.sourceUrlChanged.emit(currentNote.getGuid(), urlText.text());
+ }
+
+ @SuppressWarnings("unused")
+ private void authorChanged() {
+ noteSignal.authorChanged.emit(currentNote.getGuid(), authorText.text());
+ }
+
+ @SuppressWarnings("unused")
+ private void geoBoxChanged() {
+ int index = geoBox.currentIndex();
+ geoBox.setCurrentIndex(0);
+ if (index == 1) {
+ GeoDialog box = new GeoDialog();
+ box.setLongitude(currentNote.getAttributes().getLongitude());
+ box.setLatitude(currentNote.getAttributes().getLatitude());
+ box.setAltitude(currentNote.getAttributes().getAltitude());
+ box.exec();
+ if (!box.okPressed())
+ return;
+ double alt = box.getAltitude();
+ double lat = box.getLatitude();
+ double lon = box.getLongitude();
+ if (alt != currentNote.getAttributes().getAltitude() ||
+ lon != currentNote.getAttributes().getLongitude() ||
+ lat != currentNote.getAttributes().getLatitude()) {
+ noteSignal.geoChanged.emit(currentNote.getGuid(), lon, lat, alt);
+ currentNote.getAttributes().setAltitude(alt);
+ currentNote.getAttributes().setLongitude(lon);
+ currentNote.getAttributes().setLatitude(lat);
+ }
+ }
+
+ if (index == 2) {
+ noteSignal.geoChanged.emit(currentNote.getGuid(), 0.0, 0.0, 0.0);
+ currentNote.getAttributes().setAltitude(0.0);
+ currentNote.getAttributes().setLongitude(0.0);
+ currentNote.getAttributes().setLatitude(0.0);
+ }
+
+ if (index == 3 || index == 0) {
+ QDesktopServices.openUrl(new QUrl("http://maps.google.com/maps?z=6&q="+currentNote.getAttributes().getLatitude() +"," +currentNote.getAttributes().getLongitude()));
+ }
+ }
+
+ // ************************************************************
+ // * User chose to save an attachment. Pares out the request *
+ // * into a guid & file. Save the result. *
+ // ************************************************************
+ public void downloadAttachment(QNetworkRequest request) {
+ String guid;
+ QFileDialog fd = new QFileDialog(this);
+ fd.setFileMode(FileMode.AnyFile);
+ fd.setConfirmOverwrite(true);
+ fd.setWindowTitle(tr("Save File"));
+ fd.setAcceptMode(AcceptMode.AcceptSave);
+ fd.setDirectory(System.getProperty("user.home"));
+ String name = request.url().toString();
+
+ int pos = name.lastIndexOf(Global.attachmentNameDelimeter);
+ if (pos > -1) {
+ guid = name.substring(0, pos).replace("nnres://", "");
+ name = name.substring(pos +Global.attachmentNameDelimeter.length());
+ fd.selectFile(name);
+ pos = name.lastIndexOf('.');
+ if (pos > -1) {
+ String mimeType = "(*." + name.substring(pos + 1)
+ + ");; All Files (*)";
+ fd.setFilter(tr(mimeType));
+ }
+ } else {
+ guid = name;
+ }
+
+ // Strip URL prefix and base dir
+ guid = guid.replace("nnres://", "")
+ .replace(FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath()), "");
+ guid = guid.replace("file://", "").replace("/", "")
+ .replace(FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath()), "");
+
+ pos = guid.lastIndexOf('.');
+ if (pos > 0)
+ guid = guid.substring(0,pos);
+ if (fd.exec() != 0 && fd.selectedFiles().size() > 0) {
+ name = name.replace('\\', '/');
+ Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);
+ QFile saveFile = new QFile(fd.selectedFiles().get(0));
+ QFile.OpenMode mode = new QFile.OpenMode();
+ mode.set(QFile.OpenModeFlag.WriteOnly);
+ saveFile.open(mode);
+ QDataStream saveOut = new QDataStream(saveFile);
+ QByteArray binData = new QByteArray(resBinary.getData().getBody());
+ saveOut.writeBytes(binData.toByteArray());
+ saveFile.close();
+
+ }
+ }
+
+
+ // ************************************************************
+ // * User chose to save an attachment. Pares out the request *
+ // * into a guid & file. Save the result. --- DONE FROM downloadAttachment now!!!!!
+ // ************************************************************
+ public void downloadImage(QNetworkRequest request) {
+ QFileDialog fd = new QFileDialog(this);
+ fd.setFileMode(FileMode.AnyFile);
+ fd.setConfirmOverwrite(true);
+ fd.setWindowTitle(tr("Save File"));
+ fd.setAcceptMode(AcceptMode.AcceptSave);
+ fd.setDirectory(System.getProperty("user.home"));
+ String name = request.url().toString();
+ name = name.replace("nnres://", "");
+ String dPath = FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath());
+ name = name.replace(dPath, "");
+ int pos = name.lastIndexOf('.');
+ String guid = name;
+ if (pos > -1) {
+ String mimeType = "(*." + name.substring(pos + 1)
+ + ");; All Files (*)";
+ fd.setFilter(tr(mimeType));
+ guid = guid.substring(0,pos);
+ }
+ pos = name.lastIndexOf(Global.attachmentNameDelimeter);
+ if (pos > -1) {
+ guid = name.substring(0, pos);
+ fd.selectFile(name.substring(pos+Global.attachmentNameDelimeter.length()));
+ }
+ if (fd.exec() != 0 && fd.selectedFiles().size() > 0) {
+ Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);
+ String fileName = fd.selectedFiles().get(0);
+ QFile saveFile = new QFile(fileName);
+ QFile.OpenMode mode = new QFile.OpenMode();
+ mode.set(QFile.OpenModeFlag.WriteOnly);
+ saveFile.open(mode);
+ QDataStream saveOut = new QDataStream(saveFile);
+ QByteArray binData = new QByteArray(resBinary.getData().getBody());
+ saveOut.writeBytes(binData.toByteArray());
+ saveFile.close();
+ }
+ }
+
+
+ // *************************************************************
+ // * decrypt any hidden text. We could do an XML parse, but
+ // * it is quicker here just to scan for an <img tag & do the fix
+ // * the manual way
+ // *************************************************************
+ private void removeEncryption(String id, String plainText, boolean permanent, String slot) {
+ if (!permanent) {
+ plainText = " <table class=\"en-crypt-temp\" slot=\""
+ +slot
+ +"\""
+ +"border=1 width=100%><tbody><tr><td>"
+ +plainText+"</td></tr></tbody></table>";
+ }
+
+ String html = browser.page().mainFrame().toHtml();
+ String text = html;
+ int imagePos = html.indexOf("<img");
+ int endPos;
+ for ( ;imagePos>0; ) {
+ // Find the end tag
+ endPos = text.indexOf(">", imagePos);
+ String tag = text.substring(imagePos-1,endPos);
+ if (tag.indexOf("id=\""+id+"\"") > -1) {
+ text = text.substring(0,imagePos) +plainText+text.substring(endPos+1);
+ QTextCodec codec = QTextCodec.codecForName("UTF-8");
+ QByteArray unicode = codec.fromUnicode(text);
+ setContent(unicode);
+ if (permanent)
+ contentChanged();
+ }
+ imagePos = text.indexOf("<img", imagePos+1);
+ }
+ }
+
+
+ //****************************************************************
+ //* Focus shortcuts
+ //****************************************************************
+ @SuppressWarnings("unused")
+ private void focusTitle() {
+ titleLabel.setFocus();
+ }
+ @SuppressWarnings("unused")
+ private void focusTag() {
+ tagEdit.setFocus();
+ }
+ @SuppressWarnings("unused")
+ private void focusNote() {
+ browser.setFocus();
+ }
+ @SuppressWarnings("unused")
+ private void focusAuthor() {
+ authorLabel.setFocus();
+ }
+ @SuppressWarnings("unused")
+ private void focusUrl() {
+ urlLabel.setFocus();
+ }
+
+
+ //*****************************************************************
+ //* Set the document background color
+ //*****************************************************************
+ public void setBackgroundColor(String color) {
+ String js = "function changeBackground(color) {"
+ +"document.body.style.background = color;"
+ +"}"
+ +"changeBackground('" +color+"');";
+ browser.page().mainFrame().evaluateJavaScript(js);
+ contentChanged();
+ }
+
+
+ //****************************************************************
+ //* MicroFocus changed
+ //****************************************************************
+ private void microFocusChanged() {
+ boldButton.setDown(false);
+ italicButton.setDown(false);
+ underlineButton.setDown(false);
+ browser.openAction.setEnabled(false);
+ browser.downloadAttachment.setEnabled(false);
+ browser.downloadImage.setEnabled(false);
+ browser.rotateImageLeft.setEnabled(false);
+ browser.rotateImageRight.setEnabled(false);
+ browser.insertTableAction.setEnabled(true);
+ browser.deleteTableColumnAction.setEnabled(false);
+ browser.insertTableRowAction.setEnabled(false);
+ browser.insertTableColumnAction.setEnabled(false);
+ browser.deleteTableRowAction.setEnabled(false);
+ browser.insertLinkAction.setText(tr("Insert Hyperlink"));
+ insertHyperlink = true;
+ browser.insertQuickLinkAction.setEnabled(true);
+ currentHyperlink ="";
+ insideList = false;
+ insideTable = false;
+ insideEncryption = false;
+ forceTextPaste = false;
+
+ String js = new String( "function getCursorPos() {"
+ +"var cursorPos;"
+ +"if (window.getSelection) {"
+ +" var selObj = window.getSelection();"
+ +" var selRange = selObj.getRangeAt(0);"
+ +" var workingNode = window.getSelection().anchorNode.parentNode;"
+ +" while(workingNode != null) { "
+// +" window.jambi.printNode(workingNode.nodeName);"
+ +" if (workingNode.nodeName=='TABLE') { if (workingNode.getAttribute('class').toLowerCase() == 'en-crypt-temp') window.jambi.insideEncryption(); }"
+ +" if (workingNode.nodeName=='B') window.jambi.boldActive();"
+ +" if (workingNode.nodeName=='I') window.jambi.italicActive();"
+ +" if (workingNode.nodeName=='U') window.jambi.underlineActive();"
+ +" if (workingNode.nodeName=='UL') window.jambi.setInsideList();"
+ +" if (workingNode.nodeName=='OL') window.jambi.setInsideList();"
+ +" if (workingNode.nodeName=='LI') window.jambi.setInsideList();"
+ +" if (workingNode.nodeName=='TBODY') window.jambi.setInsideTable();"
+ +" if (workingNode.nodeName=='A') {for(var x = 0; x < workingNode.attributes.length; x++ ) {if (workingNode.attributes[x].nodeName.toLowerCase() == 'href') window.jambi.setInsideLink(workingNode.attributes[x].nodeValue);}}"
+ +" if (workingNode.nodeName=='SPAN') {"
+ +" if (workingNode.getAttribute('style') == 'text-decoration: underline;') window.jambi.underlineActive();"
+ +" }"
+ +" workingNode = workingNode.parentNode;"
+ +" }"
+ +"}"
+ +"} getCursorPos();");
+ browser.page().mainFrame().evaluateJavaScript(js);
+ }
+
+ public void printNode(String n) {
+ System.out.println("Node Vaule: " +n);
+ }
+
+ public void insideEncryption() {
+ insideEncryption = true;
+ forceTextPaste();
+ }
+
+ //****************************************************************
+ //* Insert a table row
+ //****************************************************************
+ public void insertTableRow() {
+
+ String js = new String( "function insertTableRow() {"
+ +" var selObj = window.getSelection();"
+ +" var selRange = selObj.getRangeAt(0);"
+ +" var workingNode = window.getSelection().anchorNode.parentNode;"
+ +" var cellCount = 0;"
+ +" while(workingNode != null) { "
+ +" if (workingNode.nodeName.toLowerCase()=='tr') {"
+ +" row = document.createElement('TR');"
+ +" var nodes = workingNode.getElementsByTagName('td');"
+ +" for (j=0; j<nodes.length; j=j+1) {"
+ +" cell = document.createElement('TD');"
+ +" cell.innerHTML=' ';"
+ +" row.appendChild(cell);"
+ +" }"
+ +" workingNode.parentNode.insertBefore(row,workingNode.nextSibling);"
+ +" return;"
+ +" }"
+ +" workingNode = workingNode.parentNode;"
+ +" }"
+ +"} insertTableRow();");
+ browser.page().mainFrame().evaluateJavaScript(js);
+ contentChanged();
+ }
+
+ public void insertTableColumn() {
+ String js = new String( "function insertTableColumn() {"
+ +" var selObj = window.getSelection();"
+ +" var selRange = selObj.getRangeAt(0);"
+ +" var workingNode = window.getSelection().anchorNode.parentNode;"
+ +" var current = 0;"
+ +" while (workingNode.nodeName.toLowerCase() != 'table' && workingNode != null) {"
+ +" if (workingNode.nodeName.toLowerCase() == 'td') {"
+ +" var td = workingNode;"
+ +" while (td.previousSibling != null) { "
+ +" current = current+1; td = td.previousSibling;"
+ +" }"
+ +" }"
+ +" workingNode = workingNode.parentNode; "
+ +" }"
+ +" if (workingNode == null) return;"
+ +" for (var i=0; i<workingNode.rows.length; i++) { "
+ +" var cell = workingNode.rows[i].insertCell(current+1); "
+ +" cell.innerHTML = ' '; "
+ +" }"
+ +"} insertTableColumn();");
+ browser.page().mainFrame().evaluateJavaScript(js);
+ contentChanged();
+ }
+
+ //****************************************************************
+ //* Delete a table row
+ //****************************************************************
+ public void deleteTableRow() {
+
+ String js = new String( "function deleteTableRow() {"
+ +" var selObj = window.getSelection();"
+ +" var selRange = selObj.getRangeAt(0);"
+ +" var workingNode = window.getSelection().anchorNode.parentNode;"
+ +" var cellCount = 0;"
+ +" while(workingNode != null) { "
+ +" if (workingNode.nodeName.toLowerCase()=='tr') {"
+ +" workingNode.parentNode.removeChild(workingNode);"
+ +" return;"
+ +" }"
+ +" workingNode = workingNode.parentNode;"
+ +" }"
+ +"} deleteTableRow();");
+ browser.page().mainFrame().evaluateJavaScript(js);
+ contentChanged();
+ }
+
+ public void deleteTableColumn() {
+ String js = new String( "function deleteTableColumn() {"
+ +" var selObj = window.getSelection();"
+ +" var selRange = selObj.getRangeAt(0);"
+ +" var workingNode = window.getSelection().anchorNode.parentNode;"
+ +" var current = 0;"
+ +" while (workingNode.nodeName.toLowerCase() != 'table' && workingNode != null) {"
+ +" if (workingNode.nodeName.toLowerCase() == 'td') {"
+ +" var td = workingNode;"
+ +" while (td.previousSibling != null) { "
+ +" current = current+1; td = td.previousSibling;"
+ +" }"
+ +" }"
+ +" workingNode = workingNode.parentNode; "
+ +" }"
+ +" if (workingNode == null) return;"
+ +" for (var i=0; i<workingNode.rows.length; i++) { "
+ +" workingNode.rows[i].deleteCell(current); "
+ +" }"
+ +"} deleteTableColumn();");
+ browser.page().mainFrame().evaluateJavaScript(js);
+ contentChanged();
+ }
+
+
+ public void setInsideTable() {
+ browser.insertTableRowAction.setEnabled(true);
+ browser.insertTableColumnAction.setEnabled(true);
+ browser.deleteTableRowAction.setEnabled(true);
+ browser.deleteTableColumnAction.setEnabled(true);
+ browser.insertTableAction.setEnabled(false);
+ browser.encryptAction.setEnabled(false);
+ insideTable = true;
+ }
+
+ public void setInsideLink(String link) {
+ browser.insertLinkAction.setText(tr("Edit Hyperlink"));
+ currentHyperlink = link;
+ insertHyperlink = false;
+ }
+
+ public void italicActive() {
+ italicButton.setDown(true);
+ }
+ public void boldActive() {
+ boldButton.setDown(true);
+ }
+ public void underlineActive() {
+ underlineButton.setDown(true);
+ }
+ public void forceTextPaste() {
+ forceTextPaste = true;
+ }
+ public void imageContextMenu(String f) {
+ browser.downloadImage.setEnabled(true);
+ browser.rotateImageRight.setEnabled(true);
+ browser.rotateImageLeft.setEnabled(true);
+ browser.openAction.setEnabled(true);
+ selectedFile = f;
+ }
+ public void rotateImageRight() {
+ QWebSettings.setMaximumPagesInCache(0);
+ QWebSettings.setObjectCacheCapacities(0, 0, 0);
+ QImage image = new QImage(selectedFile);
+ QMatrix matrix = new QMatrix();
+ matrix.rotate( 90.0 );
+ image = image.transformed(matrix);
+ image.save(selectedFile);
+ QWebSettings.setMaximumPagesInCache(0);
+ QWebSettings.setObjectCacheCapacities(0, 0, 0);
+ browser.setHtml(browser.page().mainFrame().toHtml());
+ browser.reload();
+ contentChanged();
+ resourceSignal.contentChanged.emit(selectedFile);
+
+ }
+ public void rotateImageLeft() {
+ QImage image = new QImage(selectedFile);
+ QMatrix matrix = new QMatrix();
+ matrix.rotate( -90.0 );
+ image = image.transformed(matrix);
+ image.save(selectedFile);
+ browser.setHtml(browser.page().mainFrame().toHtml());
+ browser.reload();
+ contentChanged();
+ resourceSignal.contentChanged.emit(selectedFile);
+ }
+ public void resourceContextMenu(String f) {
+ browser.downloadAttachment.setEnabled(true);
+ browser.openAction.setEnabled(true);
+ selectedFile = f;
+ }
+ public void latexContextMenu(String f) {
+ browser.downloadImage.setEnabled(true);
+ browser.rotateImageRight.setEnabled(true);
+ browser.rotateImageLeft.setEnabled(true);
+ browser.openAction.setEnabled(true);
+ selectedFile = f;
+ }
+
+ //****************************************************************
+ //* Apply CSS style to specified word
+ //****************************************************************
+/* public void applyStyleToWords(String word, String style) {
+ QFile script = new QFile("D:\\NeverNote\\js\\hilight1.js");
+ script.open(OpenModeFlag.ReadOnly);
+ String s = script.readAll().toString();
+ String js = new String(s +" findit('"+word+"', '"+style+"');");
+ browser.page().mainFrame().evaluateJavaScript(js);
+ System.out.println(getContent());
+ }
+*/
+ //****************************************************************
+ //* Someone tried to paste a resource between notes, so we need *
+ //* to do some special handling. *
+ //****************************************************************
+ private String fixInternotePaste(String text) {
+ logger.log(logger.EXTREME, "Fixing internote paste");
+ String returnValue = fixInternotePasteSearch(text, "<img", "src=\"");
+ return fixInternotePasteSearch(returnValue, "<a", "href=\"nnres://");
+ }
+ private String fixInternotePasteSearch(String text, String type, String locTag) {
+
+ // First, let's fix the images.
+ int startPos = text.indexOf(type);
+ int endPos;
+ for (; startPos>=0;) {
+ endPos = text.indexOf(">", startPos+1);
+ String segment = text.substring(startPos, endPos);
+ if (segment.indexOf("en-tag") > -1) {
+ String newSegment = segment;
+
+ int guidStartPos = segment.indexOf("guid=\"");
+ int guidEndPos = segment.indexOf("\"", guidStartPos+7);
+ String guid = segment.substring(guidStartPos+6,guidEndPos);
+
+ int mimeStartPos = segment.indexOf("type");
+ int mimeEndPos = segment.indexOf("\"", mimeStartPos+7);
+ String mime = segment.substring(mimeStartPos+6,mimeEndPos);
+
+ int srcStartPos = segment.indexOf("src");
+ int srcEndPos = segment.indexOf("\"", srcStartPos+6);
+ String src = segment.substring(srcStartPos+5,srcEndPos);
+
+ Calendar currentTime = new GregorianCalendar();
+ Long l = new Long(currentTime.getTimeInMillis());
+ long prevTime = l;
+ while (l==prevTime) {
+ currentTime = new GregorianCalendar();
+ l= new Long(currentTime.getTimeInMillis());
+ }
+
+ Resource r = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);
+ // if r==null, then the image doesn't exist (it was probably cut out of another note, so
+ // we need to recereate it
+ if (r==null) {
+ r = createResource(src, 1, mime, false);
+ if (r==null)
+ return "";
+ }
+ String randint = new String(Long.toString(l));
+ String extension = null;
+ if (r.getMime()!= null) {
+ extension = r.getMime().toLowerCase();
+ if (extension.indexOf("/")>-1)
+ extension = extension.substring(extension.indexOf("/")+1);
+ }
+ String newFile = randint;
+ if (r.getAttributes().getFileName() != null && r.getAttributes().getFileName() != "")
+ if (!locTag.startsWith("src"))
+ newFile = newFile+Global.attachmentNameDelimeter+r.getAttributes().getFileName();
+ r.setNoteGuid(currentNote.getGuid());
+
+ r.setGuid(randint);
+ conn.getNoteTable().noteResourceTable.saveNoteResource(r, true);
+ QFile f = new QFile(Global.getFileManager().getResDirPath(newFile));
+ QByteArray bin = new QByteArray(r.getData().getBody());
+ f.open(QFile.OpenModeFlag.WriteOnly);
+ f.write(bin);
+ f.close();
+ newSegment = newSegment.replace("guid=\""+guid, "guid=\""+randint);
+ currentNote.getResources().add(r);
+
+ int startSrcPos = newSegment.indexOf(locTag);
+ int endSrcPos = newSegment.indexOf("\"",startSrcPos+locTag.length()+1);
+ String source;
+ if (locTag.startsWith("src")) {
+ source = newSegment.substring(startSrcPos+locTag.length(),endSrcPos);
+ newSegment = newSegment.replace(source,
+ FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath(newFile)));
+ } else {
+ source = newSegment.substring(startSrcPos+locTag.length(),endSrcPos);
+ newSegment = newSegment.replace(source, newFile);
+ }
+
+ text = text.substring(0,startPos) + newSegment + text.substring(endPos);
+ }
+ startPos = text.indexOf(type, startPos+1);
+ }
+ return text;
+ }
+
+
+ public void nextPage(String file) {
+ logger.log(logger.EXTREME, "Starting nextPage()");
+
+ Integer pageNumber;
+ if (previewPageList.containsKey(file))
+ pageNumber = previewPageList.get(file)+1;
+ else
+ pageNumber = 2;
+ previewPageList.remove(file);
+ previewPageList.put(file, pageNumber);
+ PDFPreview pdfPreview = new PDFPreview();
+ boolean goodPreview = pdfPreview.setupPreview(file, "pdf", pageNumber);
+ if (goodPreview) {
+
+// String html = getContent();
+ QWebSettings.setMaximumPagesInCache(0);
+ QWebSettings.setObjectCacheCapacities(0, 0, 0);
+// browser.setContent(new QByteArray());
+ browser.setHtml(browser.page().mainFrame().toHtml());
+ browser.reload();
+// browser.setContent(new QByteArray(html));
+// browser.triggerPageAction(WebAction.Reload);
+// pdfMouseOver(selectedFile);
+ }
+ }
+
+ public void previousPage(String file) {
+ logger.log(logger.EXTREME, "Starting previousPage()");
+
+ Integer pageNumber;
+ if (previewPageList.containsKey(file))
+ pageNumber = previewPageList.get(file)-1;
+ else
+ pageNumber = 1;
+ previewPageList.remove(file);
+ previewPageList.put(file, pageNumber);
+ PDFPreview pdfPreview = new PDFPreview();
+ boolean goodPreview = pdfPreview.setupPreview(file, "pdf", pageNumber);
+ if (goodPreview) {
+
+// String html = getContent();
+ QWebSettings.setMaximumPagesInCache(0);
+ QWebSettings.setObjectCacheCapacities(0, 0, 0);
+ browser.setHtml(browser.page().mainFrame().toHtml());
+ browser.reload();
+// browser.setContent(new QByteArray(html));
+// browser.triggerPageAction(WebAction.Reload);
+ }
+ }
+
+/* public void pdfMouseOver(String name) {
+ int pageNumber;
+ if (previewPageList.containsKey(selectedFile))
+ pageNumber = previewPageList.get(selectedFile)+1;
+ else
+ pageNumber = 1;
+
+ if (pageNumber <= 1)
+ browser.previousPageAction.setEnabled(false);
+ else
+ browser.previousPageAction.setEnabled(true);
+
+ PDFPreview pdf = new PDFPreview();
+ int totalPages = pdf.getPageCount(name);
+ if (previewPageList.containsKey(selectedFile))
+ pageNumber = previewPageList.get(selectedFile)+1;
+ else
+ pageNumber = 1;
+ if (totalPages > pageNumber)
+ browser.nextPageAction.setEnabled(true);
+ else
+ browser.nextPageAction.setEnabled(false);
+ }
+
+
+ public void pdfMouseOut() {
+// browser.nextPageAction.setVisible(false);
+// browser.previousPageAction.setVisible(false);
+ }
+*/
+
+ @SuppressWarnings("unused")
+ private void toggleUndoVisible(Boolean toggle) {
+ undoAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("undo", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleRedoVisible(Boolean toggle) {
+ redoAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("redo", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleCutVisible(Boolean toggle) {
+ cutAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("cut", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleCopyVisible(Boolean toggle) {
+ copyAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("copy", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void togglePasteVisible(Boolean toggle) {
+ pasteAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("paste", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleBoldVisible(Boolean toggle) {
+ boldAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("bold", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleItalicVisible(Boolean toggle) {
+ italicAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("italic", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleUnderlineVisible(Boolean toggle) {
+ underlineAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("underline", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleStrikethroughVisible(Boolean toggle) {
+ strikethroughAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("strikethrough", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleLeftAlignVisible(Boolean toggle) {
+ leftAlignAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("alignLeft", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleRightAlignVisible(Boolean toggle) {
+ rightAlignAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("alignRight", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleCenterAlignVisible(Boolean toggle) {
+ centerAlignAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("alignCenter", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleHLineVisible(Boolean toggle) {
+ hlineAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("hline", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleIndentVisible(Boolean toggle) {
+ indentAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("indent", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleTodoVisible(Boolean toggle) {
+ todoAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("todo", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleOutdentVisible(Boolean toggle) {
+ outdentAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("outdent", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleBulletListVisible(Boolean toggle) {
+ bulletListAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("bulletList", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleNumberListVisible(Boolean toggle) {
+ numberListAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("numberList", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleFontListVisible(Boolean toggle) {
+ fontListAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("font", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleFontColorVisible(Boolean toggle) {
+ fontColorAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("fontColor", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleFontSizeVisible(Boolean toggle) {
+ fontSizeAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("fontSize", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleFontHilightVisible(Boolean toggle) {
+ fontHilightAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("fontHilight", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleSpellCheckVisible(Boolean toggle) {
+ spellCheckAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("spellCheck", toggle);
+ }
+
+
+ private void setupDictionary() {
+ File wordList = new File(Global.getFileManager().getSpellDirPath()+Locale.getDefault()+".dic");
+ try {
+ dictionary = new SpellDictionaryHashMap(wordList);
+ spellChecker = new SpellChecker(dictionary);
+
+ File userWordList;
+ userWordList = new File(Global.getFileManager().getSpellDirPathUser()+"user.dic");
+
+ // Get the local user spell dictionary
+ try {
+ userDictionary = new SpellDictionaryHashMap(userWordList);
+ } catch (FileNotFoundException e) {
+ userWordList.createNewFile();
+ userDictionary = new SpellDictionaryHashMap(userWordList);
+ } catch (IOException e) {
+ userWordList.createNewFile();
+ userDictionary = new SpellDictionaryHashMap(userWordList);
+ }
+
+ spellListener = new SuggestionListener(this, spellChecker);
+
+ // Add the user dictionary
+ spellChecker.addSpellCheckListener(spellListener);
+ spellChecker.setUserDictionary(userDictionary);
+
+ } catch (FileNotFoundException e) {
+ QMessageBox.critical(this, tr("Spell Check Error"),
+ tr("Dictionary ")+ Global.getFileManager().getSpellDirPath()+Locale.getDefault()+
+ tr(".dic was not found."));
+ } catch (IOException e) {
+ QMessageBox.critical(this, tr("Spell Check Error"),
+ tr("Dictionary ")+ Global.getFileManager().getSpellDirPath()+Locale.getDefault()+
+ tr(".dic is invalid."));
+ }
+
+ }
+
+ // Invoke spell checker dialog
+ @SuppressWarnings("unused")
+ private void spellCheckClicked() {
+
+ if (spellChecker == null) {
+ setupDictionary();
+ }
+
+ // Read user settings
+ spellChecker.getConfiguration().setBoolean(Configuration.SPELL_IGNOREDIGITWORDS,
+ Global.getSpellSetting(Configuration.SPELL_IGNOREDIGITWORDS));
+ spellChecker.getConfiguration().setBoolean(Configuration.SPELL_IGNOREINTERNETADDRESSES,
+ Global.getSpellSetting(Configuration.SPELL_IGNOREINTERNETADDRESSES));
+ spellChecker.getConfiguration().setBoolean(Configuration.SPELL_IGNOREMIXEDCASE,
+ Global.getSpellSetting(Configuration.SPELL_IGNOREMIXEDCASE));
+ spellChecker.getConfiguration().setBoolean(Configuration.SPELL_IGNOREUPPERCASE,
+ Global.getSpellSetting(Configuration.SPELL_IGNOREUPPERCASE));
+ spellChecker.getConfiguration().setBoolean(Configuration.SPELL_IGNORESENTENCECAPITALIZATION,
+ Global.getSpellSetting(Configuration.SPELL_IGNORESENTENCECAPITALIZATION));
+
+ spellListener.abortSpellCheck = false;
+ spellListener.errorsFound = false;
+ String content = getBrowser().page().mainFrame().toPlainText();
+ StringWordTokenizer tokenizer = new StringWordTokenizer(content);
+ if (!tokenizer.hasMoreWords())
+ return;
+ getBrowser().page().action(WebAction.MoveToStartOfDocument);
+
+ getBrowser().setFocus();
+ boolean found;
+
+ // Move to the start of page
+ KeyboardModifiers ctrl = new KeyboardModifiers(KeyboardModifier.ControlModifier.value());
+ QKeyEvent home = new QKeyEvent(Type.KeyPress, Key.Key_Home.value(), ctrl);
+ browser.keyPressEvent(home);
+ getBrowser().setFocus();
+
+ tokenizer = new StringWordTokenizer(content);
+ String word;
+
+ while(tokenizer.hasMoreWords()) {
+ word = tokenizer.nextWord();
+ found = getBrowser().page().findText(word);
+ if (found && !spellListener.abortSpellCheck) {
+ spellChecker.checkSpelling(new StringWordTokenizer(word));
+ getBrowser().setFocus();
+ }
+ }
+
+ // Go to the end of the document & finish up.
+ home = new QKeyEvent(Type.KeyPress, Key.Key_End.value(), ctrl);
+ browser.keyPressEvent(home);
+ if (!spellListener.errorsFound)
+ QMessageBox.information(this, tr("Spell Check Complete"),
+ tr("No Errors Found"));
+
+ }
+
+ // Source edited
+ @SuppressWarnings("unused")
+ private void sourceEdited() {
+ QTextCodec codec = QTextCodec.codecForLocale();
+ codec = QTextCodec.codecForName("UTF-8");
+ String content = codec.fromUnicode(sourceEdit.toHtml()).toString();
+ content = StringEscapeUtils.unescapeHtml4(removeTags(content));
+ QByteArray data = new QByteArray(sourceEditHeader+content+"</body></html>");
+ getBrowser().setContent(data);
+ checkNoteTitle();
+ if (currentNote != null && sourceEdit != null)
+ noteSignal.noteChanged.emit(currentNote.getGuid(), sourceEdit.toPlainText());
+ }
+
+ private void setSource() {
+ String text = getContent();
+ sourceEdit.blockSignals(true);
+ int body = text.indexOf("<body");
+ if (body > 0) {
+ body = text.indexOf(">",body);
+ if (body > 0) {
+ sourceEditHeader =text.substring(0, body+1);
+ text = text.substring(body+1);
+ }
+ }
+ text = text.replace("</body></html>", "");
+ sourceEdit.setPlainText(text);
+ sourceEdit.setReadOnly(!getBrowser().page().isContentEditable());
+ //syntaxHighlighter.rehighlight();
+ sourceEdit.blockSignals(false);
+ }
+
+ // show/hide view source window
+ public void showSource(boolean value) {
+ setSource();
+ sourceEdit.setVisible(value);
+ }
+
+ // Remove HTML tags
+ private String removeTags(String text) {
+ StringBuffer buffer = new StringBuffer(text);
+ boolean inTag = false;
+ int bodyPosition = text.indexOf("<body");
+ for (int i=buffer.length()-1; i>=0; i--) {
+ if (buffer.charAt(i) == '>')
+ inTag = true;
+ if (buffer.charAt(i) == '<')
+ inTag = false;
+ if (inTag || buffer.charAt(i) == '<' || i<bodyPosition)
+ buffer.deleteCharAt(i);
+ }
+
+ return buffer.toString();
+ }
+}
-/*\r
- * This file is part of NixNote \r
- * Copyright 2009 Randy Baumgarte\r
- * \r
- * This file may be licensed under the terms of of the\r
- * GNU General Public License Version 2 (the ``GPL'').\r
- *\r
- * Software distributed under the License is distributed\r
- * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either\r
- * express or implied. See the GPL for the specific language\r
- * governing rights and limitations.\r
- *\r
- * You should have received a copy of the GPL along with this\r
- * program. If not, go to http://www.gnu.org/licenses/gpl.html\r
- * or write to the Free Software Foundation, Inc.,\r
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
- *\r
-*/\r
-\r
-package cx.fbn.nevernote.gui;\r
-\r
-import java.awt.Desktop;\r
-import java.util.List;\r
-\r
-import com.trolltech.qt.core.QUrl;\r
-import com.trolltech.qt.core.Qt.WidgetAttribute;\r
-import com.trolltech.qt.gui.QCloseEvent;\r
-import com.trolltech.qt.gui.QDesktopServices;\r
-import com.trolltech.qt.gui.QDialog;\r
-import com.trolltech.qt.gui.QMdiSubWindow;\r
-import com.trolltech.qt.gui.QPrintDialog;\r
-import com.trolltech.qt.gui.QPrinter;\r
-\r
-import cx.fbn.nevernote.Global;\r
-import cx.fbn.nevernote.dialog.FindDialog;\r
-import cx.fbn.nevernote.sql.DatabaseConnection;\r
-\r
-public class ExternalBrowse extends QMdiSubWindow {\r
- private final DatabaseConnection conn;\r
- private final BrowserWindow browser;\r
- public Signal4<String, String, Boolean, BrowserWindow> contentsChanged;\r
- public Signal1<String> windowClosing;\r
- boolean noteDirty;\r
- String saveTitle;\r
- private final FindDialog find; // Text search in note dialog\r
-// ExternalBrowserMenuBar menu;\r
- ExternalBrowserMenuBar menu;\r
- \r
- // Constructor\r
- public ExternalBrowse(DatabaseConnection c) {\r
- setAttribute(WidgetAttribute.WA_QuitOnClose, false);\r
- setWindowTitle(tr("NixNote"));\r
- conn = c;\r
- contentsChanged = new Signal4<String, String, Boolean, BrowserWindow>();\r
- windowClosing = new Signal1<String>();\r
- browser = new BrowserWindow(conn);\r
- menu = new ExternalBrowserMenuBar(this);\r
- for (int i=0; i<menu.actions().size(); i++) {\r
- addAction(menu.actions().get(i));\r
- }\r
- \r
- setWidget(browser);\r
- noteDirty = false;\r
- browser.titleLabel.textChanged.connect(this, "titleChanged(String)");\r
- browser.getBrowser().page().contentsChanged.connect(this, "contentChanged()");\r
- find = new FindDialog();\r
- find.getOkButton().clicked.connect(this, "doFindText()");\r
- }\r
- \r
- @SuppressWarnings("unused")\r
- private void contentChanged() {\r
- noteDirty = true;\r
- contentsChanged.emit(getBrowserWindow().getNote().getGuid(), getBrowserWindow().getContent(), false, getBrowserWindow());\r
- }\r
-\r
- \r
- @Override\r
- public void closeEvent(QCloseEvent event) {\r
- if (noteDirty) \r
- contentsChanged.emit(getBrowserWindow().getNote().getGuid(), getBrowserWindow().getContent(), true, getBrowserWindow());\r
- windowClosing.emit(getBrowserWindow().getNote().getGuid());\r
- }\r
- \r
- public BrowserWindow getBrowserWindow() {\r
- return browser;\r
- }\r
- \r
- @SuppressWarnings("unused")\r
- private void titleChanged(String value) {\r
- setWindowTitle(tr("NixNote - ") +value);\r
- }\r
- \r
- @SuppressWarnings("unused")\r
- private void updateTitle(String guid, String title) {\r
- if (guid.equals(getBrowserWindow().getNote().getGuid()) &&\r
- (saveTitle != null && !title.equals(saveTitle) || saveTitle == null) ) {\r
- saveTitle = title;\r
- getBrowserWindow().loadingData(true);\r
- getBrowserWindow().setTitle(title);\r
- getBrowserWindow().getNote().setTitle(title);\r
- getBrowserWindow().loadingData(false);\r
- }\r
- }\r
- @SuppressWarnings("unused")\r
- private void updateNotebook(String guid, String notebook) {\r
- if (guid.equals(getBrowserWindow().getNote().getGuid())) {\r
- getBrowserWindow().loadingData(true);\r
- getBrowserWindow().setNotebook(notebook);\r
- getBrowserWindow().loadingData(false);\r
- }\r
- }\r
- \r
- @SuppressWarnings("unused")\r
- private void updateTags(String guid, List<String> tags) {\r
- if (guid.equals(getBrowserWindow().getNote().getGuid())) {\r
- StringBuffer tagLine = new StringBuffer(100);\r
- for (int i=0; i<tags.size(); i++) {\r
- if (i>0)\r
- tagLine.append(Global.tagDelimeter+" ");\r
- tagLine.append(tags.get(i));\r
- \r
- }\r
- getBrowserWindow().loadingData(true);\r
- getBrowserWindow().getTagLine().setText(tagLine.toString());\r
- getBrowserWindow().loadingData(false);\r
- }\r
- }\r
-\r
- \r
- @SuppressWarnings("unused")\r
- private void findText() {\r
- find.show();\r
- find.setFocusOnTextField();\r
- }\r
- @SuppressWarnings("unused")\r
- private void doFindText() {\r
- browser.getBrowser().page().findText(find.getText(), find.getFlags());\r
- find.setFocus();\r
- }\r
-\r
- \r
- @SuppressWarnings("unused")\r
- private void printNote() {\r
-\r
- QPrintDialog dialog = new QPrintDialog();\r
- if (dialog.exec() == QDialog.DialogCode.Accepted.value()) {\r
- QPrinter printer = dialog.printer();\r
- browser.getBrowser().print(printer);\r
- }\r
- }\r
- \r
- // Listener triggered when the email button is pressed\r
- @SuppressWarnings("unused")\r
- private void emailNote() {\r
- if (Desktop.isDesktopSupported()) {\r
- Desktop desktop = Desktop.getDesktop();\r
- \r
- String text2 = browser.getContentsToEmail();\r
- QUrl url = new QUrl("mailto:");\r
- url.addQueryItem("subject", browser.getTitle());\r
- url.addQueryItem("body", text2);\r
- QDesktopServices.openUrl(url);\r
- }\r
- }\r
-}\r
+/*
+ * This file is part of NixNote
+ * Copyright 2009 Randy Baumgarte
+ *
+ * This file may be licensed under the terms of of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+*/
+
+package cx.fbn.nevernote.gui;
+
+import java.awt.Desktop;
+import java.util.List;
+
+import com.trolltech.qt.core.QUrl;
+import com.trolltech.qt.core.Qt.WidgetAttribute;
+import com.trolltech.qt.gui.QCloseEvent;
+import com.trolltech.qt.gui.QDesktopServices;
+import com.trolltech.qt.gui.QDialog;
+import com.trolltech.qt.gui.QMdiSubWindow;
+import com.trolltech.qt.gui.QPrintDialog;
+import com.trolltech.qt.gui.QPrinter;
+
+import cx.fbn.nevernote.Global;
+import cx.fbn.nevernote.dialog.FindDialog;
+import cx.fbn.nevernote.neighbornote.ClipBoardObserver;
+import cx.fbn.nevernote.sql.DatabaseConnection;
+
+public class ExternalBrowse extends QMdiSubWindow {
+ private final DatabaseConnection conn;
+ private final BrowserWindow browser;
+ public Signal4<String, String, Boolean, BrowserWindow> contentsChanged;
+ public Signal1<String> windowClosing;
+ boolean noteDirty;
+ String saveTitle;
+ private final FindDialog find; // Text search in note dialog
+// ExternalBrowserMenuBar menu;
+ ExternalBrowserMenuBar menu;
+
+ // ICHANGED
+ private final ClipBoardObserver cbObserver;
+
+ // Constructor
+ // ICHANGED cbObserver引数を追加
+ public ExternalBrowse(DatabaseConnection c, ClipBoardObserver cbObserver) {
+ setAttribute(WidgetAttribute.WA_QuitOnClose, false);
+ setWindowTitle(tr("NeighborNote"));
+ conn = c;
+ // ICHANGED
+ this.cbObserver = cbObserver;
+
+ contentsChanged = new Signal4<String, String, Boolean, BrowserWindow>();
+ windowClosing = new Signal1<String>();
+ // ICHANGED
+ browser = new BrowserWindow(conn, this.cbObserver);
+
+ menu = new ExternalBrowserMenuBar(this);
+ for (int i=0; i<menu.actions().size(); i++) {
+ addAction(menu.actions().get(i));
+ }
+
+ setWidget(browser);
+ noteDirty = false;
+ browser.titleLabel.textChanged.connect(this, "titleChanged(String)");
+ browser.getBrowser().page().contentsChanged.connect(this, "contentChanged()");
+ find = new FindDialog();
+ find.getOkButton().clicked.connect(this, "doFindText()");
+ }
+
+ @SuppressWarnings("unused")
+ private void contentChanged() {
+ noteDirty = true;
+ contentsChanged.emit(getBrowserWindow().getNote().getGuid(), getBrowserWindow().getContent(), false, getBrowserWindow());
+ }
+
+
+ @Override
+ public void closeEvent(QCloseEvent event) {
+ if (noteDirty)
+ contentsChanged.emit(getBrowserWindow().getNote().getGuid(), getBrowserWindow().getContent(), true, getBrowserWindow());
+ windowClosing.emit(getBrowserWindow().getNote().getGuid());
+ }
+
+ public BrowserWindow getBrowserWindow() {
+ return browser;
+ }
+
+ @SuppressWarnings("unused")
+ private void titleChanged(String value) {
+ setWindowTitle(tr("NeighborNote - ") +value);
+ }
+
+ @SuppressWarnings("unused")
+ private void updateTitle(String guid, String title) {
+ if (guid.equals(getBrowserWindow().getNote().getGuid()) &&
+ (saveTitle != null && !title.equals(saveTitle) || saveTitle == null) ) {
+ saveTitle = title;
+ getBrowserWindow().loadingData(true);
+ getBrowserWindow().setTitle(title);
+ getBrowserWindow().getNote().setTitle(title);
+ getBrowserWindow().loadingData(false);
+ }
+ }
+ @SuppressWarnings("unused")
+ private void updateNotebook(String guid, String notebook) {
+ if (guid.equals(getBrowserWindow().getNote().getGuid())) {
+ getBrowserWindow().loadingData(true);
+ getBrowserWindow().setNotebook(notebook);
+ getBrowserWindow().loadingData(false);
+ }
+ }
+
+ @SuppressWarnings("unused")
+ private void updateTags(String guid, List<String> tags) {
+ if (guid.equals(getBrowserWindow().getNote().getGuid())) {
+ StringBuffer tagLine = new StringBuffer(100);
+ for (int i=0; i<tags.size(); i++) {
+ if (i>0)
+ tagLine.append(Global.tagDelimeter+" ");
+ tagLine.append(tags.get(i));
+
+ }
+ getBrowserWindow().loadingData(true);
+ getBrowserWindow().getTagLine().setText(tagLine.toString());
+ getBrowserWindow().loadingData(false);
+ }
+ }
+
+
+ @SuppressWarnings("unused")
+ private void findText() {
+ find.show();
+ find.setFocusOnTextField();
+ }
+ @SuppressWarnings("unused")
+ private void doFindText() {
+ browser.getBrowser().page().findText(find.getText(), find.getFlags());
+ find.setFocus();
+ }
+
+
+ @SuppressWarnings("unused")
+ private void printNote() {
+
+ QPrintDialog dialog = new QPrintDialog();
+ if (dialog.exec() == QDialog.DialogCode.Accepted.value()) {
+ QPrinter printer = dialog.printer();
+ browser.getBrowser().print(printer);
+ }
+ }
+
+ // Listener triggered when the email button is pressed
+ @SuppressWarnings("unused")
+ private void emailNote() {
+ if (Desktop.isDesktopSupported()) {
+ Desktop desktop = Desktop.getDesktop();
+
+ String text2 = browser.getContentsToEmail();
+ QUrl url = new QUrl("mailto:");
+ url.addQueryItem("subject", browser.getTitle());
+ url.addQueryItem("body", text2);
+ QDesktopServices.openUrl(url);
+ }
+ }
+}
-/*\r
- * This file is part of NixNote \r
- * Copyright 2009 Randy Baumgarte\r
- * \r
- * This file may be licensed under the terms of of the\r
- * GNU General Public License Version 2 (the ``GPL'').\r
- *\r
- * Software distributed under the License is distributed\r
- * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either\r
- * express or implied. See the GPL for the specific language\r
- * governing rights and limitations.\r
- *\r
- * You should have received a copy of the GPL along with this\r
- * program. If not, go to http://www.gnu.org/licenses/gpl.html\r
- * or write to the Free Software Foundation, Inc.,\r
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
- *\r
-*/\r
-package cx.fbn.nevernote.gui;\r
-\r
-import com.trolltech.qt.gui.QAction;\r
-import com.trolltech.qt.gui.QMenu;\r
-import com.trolltech.qt.gui.QMenuBar;\r
-\r
-import cx.fbn.nevernote.Global;\r
-import cx.fbn.nevernote.NeverNote;\r
-\r
-public class MainMenuBar extends QMenuBar {\r
-\r
- private final NeverNote parent;\r
- public QAction printAction; // Action when a user selects Print from the file menu\r
- public QAction connectAction; // Connect/Disconnect to Evernote\r
- public QAction fullReindexAction; // Action when a user wants to reindex the entire database\r
- public QAction synchronizeAction; // Synchronize data with Evernote \r
- public QAction selectiveSyncAction; // Specify which notebooks or tags to ignore\r
- public QAction settingsAction; // Show user config settings\r
- public QAction emailAction; // Action when a user selects "email"\r
- public QAction backupAction; // Backup the database\r
- public QAction restoreAction; // Restore from a backup\r
- public QAction emptyTrashAction; // Action when a user wants to clear the trash file\r
- public QAction exitAction; // Action when user selects "exit"\r
- public QAction aboutAction; // Action when a user selects "About"\r
- public QAction checkForUpdates; // Check for newer versions\r
- public QAction loggerAction; // Action when a user selects "Log"\r
- public QAction releaseAction; // Release notes\r
-\r
- public QAction noteAdd; // Add a note\r
- public QAction noteAttributes; // Action when a user selects note attributes\r
- public QAction noteTags; // Assign a note tags\r
- public QAction noteDelete; // Delete the current note\r
- public QAction noteRestoreAction; // Restore a note\r
- public QAction noteReindex; // Action when a user wants to reindex a note\r
- public QAction noteDuplicateAction; // Duplicate an existing note\r
- public QAction noteMergeAction; // Merge notes\r
- public QAction noteExportAction; // Export notes\r
- public QAction noteImportAction; // Import notes\r
- public QAction noteCopyAsUrlAction; // Copy the note as a URL\r
- \r
- public QAction editFind; // find text in the current note\r
- public QAction editUndo; // Undo last change\r
- public QAction editRedo; // Redo last change\r
- public QAction editCut; // Cut selected text\r
- public QAction editPaste; // Paste selected text\r
- public QAction editPasteWithoutFormat; // Paste selected text\r
- public QAction editCopy; // Copy selected text;\r
- \r
- public QAction wideListView; // View with list on the top\r
- public QAction narrowListView; // View with list on the side\r
- public QAction thumbnailView; // view thumbnails\r
- public QAction hideSavedSearches; // show/hide saved searches\r
- public QAction hideZoom; // show/hide the zoom spinner\r
- public QAction hideSearch; // Show/hide the search window\r
- public QAction hideQuota; // show/hide the quota window\r
- public QAction hideNotebooks; // show/hide notebooks\r
- public QAction hideTags; // show/hide tags\r
- public QAction hideAttributes; // show/hide note information\r
- public QAction hideTrash; // show/hide trash tree\r
- public QAction hideNoteList; // show/hide the list of notes\r
- public QAction showEditorBar; // show/hide the editor button bar\r
- public QAction hideLeftSide; // Hide the entire left side\r
- public QAction viewSource; // View the source HTML of a note\r
- \r
- public QAction formatBold; // Bold selected text\r
- public QAction formatItalic; // Italics selected text\r
- public QAction formatUnderline; // Underline selected text\r
- public QAction formatStrikethrough; // Strikethrough selected text\r
- public QAction formatSuperscript; // Superscript selected text\r
- public QAction formatSubscript; // Subscript selected text\r
- public QAction formatNumberList; // insert a numbered list\r
- public QAction formatBulletList; // insert a bulleted list;\r
- public QAction alignLeftAction; // Left justify text\r
- public QAction alignRightAction; // Right justify text\r
- public QAction alignCenterAction; // Center text\r
- public QAction horizontalLineAction; // Insert a horizontal line\r
- public QAction indentAction; // Indent\r
- public QAction outdentAction; // outdent menu action\r
- \r
- public QAction noteOnlineHistoryAction; // Pull note history from Evernote\r
- \r
- public QAction accountAction; // Account dialog box action\r
- public QAction disableIndexing; // put indexing on hold.\r
-// public QAction compactAction; // free unused space in the database\r
- public QAction databaseStatusAction; // Current database status\r
- public QAction folderImportAction; // Automatically import files \r
- public QAction spellCheckAction; // Spell checker\r
- public QAction encryptDatabaseAction; // Encrypt the local database\r
- \r
- public QAction notebookEditAction; // Edit the selected notebook\r
- public QAction notebookAddAction; // Add a new notebook\r
- public QAction notebookDeleteAction; // Delete a notebook\r
- public QAction notebookPublishAction; // Publish a notebook\r
- public QAction notebookShareAction; // Share a notebook with others\r
- public QAction notebookCloseAction; // Close notebooks\r
- public QAction notebookIconAction; // Change the icon\r
- public QAction notebookStackAction; // Stack/Unstack the icon.\r
- \r
- public QAction savedSearchAddAction; // Add a saved search\r
- public QAction savedSearchEditAction; // Edit a saved search\r
- public QAction savedSearchDeleteAction; // Delete a saved search\r
- public QAction savedSearchIconAction; // Change a saved search icon\r
- \r
- public QAction tagEditAction; // Edit a tag\r
- public QAction tagAddAction; // Add a tag\r
- public QAction tagDeleteAction; // Delete a tag\r
- public QAction tagIconAction; // Change the icon\r
- public QAction tagMergeAction; // Merge tags\r
- \r
- //**************************************************************************\r
- //* Menu Bar Titles\r
- //**************************************************************************\r
- \r
- private QMenu fileMenu; // File menu\r
- private QMenu noteMenu; // Note menu \r
- private QMenu notebookMenu; // Notebook menu\r
- private QMenu tagMenu; // Tag menu\r
- private QMenu savedSearchMenu; // Saved Searches \r
-\r
- private QMenu editMenu; // Edit menu\r
-\r
- private QMenu formatMenu; // Text format menu\r
- private QMenu viewMenu; // show/hide stuff\r
- private QMenu listMenu; // bullet or numbered list\r
- private QMenu indentMenu; // indent or outdent menu\r
- private QMenu alignMenu; // Left/Right/Center justify\r
- \r
-// private QMenu onlineMenu; // View online stuff (if connected)\r
- \r
- private QMenu toolsMenu; // Tools menu\r
- \r
- private QMenu helpMenu; \r
- \r
- public MainMenuBar(NeverNote p) {\r
- parent = p;\r
- \r
- \r
- fullReindexAction = new QAction(tr("Reindex Database"), this);\r
- fullReindexAction.setToolTip(tr("Reindex all notes"));\r
- fullReindexAction.triggered.connect(parent, "fullReindex()");\r
- setupShortcut(fullReindexAction, "Tools_Reindex_Database");\r
- \r
- printAction = new QAction(tr("Print"), this);\r
- printAction.setToolTip(tr("Print the current note"));\r
- printAction.triggered.connect(parent, "printNote()");\r
- setupShortcut(printAction, "File_Print");\r
- \r
- emailAction = new QAction(tr("Email"), this);\r
- emailAction.setToolTip(tr("Email the current note"));\r
- emailAction.triggered.connect(parent, "emailNote()");\r
- setupShortcut(emailAction, "File_Email");\r
- \r
- backupAction = new QAction(tr("Backup Database"), this);\r
- backupAction.setToolTip(tr("Backup the current database"));\r
- backupAction.triggered.connect(parent, "databaseBackup()");\r
- setupShortcut(backupAction, "File_Backup");\r
-\r
- restoreAction = new QAction(tr("Restore Database"), this);\r
- restoreAction.setToolTip(tr("Restore the database from a backup"));\r
- restoreAction.triggered.connect(parent, "databaseRestore()");\r
- setupShortcut(restoreAction, "File_Restore");\r
- \r
- emptyTrashAction = new QAction(tr("Empty Trash"), this);\r
- emptyTrashAction.setToolTip(tr("Empty the trash folder"));\r
- emptyTrashAction.triggered.connect(parent, "emptyTrash()");\r
- setupShortcut(emptyTrashAction, "File_Empty_Trash");\r
- \r
- noteRestoreAction = new QAction(tr("Restore"), this);\r
- noteRestoreAction.setToolTip(tr("Restore a deleted file from the trash"));\r
- noteRestoreAction.triggered.connect(parent, "restoreNote()");\r
- noteRestoreAction.setVisible(false);\r
- setupShortcut(noteRestoreAction, "File_Note_Restore");\r
- \r
- settingsAction = new QAction(tr("Preferences"), this);\r
- settingsAction.setToolTip(tr("Program settings"));\r
- settingsAction.triggered.connect(parent, "settings()");\r
- setupShortcut(settingsAction, "Edit_Preferences");\r
- \r
- exitAction = new QAction(tr("Exit"), this);\r
- exitAction.setToolTip(tr("Close the program"));\r
- exitAction.triggered.connect(parent, "closeNeverNote()");\r
- exitAction.setShortcut("Ctrl+Q");\r
- setupShortcut(exitAction, "File_Exit");\r
- \r
- noteAttributes = new QAction(tr("Extended Information"), this);\r
- noteAttributes.setToolTip(tr("Show/Hide extended note attributes"));\r
- noteAttributes.triggered.connect(parent, "toggleNoteInformation()");\r
- noteAttributes.setShortcut("F8");\r
- setupShortcut(noteAttributes, "View_Extended_Information");\r
- \r
- noteReindex = new QAction(tr("Reindex"), this);\r
- noteReindex.setToolTip(tr("Reindex this note"));\r
- noteReindex.triggered.connect(parent, "reindexNote()");\r
- setupShortcut(noteReindex, "File_Note_Reindex");\r
- \r
- noteDuplicateAction = new QAction(tr("Duplicate"), this);\r
- noteDuplicateAction.setToolTip(tr("Duplicate this note"));\r
- noteDuplicateAction.triggered.connect(parent, "duplicateNote()");\r
- setupShortcut(noteReindex, "File_Note_Duplicate");\r
- \r
- noteMergeAction = new QAction(tr("Merge Notes"), this);\r
- noteMergeAction.setToolTip(tr("Merge Multiple notes"));\r
- noteMergeAction.triggered.connect(parent, "mergeNotes()");\r
- setupShortcut(noteMergeAction, "File_Note_Merge");\r
- \r
- noteExportAction = new QAction(tr("Export Selected Notes"), this);\r
- noteExportAction.setToolTip(tr("Export selected notes"));\r
- noteExportAction.triggered.connect(parent, "exportNotes()");\r
- setupShortcut(noteExportAction, "File_Note_Export");\r
- \r
- noteCopyAsUrlAction = new QAction(tr("Copy as URL"), this);\r
- noteCopyAsUrlAction.setToolTip(tr("Copy as URL"));\r
- noteCopyAsUrlAction.triggered.connect(parent, "copyAsUrlClicked()");\r
- setupShortcut(noteCopyAsUrlAction, "Note_Copy_As_Url");\r
- \r
- noteImportAction = new QAction(tr("Import Notes"), this);\r
- noteImportAction.setToolTip(tr("Import notes"));\r
- noteImportAction.triggered.connect(parent, "importNotes()");\r
- setupShortcut(noteImportAction, "File_Note_Import");\r
- \r
- noteAdd = new QAction(tr("Add"), this);\r
- noteAdd.setToolTip(tr("Add a new note"));\r
- noteAdd.triggered.connect(parent, "addNote()");\r
- setupShortcut(noteAdd, "File_Note_Add");\r
- \r
- noteTags = new QAction(tr("Modify Tags"), this);\r
- noteTags.setToolTip(tr("Change the tags assigned to this note"));\r
- noteTags.triggered.connect(parent.browserWindow, "modifyTags()");\r
- setupShortcut(noteTags, "File_Note_Modify_Tags");\r
- \r
- noteDelete = new QAction(tr("Delete"), this);\r
- noteDelete.setToolTip(tr("Delete this note"));\r
- noteDelete.triggered.connect(parent, "deleteNote()");\r
- setupShortcut(noteDelete, "File_Note_Delete");\r
- \r
- editFind = new QAction(tr("Find In Note"), this);\r
- editFind.setToolTip(tr("Find a string in the current note"));\r
- editFind.triggered.connect(parent, "findText()");\r
- setupShortcut(editFind, "Edit_Find_In_Note");\r
- //editFind.setShortcut("Ctrl+F");\r
- \r
- editUndo = new QAction(tr("Undo"), this);\r
- editUndo.setToolTip(tr("Undo"));\r
- editUndo.triggered.connect(parent.browserWindow, "undoClicked()"); \r
- setupShortcut(editUndo, "Edit_Undo");\r
- //editUndo.setShortcut("Ctrl+Z");\r
- \r
- editRedo = new QAction(tr("Redo"), this);\r
- editRedo.setToolTip(tr("Redo"));\r
- editRedo.triggered.connect(parent.browserWindow, "redoClicked()");\r
- setupShortcut(editRedo, "Edit_Redo");\r
- //editRedo.setShortcut("Ctrl+Y");\r
- \r
- editCut = new QAction(tr("Cut"), this);\r
- editCut.setToolTip(tr("Cut"));\r
- editCut.triggered.connect(parent.browserWindow, "cutClicked()");\r
- setupShortcut(editCut, "Edit_Cut");\r
- //editCut.setShortcut("Ctrl+X");\r
- \r
- editCopy = new QAction(tr("Copy"), this);\r
- editCopy.setToolTip(tr("Copy"));\r
- editCopy.triggered.connect(parent.browserWindow, "copyClicked()");\r
- setupShortcut(editCopy, "Edit_Copy");\r
- //editCopy.setShortcut("Ctrl+C");\r
-\r
- \r
- editPaste = new QAction(tr("Paste"), this);\r
- editPaste.setToolTip(tr("Paste"));\r
- editPaste.triggered.connect(parent.browserWindow, "pasteClicked()");\r
- setupShortcut(editPaste, "Edit_Paste");\r
-\r
- editPasteWithoutFormat = new QAction(tr("Paste Without Formatting"), this);\r
- editPasteWithoutFormat.setToolTip(tr("Paste Without Formatting"));\r
- editPasteWithoutFormat.triggered.connect(parent.browserWindow, "pasteWithoutFormattingClicked()");\r
- setupShortcut(editPasteWithoutFormat, "Edit_Paste_Without_Formatting");\r
- \r
- hideNoteList = new QAction(tr("Show Note List"), this);\r
- hideNoteList.setToolTip(tr("Show/Hide Note List"));\r
- hideNoteList.triggered.connect(parent, "toggleNoteListWindow()");\r
- hideNoteList.setCheckable(true);\r
- hideNoteList.setChecked(true);\r
- setupShortcut(hideNoteList, "View_Show_Note_List");\r
- \r
- hideTags = new QAction(tr("Show Tags"), this);\r
- hideTags.setToolTip(tr("Show/Hide Tags"));\r
- hideTags.triggered.connect(parent, "toggleTagWindow()");\r
- hideTags.setCheckable(true);\r
- hideTags.setChecked(true);\r
- setupShortcut(hideTags, "View_Show_Tags");\r
- \r
- hideNotebooks = new QAction(tr("Show Notebooks"), this);\r
- hideNotebooks.setToolTip(tr("Show/Hide Notebooks"));\r
- hideNotebooks.triggered.connect(parent, "toggleNotebookWindow()");\r
- hideNotebooks.setCheckable(true);\r
- hideNotebooks.setChecked(true);\r
- setupShortcut(hideNotebooks, "View_Show_Notebooks");\r
- \r
- hideZoom = new QAction(tr("Show Zoom"), this);\r
- hideZoom.setToolTip(tr("Show/Hide Zoom"));\r
- hideZoom.triggered.connect(parent, "toggleZoomWindow()");\r
- hideZoom.setCheckable(true);\r
- hideZoom.setChecked(true);\r
- setupShortcut(hideZoom, "View_Show_Zoom");\r
- \r
- hideQuota = new QAction(tr("Show Quota Bar"), this);\r
- hideQuota.setToolTip(tr("Show/Hide Quota"));\r
- hideQuota.triggered.connect(parent, "toggleQuotaWindow()");\r
- hideQuota.setCheckable(true);\r
- hideQuota.setChecked(true);\r
- setupShortcut(hideQuota, "View_Show_Quota");\r
- \r
- hideSearch = new QAction(tr("Show Search Box"), this);\r
- hideSearch.setToolTip(tr("Show/Hide Search Box"));\r
- hideSearch.triggered.connect(parent, "toggleSearchWindow()");\r
- hideSearch.setCheckable(true);\r
- hideSearch.setChecked(true);\r
- setupShortcut(hideSearch, "View_Show_Search");\r
-\r
- wideListView = new QAction(tr("Wide List View"), this);\r
- wideListView.setToolTip(tr("Wide List View"));\r
- wideListView.setCheckable(true);\r
- wideListView.changed.connect(parent, "wideListView()");\r
- setupShortcut(wideListView, "View_Wide_List");\r
- \r
- narrowListView = new QAction(tr("Narrow List View"), this);\r
- narrowListView.setToolTip(tr("Narrow List View"));\r
- narrowListView.setCheckable(true);\r
- narrowListView.changed.connect(parent, "narrowListView()");\r
- setupShortcut(narrowListView, "View_Narrow_List");\r
- \r
- thumbnailView = new QAction(tr("Preview"), this);\r
- thumbnailView.setToolTip(tr("Preview Notes"));\r
- thumbnailView.triggered.connect(parent, "thumbnailView()");\r
- setupShortcut(thumbnailView, "View_Thumbnail");\r
- \r
- hideSavedSearches = new QAction(tr("Show Saved Searches"), this);\r
- hideSavedSearches.setToolTip(tr("Show/Hide Saved Searches"));\r
- hideSavedSearches.triggered.connect(parent, "toggleSavedSearchWindow()");\r
- hideSavedSearches.setCheckable(true);\r
- hideSavedSearches.setChecked(true);\r
- setupShortcut(hideSavedSearches, "View_Show_SavedSearches");\r
- \r
- hideAttributes = new QAction(tr("Show Attribute Searches"), this);\r
- hideAttributes.setToolTip(tr("Show/Hide Attribute Searches"));\r
- hideAttributes.triggered.connect(parent, "toggleAttributesWindow()");\r
- hideAttributes.setCheckable(true);\r
- hideAttributes.setChecked(true);\r
- setupShortcut(hideAttributes, "View_Show_Attribute_Searches");\r
-\r
- hideTrash = new QAction(tr("Show Trash"), this);\r
- hideTrash.setToolTip(tr("Show/Hide Trash Tree"));\r
- hideTrash.triggered.connect(parent, "toggleTrashWindow()");\r
- hideTrash.setCheckable(true);\r
- hideTrash.setChecked(true);\r
- setupShortcut(hideTrash, "View_Show_Trash");\r
- \r
-\r
- showEditorBar = new QAction(tr("Show Editor Button Bar"), this);\r
- showEditorBar.setToolTip(tr("Show/Hide Editor Button Bar"));\r
- showEditorBar.triggered.connect(parent, "toggleEditorButtonBar()");\r
- showEditorBar.setCheckable(true);\r
- showEditorBar.setChecked(true);\r
- setupShortcut(showEditorBar, "View_Show_Editor_Button_Bar");\r
- \r
-\r
- hideLeftSide = new QAction(tr("Hide Left Side Panels"), this);\r
- hideLeftSide.setToolTip(tr("Hide The Entire Left Side"));\r
- hideLeftSide.triggered.connect(parent, "toggleLeftSide()");\r
- hideLeftSide.setCheckable(true);\r
- hideLeftSide.setChecked(false);\r
- setupShortcut(hideLeftSide, "View_Show_Left_Side");\r
- //hideLeftSide.setShortcut("F11");\r
- \r
- viewSource = new QAction(tr("View Source"), this);\r
- viewSource.setToolTip(tr("View the source HTML for a note"));\r
- viewSource.triggered.connect(parent, "viewSource()");\r
- viewSource.setCheckable(true);\r
- viewSource.setChecked(false);\r
- setupShortcut(viewSource, "View_Source");\r
- //hideLeftSide.setShortcut("F11");\r
-\r
- alignLeftAction = new QAction(tr("Left"), this);\r
- alignLeftAction.setToolTip(tr("Left Align"));\r
- alignLeftAction.triggered.connect(parent.browserWindow, "justifyLeftClicked()");\r
- setupShortcut(alignLeftAction, "Format_Alignment_Left");\r
- //alignLeftAction.setShortcut("Ctrl+L");\r
- \r
- alignRightAction = new QAction(tr("Right"), this);\r
- alignRightAction.setToolTip(tr("Right Align"));\r
- alignRightAction.triggered.connect(parent.browserWindow, "justifyRightClicked()");\r
- setupShortcut(alignRightAction, "Format_Alignment_Right");\r
- //alignRightAction.setShortcut("Ctrl+R");\r
- \r
- alignCenterAction = new QAction(tr("Center"), this);\r
- alignCenterAction.setToolTip(tr("Center Align"));\r
- alignCenterAction.triggered.connect(parent.browserWindow, "justifyCenterClicked()");\r
- setupShortcut(alignCenterAction, "Format_Alignment_Center");\r
- //alignCenterAction.setShortcut("Ctrl+C");\r
- \r
- formatBold = new QAction(tr("Bold"), this);\r
- formatBold.setToolTip(tr("Bold"));\r
- formatBold.triggered.connect(parent.browserWindow, "boldClicked()");\r
- setupShortcut(formatBold, "Format_Bold");\r
- //formatBold.setShortcut("Ctrl+B");\r
- \r
- formatItalic = new QAction(tr("Italic"), this);\r
- formatItalic.setToolTip(tr("Italic"));\r
- formatItalic.triggered.connect(parent.browserWindow, "italicClicked()");\r
- setupShortcut(formatItalic, "Format_Italic");\r
- //formatItalic.setShortcut("Ctrl+I");\r
- \r
- formatUnderline = new QAction(tr("Underline"), this);\r
- formatUnderline.setToolTip(tr("Underline"));\r
- formatUnderline.triggered.connect(parent.browserWindow, "underlineClicked()");\r
- setupShortcut(formatUnderline, "Format_Underline");\r
-// formatUnderline.setShortcut("Ctrl+U");\r
-\r
- \r
- formatSuperscript = new QAction(tr("Superscript"), this);\r
- formatSuperscript.setToolTip(tr("Superscript"));\r
- formatSuperscript.triggered.connect(parent.browserWindow, "superscriptClicked()");\r
- setupShortcut(formatSuperscript, "Format_Superscript");\r
-\r
-\r
- formatSubscript = new QAction(tr("Subscript"), this);\r
- formatSubscript.setToolTip(tr("Subscript"));\r
- formatSubscript.triggered.connect(parent.browserWindow, "subscriptClicked()");\r
- setupShortcut(formatSubscript, "Format_Subscript");\r
-\r
- \r
- formatStrikethrough = new QAction(tr("Strikethrough"), this);\r
- formatStrikethrough.setToolTip(tr("Strikethrough"));\r
- formatStrikethrough.triggered.connect(parent.browserWindow, "strikethroughClicked()");\r
- setupShortcut(formatStrikethrough, "Format_Strikethrough");\r
-\r
- horizontalLineAction = new QAction(tr("Horizontal Line"), this);\r
- horizontalLineAction.setToolTip(tr("Horizontal Line"));\r
- horizontalLineAction.triggered.connect(parent.browserWindow, "hlineClicked()");\r
- setupShortcut(horizontalLineAction, "Format_Horizontal_Line");\r
- \r
- formatBulletList = new QAction(tr("Bulleted List"), this);\r
-// formatBulletList.setText(tr("Numbered List"));\r
- formatBulletList.triggered.connect(parent.browserWindow, "bulletListClicked()");\r
- setupShortcut(formatBulletList, "Format_List_Bullet");\r
-// formatBulletList.setShortcut("Ctrl+Shift+B");\r
- \r
- formatNumberList = new QAction(tr("Numbered List"), this);\r
- formatNumberList.setText(tr("Numbered list"));\r
- formatNumberList.triggered.connect(parent.browserWindow, "numberListClicked()");\r
- setupShortcut(formatNumberList, "Format_List_Numbered");\r
-// formatNumberList.setShortcut("Ctrl+Shift+O");\r
-\r
- indentAction = new QAction(tr(">> Increase"), this);\r
- indentAction.setText(tr(">> Increase"));\r
- indentAction.triggered.connect(parent.browserWindow, "indentClicked()");\r
- setupShortcut(indentAction, "Format_Indent_Increase");\r
- //indentAction.setShortcut("Ctrl+M");\r
-\r
- outdentAction = new QAction(tr("<< Decrease"), this);\r
- outdentAction.setText(tr("<< Decrease"));\r
- outdentAction.triggered.connect(parent.browserWindow, "outdentClicked()");\r
- setupShortcut(outdentAction, "Format_Indent_Decrease");\r
- //outdentAction.setShortcut("Ctrl+Shift+M");\r
- \r
- notebookAddAction = new QAction(tr("Add"), this);\r
- notebookAddAction.triggered.connect(parent, "addNotebook()");\r
- setupShortcut(notebookAddAction, "File_Notebook_Add");\r
- \r
- notebookEditAction = new QAction(tr("Edit"), this);\r
- notebookEditAction.setEnabled(false);\r
- notebookEditAction.triggered.connect(parent, "editNotebook()");\r
- setupShortcut(notebookEditAction, "File_Notebook_Edit");\r
- \r
- notebookDeleteAction = new QAction(tr("Delete"), this);\r
- notebookDeleteAction.setEnabled(false);\r
- notebookDeleteAction.triggered.connect(parent, "deleteNotebook()");\r
- setupShortcut(notebookDeleteAction, "File_Notebook_Delete");\r
- \r
- notebookPublishAction = new QAction(tr("Share With The World"), this);\r
- notebookPublishAction.setEnabled(false);\r
- notebookPublishAction.setVisible(false);\r
- notebookPublishAction.triggered.connect(parent, "publishNotebook()");\r
- setupShortcut(notebookPublishAction, "File_Notebook_Publish");\r
-\r
- notebookShareAction = new QAction(tr("Share With Individuals"), this);\r
- notebookShareAction.setEnabled(false);\r
- notebookShareAction.setVisible(false);\r
- notebookShareAction.triggered.connect(parent, "shareNotebook()");\r
- setupShortcut(notebookShareAction, "File_Notebook_Share");\r
- \r
- \r
- notebookCloseAction = new QAction(tr("Open/Close Notebooks"), this);\r
- notebookCloseAction.setEnabled(true);\r
- notebookCloseAction.triggered.connect(parent, "closeNotebooks()");\r
- setupShortcut(notebookCloseAction, "File_Notebook_Close");\r
-\r
- notebookIconAction = new QAction(tr("Change Icon"), this);\r
- notebookIconAction.setEnabled(false);\r
- notebookIconAction.triggered.connect(parent, "setNotebookIcon()");\r
- setupShortcut(notebookIconAction, "File_Notebook_Icon");\r
- \r
- notebookStackAction = new QAction(tr("Set Stack"), this);\r
- notebookStackAction.setEnabled(false);\r
- notebookStackAction.triggered.connect(parent, "stackNotebook()");\r
- setupShortcut(notebookStackAction, "File_Notebook_Stack");\r
- \r
- tagAddAction = new QAction(tr("Add"),this);\r
- tagAddAction.triggered.connect(parent, "addTag()");\r
- setupShortcut(tagAddAction, "File_Tag_Add");\r
- \r
- tagEditAction = new QAction(tr("Edit"), this);\r
- tagEditAction.triggered.connect(parent, "editTag()");\r
- tagEditAction.setEnabled(false);\r
- setupShortcut(tagEditAction, "File_Tag_Edit");\r
- \r
- tagDeleteAction = new QAction(tr("Delete"), this);\r
- tagDeleteAction.triggered.connect(parent, "deleteTag()");\r
- tagDeleteAction.setEnabled(false); \r
- setupShortcut(tagDeleteAction, "File_Tag_Delete");\r
- \r
- tagIconAction = new QAction(tr("Change Icon"), this);\r
- tagIconAction.triggered.connect(parent, "setTagIcon()");\r
- tagIconAction.setEnabled(false); \r
- setupShortcut(tagIconAction, "File_Tag_Icon");\r
- \r
- tagMergeAction = new QAction(tr("Merge Tags"), this);\r
- tagMergeAction.triggered.connect(parent, "mergeTags()");\r
- tagMergeAction.setEnabled(false); \r
- setupShortcut(tagMergeAction, "File_Tag_Merge");\r
- \r
- savedSearchAddAction = new QAction(tr("Add"),this);\r
- savedSearchAddAction.triggered.connect(parent, "addSavedSearch()");\r
- setupShortcut(savedSearchAddAction, "File_SavedSearch_Add");\r
- \r
- savedSearchEditAction = new QAction(tr("Edit"), this);\r
- savedSearchEditAction.triggered.connect(parent, "editSavedSearch()");\r
- savedSearchEditAction.setEnabled(false);\r
- setupShortcut(savedSearchEditAction, "File_SavedSearch_Edit");\r
- \r
- savedSearchDeleteAction = new QAction(tr("Delete"), this);\r
- savedSearchDeleteAction.triggered.connect(parent, "deleteSavedSearch()");\r
- savedSearchDeleteAction.setEnabled(false); \r
- setupShortcut(savedSearchDeleteAction, "File_SavedSearch_Delete");\r
-\r
- savedSearchIconAction = new QAction(tr("Change Icon"), this);\r
- savedSearchIconAction.triggered.connect(parent, "setSavedSearchIcon()");\r
- savedSearchIconAction.setEnabled(false); \r
- setupShortcut(savedSearchIconAction, "File_SavedSearch_Icon"); \r
- \r
- connectAction = new QAction(tr("Connect"), this);\r
- connectAction.setToolTip("Connect to Evernote");\r
- connectAction.triggered.connect(parent, "remoteConnect()");\r
- setupShortcut(connectAction, "Tools_Connect");\r
- \r
- synchronizeAction = new QAction(tr("Synchronize with Evernote"), this);\r
- synchronizeAction.setToolTip("Delete all local data & get a fresh copy");\r
- synchronizeAction.triggered.connect(parent, "evernoteSync()");\r
- synchronizeAction.setEnabled(false);\r
- setupShortcut(synchronizeAction, "Tools_Synchronize");\r
- //synchronizeAction.setShortcut("F9");\r
- \r
- noteOnlineHistoryAction = new QAction(tr("Note History"), this);\r
- noteOnlineHistoryAction.triggered.connect(parent, "viewNoteHistory()");\r
- noteOnlineHistoryAction.setEnabled(false);\r
- setupShortcut(noteOnlineHistoryAction, "File_Note_History");\r
- \r
- selectiveSyncAction = new QAction(tr("Selective Synchronize"), this);\r
- selectiveSyncAction.setToolTip("Selectively ignore some notes");\r
- selectiveSyncAction.triggered.connect(parent, "setupSelectiveSync()");\r
- selectiveSyncAction.setEnabled(false);\r
- setupShortcut(synchronizeAction, "File_Selective_Sync");\r
- \r
- \r
- \r
- accountAction = new QAction(tr("Account Information"), this);\r
- accountAction.setToolTip(tr("Account Information"));\r
- accountAction.triggered.connect(parent, "accountInformation()");\r
- setupShortcut(accountAction, "Tools_Account_Information");\r
- \r
-// compactAction = new QAction(tr("Compact Database"), this);\r
-// compactAction.setToolTip(tr("Free unused database space"));\r
-// compactAction.triggered.connect(parent, "compactDatabase()");\r
-// setupShortcut(compactAction, "Tools_Compact_Database");\r
-\r
- databaseStatusAction = new QAction(tr("Database Status"), this);\r
- databaseStatusAction.setToolTip(tr("Show current database information"));\r
- databaseStatusAction.triggered.connect(parent, "databaseStatus()");\r
- setupShortcut(databaseStatusAction, "Tools_Database_Status");\r
- \r
- \r
- disableIndexing = new QAction(tr("Disable Note Indexing"), this);\r
- disableIndexing.setToolTip(tr("Manually Stop Note Indexing"));\r
- disableIndexing.triggered.connect(parent, "toggleNoteIndexing()");\r
- disableIndexing.setCheckable(true);\r
- disableIndexing.setChecked(false);\r
- setupShortcut(disableIndexing, "Tools_Disable_Note_Indexing");\r
- \r
- \r
- folderImportAction = new QAction(tr("Automatic Folder Importing"), this);\r
- folderImportAction.setToolTip(tr("Import Files Automatically"));\r
- folderImportAction.triggered.connect(parent, "folderImport()");\r
- setupShortcut(folderImportAction, "Tools_Folder_Import");\r
- \r
- spellCheckAction = new QAction(tr("Spell Check"), this);\r
- spellCheckAction.setToolTip(tr("Check for spelling errors"));\r
- spellCheckAction.triggered.connect(parent.browserWindow, "spellCheckClicked()");\r
- setupShortcut(spellCheckAction, "Tools_Spell_Check");\r
-\r
- encryptDatabaseAction = new QAction(tr("Encrypt Database"), this);\r
- encryptDatabaseAction.setToolTip(tr("Encrypt the database upon shutdown"));\r
- encryptDatabaseAction.triggered.connect(parent, "doDatabaseEncrypt()");\r
- setupShortcut(encryptDatabaseAction, "Tools_Database_Encrypt");\r
- if (Global.cipherPassword != null && Global.cipherPassword != "") {\r
- encryptDatabaseAction.setText("Decrypt Database");\r
- encryptDatabaseAction.setToolTip("Decrypt the database upon shutdown");\r
- }\r
- \r
- loggerAction = new QAction(tr("Logs"), this);\r
- loggerAction.setToolTip(tr("Show the detailed application log"));\r
- loggerAction.triggered.connect(parent, "logger()");\r
- setupShortcut(loggerAction, "About_Log");\r
- \r
- releaseAction = new QAction(tr("Release Notes"), this);\r
- releaseAction.setToolTip(tr("Release notes"));\r
- releaseAction.triggered.connect(parent, "releaseNotes()"); \r
- setupShortcut(releaseAction, "About_Release_Notes");\r
- \r
- checkForUpdates = new QAction(tr("Check For Updates"), this);\r
- checkForUpdates.setToolTip(tr("Check for newer versions"));\r
- checkForUpdates.triggered.connect(parent, "checkForUpdates()"); \r
- setupShortcut(checkForUpdates, "Help_Check_For_Updates");\r
- \r
- aboutAction = new QAction(tr("About"), this);\r
- aboutAction.setToolTip(tr("About NixNote"));\r
- aboutAction.triggered.connect(parent, "about()"); \r
- setupShortcut(aboutAction, "About_About");\r
- \r
- setupMenuBar();\r
- }\r
- \r
- public void setupMenuBar() {\r
- fileMenu = addMenu(tr("&File"));\r
- \r
- noteMenu = fileMenu.addMenu(tr("&Note"));\r
- notebookMenu = fileMenu.addMenu(tr("Notebook"));\r
- tagMenu = fileMenu.addMenu(tr("Tag"));\r
- savedSearchMenu = fileMenu.addMenu(tr("Saved Searches"));\r
- fileMenu.addSeparator();\r
- fileMenu.addAction(emailAction);\r
- fileMenu.addAction(printAction);\r
- fileMenu.addSeparator();\r
- fileMenu.addAction(noteImportAction);\r
- fileMenu.addAction(noteExportAction);\r
- fileMenu.addAction(backupAction);\r
- fileMenu.addAction(restoreAction);\r
- fileMenu.addSeparator();\r
- fileMenu.addAction(selectiveSyncAction);\r
- //fileMenu.addAction(parent.browserWindow.browser.downloadAttachment);\r
- fileMenu.addSeparator();\r
- fileMenu.addAction(emptyTrashAction);\r
- fileMenu.addAction(exitAction);\r
-\r
- editMenu = addMenu(tr("&Edit"));\r
- editMenu.addAction(editFind);\r
- editMenu.addSeparator();\r
- editMenu.addAction(editUndo);\r
- editMenu.addAction(editRedo);\r
- editMenu.addSeparator();\r
- editMenu.addAction(editCut);\r
- editMenu.addAction(editCopy);\r
- editMenu.addAction(editPaste);\r
- editMenu.addAction(editPasteWithoutFormat);\r
- editMenu.addSeparator();\r
- editMenu.addAction(settingsAction);\r
- \r
- viewMenu = addMenu(tr("&View"));\r
- viewMenu.addAction(noteAttributes);\r
- viewMenu.addAction(viewSource);\r
- viewMenu.addSeparator();\r
- viewMenu.addAction(wideListView);\r
- viewMenu.addAction(narrowListView);\r
- viewMenu.addAction(thumbnailView);\r
- viewMenu.addSeparator();\r
- viewMenu.addAction(hideNoteList);\r
- viewMenu.addAction(hideSearch);\r
- viewMenu.addAction(hideQuota);\r
- viewMenu.addAction(hideZoom);\r
- viewMenu.addAction(hideNotebooks);\r
- viewMenu.addAction(hideTags);\r
- viewMenu.addAction(hideAttributes);\r
- viewMenu.addAction(hideSavedSearches);\r
- viewMenu.addAction(hideTrash);\r
- viewMenu.addAction(showEditorBar);\r
- viewMenu.addAction(hideLeftSide);\r
- \r
- formatMenu = addMenu(tr("F&ormat"));\r
- formatMenu.addAction(formatBold);\r
- formatMenu.addAction(formatUnderline);\r
- formatMenu.addAction(formatItalic);\r
- formatMenu.addSeparator();\r
- formatMenu.addAction(formatStrikethrough);\r
- formatMenu.addAction(horizontalLineAction);\r
- formatMenu.addSeparator();\r
- formatMenu.addAction(formatSuperscript);\r
- formatMenu.addAction(formatSubscript);\r
- formatMenu.addSeparator();\r
- //formatMenu.addAction(parent.browserWindow.browser.todoAction);\r
- //formatMenu.addAction(parent.browserWindow.browser.encryptAction);\r
- //formatMenu.addAction(parent.browserWindow.browser.insertLinkAction);\r
- //formatMenu.addAction(parent.browserWindow.browser.insertQuickLinkAction);\r
- //formatMenu.addAction(parent.browserWindow.browser.insertLatexAction);\r
- formatMenu.addMenu(parent.browserWindow.browser.tableMenu);\r
- formatMenu.addMenu(parent.browserWindow.browser.imageMenu);\r
- formatMenu.addSeparator();\r
-\r
- alignMenu = formatMenu.addMenu(tr("Alignment"));\r
- alignMenu.addAction(alignLeftAction);\r
- alignMenu.addAction(alignCenterAction);\r
- alignMenu.addAction(alignRightAction);\r
- \r
- listMenu = formatMenu.addMenu(tr("Lists"));\r
- listMenu.addAction(formatBulletList);\r
- listMenu.addAction(formatNumberList);\r
- indentMenu = formatMenu.addMenu(tr("Indent"));\r
- indentMenu.addAction(indentAction);\r
- indentMenu.addAction(outdentAction);\r
- \r
- noteAttributes.setCheckable(true);\r
- noteMenu.addAction(noteAdd);\r
- noteMenu.addAction(noteDelete);\r
- //noteMenu.addAction(noteCopyAsUrlAction);\r
- noteMenu.addAction(noteReindex);\r
- noteMenu.addSeparator();\r
- noteMenu.addAction(noteTags);\r
- noteMenu.addAction(noteRestoreAction);\r
- noteMenu.addSeparator();\r
- noteMenu.addAction(noteOnlineHistoryAction);\r
- noteMenu.addAction(noteDuplicateAction);\r
- noteMenu.addAction(noteMergeAction);\r
-\r
- \r
- notebookMenu.addAction(notebookAddAction);\r
- notebookMenu.addAction(notebookEditAction);\r
- notebookMenu.addAction(notebookDeleteAction);\r
- notebookMenu.addSeparator();\r
- notebookMenu.addAction(notebookPublishAction);\r
- notebookMenu.addAction(notebookShareAction);\r
- notebookMenu.addSeparator();\r
- notebookMenu.addAction(notebookStackAction);\r
- notebookMenu.addAction(notebookCloseAction);\r
- notebookMenu.addSeparator();\r
- notebookMenu.addAction(notebookIconAction);\r
- \r
- tagMenu.addAction(tagAddAction);\r
- tagMenu.addAction(tagEditAction);\r
- tagMenu.addAction(tagDeleteAction);\r
- tagMenu.addAction(tagMergeAction);\r
- tagMenu.addSeparator();\r
- tagMenu.addAction(tagIconAction);\r
- \r
- savedSearchMenu.addAction(savedSearchAddAction);\r
- savedSearchMenu.addAction(savedSearchEditAction);\r
- savedSearchMenu.addAction(savedSearchDeleteAction);\r
- savedSearchMenu.addSeparator();\r
- savedSearchMenu.addAction(savedSearchIconAction);\r
- \r
-// onlineMenu = addMenu(tr("&Online"));\r
-// onlineMenu.addAction(synchronizeAction);\r
-// onlineMenu.addAction(connectAction);\r
-// onlineMenu.addSeparator();\r
-// onlineMenu.addAction(noteOnlineHistoryAction);\r
-// onlineMenu.addAction(selectiveSyncAction);\r
- \r
- toolsMenu = addMenu(tr("&Tools"));\r
- toolsMenu.addAction(synchronizeAction);\r
- toolsMenu.addAction(connectAction);\r
- toolsMenu.addSeparator();\r
- toolsMenu.addAction(spellCheckAction);\r
- toolsMenu.addAction(accountAction);\r
- toolsMenu.addAction(fullReindexAction);\r
- toolsMenu.addAction(disableIndexing);\r
-// toolsMenu.addAction(compactAction);\r
- toolsMenu.addSeparator();\r
- toolsMenu.addAction(encryptDatabaseAction);\r
- toolsMenu.addAction(databaseStatusAction);\r
- toolsMenu.addSeparator();\r
- toolsMenu.addAction(folderImportAction);\r
-\r
- helpMenu = addMenu(tr("&Help"));\r
- helpMenu.addAction(releaseAction);\r
- helpMenu.addAction(checkForUpdates);\r
- helpMenu.addAction(loggerAction);\r
- helpMenu.addSeparator();\r
- helpMenu.addAction(aboutAction);\r
- \r
- addMenu(fileMenu);\r
- addMenu(editMenu);\r
- addMenu(viewMenu);\r
- addMenu(formatMenu);\r
-// addMenu(onlineMenu);\r
- addMenu(toolsMenu);\r
- addMenu(helpMenu);\r
-\r
- }\r
-\r
- public void setupToolBarVisible() {\r
- viewMenu.addAction(parent.toolBar.toggleViewAction());\r
- setupShortcut(parent.toolBar.toggleViewAction(), "View_Toolbar");\r
- }\r
- \r
- private void setupShortcut(QAction action, String text) {\r
- if (!Global.shortcutKeys.containsAction(text))\r
- return;\r
- action.setShortcut(Global.shortcutKeys.getShortcut(text));\r
- }\r
-\r
-}\r
+/*
+ * This file is part of NixNote
+ * Copyright 2009 Randy Baumgarte
+ *
+ * This file may be licensed under the terms of of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+*/
+package cx.fbn.nevernote.gui;
+
+import com.trolltech.qt.gui.QAction;
+import com.trolltech.qt.gui.QMenu;
+import com.trolltech.qt.gui.QMenuBar;
+
+import cx.fbn.nevernote.Global;
+import cx.fbn.nevernote.NeverNote;
+
+public class MainMenuBar extends QMenuBar {
+
+ private final NeverNote parent;
+ public QAction printAction; // Action when a user selects Print from the file menu
+ public QAction connectAction; // Connect/Disconnect to Evernote
+ public QAction fullReindexAction; // Action when a user wants to reindex the entire database
+ public QAction synchronizeAction; // Synchronize data with Evernote
+ public QAction selectiveSyncAction; // Specify which notebooks or tags to ignore
+ public QAction settingsAction; // Show user config settings
+ public QAction emailAction; // Action when a user selects "email"
+ public QAction backupAction; // Backup the database
+ public QAction restoreAction; // Restore from a backup
+ public QAction emptyTrashAction; // Action when a user wants to clear the trash file
+ public QAction exitAction; // Action when user selects "exit"
+ public QAction aboutAction; // Action when a user selects "About"
+ public QAction checkForUpdates; // Check for newer versions
+ public QAction loggerAction; // Action when a user selects "Log"
+ public QAction releaseAction; // Release notes
+
+ public QAction noteAdd; // Add a note
+ public QAction noteAttributes; // Action when a user selects note attributes
+ public QAction noteTags; // Assign a note tags
+ public QAction noteDelete; // Delete the current note
+ public QAction noteRestoreAction; // Restore a note
+ public QAction noteReindex; // Action when a user wants to reindex a note
+ public QAction noteDuplicateAction; // Duplicate an existing note
+ public QAction noteMergeAction; // Merge notes
+ public QAction noteExportAction; // Export notes
+ public QAction noteImportAction; // Import notes
+ public QAction noteCopyAsUrlAction; // Copy the note as a URL
+ // ICHANGED
+ public QAction noteOpenNewTab; // 新しいタブで開く
+ public QAction noteAddNewTab; // 新しいタブでノート追加
+
+ public QAction editFind; // find text in the current note
+ public QAction editUndo; // Undo last change
+ public QAction editRedo; // Redo last change
+ public QAction editCut; // Cut selected text
+ public QAction editPaste; // Paste selected text
+ public QAction editPasteWithoutFormat; // Paste selected text
+ public QAction editCopy; // Copy selected text;
+
+ public QAction wideListView; // View with list on the top
+ public QAction narrowListView; // View with list on the side
+ public QAction thumbnailView; // view thumbnails
+ public QAction hideSavedSearches; // show/hide saved searches
+ public QAction hideZoom; // show/hide the zoom spinner
+ public QAction hideSearch; // Show/hide the search window
+ public QAction hideQuota; // show/hide the quota window
+ public QAction hideNotebooks; // show/hide notebooks
+ public QAction hideTags; // show/hide tags
+ public QAction hideAttributes; // show/hide note information
+ public QAction hideTrash; // show/hide trash tree
+ public QAction hideNoteList; // show/hide the list of notes
+ public QAction showEditorBar; // show/hide the editor button bar
+ public QAction hideLeftSide; // Hide the entire left side
+ public QAction viewSource; // View the source HTML of a note
+
+ public QAction formatBold; // Bold selected text
+ public QAction formatItalic; // Italics selected text
+ public QAction formatUnderline; // Underline selected text
+ public QAction formatStrikethrough; // Strikethrough selected text
+ public QAction formatSuperscript; // Superscript selected text
+ public QAction formatSubscript; // Subscript selected text
+ public QAction formatNumberList; // insert a numbered list
+ public QAction formatBulletList; // insert a bulleted list;
+ public QAction alignLeftAction; // Left justify text
+ public QAction alignRightAction; // Right justify text
+ public QAction alignCenterAction; // Center text
+ public QAction horizontalLineAction; // Insert a horizontal line
+ public QAction indentAction; // Indent
+ public QAction outdentAction; // outdent menu action
+
+ public QAction noteOnlineHistoryAction; // Pull note history from Evernote
+
+ public QAction accountAction; // Account dialog box action
+ public QAction disableIndexing; // put indexing on hold.
+// public QAction compactAction; // free unused space in the database
+ public QAction databaseStatusAction; // Current database status
+ public QAction folderImportAction; // Automatically import files
+ public QAction spellCheckAction; // Spell checker
+ public QAction encryptDatabaseAction; // Encrypt the local database
+
+ public QAction notebookEditAction; // Edit the selected notebook
+ public QAction notebookAddAction; // Add a new notebook
+ public QAction notebookDeleteAction; // Delete a notebook
+ public QAction notebookPublishAction; // Publish a notebook
+ public QAction notebookShareAction; // Share a notebook with others
+ public QAction notebookCloseAction; // Close notebooks
+ public QAction notebookIconAction; // Change the icon
+ public QAction notebookStackAction; // Stack/Unstack the icon.
+
+ public QAction savedSearchAddAction; // Add a saved search
+ public QAction savedSearchEditAction; // Edit a saved search
+ public QAction savedSearchDeleteAction; // Delete a saved search
+ public QAction savedSearchIconAction; // Change a saved search icon
+
+ public QAction tagEditAction; // Edit a tag
+ public QAction tagAddAction; // Add a tag
+ public QAction tagDeleteAction; // Delete a tag
+ public QAction tagIconAction; // Change the icon
+ public QAction tagMergeAction; // Merge tags
+
+ //**************************************************************************
+ //* Menu Bar Titles
+ //**************************************************************************
+
+ private QMenu fileMenu; // File menu
+ private QMenu noteMenu; // Note menu
+ private QMenu notebookMenu; // Notebook menu
+ private QMenu tagMenu; // Tag menu
+ private QMenu savedSearchMenu; // Saved Searches
+
+ private QMenu editMenu; // Edit menu
+
+ private QMenu formatMenu; // Text format menu
+ private QMenu viewMenu; // show/hide stuff
+ private QMenu listMenu; // bullet or numbered list
+ private QMenu indentMenu; // indent or outdent menu
+ private QMenu alignMenu; // Left/Right/Center justify
+
+// private QMenu onlineMenu; // View online stuff (if connected)
+
+ private QMenu toolsMenu; // Tools menu
+
+ private QMenu helpMenu;
+
+ // ICHANGED
+ private QMenu tableMenu;
+ private QMenu imageMenu;
+ private BrowserWindow prevBW;
+
+ public MainMenuBar(NeverNote p) {
+ parent = p;
+
+ // ICHANGED
+ prevBW = parent.browserWindow;
+
+ fullReindexAction = new QAction(tr("Reindex Database"), this);
+ fullReindexAction.setToolTip(tr("Reindex all notes"));
+ fullReindexAction.triggered.connect(parent, "fullReindex()");
+ setupShortcut(fullReindexAction, "Tools_Reindex_Database");
+
+ printAction = new QAction(tr("Print"), this);
+ printAction.setToolTip(tr("Print the current note"));
+ printAction.triggered.connect(parent, "printNote()");
+ setupShortcut(printAction, "File_Print");
+
+ emailAction = new QAction(tr("Email"), this);
+ emailAction.setToolTip(tr("Email the current note"));
+ emailAction.triggered.connect(parent, "emailNote()");
+ setupShortcut(emailAction, "File_Email");
+
+ backupAction = new QAction(tr("Backup Database"), this);
+ backupAction.setToolTip(tr("Backup the current database"));
+ backupAction.triggered.connect(parent, "databaseBackup()");
+ setupShortcut(backupAction, "File_Backup");
+
+ restoreAction = new QAction(tr("Restore Database"), this);
+ restoreAction.setToolTip(tr("Restore the database from a backup"));
+ restoreAction.triggered.connect(parent, "databaseRestore()");
+ setupShortcut(restoreAction, "File_Restore");
+
+ emptyTrashAction = new QAction(tr("Empty Trash"), this);
+ emptyTrashAction.setToolTip(tr("Empty the trash folder"));
+ emptyTrashAction.triggered.connect(parent, "emptyTrash()");
+ setupShortcut(emptyTrashAction, "File_Empty_Trash");
+
+ noteRestoreAction = new QAction(tr("Restore"), this);
+ noteRestoreAction.setToolTip(tr("Restore a deleted file from the trash"));
+ noteRestoreAction.triggered.connect(parent, "restoreNote()");
+ noteRestoreAction.setVisible(false);
+ setupShortcut(noteRestoreAction, "File_Note_Restore");
+
+ settingsAction = new QAction(tr("Preferences"), this);
+ settingsAction.setToolTip(tr("Program settings"));
+ settingsAction.triggered.connect(parent, "settings()");
+ setupShortcut(settingsAction, "Edit_Preferences");
+
+ exitAction = new QAction(tr("Exit"), this);
+ exitAction.setToolTip(tr("Close the program"));
+ exitAction.triggered.connect(parent, "closeNeverNote()");
+ exitAction.setShortcut("Ctrl+Q");
+ setupShortcut(exitAction, "File_Exit");
+
+ noteAttributes = new QAction(tr("Extended Information"), this);
+ noteAttributes.setToolTip(tr("Show/Hide extended note attributes"));
+ noteAttributes.triggered.connect(parent, "toggleNoteInformation()");
+ noteAttributes.setShortcut("F8");
+ setupShortcut(noteAttributes, "View_Extended_Information");
+
+ noteReindex = new QAction(tr("Reindex"), this);
+ noteReindex.setToolTip(tr("Reindex this note"));
+ noteReindex.triggered.connect(parent, "reindexNote()");
+ setupShortcut(noteReindex, "File_Note_Reindex");
+
+ noteDuplicateAction = new QAction(tr("Duplicate"), this);
+ noteDuplicateAction.setToolTip(tr("Duplicate this note"));
+ noteDuplicateAction.triggered.connect(parent, "duplicateNote()");
+ setupShortcut(noteReindex, "File_Note_Duplicate");
+
+ noteMergeAction = new QAction(tr("Merge Notes"), this);
+ noteMergeAction.setToolTip(tr("Merge Multiple notes"));
+ noteMergeAction.triggered.connect(parent, "mergeNotes()");
+ setupShortcut(noteMergeAction, "File_Note_Merge");
+
+ noteExportAction = new QAction(tr("Export Selected Notes"), this);
+ noteExportAction.setToolTip(tr("Export selected notes"));
+ noteExportAction.triggered.connect(parent, "exportNotes()");
+ setupShortcut(noteExportAction, "File_Note_Export");
+
+ noteCopyAsUrlAction = new QAction(tr("Copy as URL"), this);
+ noteCopyAsUrlAction.setToolTip(tr("Copy as URL"));
+ noteCopyAsUrlAction.triggered.connect(parent, "copyAsUrlClicked()");
+ setupShortcut(noteCopyAsUrlAction, "Note_Copy_As_Url");
+
+ noteImportAction = new QAction(tr("Import Notes"), this);
+ noteImportAction.setToolTip(tr("Import notes"));
+ noteImportAction.triggered.connect(parent, "importNotes()");
+ setupShortcut(noteImportAction, "File_Note_Import");
+
+ noteAdd = new QAction(tr("Add"), this);
+ noteAdd.setToolTip(tr("Add a new note"));
+ noteAdd.triggered.connect(parent, "addNote()");
+ setupShortcut(noteAdd, "File_Note_Add");
+
+ noteTags = new QAction(tr("Modify Tags"), this);
+ noteTags.setToolTip(tr("Change the tags assigned to this note"));
+ noteTags.triggered.connect(parent.browserWindow, "modifyTags()");
+ setupShortcut(noteTags, "File_Note_Modify_Tags");
+
+ noteDelete = new QAction(tr("Delete"), this);
+ noteDelete.setToolTip(tr("Delete this note"));
+ noteDelete.triggered.connect(parent, "deleteNote()");
+ setupShortcut(noteDelete, "File_Note_Delete");
+
+ // ICHANGED 新しいタブで開くアクション生成
+ noteOpenNewTab = new QAction(tr("Open in New Tab"), this);
+ noteOpenNewTab.setToolTip(tr("Open this note in new tab"));
+ noteOpenNewTab.triggered.connect(parent, "openNewTab()");
+ setupShortcut(noteOpenNewTab, "File_Note_Open_New_Tab");
+
+ // ICHANGED 新しいタブでノート追加アクション生成
+ noteAddNewTab = new QAction(tr("Add in New Tab"), this);
+ noteAddNewTab.setToolTip(tr("Add a new note in new tab"));
+ noteAddNewTab.triggered.connect(parent, "noteAddNewTab()");
+ setupShortcut(noteAddNewTab, "File_Note_Add_New_Tab");
+
+ editFind = new QAction(tr("Find In Note"), this);
+ editFind.setToolTip(tr("Find a string in the current note"));
+ editFind.triggered.connect(parent, "findText()");
+ setupShortcut(editFind, "Edit_Find_In_Note");
+ //editFind.setShortcut("Ctrl+F");
+
+ editUndo = new QAction(tr("Undo"), this);
+ editUndo.setToolTip(tr("Undo"));
+ editUndo.triggered.connect(parent.browserWindow, "undoClicked()");
+ setupShortcut(editUndo, "Edit_Undo");
+ //editUndo.setShortcut("Ctrl+Z");
+
+ editRedo = new QAction(tr("Redo"), this);
+ editRedo.setToolTip(tr("Redo"));
+ editRedo.triggered.connect(parent.browserWindow, "redoClicked()");
+ setupShortcut(editRedo, "Edit_Redo");
+ //editRedo.setShortcut("Ctrl+Y");
+
+ editCut = new QAction(tr("Cut"), this);
+ editCut.setToolTip(tr("Cut"));
+ editCut.triggered.connect(parent.browserWindow, "cutClicked()");
+ setupShortcut(editCut, "Edit_Cut");
+ //editCut.setShortcut("Ctrl+X");
+
+ editCopy = new QAction(tr("Copy"), this);
+ editCopy.setToolTip(tr("Copy"));
+ editCopy.triggered.connect(parent.browserWindow, "copyClicked()");
+ setupShortcut(editCopy, "Edit_Copy");
+ //editCopy.setShortcut("Ctrl+C");
+
+
+ editPaste = new QAction(tr("Paste"), this);
+ editPaste.setToolTip(tr("Paste"));
+ editPaste.triggered.connect(parent.browserWindow, "pasteClicked()");
+ setupShortcut(editPaste, "Edit_Paste");
+
+ editPasteWithoutFormat = new QAction(tr("Paste Without Formatting"), this);
+ editPasteWithoutFormat.setToolTip(tr("Paste Without Formatting"));
+ editPasteWithoutFormat.triggered.connect(parent.browserWindow, "pasteWithoutFormattingClicked()");
+ setupShortcut(editPasteWithoutFormat, "Edit_Paste_Without_Formatting");
+
+ hideNoteList = new QAction(tr("Show Note List"), this);
+ hideNoteList.setToolTip(tr("Show/Hide Note List"));
+ hideNoteList.triggered.connect(parent, "toggleNoteListWindow()");
+ hideNoteList.setCheckable(true);
+ hideNoteList.setChecked(true);
+ setupShortcut(hideNoteList, "View_Show_Note_List");
+
+ hideTags = new QAction(tr("Show Tags"), this);
+ hideTags.setToolTip(tr("Show/Hide Tags"));
+ hideTags.triggered.connect(parent, "toggleTagWindow()");
+ hideTags.setCheckable(true);
+ hideTags.setChecked(true);
+ setupShortcut(hideTags, "View_Show_Tags");
+
+ hideNotebooks = new QAction(tr("Show Notebooks"), this);
+ hideNotebooks.setToolTip(tr("Show/Hide Notebooks"));
+ hideNotebooks.triggered.connect(parent, "toggleNotebookWindow()");
+ hideNotebooks.setCheckable(true);
+ hideNotebooks.setChecked(true);
+ setupShortcut(hideNotebooks, "View_Show_Notebooks");
+
+ hideZoom = new QAction(tr("Show Zoom"), this);
+ hideZoom.setToolTip(tr("Show/Hide Zoom"));
+ hideZoom.triggered.connect(parent, "toggleZoomWindow()");
+ hideZoom.setCheckable(true);
+ hideZoom.setChecked(true);
+ setupShortcut(hideZoom, "View_Show_Zoom");
+
+ hideQuota = new QAction(tr("Show Quota Bar"), this);
+ hideQuota.setToolTip(tr("Show/Hide Quota"));
+ hideQuota.triggered.connect(parent, "toggleQuotaWindow()");
+ hideQuota.setCheckable(true);
+ hideQuota.setChecked(true);
+ setupShortcut(hideQuota, "View_Show_Quota");
+
+ hideSearch = new QAction(tr("Show Search Box"), this);
+ hideSearch.setToolTip(tr("Show/Hide Search Box"));
+ hideSearch.triggered.connect(parent, "toggleSearchWindow()");
+ hideSearch.setCheckable(true);
+ hideSearch.setChecked(true);
+ setupShortcut(hideSearch, "View_Show_Search");
+
+ wideListView = new QAction(tr("Wide List View"), this);
+ wideListView.setToolTip(tr("Wide List View"));
+ wideListView.setCheckable(true);
+ wideListView.changed.connect(parent, "wideListView()");
+ setupShortcut(wideListView, "View_Wide_List");
+
+ narrowListView = new QAction(tr("Narrow List View"), this);
+ narrowListView.setToolTip(tr("Narrow List View"));
+ narrowListView.setCheckable(true);
+ narrowListView.changed.connect(parent, "narrowListView()");
+ setupShortcut(narrowListView, "View_Narrow_List");
+
+ thumbnailView = new QAction(tr("Preview"), this);
+ thumbnailView.setToolTip(tr("Preview Notes"));
+ thumbnailView.triggered.connect(parent, "thumbnailView()");
+ setupShortcut(thumbnailView, "View_Thumbnail");
+
+ hideSavedSearches = new QAction(tr("Show Saved Searches"), this);
+ hideSavedSearches.setToolTip(tr("Show/Hide Saved Searches"));
+ hideSavedSearches.triggered.connect(parent, "toggleSavedSearchWindow()");
+ hideSavedSearches.setCheckable(true);
+ hideSavedSearches.setChecked(true);
+ setupShortcut(hideSavedSearches, "View_Show_SavedSearches");
+
+ hideAttributes = new QAction(tr("Show Attribute Searches"), this);
+ hideAttributes.setToolTip(tr("Show/Hide Attribute Searches"));
+ hideAttributes.triggered.connect(parent, "toggleAttributesWindow()");
+ hideAttributes.setCheckable(true);
+ hideAttributes.setChecked(true);
+ setupShortcut(hideAttributes, "View_Show_Attribute_Searches");
+
+ hideTrash = new QAction(tr("Show Trash"), this);
+ hideTrash.setToolTip(tr("Show/Hide Trash Tree"));
+ hideTrash.triggered.connect(parent, "toggleTrashWindow()");
+ hideTrash.setCheckable(true);
+ hideTrash.setChecked(true);
+ setupShortcut(hideTrash, "View_Show_Trash");
+
+
+ showEditorBar = new QAction(tr("Show Editor Button Bar"), this);
+ showEditorBar.setToolTip(tr("Show/Hide Editor Button Bar"));
+ showEditorBar.triggered.connect(parent, "toggleEditorButtonBar()");
+ showEditorBar.setCheckable(true);
+ showEditorBar.setChecked(true);
+ setupShortcut(showEditorBar, "View_Show_Editor_Button_Bar");
+
+
+ hideLeftSide = new QAction(tr("Hide Left Side Panels"), this);
+ hideLeftSide.setToolTip(tr("Hide The Entire Left Side"));
+ hideLeftSide.triggered.connect(parent, "toggleLeftSide()");
+ hideLeftSide.setCheckable(true);
+ hideLeftSide.setChecked(false);
+ setupShortcut(hideLeftSide, "View_Show_Left_Side");
+ //hideLeftSide.setShortcut("F11");
+
+ viewSource = new QAction(tr("View Source"), this);
+ viewSource.setToolTip(tr("View the source HTML for a note"));
+ viewSource.triggered.connect(parent, "viewSource()");
+ viewSource.setCheckable(true);
+ viewSource.setChecked(false);
+ setupShortcut(viewSource, "View_Source");
+ //hideLeftSide.setShortcut("F11");
+
+ alignLeftAction = new QAction(tr("Left"), this);
+ alignLeftAction.setToolTip(tr("Left Align"));
+ alignLeftAction.triggered.connect(parent.browserWindow, "justifyLeftClicked()");
+ setupShortcut(alignLeftAction, "Format_Alignment_Left");
+ //alignLeftAction.setShortcut("Ctrl+L");
+
+ alignRightAction = new QAction(tr("Right"), this);
+ alignRightAction.setToolTip(tr("Right Align"));
+ alignRightAction.triggered.connect(parent.browserWindow, "justifyRightClicked()");
+ setupShortcut(alignRightAction, "Format_Alignment_Right");
+ //alignRightAction.setShortcut("Ctrl+R");
+
+ alignCenterAction = new QAction(tr("Center"), this);
+ alignCenterAction.setToolTip(tr("Center Align"));
+ alignCenterAction.triggered.connect(parent.browserWindow, "justifyCenterClicked()");
+ setupShortcut(alignCenterAction, "Format_Alignment_Center");
+ //alignCenterAction.setShortcut("Ctrl+C");
+
+ formatBold = new QAction(tr("Bold"), this);
+ formatBold.setToolTip(tr("Bold"));
+ formatBold.triggered.connect(parent.browserWindow, "boldClicked()");
+ setupShortcut(formatBold, "Format_Bold");
+ //formatBold.setShortcut("Ctrl+B");
+
+ formatItalic = new QAction(tr("Italic"), this);
+ formatItalic.setToolTip(tr("Italic"));
+ formatItalic.triggered.connect(parent.browserWindow, "italicClicked()");
+ setupShortcut(formatItalic, "Format_Italic");
+ //formatItalic.setShortcut("Ctrl+I");
+
+ formatUnderline = new QAction(tr("Underline"), this);
+ formatUnderline.setToolTip(tr("Underline"));
+ formatUnderline.triggered.connect(parent.browserWindow, "underlineClicked()");
+ setupShortcut(formatUnderline, "Format_Underline");
+// formatUnderline.setShortcut("Ctrl+U");
+
+
+ formatSuperscript = new QAction(tr("Superscript"), this);
+ formatSuperscript.setToolTip(tr("Superscript"));
+ formatSuperscript.triggered.connect(parent.browserWindow, "superscriptClicked()");
+ setupShortcut(formatSuperscript, "Format_Superscript");
+
+
+ formatSubscript = new QAction(tr("Subscript"), this);
+ formatSubscript.setToolTip(tr("Subscript"));
+ formatSubscript.triggered.connect(parent.browserWindow, "subscriptClicked()");
+ setupShortcut(formatSubscript, "Format_Subscript");
+
+
+ formatStrikethrough = new QAction(tr("Strikethrough"), this);
+ formatStrikethrough.setToolTip(tr("Strikethrough"));
+ formatStrikethrough.triggered.connect(parent.browserWindow, "strikethroughClicked()");
+ setupShortcut(formatStrikethrough, "Format_Strikethrough");
+
+ horizontalLineAction = new QAction(tr("Horizontal Line"), this);
+ horizontalLineAction.setToolTip(tr("Horizontal Line"));
+ horizontalLineAction.triggered.connect(parent.browserWindow, "hlineClicked()");
+ setupShortcut(horizontalLineAction, "Format_Horizontal_Line");
+
+ formatBulletList = new QAction(tr("Bulleted List"), this);
+// formatBulletList.setText(tr("Numbered List"));
+ formatBulletList.triggered.connect(parent.browserWindow, "bulletListClicked()");
+ setupShortcut(formatBulletList, "Format_List_Bullet");
+// formatBulletList.setShortcut("Ctrl+Shift+B");
+
+ formatNumberList = new QAction(tr("Numbered List"), this);
+ formatNumberList.setText(tr("Numbered list"));
+ formatNumberList.triggered.connect(parent.browserWindow, "numberListClicked()");
+ setupShortcut(formatNumberList, "Format_List_Numbered");
+// formatNumberList.setShortcut("Ctrl+Shift+O");
+
+ indentAction = new QAction(tr(">> Increase"), this);
+ indentAction.setText(tr(">> Increase"));
+ indentAction.triggered.connect(parent.browserWindow, "indentClicked()");
+ setupShortcut(indentAction, "Format_Indent_Increase");
+ //indentAction.setShortcut("Ctrl+M");
+
+ outdentAction = new QAction(tr("<< Decrease"), this);
+ outdentAction.setText(tr("<< Decrease"));
+ outdentAction.triggered.connect(parent.browserWindow, "outdentClicked()");
+ setupShortcut(outdentAction, "Format_Indent_Decrease");
+ //outdentAction.setShortcut("Ctrl+Shift+M");
+
+ notebookAddAction = new QAction(tr("Add"), this);
+ notebookAddAction.triggered.connect(parent, "addNotebook()");
+ setupShortcut(notebookAddAction, "File_Notebook_Add");
+
+ notebookEditAction = new QAction(tr("Edit"), this);
+ notebookEditAction.setEnabled(false);
+ notebookEditAction.triggered.connect(parent, "editNotebook()");
+ setupShortcut(notebookEditAction, "File_Notebook_Edit");
+
+ notebookDeleteAction = new QAction(tr("Delete"), this);
+ notebookDeleteAction.setEnabled(false);
+ notebookDeleteAction.triggered.connect(parent, "deleteNotebook()");
+ setupShortcut(notebookDeleteAction, "File_Notebook_Delete");
+
+ notebookPublishAction = new QAction(tr("Share With The World"), this);
+ notebookPublishAction.setEnabled(false);
+ notebookPublishAction.setVisible(false);
+ notebookPublishAction.triggered.connect(parent, "publishNotebook()");
+ setupShortcut(notebookPublishAction, "File_Notebook_Publish");
+
+ notebookShareAction = new QAction(tr("Share With Individuals"), this);
+ notebookShareAction.setEnabled(false);
+ notebookShareAction.setVisible(false);
+ notebookShareAction.triggered.connect(parent, "shareNotebook()");
+ setupShortcut(notebookShareAction, "File_Notebook_Share");
+
+
+ notebookCloseAction = new QAction(tr("Open/Close Notebooks"), this);
+ notebookCloseAction.setEnabled(true);
+ notebookCloseAction.triggered.connect(parent, "closeNotebooks()");
+ setupShortcut(notebookCloseAction, "File_Notebook_Close");
+
+ notebookIconAction = new QAction(tr("Change Icon"), this);
+ notebookIconAction.setEnabled(false);
+ notebookIconAction.triggered.connect(parent, "setNotebookIcon()");
+ setupShortcut(notebookIconAction, "File_Notebook_Icon");
+
+ notebookStackAction = new QAction(tr("Set Stack"), this);
+ notebookStackAction.setEnabled(false);
+ notebookStackAction.triggered.connect(parent, "stackNotebook()");
+ setupShortcut(notebookStackAction, "File_Notebook_Stack");
+
+ tagAddAction = new QAction(tr("Add"),this);
+ tagAddAction.triggered.connect(parent, "addTag()");
+ setupShortcut(tagAddAction, "File_Tag_Add");
+
+ tagEditAction = new QAction(tr("Edit"), this);
+ tagEditAction.triggered.connect(parent, "editTag()");
+ tagEditAction.setEnabled(false);
+ setupShortcut(tagEditAction, "File_Tag_Edit");
+
+ tagDeleteAction = new QAction(tr("Delete"), this);
+ tagDeleteAction.triggered.connect(parent, "deleteTag()");
+ tagDeleteAction.setEnabled(false);
+ setupShortcut(tagDeleteAction, "File_Tag_Delete");
+
+ tagIconAction = new QAction(tr("Change Icon"), this);
+ tagIconAction.triggered.connect(parent, "setTagIcon()");
+ tagIconAction.setEnabled(false);
+ setupShortcut(tagIconAction, "File_Tag_Icon");
+
+ tagMergeAction = new QAction(tr("Merge Tags"), this);
+ tagMergeAction.triggered.connect(parent, "mergeTags()");
+ tagMergeAction.setEnabled(false);
+ setupShortcut(tagMergeAction, "File_Tag_Merge");
+
+ savedSearchAddAction = new QAction(tr("Add"),this);
+ savedSearchAddAction.triggered.connect(parent, "addSavedSearch()");
+ setupShortcut(savedSearchAddAction, "File_SavedSearch_Add");
+
+ savedSearchEditAction = new QAction(tr("Edit"), this);
+ savedSearchEditAction.triggered.connect(parent, "editSavedSearch()");
+ savedSearchEditAction.setEnabled(false);
+ setupShortcut(savedSearchEditAction, "File_SavedSearch_Edit");
+
+ savedSearchDeleteAction = new QAction(tr("Delete"), this);
+ savedSearchDeleteAction.triggered.connect(parent, "deleteSavedSearch()");
+ savedSearchDeleteAction.setEnabled(false);
+ setupShortcut(savedSearchDeleteAction, "File_SavedSearch_Delete");
+
+ savedSearchIconAction = new QAction(tr("Change Icon"), this);
+ savedSearchIconAction.triggered.connect(parent, "setSavedSearchIcon()");
+ savedSearchIconAction.setEnabled(false);
+ setupShortcut(savedSearchIconAction, "File_SavedSearch_Icon");
+
+ connectAction = new QAction(tr("Connect"), this);
+ connectAction.setToolTip("Connect to Evernote");
+ connectAction.triggered.connect(parent, "remoteConnect()");
+ setupShortcut(connectAction, "Tools_Connect");
+
+ synchronizeAction = new QAction(tr("Synchronize with Evernote"), this);
+ synchronizeAction.setToolTip("Delete all local data & get a fresh copy");
+ synchronizeAction.triggered.connect(parent, "evernoteSync()");
+ synchronizeAction.setEnabled(false);
+ setupShortcut(synchronizeAction, "Tools_Synchronize");
+ //synchronizeAction.setShortcut("F9");
+
+ noteOnlineHistoryAction = new QAction(tr("Note History"), this);
+ noteOnlineHistoryAction.triggered.connect(parent, "viewNoteHistory()");
+ noteOnlineHistoryAction.setEnabled(false);
+ setupShortcut(noteOnlineHistoryAction, "File_Note_History");
+
+ selectiveSyncAction = new QAction(tr("Selective Synchronize"), this);
+ selectiveSyncAction.setToolTip("Selectively ignore some notes");
+ selectiveSyncAction.triggered.connect(parent, "setupSelectiveSync()");
+ selectiveSyncAction.setEnabled(false);
+ setupShortcut(synchronizeAction, "File_Selective_Sync");
+
+
+
+ accountAction = new QAction(tr("Account Information"), this);
+ accountAction.setToolTip(tr("Account Information"));
+ accountAction.triggered.connect(parent, "accountInformation()");
+ setupShortcut(accountAction, "Tools_Account_Information");
+
+// compactAction = new QAction(tr("Compact Database"), this);
+// compactAction.setToolTip(tr("Free unused database space"));
+// compactAction.triggered.connect(parent, "compactDatabase()");
+// setupShortcut(compactAction, "Tools_Compact_Database");
+
+ databaseStatusAction = new QAction(tr("Database Status"), this);
+ databaseStatusAction.setToolTip(tr("Show current database information"));
+ databaseStatusAction.triggered.connect(parent, "databaseStatus()");
+ setupShortcut(databaseStatusAction, "Tools_Database_Status");
+
+
+ disableIndexing = new QAction(tr("Disable Note Indexing"), this);
+ disableIndexing.setToolTip(tr("Manually Stop Note Indexing"));
+ disableIndexing.triggered.connect(parent, "toggleNoteIndexing()");
+ disableIndexing.setCheckable(true);
+ disableIndexing.setChecked(false);
+ setupShortcut(disableIndexing, "Tools_Disable_Note_Indexing");
+
+
+ folderImportAction = new QAction(tr("Automatic Folder Importing"), this);
+ folderImportAction.setToolTip(tr("Import Files Automatically"));
+ folderImportAction.triggered.connect(parent, "folderImport()");
+ setupShortcut(folderImportAction, "Tools_Folder_Import");
+
+ spellCheckAction = new QAction(tr("Spell Check"), this);
+ spellCheckAction.setToolTip(tr("Check for spelling errors"));
+ spellCheckAction.triggered.connect(parent.browserWindow, "spellCheckClicked()");
+ setupShortcut(spellCheckAction, "Tools_Spell_Check");
+
+ encryptDatabaseAction = new QAction(tr("Encrypt Database"), this);
+ encryptDatabaseAction.setToolTip(tr("Encrypt the database upon shutdown"));
+ encryptDatabaseAction.triggered.connect(parent, "doDatabaseEncrypt()");
+ setupShortcut(encryptDatabaseAction, "Tools_Database_Encrypt");
+ if (Global.cipherPassword != null && Global.cipherPassword != "") {
+ encryptDatabaseAction.setText("Decrypt Database");
+ encryptDatabaseAction.setToolTip("Decrypt the database upon shutdown");
+ }
+
+ loggerAction = new QAction(tr("Logs"), this);
+ loggerAction.setToolTip(tr("Show the detailed application log"));
+ loggerAction.triggered.connect(parent, "logger()");
+ setupShortcut(loggerAction, "About_Log");
+
+ releaseAction = new QAction(tr("Release Notes"), this);
+ releaseAction.setToolTip(tr("Release notes"));
+ releaseAction.triggered.connect(parent, "releaseNotes()");
+ setupShortcut(releaseAction, "About_Release_Notes");
+
+ checkForUpdates = new QAction(tr("Check For Updates"), this);
+ checkForUpdates.setToolTip(tr("Check for newer versions"));
+ checkForUpdates.triggered.connect(parent, "checkForUpdates()");
+ setupShortcut(checkForUpdates, "Help_Check_For_Updates");
+ // ICHANGED TODO とりあえず封印
+ checkForUpdates.setEnabled(false);
+
+ aboutAction = new QAction(tr("About"), this);
+ aboutAction.setToolTip(tr("About NeighborNote"));
+ aboutAction.triggered.connect(parent, "about()");
+ setupShortcut(aboutAction, "About_About");
+
+ setupMenuBar();
+ }
+
+ public void setupMenuBar() {
+ fileMenu = addMenu(tr("&File"));
+
+ noteMenu = fileMenu.addMenu(tr("&Note"));
+ notebookMenu = fileMenu.addMenu(tr("Notebook"));
+ tagMenu = fileMenu.addMenu(tr("Tag"));
+ savedSearchMenu = fileMenu.addMenu(tr("Saved Searches"));
+ fileMenu.addSeparator();
+ fileMenu.addAction(emailAction);
+ fileMenu.addAction(printAction);
+ fileMenu.addSeparator();
+ fileMenu.addAction(noteImportAction);
+ fileMenu.addAction(noteExportAction);
+ fileMenu.addAction(backupAction);
+ fileMenu.addAction(restoreAction);
+ fileMenu.addSeparator();
+ fileMenu.addAction(selectiveSyncAction);
+ //fileMenu.addAction(parent.browserWindow.browser.downloadAttachment);
+ fileMenu.addSeparator();
+ fileMenu.addAction(emptyTrashAction);
+ fileMenu.addAction(exitAction);
+
+ editMenu = addMenu(tr("&Edit"));
+ editMenu.addAction(editFind);
+ editMenu.addSeparator();
+ editMenu.addAction(editUndo);
+ editMenu.addAction(editRedo);
+ editMenu.addSeparator();
+ editMenu.addAction(editCut);
+ editMenu.addAction(editCopy);
+ editMenu.addAction(editPaste);
+ editMenu.addAction(editPasteWithoutFormat);
+ editMenu.addSeparator();
+ editMenu.addAction(settingsAction);
+
+ viewMenu = addMenu(tr("&View"));
+ viewMenu.addAction(noteAttributes);
+ viewMenu.addAction(viewSource);
+ viewMenu.addSeparator();
+ viewMenu.addAction(wideListView);
+ viewMenu.addAction(narrowListView);
+ viewMenu.addAction(thumbnailView);
+ viewMenu.addSeparator();
+ viewMenu.addAction(hideNoteList);
+ viewMenu.addAction(hideSearch);
+ viewMenu.addAction(hideQuota);
+ viewMenu.addAction(hideZoom);
+ viewMenu.addAction(hideNotebooks);
+ viewMenu.addAction(hideTags);
+ viewMenu.addAction(hideAttributes);
+ viewMenu.addAction(hideSavedSearches);
+ viewMenu.addAction(hideTrash);
+ viewMenu.addAction(showEditorBar);
+ viewMenu.addAction(hideLeftSide);
+
+ formatMenu = addMenu(tr("F&ormat"));
+ formatMenu.addAction(formatBold);
+ formatMenu.addAction(formatUnderline);
+ formatMenu.addAction(formatItalic);
+ formatMenu.addSeparator();
+ formatMenu.addAction(formatStrikethrough);
+ formatMenu.addAction(horizontalLineAction);
+ formatMenu.addSeparator();
+ formatMenu.addAction(formatSuperscript);
+ formatMenu.addAction(formatSubscript);
+ formatMenu.addSeparator();
+ //formatMenu.addAction(parent.browserWindow.browser.todoAction);
+ //formatMenu.addAction(parent.browserWindow.browser.encryptAction);
+ //formatMenu.addAction(parent.browserWindow.browser.insertLinkAction);
+ //formatMenu.addAction(parent.browserWindow.browser.insertQuickLinkAction);
+ //formatMenu.addAction(parent.browserWindow.browser.insertLatexAction);
+ formatMenu.addMenu(parent.browserWindow.browser.tableMenu);
+ formatMenu.addMenu(parent.browserWindow.browser.imageMenu);
+ formatMenu.addSeparator();
+
+ // ICHANGED
+ // ライブラリにremoveMenu()が存在しないので、removeAction()で消せるようにTable,Imageメニューをここで再定義
+ tableMenu = new QMenu();
+ tableMenu.setTitle(tr("Table"));
+ tableMenu.addAction(parent.browserWindow.browser.insertTableAction);
+ tableMenu.addAction(parent.browserWindow.browser.insertTableRowAction);
+ tableMenu
+ .addAction(parent.browserWindow.browser.insertTableColumnAction);
+ tableMenu.addAction(parent.browserWindow.browser.deleteTableRowAction);
+ tableMenu
+ .addAction(parent.browserWindow.browser.deleteTableColumnAction);
+ imageMenu = new QMenu();
+ imageMenu.setTitle(tr("Image"));
+ imageMenu.addAction(parent.browserWindow.browser.downloadImage);
+ imageMenu.addAction(parent.browserWindow.browser.rotateImageRight);
+ imageMenu.addAction(parent.browserWindow.browser.rotateImageLeft);
+
+ alignMenu = formatMenu.addMenu(tr("Alignment"));
+ alignMenu.addAction(alignLeftAction);
+ alignMenu.addAction(alignCenterAction);
+ alignMenu.addAction(alignRightAction);
+
+ listMenu = formatMenu.addMenu(tr("Lists"));
+ listMenu.addAction(formatBulletList);
+ listMenu.addAction(formatNumberList);
+ indentMenu = formatMenu.addMenu(tr("Indent"));
+ indentMenu.addAction(indentAction);
+ indentMenu.addAction(outdentAction);
+
+ noteAttributes.setCheckable(true);
+ // ICHANGED
+ noteMenu.addAction(noteOpenNewTab);
+
+ noteMenu.addAction(noteAdd);
+ // ICHANGED
+ noteMenu.addAction(noteAddNewTab);
+
+ noteMenu.addAction(noteDelete);
+ //noteMenu.addAction(noteCopyAsUrlAction);
+ noteMenu.addAction(noteReindex);
+ noteMenu.addSeparator();
+ noteMenu.addAction(noteTags);
+ noteMenu.addAction(noteRestoreAction);
+ noteMenu.addSeparator();
+ noteMenu.addAction(noteOnlineHistoryAction);
+ noteMenu.addAction(noteDuplicateAction);
+ noteMenu.addAction(noteMergeAction);
+
+
+ notebookMenu.addAction(notebookAddAction);
+ notebookMenu.addAction(notebookEditAction);
+ notebookMenu.addAction(notebookDeleteAction);
+ notebookMenu.addSeparator();
+ notebookMenu.addAction(notebookPublishAction);
+ notebookMenu.addAction(notebookShareAction);
+ notebookMenu.addSeparator();
+ notebookMenu.addAction(notebookStackAction);
+ notebookMenu.addAction(notebookCloseAction);
+ notebookMenu.addSeparator();
+ notebookMenu.addAction(notebookIconAction);
+
+ tagMenu.addAction(tagAddAction);
+ tagMenu.addAction(tagEditAction);
+ tagMenu.addAction(tagDeleteAction);
+ tagMenu.addAction(tagMergeAction);
+ tagMenu.addSeparator();
+ tagMenu.addAction(tagIconAction);
+
+ savedSearchMenu.addAction(savedSearchAddAction);
+ savedSearchMenu.addAction(savedSearchEditAction);
+ savedSearchMenu.addAction(savedSearchDeleteAction);
+ savedSearchMenu.addSeparator();
+ savedSearchMenu.addAction(savedSearchIconAction);
+
+// onlineMenu = addMenu(tr("&Online"));
+// onlineMenu.addAction(synchronizeAction);
+// onlineMenu.addAction(connectAction);
+// onlineMenu.addSeparator();
+// onlineMenu.addAction(noteOnlineHistoryAction);
+// onlineMenu.addAction(selectiveSyncAction);
+
+ toolsMenu = addMenu(tr("&Tools"));
+ toolsMenu.addAction(synchronizeAction);
+ toolsMenu.addAction(connectAction);
+ toolsMenu.addSeparator();
+ toolsMenu.addAction(spellCheckAction);
+ toolsMenu.addAction(accountAction);
+ toolsMenu.addAction(fullReindexAction);
+ toolsMenu.addAction(disableIndexing);
+// toolsMenu.addAction(compactAction);
+ toolsMenu.addSeparator();
+ toolsMenu.addAction(encryptDatabaseAction);
+ toolsMenu.addAction(databaseStatusAction);
+ toolsMenu.addSeparator();
+ toolsMenu.addAction(folderImportAction);
+
+ helpMenu = addMenu(tr("&Help"));
+ helpMenu.addAction(releaseAction);
+ helpMenu.addAction(checkForUpdates);
+ helpMenu.addAction(loggerAction);
+ helpMenu.addSeparator();
+ helpMenu.addAction(aboutAction);
+
+ addMenu(fileMenu);
+ addMenu(editMenu);
+ addMenu(viewMenu);
+ addMenu(formatMenu);
+// addMenu(onlineMenu);
+ addMenu(toolsMenu);
+ addMenu(helpMenu);
+
+ }
+
+ public void setupToolBarVisible() {
+ viewMenu.addAction(parent.toolBar.toggleViewAction());
+ setupShortcut(parent.toolBar.toggleViewAction(), "View_Toolbar");
+ }
+
+ private void setupShortcut(QAction action, String text) {
+ if (!Global.shortcutKeys.containsAction(text))
+ return;
+ action.setShortcut(Global.shortcutKeys.getShortcut(text));
+ }
+
+ // ICHANGED
+ public void refreshTargetWindow() {
+ // 以前のブラウザウィンドウとの接続を切断
+ noteTags.triggered.disconnect(prevBW, "modifyTags()");
+ editUndo.triggered.disconnect(prevBW, "undoClicked()");
+ editRedo.triggered.disconnect(prevBW, "redoClicked()");
+ editCut.triggered.disconnect(prevBW, "cutClicked()");
+ editCopy.triggered.disconnect(prevBW, "copyClicked()");
+ editPaste.triggered.disconnect(prevBW, "pasteClicked()");
+ editPasteWithoutFormat.triggered.disconnect(prevBW,
+ "pasteWithoutFormattingClicked()");
+
+ alignLeftAction.triggered.disconnect(prevBW, "justifyLeftClicked()");
+ alignRightAction.triggered.disconnect(prevBW, "justifyRightClicked()");
+ alignCenterAction.triggered
+ .disconnect(prevBW, "justifyCenterClicked()");
+ formatBold.triggered.disconnect(prevBW, "boldClicked()");
+ formatItalic.triggered.disconnect(prevBW, "italicClicked()");
+ formatUnderline.triggered.disconnect(prevBW, "underlineClicked()");
+ formatSuperscript.triggered.disconnect(prevBW, "superscriptClicked()");
+ formatSubscript.triggered.disconnect(prevBW, "subscriptClicked()");
+ formatStrikethrough.triggered.disconnect(prevBW,
+ "strikethroughClicked()");
+ horizontalLineAction.triggered.disconnect(prevBW, "hlineClicked()");
+ formatBulletList.triggered.disconnect(prevBW, "bulletListClicked()");
+ formatNumberList.triggered.disconnect(prevBW, "numberListClicked()");
+ indentAction.triggered.disconnect(prevBW, "indentClicked()");
+ outdentAction.triggered.disconnect(prevBW, "outdentClicked()");
+
+ spellCheckAction.triggered.disconnect(prevBW, "spellCheckClicked()");
+
+ // 新たなブラウザウィンドウと接続
+ noteTags.triggered.connect(parent.browserWindow, "modifyTags()");
+ editUndo.triggered.connect(parent.browserWindow, "undoClicked()");
+ editRedo.triggered.connect(parent.browserWindow, "redoClicked()");
+ editCut.triggered.connect(parent.browserWindow, "cutClicked()");
+ editCopy.triggered.connect(parent.browserWindow, "copyClicked()");
+ editPaste.triggered.connect(parent.browserWindow, "pasteClicked()");
+ editPasteWithoutFormat.triggered.connect(parent.browserWindow,
+ "pasteWithoutFormattingClicked()");
+
+ alignLeftAction.triggered.connect(parent.browserWindow,
+ "justifyLeftClicked()");
+ alignRightAction.triggered.connect(parent.browserWindow,
+ "justifyRightClicked()");
+ alignCenterAction.triggered.connect(parent.browserWindow,
+ "justifyCenterClicked()");
+ formatBold.triggered.connect(parent.browserWindow, "boldClicked()");
+ formatItalic.triggered.connect(parent.browserWindow, "italicClicked()");
+ formatUnderline.triggered.connect(parent.browserWindow,
+ "underlineClicked()");
+ formatSuperscript.triggered.connect(parent.browserWindow,
+ "superscriptClicked()");
+ formatSubscript.triggered.connect(parent.browserWindow,
+ "subscriptClicked()");
+ formatStrikethrough.triggered.connect(parent.browserWindow,
+ "strikethroughClicked()");
+ horizontalLineAction.triggered.connect(parent.browserWindow,
+ "hlineClicked()");
+ formatBulletList.triggered.connect(parent.browserWindow,
+ "bulletListClicked()");
+ formatNumberList.triggered.connect(parent.browserWindow,
+ "numberListClicked()");
+ indentAction.triggered.connect(parent.browserWindow, "indentClicked()");
+ outdentAction.triggered.connect(parent.browserWindow,
+ "outdentClicked()");
+
+ spellCheckAction.triggered.connect(parent.browserWindow,
+ "spellCheckClicked()");
+
+ // メニューバーに新しいアクションを挿入
+ fileMenu.insertAction(prevBW.browser.downloadAttachment,
+ parent.browserWindow.browser.downloadAttachment);
+
+ formatMenu.insertAction(prevBW.browser.todoAction,
+ parent.browserWindow.browser.todoAction);
+ formatMenu.insertAction(prevBW.browser.encryptAction,
+ parent.browserWindow.browser.encryptAction);
+ formatMenu.insertAction(prevBW.browser.insertLinkAction,
+ parent.browserWindow.browser.insertLinkAction);
+ formatMenu.insertAction(prevBW.browser.insertQuickLinkAction,
+ parent.browserWindow.browser.insertQuickLinkAction);
+ formatMenu.insertAction(prevBW.browser.insertLatexAction,
+ parent.browserWindow.browser.insertLatexAction);
+
+ tableMenu.insertAction(prevBW.browser.insertTableAction,
+ parent.browserWindow.browser.insertTableAction);
+ tableMenu.insertAction(prevBW.browser.insertTableRowAction,
+ parent.browserWindow.browser.insertTableRowAction);
+ tableMenu.insertAction(prevBW.browser.insertTableColumnAction,
+ parent.browserWindow.browser.insertTableColumnAction);
+ tableMenu.insertAction(prevBW.browser.deleteTableRowAction,
+ parent.browserWindow.browser.deleteTableRowAction);
+ tableMenu.insertAction(prevBW.browser.deleteTableColumnAction,
+ parent.browserWindow.browser.deleteTableColumnAction);
+
+ imageMenu.insertAction(prevBW.browser.downloadImage,
+ parent.browserWindow.browser.downloadImage);
+ imageMenu.insertAction(prevBW.browser.rotateImageRight,
+ parent.browserWindow.browser.rotateImageRight);
+ imageMenu.insertAction(prevBW.browser.rotateImageLeft,
+ parent.browserWindow.browser.rotateImageLeft);
+
+ // メニューバーから古いアクションを削除
+ fileMenu.removeAction(prevBW.browser.downloadAttachment);
+
+ formatMenu.removeAction(prevBW.browser.todoAction);
+ formatMenu.removeAction(prevBW.browser.encryptAction);
+ formatMenu.removeAction(prevBW.browser.insertLinkAction);
+ formatMenu.removeAction(prevBW.browser.insertQuickLinkAction);
+ formatMenu.removeAction(prevBW.browser.insertLatexAction);
+
+ tableMenu.removeAction(prevBW.browser.insertTableAction);
+ tableMenu.removeAction(prevBW.browser.insertTableRowAction);
+ tableMenu.removeAction(prevBW.browser.insertTableColumnAction);
+ tableMenu.removeAction(prevBW.browser.deleteTableRowAction);
+ tableMenu.removeAction(prevBW.browser.deleteTableColumnAction);
+
+ imageMenu.removeAction(prevBW.browser.downloadImage);
+ imageMenu.removeAction(prevBW.browser.rotateImageRight);
+ imageMenu.removeAction(prevBW.browser.rotateImageLeft);
+
+ // prevBWを更新
+ prevBW = parent.browserWindow;
+ }
+
+}
--- /dev/null
+// ICHANGED
+package cx.fbn.nevernote.gui;
+
+import com.trolltech.qt.core.Qt;
+import com.trolltech.qt.gui.QKeyEvent;
+import com.trolltech.qt.gui.QMenu;
+import com.trolltech.qt.gui.QMouseEvent;
+
+public class NoteTableContextMenu extends QMenu {
+ private final TableView parent;
+
+ public NoteTableContextMenu(TableView tableView) {
+ this.parent = tableView;
+ }
+
+
+ @Override
+ protected void mousePressEvent(QMouseEvent event){
+ super.mousePressEvent(event);
+
+ int x = event.x();
+ int y = event.y();
+
+ if(x < 0 || this.width() < x){
+ parent.restoreSelectedNoteInfo();
+ }else if(y < 0 || this.height() < y){
+ parent.restoreSelectedNoteInfo();
+ }
+ }
+
+ // ノートテーブルでマウス右ボタンを押してコンテキストメニューを出し、そのままコンテキストメニュー上を通過してコンテキストメニュー外でボタンを離すと
+ // コンテキストメニューが閉じてしまう問題への対処
+ @Override
+ protected void mouseReleaseEvent(QMouseEvent event){
+ super.mouseReleaseEvent(event);
+
+ int x = event.x();
+ int y = event.y();
+
+ if(x < 0 || this.width() < x){
+ parent.restoreSelectedNoteInfo();
+ }else if(y < 0 || this.height() < y){
+ parent.restoreSelectedNoteInfo();
+ }
+ }
+
+ @Override
+ protected void keyPressEvent(QKeyEvent event){
+ super.keyPressEvent(event);
+
+ if(event.key() == Qt.Key.Key_Escape.value()){
+ parent.restoreSelectedNoteInfo();
+ }
+ }
+}
--- /dev/null
+// ICHANGED
+package cx.fbn.nevernote.gui;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import com.evernote.edam.type.Note;
+import com.trolltech.qt.core.QSize;
+import com.trolltech.qt.core.Qt.MouseButton;
+import com.trolltech.qt.gui.QAction;
+import com.trolltech.qt.gui.QApplication;
+import com.trolltech.qt.gui.QContextMenuEvent;
+import com.trolltech.qt.gui.QListWidget;
+import com.trolltech.qt.gui.QListWidgetItem;
+import com.trolltech.qt.gui.QMenu;
+
+import cx.fbn.nevernote.Global;
+import cx.fbn.nevernote.NeverNote;
+import cx.fbn.nevernote.sql.DatabaseConnection;
+import cx.fbn.nevernote.utilities.ApplicationLogger;
+
+public class RensoNoteList extends QListWidget {
+ private final DatabaseConnection conn;
+ private final ApplicationLogger logger;
+ private final HashMap<QListWidgetItem, String> rensoNoteListItems;
+ private final List<RensoNoteListItem> rensoNoteListTrueItems;
+ private String rensoNotePressedItemGuid;
+
+ private final QAction openNewTabAction;
+ private final QAction starAction;
+ private final QAction unstarAction;
+ private final QAction excludeNoteAction;
+ private final NeverNote parent;
+ private final QMenu menu;
+ private int allPointSum;
+
+ public RensoNoteList(DatabaseConnection c, NeverNote p) {
+ logger = new ApplicationLogger("rensoNoteList.log");
+ logger.log(logger.HIGH, "Setting up rensoNoteList");
+ allPointSum = 0;
+
+ conn = c;
+ this.parent = p;
+ rensoNoteListItems = new HashMap<QListWidgetItem, String>();
+ rensoNoteListTrueItems = new ArrayList<RensoNoteListItem>();
+
+ this.itemPressed.connect(this, "rensoNoteItemPressed(QListWidgetItem)");
+
+ // コンテキストメニュー作成
+ menu = new QMenu(this);
+ // 新しいタブで開くアクション生成
+ openNewTabAction = new QAction(tr("Open in New Tab"), this);
+ openNewTabAction.setToolTip(tr("Open this note in new tab"));
+ openNewTabAction.triggered.connect(parent, "openNewTabFromRNL()");
+ // スターをつけるアクション生成
+ starAction = new QAction(tr("STAR"), this);
+ starAction.setToolTip(tr("Star this item"));
+ starAction.triggered.connect(parent, "starNote()");
+ // スターを外すアクション生成
+ unstarAction = new QAction(tr("UNSTAR"), this);
+ unstarAction.setToolTip(tr("Unstar this item"));
+ unstarAction.triggered.connect(parent, "unstarNote()");
+ // このノートを除外するアクション生成
+ excludeNoteAction = new QAction(tr("Exclude"), this);
+ excludeNoteAction.setToolTip(tr("Exclude this note from RensoNoteList"));
+ excludeNoteAction.triggered.connect(parent, "excludeNote()");
+ // コンテキストメニューに登録
+ menu.addAction(openNewTabAction);
+ menu.addAction(excludeNoteAction);
+ menu.aboutToHide.connect(this, "contextMenuHidden()");
+
+ logger.log(logger.HIGH, "rensoNoteList setup complete");
+ }
+
+ public void refreshRensoNoteList(String guid) {
+ logger.log(logger.HIGH, "Entering RensoNoteList.refreshRensoNoteList");
+
+ this.clear();
+ rensoNoteListItems.clear();
+ rensoNoteListTrueItems.clear();
+
+ if (!this.isEnabled()) {
+ return;
+ }
+ if (guid == null || guid.equals("")) {
+ return;
+ }
+
+ HashMap<String, Integer> mergedHistory = new HashMap<String, Integer>();
+
+ // browseHistory<guid, 回数(ポイント)>
+ HashMap<String, Integer> browseHistory = conn.getHistoryTable().getBehaviorHistory("browse", guid);
+ addWeight(browseHistory, Global.getBrowseWeight());
+ mergedHistory = mergeHistory(browseHistory, new HashMap<String, Integer>());
+
+ // copy&pasteHistory<guid, 回数(ポイント)>
+ HashMap<String, Integer> copyAndPasteHistory = conn.getHistoryTable().getBehaviorHistory("copy & paste", guid);
+ addWeight(copyAndPasteHistory, Global.getCopyPasteWeight());
+ mergedHistory = mergeHistory(copyAndPasteHistory, mergedHistory);
+
+ // addNewNoteHistory<guid, 回数(ポイント)>
+ HashMap<String, Integer> addNewNoteHistory = conn.getHistoryTable().getBehaviorHistory("addNewNote", guid);
+ addWeight(addNewNoteHistory, Global.getAddNewNoteWeight());
+ mergedHistory = mergeHistory(addNewNoteHistory, mergedHistory);
+
+ // rensoItemClickHistory<guid, 回数(ポイント)>
+ HashMap<String, Integer> rensoItemClickHistory = conn.getHistoryTable().getBehaviorHistory("rensoItemClick", guid);
+ addWeight(rensoItemClickHistory, Global.getRensoItemClickWeight());
+ mergedHistory = mergeHistory(rensoItemClickHistory, mergedHistory);
+
+ // sameTagHistory<guid, 回数(ポイント)>
+ HashMap<String, Integer> sameTagHistory = conn.getHistoryTable().getBehaviorHistory("sameTag", guid);
+ addWeight(sameTagHistory, Global.getSameTagWeight());
+ mergedHistory = mergeHistory(sameTagHistory, mergedHistory);
+
+ // sameNotebookNoteHistory<guid, 回数(ポイント)>
+ HashMap<String, Integer> sameNotebookHistory = conn.getHistoryTable().getBehaviorHistory("sameNotebook", guid);
+ addWeight(sameNotebookHistory, Global.getSameNotebookWeight());
+ mergedHistory = mergeHistory(sameNotebookHistory, mergedHistory);
+
+ // すべての関連ポイントの合計を取得(関連度のパーセント算出に利用)
+ allPointSum = 0;
+ for (int p : mergedHistory.values()) {
+ allPointSum += p;
+ }
+
+ addRensoNoteList(mergedHistory);
+
+ logger.log(logger.HIGH, "Leaving RensoNoteList.refreshRensoNoteList");
+ }
+
+ // 操作回数に重み付けする
+ private void addWeight(HashMap<String, Integer> history, int weight){
+ Set<String> keySet = history.keySet();
+ Iterator<String> hist_iterator = keySet.iterator();
+ while(hist_iterator.hasNext()){
+ String key = hist_iterator.next();
+ history.put(key, history.get(key) * weight);
+ }
+ }
+
+ // 引数1と引数2をマージしたハッシュマップを返す
+ private HashMap<String, Integer> mergeHistory(HashMap<String, Integer> History1, HashMap<String, Integer> History2){
+ HashMap<String, Integer> mergedHistory = new HashMap<String, Integer>();
+
+ mergedHistory.putAll(History1);
+
+ Set<String> keySet = History2.keySet();
+ Iterator<String> hist2_iterator = keySet.iterator();
+ while(hist2_iterator.hasNext()){
+ String key = hist2_iterator.next();
+ if(mergedHistory.containsKey(key)){
+ mergedHistory.put(key, mergedHistory.get(key) + History2.get(key));
+ }else {
+ mergedHistory.put(key, History2.get(key));
+ }
+ }
+
+ return mergedHistory;
+ }
+
+ private void addRensoNoteList(HashMap<String, Integer> History){
+ String currentNoteGuid = new String(parent.getCurrentNoteGuid());
+
+ // スター付きノートとスター無しノートを分ける
+ HashMap<String, Integer> staredNotes = new HashMap<String, Integer>(); // スター付きノートのマップ
+ HashMap<String, Integer> normalNotes = new HashMap<String, Integer>(); // スター無しノートのマップ
+ for (String nextGuid: History.keySet()) {
+ int relationPoint = History.get(nextGuid);
+ boolean isStared = conn.getStaredTable().existNote(currentNoteGuid, nextGuid);
+ if (isStared) {
+ staredNotes.put(nextGuid, relationPoint);
+ } else {
+ normalNotes.put(nextGuid, relationPoint);
+ }
+ }
+
+ // 連想ノートリストアイテムの最大表示数まで繰り返す
+ for (int i = 0; i < Global.getRensoListItemMaximum(); i++) {
+ // スター付きノートがあれば先に処理する
+ HashMap<String, Integer> tmpMap = new HashMap<String, Integer>();
+ if (!staredNotes.isEmpty()) {
+ tmpMap = staredNotes;
+ }else if (!normalNotes.isEmpty()) {
+ tmpMap = normalNotes;
+ }
+
+ // 操作回数が多い順に取り出して連想ノートリストに追加する
+ if (!tmpMap.isEmpty()) {
+ int maxNum = -1;
+ String maxGuid = new String();
+
+ for (String nextGuid: tmpMap.keySet()) {
+ int relationPoint = tmpMap.get(nextGuid);
+
+ // 最大ノート探索する
+ if (relationPoint > maxNum) {
+ maxNum = relationPoint;
+ maxGuid = nextGuid;
+ }
+ }
+
+ // 次の最大値探索で邪魔なので最大値をHashMapから削除
+ tmpMap.remove(maxGuid);
+
+ // 関連度最大のノートがアクティブか確認
+ Note maxNote = conn.getNoteTable().getNote(maxGuid, true, false, false, false, true);
+ boolean isNoteActive = false;
+ if(maxNote != null) {
+ isNoteActive = maxNote.isActive();
+ }
+
+ // 存在していて、かつ関連度0でなければノート情報を取得して連想ノートリストに追加
+ if (isNoteActive && maxNum > 0) {
+ // スター付きか確認
+ boolean isStared;
+ isStared = conn.getStaredTable().existNote(currentNoteGuid, maxGuid);
+
+ QListWidgetItem item = new QListWidgetItem();
+ RensoNoteListItem myItem = new RensoNoteListItem(maxNote, maxNum, isStared, allPointSum, conn, this);
+ item.setSizeHint(new QSize(0, 90));
+ this.addItem(item);
+ this.setItemWidget(item, myItem);
+ rensoNoteListItems.put(item, maxGuid);
+ rensoNoteListTrueItems.add(myItem);
+ } else {
+ break;
+ }
+ }
+ }
+ }
+
+ // リストのアイテムから対象ノートのguidを取得
+ public String getNoteGuid(QListWidgetItem item) {
+ return rensoNoteListItems.get(item);
+ }
+
+ // 関連ノートリストの右クリックメニュー
+ @Override
+ public void contextMenuEvent(QContextMenuEvent event){
+ // STAR, UNSTARがあれば、一度消す
+ List<QAction> menuActions = new ArrayList<QAction>(menu.actions());
+ if (menuActions.contains(starAction)) {
+ menu.removeAction(starAction);
+ }
+ if (menuActions.contains(unstarAction)) {
+ menu.removeAction(unstarAction);
+ }
+
+ // 対象アイテムがスター付きなら「UNSTAR」、スター無しなら「STAR」を追加
+ String currentNoteGuid = parent.getCurrentNoteGuid();
+ boolean isExist = conn.getStaredTable().existNote(currentNoteGuid, rensoNotePressedItemGuid);
+ if (isExist) {
+ menu.insertAction(excludeNoteAction, unstarAction);
+ } else {
+ menu.insertAction(excludeNoteAction, starAction);
+ }
+
+ // コンテキストメニューを表示
+ menu.exec(event.globalPos());
+ }
+
+ // コンテキストメニューが表示されているかどうか
+ public boolean isContextMenuVisible() {
+ return menu.isVisible();
+ }
+
+ // コンテキストメニューが閉じられた時
+ @SuppressWarnings("unused")
+ private void contextMenuHidden() {
+ for (int i = 0; i < rensoNoteListTrueItems.size(); i++) {
+ RensoNoteListItem item = rensoNoteListTrueItems.get(i);
+ item.setDefaultBackground();
+ }
+ }
+
+ // ユーザが連想ノートリストのアイテムを選択した時の処理
+ @SuppressWarnings("unused")
+ private void rensoNoteItemPressed(QListWidgetItem current) {
+ rensoNotePressedItemGuid = null;
+ // 右クリックだったときの処理
+ if (QApplication.mouseButtons().isSet(MouseButton.RightButton)) {
+ rensoNotePressedItemGuid = getNoteGuid(current);
+ }
+ }
+}
--- /dev/null
+// ICHANGED
+package cx.fbn.nevernote.gui;
+
+import java.text.SimpleDateFormat;
+
+import com.evernote.edam.type.Note;
+import com.trolltech.qt.core.QEvent;
+import com.trolltech.qt.core.QFile;
+import com.trolltech.qt.core.QRectF;
+import com.trolltech.qt.core.Qt;
+import com.trolltech.qt.gui.QColor;
+import com.trolltech.qt.gui.QFont;
+import com.trolltech.qt.gui.QImage;
+import com.trolltech.qt.gui.QMouseEvent;
+import com.trolltech.qt.gui.QPaintEvent;
+import com.trolltech.qt.gui.QPainter;
+import com.trolltech.qt.gui.QPalette;
+import com.trolltech.qt.gui.QTextOption;
+import com.trolltech.qt.gui.QWidget;
+
+import cx.fbn.nevernote.Global;
+import cx.fbn.nevernote.sql.DatabaseConnection;
+
+public class RensoNoteListItem extends QWidget{
+ private final DatabaseConnection conn;
+ private final String noteGuid;
+ private final String noteTitle;
+ private final int relationPoints;
+ private final String noteCreated;
+ private final String tagNames;
+ private String noteContent;
+ private final RensoNoteList parent;
+ private final boolean isStared;
+ private final int allPointSum;
+
+ private final String iconPath = new String("classpath:cx/fbn/nevernote/icons/");
+
+ public RensoNoteListItem(Note note, int relationPoints, boolean isStared, int allPointSum, DatabaseConnection c, RensoNoteList parent){
+
+ this.conn = c;
+ this.parent = parent;
+ this.isStared = isStared;
+ this.allPointSum = allPointSum;
+ this.noteGuid = new String(note.getGuid());
+
+ this.noteTitle = new String(note.getTitle());
+ this.relationPoints = relationPoints;
+ SimpleDateFormat simple = new SimpleDateFormat("yyyy/MM/dd");
+ this.noteCreated = new StringBuilder(simple.format(note.getCreated())).toString();
+
+ StringBuilder sb = new StringBuilder();
+
+ for (int i = 0; i < note.getTagNames().size(); i++) {
+ sb.append(note.getTagNames().get(i));
+ if(i + 1 < note.getTagNames().size()){
+ sb.append(Global.tagDelimeter + " ");
+ }
+ }
+
+ this.tagNames = new String(sb);
+
+ // this.noteContent = new String(note.getContent());
+ this.noteContent = conn.getNoteTable().getNoteContentNoUTFConversion(note.getGuid());
+ this.noteContent = this.noteContent.replaceAll("<.+?>", "");
+ this.noteContent = this.noteContent.replaceAll("\\s{2,}", " ");
+ String kaigyo = System.getProperty("line.separator");
+ this.noteContent = this.noteContent.replaceAll(kaigyo, "");
+
+ QPalette p = new QPalette();
+ p.setColor(QPalette.ColorRole.Window, new QColor(255, 255, 255));
+ this.setPalette(p);
+ this.setAutoFillBackground(true);
+ this.setBackgroundRole(QPalette.ColorRole.Window);
+ }
+
+ @Override
+ protected void paintEvent(QPaintEvent event){
+ QPainter painter = new QPainter(this);
+
+ // 枠線
+ painter.setPen(QColor.lightGray);
+ painter.drawLine(0, rect().height() - 1, rect().width() - 1, rect().height() - 1);
+
+ // 項目の中身
+ // フォント設定
+ painter.setPen(QColor.black);
+ QFont titleFont = new QFont();
+ titleFont.setPixelSize(15);
+ titleFont.setBold(true);
+ QFont normalFont = new QFont();
+ normalFont.setPixelSize(12);
+
+ // タイトル
+ painter.setFont(titleFont);
+ painter.drawText(85, 3, size().width() - 130, 20, Qt.AlignmentFlag.AlignLeft.value(), noteTitle);
+ // 関連度
+ double ratio = (double)relationPoints / allPointSum;
+ int green = (int) (255 * (1.0 - ratio));
+ painter.setPen(new QColor(255, green, 0));
+ painter.drawText(size().width() - 40, 3, 40, 20, Qt.AlignmentFlag.AlignRight.value(), String.valueOf((int)(ratio * 100)) + "%");
+ // ノート作成日時
+ painter.setFont(normalFont);
+ painter.setPen(new QColor(60, 65, 255));
+ painter.drawText(85, 23, 75, 17, Qt.AlignmentFlag.AlignLeft.value(), noteCreated);
+ // タグ
+ painter.setPen(QColor.black);
+ painter.drawText(165, 23, size().width() - 165, 17, Qt.AlignmentFlag.AlignLeft.value(), tagNames);
+ // ノート内容
+ QTextOption option = new QTextOption();
+ option.setAlignment(Qt.AlignmentFlag.AlignLeft);
+ option.setUseDesignMetrics(true);
+ painter.drawText(new QRectF(85, 40, width() - 85, 40), noteContent, option);
+
+ // サムネイル
+ QImage img;
+ String thumbnailName = Global.getFileManager().getResDirPath("thumbnail-" + noteGuid + ".png");
+ QFile thumbnail = new QFile(thumbnailName);
+ if (!thumbnail.exists()) {
+ img = new QImage();
+ img.loadFromData(conn.getNoteTable().getThumbnail(noteGuid));
+ } else {
+ img = new QImage(thumbnailName);
+ }
+ painter.drawImage(2, 4, img, 0, 0, 80, rect().height() - 10);
+ painter.setPen(QColor.lightGray);
+ painter.drawRect(2, 4, 80, rect().height() - 10);
+
+ // スター
+ if (isStared) {
+ QImage starImage = new QImage(iconPath+"star.png");
+ starImage = starImage.scaled(30, 30, Qt.AspectRatioMode.IgnoreAspectRatio, Qt.TransformationMode.SmoothTransformation);
+ painter.drawImage(0, 0, starImage, 0, 0, starImage.width(), starImage.height());
+ }
+
+ painter.end();
+ }
+
+ @Override
+ protected void enterEvent(QEvent e){
+ if (!parent.isContextMenuVisible()) {
+ QPalette p = new QPalette();
+ p.setColor(QPalette.ColorRole.Window, new QColor(225, 235, 255));
+ this.setPalette(p);
+ }
+ }
+
+ @Override
+ protected void leaveEvent(QEvent e){
+ if (!parent.isContextMenuVisible()) {
+ setDefaultBackground();
+ }
+ }
+
+ @Override
+ protected void mousePressEvent(QMouseEvent e) {
+ QPalette p = new QPalette();
+ p.setColor(QPalette.ColorRole.Window, new QColor(165, 175, 255));
+ this.setPalette(p);
+
+ super.mousePressEvent(e);
+ }
+
+ public void setDefaultBackground() {
+ QPalette p = new QPalette();
+ p.setColor(QPalette.ColorRole.Window, new QColor(255, 255, 255));
+ this.setPalette(p);
+ }
+}
public String File_Note_Delete; // Delete a tag\r
public String File_Note_Restore; // Undelete a note\r
public String File_Note_Duplicate; // duplicate a note\r
+ // ICHANGED\r
+ public String File_Note_Open_New_Tab; // 新しいタブでノートを開く\r
+ public String File_Note_Add_New_Tab; // 新しいタブでノート追加\r
+ \r
public String File_Notebook_Add; // Add a notebook\r
public String File_Notebook_Edit; // Edit an existing notebook\r
public String File_Notebook_Delete; // Delete the existing notebook\r
File_Note_Delete = new String(); // Delete a tag\r
File_Note_Restore = new String(); // Undelete a note\r
File_Note_Duplicate = new String(); // Duplicate a note\r
+ // ICHANGED\r
+ File_Note_Add_New_Tab = new String(); // 新しいタブでノートを開く\r
+ File_Note_Open_New_Tab = new String(); // 新しいタブでノート追加\r
+ \r
File_Notebook_Add = new String(); // Add a notebook\r
File_Notebook_Edit = new String(); // Edit an existing notebook\r
File_Notebook_Delete = new String(); // Delete the existing notebook\r
loadKey("File_Backup", File_Backup);\r
loadKey("File_Restore", File_Restore);\r
loadKey("File_Exit", File_Exit);\r
+ // ICHANGED\r
+ loadKey("File_Note_Add_New_Tab", File_Note_Add_New_Tab);\r
+ loadKey("File_Note_Open_New_Tab", File_Note_Open_New_Tab);\r
\r
loadKey("Edit_Find_In_Note", Edit_Find_In_Note);\r
loadKey("Edit_Undo", Edit_Undo);\r
--- /dev/null
+// ICHANGED
+package cx.fbn.nevernote.gui;
+
+import java.awt.Desktop;
+
+import com.trolltech.qt.core.QUrl;
+import com.trolltech.qt.gui.QDesktopServices;
+import com.trolltech.qt.gui.QDialog;
+import com.trolltech.qt.gui.QPrintDialog;
+import com.trolltech.qt.gui.QPrinter;
+import com.trolltech.qt.gui.QVBoxLayout;
+import com.trolltech.qt.gui.QWidget;
+
+import cx.fbn.nevernote.dialog.FindDialog;
+import cx.fbn.nevernote.neighbornote.ClipBoardObserver;
+import cx.fbn.nevernote.sql.DatabaseConnection;
+
+public class TabBrowse extends QWidget {
+ private final DatabaseConnection conn;
+ private final BrowserWindow browser;
+ public Signal4<String, String, Boolean, BrowserWindow> contentsChanged;
+ private boolean noteDirty;
+ String saveTitle;
+ private final FindDialog find; // Text search in note dialog
+ private final TabBrowserWidget parent;
+ private final ClipBoardObserver cbObserver;
+
+ // コンストラクタ
+ public TabBrowse(DatabaseConnection c, TabBrowserWidget p, ClipBoardObserver cbObserver) {
+ conn = c;
+ parent = p;
+ this.cbObserver = cbObserver;
+ contentsChanged = new Signal4<String, String, Boolean, BrowserWindow>();
+ browser = new BrowserWindow(conn, this.cbObserver);
+ QVBoxLayout v = new QVBoxLayout();
+ v.addWidget(browser);
+ setLayout(v);
+ noteDirty = false;
+ browser.titleLabel.textChanged.connect(this, "titleChanged(String)");
+ browser.getBrowser().page().contentsChanged.connect(this,
+ "contentChanged()");
+ find = new FindDialog();
+ find.getOkButton().clicked.connect(this, "doFindText()");
+ }
+
+ @SuppressWarnings("unused")
+ private void contentChanged() {
+ noteDirty = true;
+ contentsChanged.emit(getBrowserWindow().getNote().getGuid(),
+ getBrowserWindow().getContent(), false, getBrowserWindow());
+ }
+
+ public BrowserWindow getBrowserWindow() {
+ return browser;
+ }
+
+
+ @SuppressWarnings("unused")
+ private void titleChanged(String value) {
+ int index = parent.indexOf(this);
+ if(index >= 0){
+ parent.setTabTitle(index, value);
+ }
+ }
+
+ /*
+ @SuppressWarnings("unused")
+ private void updateTitle(String guid, String title) {
+ if (guid.equals(getBrowserWindow().getNote().getGuid())
+ && (saveTitle != null && !title.equals(saveTitle) || saveTitle == null)) {
+ saveTitle = title;
+ getBrowserWindow().loadingData(true);
+ getBrowserWindow().setTitle(title);
+ getBrowserWindow().getNote().setTitle(title);
+ getBrowserWindow().loadingData(false);
+ }
+ }
+ */
+
+ /*
+ @SuppressWarnings("unused")
+ private void updateNotebook(String guid, String notebook) {
+ if (guid.equals(getBrowserWindow().getNote().getGuid())) {
+ getBrowserWindow().loadingData(true);
+ getBrowserWindow().setNotebook(notebook);
+ getBrowserWindow().loadingData(false);
+ }
+ }
+ */
+
+ /*
+ @SuppressWarnings("unused")
+ private void updateTags(String guid, List<String> tags) {
+ if (guid.equals(getBrowserWindow().getNote().getGuid())) {
+ StringBuffer tagLine = new StringBuffer(100);
+ for (int i = 0; i < tags.size(); i++) {
+ if (i > 0)
+ tagLine.append(Global.tagDelimeter + " ");
+ tagLine.append(tags.get(i));
+
+ }
+ getBrowserWindow().loadingData(true);
+ getBrowserWindow().getTagLine().setText(tagLine.toString());
+ getBrowserWindow().loadingData(false);
+ }
+ }
+ */
+
+ @SuppressWarnings("unused")
+ private void findText() {
+ find.show();
+ find.setFocusOnTextField();
+ }
+
+ @SuppressWarnings("unused")
+ private void doFindText() {
+ browser.getBrowser().page().findText(find.getText(), find.getFlags());
+ find.setFocus();
+ }
+
+ @SuppressWarnings("unused")
+ private void printNote() {
+
+ QPrintDialog dialog = new QPrintDialog();
+ if (dialog.exec() == QDialog.DialogCode.Accepted.value()) {
+ QPrinter printer = dialog.printer();
+ browser.getBrowser().print(printer);
+ }
+ }
+
+ // Listener triggered when the email button is pressed
+ @SuppressWarnings("unused")
+ private void emailNote() {
+ if (Desktop.isDesktopSupported()) {
+ Desktop desktop = Desktop.getDesktop();
+
+ String text2 = browser.getContentsToEmail();
+ QUrl url = new QUrl("mailto:");
+ url.addQueryItem("subject", browser.getTitle());
+ url.addQueryItem("body", text2);
+ QDesktopServices.openUrl(url);
+ }
+ }
+
+ // noteDirtyの値を返す
+ public boolean getNoteDirty() {
+ return noteDirty;
+ }
+}
--- /dev/null
+// ICHANGED
+package cx.fbn.nevernote.gui;
+
+import com.trolltech.qt.core.Qt;
+import com.trolltech.qt.gui.QLabel;
+import com.trolltech.qt.gui.QTabBar;
+
+public class TabBrowserBar extends QTabBar {
+
+ public TabBrowserBar(){
+ super();
+ }
+
+ public void addNewTab(int index, String title){
+ QLabel label = new QLabel(title);
+ label.setAlignment(Qt.AlignmentFlag.AlignLeft);
+ int tabWidth = this.tabSizeHint(index).width();
+ label.setFixedWidth(tabWidth - 35);
+ this.setTabButton(index, QTabBar.ButtonPosition.LeftSide, label);
+ }
+
+ public void setTabTitle(int index, String title) {
+ QLabel label = (QLabel)this.tabButton(index, QTabBar.ButtonPosition.LeftSide);
+ label.setText(title);
+ }
+
+}
--- /dev/null
+// ICHANGED
+package cx.fbn.nevernote.gui;
+
+import com.trolltech.qt.gui.QTabWidget;
+import com.trolltech.qt.gui.QWidget;
+
+public class TabBrowserWidget extends QTabWidget {
+ TabBrowserBar bar;
+
+ public TabBrowserWidget(QWidget parent) {
+ super(parent);
+ bar = new TabBrowserBar();
+ this.setTabBar(bar);
+ }
+
+ public int addNewTab(QWidget widget, String title){
+ int index = this.addTab(widget, new String());
+ bar.addNewTab(index, title);
+ this.setTabToolTip(index, title);
+ return index;
+ }
+
+ public void setTabTitle(int index, String title) {
+ bar.setTabTitle(index, title);
+ this.setTabToolTip(index, title);
+ }
+
+}
-/*\r
- * This file is part of NixNote \r
- * Copyright 2009 Randy Baumgarte\r
- * \r
- * This file may be licensed under the terms of of the\r
- * GNU General Public License Version 2 (the ``GPL'').\r
- *\r
- * Software distributed under the License is distributed\r
- * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either\r
- * express or implied. See the GPL for the specific language\r
- * governing rights and limitations.\r
- *\r
- * You should have received a copy of the GPL along with this\r
- * program. If not, go to http://www.gnu.org/licenses/gpl.html\r
- * or write to the Free Software Foundation, Inc.,\r
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
- *\r
-*/\r
-package cx.fbn.nevernote.gui;\r
-\r
-import java.util.List;\r
-import java.util.SortedMap;\r
-\r
-import com.evernote.edam.type.Note;\r
-import com.trolltech.qt.core.QByteArray;\r
-import com.trolltech.qt.core.QModelIndex;\r
-import com.trolltech.qt.core.Qt;\r
-import com.trolltech.qt.core.Qt.Orientation;\r
-import com.trolltech.qt.core.Qt.SortOrder;\r
-import com.trolltech.qt.gui.QAbstractItemView;\r
-import com.trolltech.qt.gui.QAction;\r
-import com.trolltech.qt.gui.QApplication;\r
-import com.trolltech.qt.gui.QColor;\r
-import com.trolltech.qt.gui.QContextMenuEvent;\r
-import com.trolltech.qt.gui.QDragEnterEvent;\r
-import com.trolltech.qt.gui.QDropEvent;\r
-import com.trolltech.qt.gui.QFontMetrics;\r
-import com.trolltech.qt.gui.QKeyEvent;\r
-import com.trolltech.qt.gui.QKeySequence.StandardKey;\r
-import com.trolltech.qt.gui.QMenu;\r
-import com.trolltech.qt.gui.QTableView;\r
-\r
-import cx.fbn.nevernote.Global;\r
-import cx.fbn.nevernote.evernote.NoteMetadata;\r
-import cx.fbn.nevernote.filters.NoteSortFilterProxyModel;\r
-import cx.fbn.nevernote.signals.NoteSignal;\r
-import cx.fbn.nevernote.utilities.ApplicationLogger;\r
-import cx.fbn.nevernote.utilities.ListManager;\r
-\r
-public class TableView extends QTableView {\r
- private final ListManager runner;\r
- private final ApplicationLogger logger;\r
- public NoteSortFilterProxyModel proxyModel; // note sort model\r
- private QAction deleteAction;\r
- private QAction addAction;\r
- private QAction restoreAction;\r
- private QAction noteHistoryAction;\r
- private QAction duplicateAction;\r
- private QAction mergeNotesAction;\r
- \r
- // Note title colors\r
- private QAction noteTitleColorWhite;\r
- private QAction noteTitleColorRed;\r
- private QAction noteTitleColorBlue;\r
- private QAction noteTitleColorGreen;\r
- private QAction noteTitleColorYellow;\r
- private QAction noteTitleColorBlack;\r
- private QAction noteTitleColorGray;\r
- private QAction noteTitleColorCyan;\r
- private QAction noteTitleColorMagenta;\r
- private QAction notePinned;\r
- private QAction copyAsUrlAction;\r
-\r
-\r
- \r
- public TableViewHeader header;\r
- int fontHeight;\r
- public Signal1<String> rowChanged;\r
- public Signal0 resetViewport;\r
- public NoteSignal noteSignal;\r
- \r
- public TableView(ApplicationLogger l, ListManager m) {\r
- logger = l;\r
- header = new TableViewHeader(Orientation.Horizontal,this);\r
- setHorizontalHeader(header);\r
- header.setMovable(true);\r
- header.subjectDateAction.toggled.connect(this, "toggleSubjectDate(Boolean)");\r
- header.createdDateAction.toggled.connect(this, "toggleCreationDate(Boolean)");\r
- header.changedDateAction.toggled.connect(this, "toggleChangedDate(Boolean)");\r
- header.authorAction.toggled.connect(this, "toggleAuthor(Boolean)");\r
- header.urlAction.toggled.connect(this, "toggleSourceUrl(Boolean)");\r
- header.pinnedAction.toggled.connect(this, "togglePinned(Boolean)");\r
- header.tagsAction.toggled.connect(this, "toggleTags(Boolean)");\r
- header.notebookAction.toggled.connect(this, "toggleNotebook(Boolean)");\r
- header.synchronizedAction.toggled.connect(this, "toggleSynchronized(Boolean)");\r
- header.guidAction.toggled.connect(this, "toggleGuid(Boolean)");\r
- header.thumbnailAction.toggled.connect(this, "toggleThumbnail(Boolean)");\r
- header.titleAction.toggled.connect(this, "toggleTitle(Boolean)");\r
- \r
- noteSignal = new NoteSignal();\r
- setAcceptDrops(true);\r
- setDragEnabled(true);\r
- setDragDropMode(QAbstractItemView.DragDropMode.DragDrop);\r
- setDropIndicatorShown(false);\r
- \r
- runner = m; \r
- \r
- runner.getNoteTableModel().setHeaderData(Global.noteTableCreationPosition, Qt.Orientation.Horizontal, tr("Date Created"), Qt.ItemDataRole.DisplayRole);\r
- runner.getNoteTableModel().setHeaderData(Global.noteTableTagPosition, Qt.Orientation.Horizontal, tr("Tags"), Qt.ItemDataRole.DisplayRole);\r
- runner.getNoteTableModel().setHeaderData(Global.noteTableGuidPosition, Qt.Orientation.Horizontal, tr("Guid"), Qt.ItemDataRole.DisplayRole);\r
- runner.getNoteTableModel().setHeaderData(Global.noteTableNotebookPosition, Qt.Orientation.Horizontal, tr("Notebook"), Qt.ItemDataRole.DisplayRole);\r
- runner.getNoteTableModel().setHeaderData(Global.noteTableTitlePosition, Qt.Orientation.Horizontal, tr("Title"), Qt.ItemDataRole.DisplayRole);\r
- runner.getNoteTableModel().setHeaderData(Global.noteTableChangedPosition, Qt.Orientation.Horizontal, tr("Date Changed"), Qt.ItemDataRole.DisplayRole);\r
- runner.getNoteTableModel().setHeaderData(Global.noteTableAuthorPosition, Qt.Orientation.Horizontal, tr("Author"), Qt.ItemDataRole.DisplayRole);\r
- runner.getNoteTableModel().setHeaderData(Global.noteTableSourceUrlPosition, Qt.Orientation.Horizontal, tr("Source Url"), Qt.ItemDataRole.DisplayRole);\r
- runner.getNoteTableModel().setHeaderData(Global.noteTableSubjectDatePosition, Qt.Orientation.Horizontal, tr("Subject Date"), Qt.ItemDataRole.DisplayRole);\r
- runner.getNoteTableModel().setHeaderData(Global.noteTableSynchronizedPosition, Qt.Orientation.Horizontal, tr("Sync"), Qt.ItemDataRole.DisplayRole);\r
- runner.getNoteTableModel().setHeaderData(Global.noteTablePinnedPosition, Qt.Orientation.Horizontal, tr("Pinned"), Qt.ItemDataRole.DisplayRole);\r
- runner.getNoteTableModel().setHeaderData(Global.noteTableThumbnailPosition, Qt.Orientation.Horizontal, tr("Thumbnail"), Qt.ItemDataRole.DisplayRole);\r
- header.sortIndicatorChanged.connect(this, "resetViewport()");\r
- \r
- proxyModel = new NoteSortFilterProxyModel(this);\r
- proxyModel.setSourceModel(runner.getNoteTableModel());\r
- setAlternatingRowColors(false);\r
- setModel(proxyModel);\r
- runner.getNoteTableModel().setSortProxyModel(proxyModel);\r
- \r
- setSortingEnabled(true);\r
- int sortCol = proxyModel.sortColumn();\r
- SortOrder sortOrder = proxyModel.sortOrder();\r
- sortByColumn(sortCol, sortOrder);\r
-\r
- setSelectionBehavior(SelectionBehavior.SelectRows);\r
- setSelectionMode(SelectionMode.SingleSelection);\r
- verticalHeader().setVisible(false);\r
- hideColumn(Global.noteTableGuidPosition); // Hide the guid column\r
- setShowGrid(false);\r
- setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers);\r
- \r
- QFontMetrics f = QApplication.fontMetrics();\r
- fontHeight = f.height();\r
- rowChanged = new Signal1<String>();\r
- resetViewport = new Signal0();\r
- \r
- NoteTableDateDelegate dateDelegate = new NoteTableDateDelegate();\r
- setItemDelegateForColumn(Global.noteTableCreationPosition, dateDelegate);\r
- setItemDelegateForColumn(Global.noteTableChangedPosition, dateDelegate);\r
- setItemDelegateForColumn(Global.noteTableSubjectDatePosition, dateDelegate);\r
- \r
- }\r
- \r
- // This should rescroll to the current item in the list when a column is \r
- // sorted. Somehow I can't get this to work, but this part is correct.\r
- @SuppressWarnings("unused")\r
- private void resetViewport() {\r
-// if (currentIndex() == null) \r
-// return;\r
- \r
-// resetViewport.emit();\r
- }\r
- \r
- \r
- public void load(boolean reload) {\r
- proxyModel.clear();\r
- setSortingEnabled(false);\r
- QFontMetrics f = QApplication.fontMetrics();\r
- if (!Global.isColumnVisible("thumbnail"))\r
- verticalHeader().setDefaultSectionSize(f.height());\r
- else {\r
- if (Global.getListView() == Global.View_List_Wide)\r
- verticalHeader().setDefaultSectionSize(Global.smallThumbnailSize.height());\r
- else\r
- verticalHeader().setDefaultSectionSize(Global.largeThumbnailSize.height());\r
- }\r
- for (int i=0; i<runner.getNoteIndex().size(); i++) {\r
- String guid = runner.getNoteIndex().get(i).getGuid();\r
- NoteMetadata metaInfo = runner.getNoteMetadata().get(guid);\r
- if (Global.showDeleted == true && !runner.getNoteIndex().get(i).isActive()) {\r
- proxyModel.addGuid(guid, null);\r
- }\r
- if (!Global.showDeleted == true && \r
- (runner.getNoteIndex().get(i).isActive() || \r
- metaInfo.isPinned())) { \r
- proxyModel.addGuid(guid, metaInfo);\r
- }\r
- }\r
-\r
- if (!reload) {\r
- logger.log(logger.EXTREME, "TableView.load() reload starting.");\r
- proxyModel.filter();\r
- setSortingEnabled(true);\r
- logger.log(logger.EXTREME, "TableView.load() leaving reload.");\r
- return;\r
- }\r
- logger.log(logger.EXTREME, "TableView.load() Filling table data from scratch");\r
- \r
- for (int i=0; i<runner.getMasterNoteIndex().size(); i++) {\r
- if (runner.getMasterNoteIndex().get(i) != null) { \r
- Note note = runner.getMasterNoteIndex().get(i);\r
- NoteMetadata meta = runner.getNoteMetadata().get(note.getGuid());\r
- insertRow(runner.getMasterNoteIndex().get(i), meta, false, i); \r
- }\r
- } \r
- proxyModel.invalidate();\r
- \r
- resizeColumnWidths();\r
- repositionColumns();\r
- \r
- proxyModel.filter();\r
- \r
- setSortingEnabled(true);\r
- resetViewport.emit();\r
- }\r
- \r
- public void repositionColumns() {\r
- int from = header.visualIndex(Global.noteTableCreationPosition);\r
- int to = Global.getColumnPosition("noteTableCreationPosition");\r
- if (to>=0) header.moveSection(from, to);\r
-\r
- from = header.visualIndex(Global.noteTableTitlePosition);\r
- to = Global.getColumnPosition("noteTableTitlePosition");\r
- if (to>=0) header.moveSection(from, to);\r
- \r
- from = header.visualIndex(Global.noteTableTagPosition);\r
- to = Global.getColumnPosition("noteTableTagPosition");\r
- if (to>=0) header.moveSection(from, to);\r
- \r
- from = header.visualIndex(Global.noteTableNotebookPosition);\r
- to = Global.getColumnPosition("noteTableNotebookPosition");\r
- if (to>=0) header.moveSection(from, to);\r
- \r
- from = header.visualIndex(Global.noteTableChangedPosition);\r
- to = Global.getColumnPosition("noteTableChangedPosition");\r
- if (to>=0) header.moveSection(from, to);\r
- \r
- from = header.visualIndex(Global.noteTableSourceUrlPosition);\r
- to = Global.getColumnPosition("noteTableSourceUrlPosition");\r
- if (to>=0) header.moveSection(from, to);\r
- \r
- from = header.visualIndex(Global.noteTableAuthorPosition);\r
- to = Global.getColumnPosition("noteTableAuthorPosition");\r
- if (to>=0) header.moveSection(from, to);\r
- \r
- from = header.visualIndex(Global.noteTableSubjectDatePosition);\r
- to = Global.getColumnPosition("noteTableSubjectDatePosition");\r
- if (to>=0) header.moveSection(from, to);\r
- \r
- from = header.visualIndex(Global.noteTableSynchronizedPosition);\r
- to = Global.getColumnPosition("noteTableSynchronizedPosition");\r
- if (to>=0) header.moveSection(from, to);\r
-\r
- from = header.visualIndex(Global.noteTablePinnedPosition);\r
- to = Global.getColumnPosition("noteTablePinnedPosition");\r
- if (to>=0) header.moveSection(from, to);\r
-\r
- \r
- from = header.visualIndex(Global.noteTableGuidPosition);\r
- to = Global.getColumnPosition("noteTableGuidPosition");\r
- if (to>=0) header.moveSection(from, to);\r
- \r
- \r
- from = header.visualIndex(Global.noteTableThumbnailPosition);\r
- to = Global.getColumnPosition("noteTableThumbnailPosition");\r
- if (to>=0) header.moveSection(from, to);\r
-\r
- }\r
- \r
- public void resizeColumnWidths() {\r
- int width;\r
- width = Global.getColumnWidth("noteTableCreationPosition");\r
- if (width>0) setColumnWidth(Global.noteTableCreationPosition, width);\r
- width = Global.getColumnWidth("noteTableChangedPosition");\r
- if (width>0) setColumnWidth(Global.noteTableChangedPosition, width);\r
- width = Global.getColumnWidth("noteTableTitlePosition");\r
- if (width>0) setColumnWidth(Global.noteTableTitlePosition, width);\r
- width = Global.getColumnWidth("noteTableTagPosition");\r
- if (width>0) setColumnWidth(Global.noteTableTagPosition, width);\r
- width = Global.getColumnWidth("noteTableGuidPosition");\r
- if (width>0) setColumnWidth(Global.noteTableGuidPosition, width);\r
- width = Global.getColumnWidth("noteTableNotebookPosition");\r
- if (width>0) setColumnWidth(Global.noteTableNotebookPosition, width);\r
- width = Global.getColumnWidth("noteTableSourceUrlPosition");\r
- if (width>0) setColumnWidth(Global.noteTableSourceUrlPosition, width);\r
- width = Global.getColumnWidth("noteTableAuthorPosition");\r
- if (width>0) setColumnWidth(Global.noteTableAuthorPosition, width);\r
- width = Global.getColumnWidth("noteTableSubjectDatePosition");\r
- if (width>0) setColumnWidth(Global.noteTableSubjectDatePosition, width);\r
- width = Global.getColumnWidth("noteTableSynchronizedPosition");\r
- if (width>0) setColumnWidth(Global.noteTableSynchronizedPosition, width);\r
- width = Global.getColumnWidth("noteTableThumbnailPosition");\r
- if (width>0) setColumnWidth(Global.noteTablePinnedPosition, width);\r
- width = Global.getColumnWidth("noteTablePinnedPosition");\r
- if (width>0) setColumnWidth(Global.noteTableThumbnailPosition, width);\r
- width = Global.getColumnWidth("noteTableGuidPosition");\r
- if (width>0) setColumnWidth(Global.noteTableGuidPosition, width);\r
-\r
- }\r
- \r
- public void resizeRowHeights() {\r
- int height;\r
- if (!Global.isColumnVisible("thumbnail") || !Global.enableThumbnails()) {\r
- QFontMetrics f = QApplication.fontMetrics();\r
- verticalHeader().setDefaultSectionSize(f.height());\r
- height = fontHeight;\r
- } else {\r
- if (Global.getListView() == Global.View_List_Wide) {\r
- verticalHeader().setDefaultSectionSize(Global.smallThumbnailSize.height());\r
- height = Global.smallThumbnailSize.height();\r
- } else {\r
- verticalHeader().setDefaultSectionSize(Global.largeThumbnailSize.height());\r
- height = Global.largeThumbnailSize.height();\r
- }\r
- }\r
- for (int i=0; i<runner.getNoteTableModel().rowCount(); i++) {\r
- setRowHeight(i, height);\r
- }\r
- }\r
- \r
- public void insertRow(Note tempNote, NoteMetadata meta, boolean newNote, int row) {\r
- if (newNote)\r
- proxyModel.addGuid(tempNote.getGuid(), meta);\r
- if (row > runner.getNoteTableModel().rowCount())\r
- runner.getNoteTableModel().insertRow(0);\r
- \r
- if (row < 0) {\r
- row = runner.getNoteTableModel().rowCount();\r
- runner.getNoteTableModel().insertRow(row);\r
- }\r
- if (newNote) {\r
- resizeRowHeights();\r
- }\r
- }\r
- protected boolean filterAcceptsRow(int sourceRow, QModelIndex sourceParent) {\r
- return true;\r
- }\r
-\r
- public void setAddAction(QAction a) {\r
- addAction = a;\r
- }\r
- \r
- public void setMergeNotesAction(QAction a) {\r
- mergeNotesAction = a;\r
- }\r
- \r
- public void setCopyAsUrlAction(QAction a) {\r
- copyAsUrlAction = a;\r
- }\r
- \r
- public void setNoteHistoryAction(QAction a) {\r
- noteHistoryAction = a;\r
- }\r
- \r
- public void setDeleteAction(QAction d) {\r
- deleteAction = d;\r
- }\r
- \r
- public void setRestoreAction(QAction r) {\r
- restoreAction = r;\r
- }\r
- public void setNoteDuplicateAction(QAction d) {\r
- duplicateAction = d;\r
- }\r
- \r
- @Override\r
- public void keyPressEvent(QKeyEvent e) {\r
- if (e.matches(StandardKey.MoveToStartOfDocument)) {\r
- if (runner.getNoteTableModel().rowCount() > 0) {\r
- clearSelection();\r
- selectRow(0);\r
- }\r
- }\r
- if (e.matches(StandardKey.MoveToEndOfDocument)) {\r
- if (runner.getNoteTableModel().rowCount() > 0) {\r
- clearSelection();\r
- selectRow(model().rowCount()-1);\r
- }\r
- }\r
- super.keyPressEvent(e);\r
- }\r
- \r
- @Override\r
- public void contextMenuEvent(QContextMenuEvent event) {\r
- QMenu menu = new QMenu(this);\r
- if (Global.showDeleted) {\r
- menu.addAction(restoreAction);\r
- } else {\r
- menu.addAction(addAction);\r
- }\r
- menu.addAction(deleteAction);\r
- menu.addSeparator();\r
- menu.addAction(duplicateAction);\r
- menu.addAction(copyAsUrlAction);\r
- menu.addSeparator();\r
- menu.addAction(noteHistoryAction);\r
- menu.addAction(mergeNotesAction);\r
- \r
- QMenu titleColorMenu = new QMenu();\r
- titleColorMenu.setTitle(tr("Title Color"));\r
- menu.addMenu(titleColorMenu);\r
- noteTitleColorWhite = new QAction(titleColorMenu);\r
- noteTitleColorRed = new QAction(titleColorMenu);\r
- noteTitleColorBlue = new QAction(titleColorMenu);\r
- noteTitleColorGreen = new QAction(titleColorMenu);\r
- noteTitleColorYellow = new QAction(titleColorMenu);\r
- noteTitleColorBlack = new QAction(titleColorMenu);\r
- noteTitleColorGray = new QAction(titleColorMenu);\r
- noteTitleColorCyan = new QAction(titleColorMenu);\r
- noteTitleColorMagenta = new QAction(titleColorMenu);\r
- \r
- notePinned = new QAction(titleColorMenu);\r
- menu.addAction(notePinned);\r
- \r
- noteTitleColorWhite.setText(tr("White"));\r
- noteTitleColorRed.setText(tr("Red"));\r
- noteTitleColorBlue.setText(tr("Blue"));\r
- noteTitleColorGreen.setText(tr("Green"));\r
- noteTitleColorYellow.setText(tr("Yellow"));\r
- noteTitleColorBlack.setText(tr("Black"));\r
- noteTitleColorGray.setText(tr("Gray"));\r
- noteTitleColorCyan.setText(tr("Cyan"));\r
- noteTitleColorMagenta.setText(tr("Magenta"));\r
- notePinned.setText(tr("Pin/Unpin"));\r
- \r
- titleColorMenu.addAction(noteTitleColorWhite);\r
- titleColorMenu.addAction(noteTitleColorRed);\r
- titleColorMenu.addAction(noteTitleColorBlue);\r
- titleColorMenu.addAction(noteTitleColorGreen);\r
- titleColorMenu.addAction(noteTitleColorYellow);\r
- titleColorMenu.addAction(noteTitleColorBlack);\r
- titleColorMenu.addAction(noteTitleColorGray);\r
- titleColorMenu.addAction(noteTitleColorCyan);\r
- titleColorMenu.addAction(noteTitleColorMagenta);\r
- \r
- noteTitleColorWhite.triggered.connect(this, "titleColorWhite()");\r
- \r
- noteTitleColorWhite.triggered.connect(this, "titleColorWhite()");\r
- noteTitleColorRed.triggered.connect(this, "titleColorRed()");\r
- noteTitleColorBlue.triggered.connect(this, "titleColorBlue()");\r
- noteTitleColorGreen.triggered.connect(this, "titleColorGreen()");\r
- noteTitleColorYellow.triggered.connect(this, "titleColorYellow()");\r
- noteTitleColorBlack.triggered.connect(this, "titleColorBlack()");\r
- noteTitleColorGray.triggered.connect(this, "titleColorGray()");\r
- noteTitleColorCyan.triggered.connect(this, "titleColorCyan()");\r
- noteTitleColorMagenta.triggered.connect(this, "titleColorMagenta()");\r
- notePinned.triggered.connect(this, "notePinned()");\r
- menu.exec(event.globalPos());\r
- }\r
- \r
- \r
- @SuppressWarnings("unused")\r
- private void titleColorWhite() {noteSignal.titleColorChanged.emit(QColor.white.rgb());}\r
- @SuppressWarnings("unused")\r
- private void titleColorRed() {noteSignal.titleColorChanged.emit(QColor.red.rgb());}\r
- @SuppressWarnings("unused")\r
- private void titleColorBlue() {noteSignal.titleColorChanged.emit(QColor.blue.rgb());}\r
- @SuppressWarnings("unused")\r
- private void titleColorGreen() {noteSignal.titleColorChanged.emit(QColor.green.rgb());}\r
- @SuppressWarnings("unused")\r
- private void titleColorYellow(){noteSignal.titleColorChanged.emit(QColor.yellow.rgb());}\r
- @SuppressWarnings("unused")\r
- private void titleColorBlack() {noteSignal.titleColorChanged.emit(QColor.black.rgb());}\r
- @SuppressWarnings("unused")\r
- private void titleColorGray() {noteSignal.titleColorChanged.emit(QColor.gray.rgb());}\r
- @SuppressWarnings("unused")\r
- private void titleColorCyan() {noteSignal.titleColorChanged.emit(QColor.cyan.rgb());}\r
- @SuppressWarnings("unused")\r
- private void titleColorMagenta() {noteSignal.titleColorChanged.emit(QColor.magenta.rgb());}\r
- @SuppressWarnings("unused")\r
- private void notePinned() {noteSignal.notePinned.emit();}\r
- \r
-\r
- @Override\r
- public void dragEnterEvent(QDragEnterEvent event) {\r
- StringBuffer guid = new StringBuffer(1000);\r
- \r
- showColumn(Global.noteTableGuidPosition);\r
- List<QModelIndex> selections = selectionModel().selectedRows();\r
- hideColumn(Global.noteTableGuidPosition);\r
- \r
- if (selections.size() > 0) {\r
- QModelIndex index;\r
- for (int i=0; i<selections.size(); i++) {\r
- int row = selections.get(i).row();\r
- index = proxyModel.index(row, Global.noteTableGuidPosition);\r
- SortedMap<Integer, Object> ix = proxyModel.itemData(index);\r
- guid.append((String)ix.values().toArray()[0]);\r
- guid.append(" ");\r
- }\r
- }\r
- event.mimeData().setData("application/x-nevernote-note", new QByteArray(guid.toString()));\r
- event.accept();\r
- \r
- }\r
- \r
- @Override\r
- public void dropEvent(QDropEvent event) {\r
- if (event.source() == this)\r
- event.ignore();\r
- }\r
- \r
- // Return a column width\r
- public int getColumnWidth(int col) {\r
- return columnWidth(col);\r
- }\r
- \r
- public void toggleSubjectDate(Boolean toggle) {\r
- Global.saveColumnVisible("dateSubject", toggle);\r
- setColumnHidden(Global.noteTableSubjectDatePosition, !toggle);\r
- }\r
- \r
- public void toggleChangedDate(Boolean toggle) {\r
- Global.saveColumnVisible("dateChanged", toggle);\r
- setColumnHidden(Global.noteTableChangedPosition, !toggle);\r
- }\r
- \r
- \r
- public void toggleCreationDate(Boolean toggle) {\r
- Global.saveColumnVisible("dateCreated", toggle);\r
- setColumnHidden(Global.noteTableCreationPosition, !toggle);\r
- }\r
- \r
- public void toggleSourceUrl(Boolean toggle) {\r
- Global.saveColumnVisible("sourceUrl", toggle);\r
- setColumnHidden(Global.noteTableSourceUrlPosition, !toggle);\r
- }\r
- \r
- public void toggleAuthor(Boolean toggle) {\r
- Global.saveColumnVisible("author", toggle);\r
- setColumnHidden(Global.noteTableAuthorPosition, !toggle);\r
- }\r
- \r
- public void toggleNotebook(Boolean toggle) {\r
- Global.saveColumnVisible("notebook", toggle);\r
- setColumnHidden(Global.noteTableNotebookPosition, !toggle);\r
- }\r
-\r
- public void toggleTitle(Boolean toggle) {\r
- Global.saveColumnVisible("title", toggle);\r
- setColumnHidden(Global.noteTableTitlePosition, !toggle);\r
- }\r
-\r
- public void toggleTags(Boolean toggle) {\r
- Global.saveColumnVisible("tags", toggle);\r
- setColumnHidden(Global.noteTableTagPosition, !toggle);\r
- }\r
- \r
- public void toggleSynchronized(Boolean toggle) {\r
- Global.saveColumnVisible("synchronized", toggle);\r
- setColumnHidden(Global.noteTableSynchronizedPosition, !toggle);\r
- }\r
- public void togglePinned(Boolean toggle) {\r
- Global.saveColumnVisible("pinned", toggle);\r
- setColumnHidden(Global.noteTablePinnedPosition, !toggle);\r
- }\r
- public void toggleGuid(Boolean toggle) {\r
- Global.saveColumnVisible("guid", toggle);\r
- setColumnHidden(Global.noteTableGuidPosition, !toggle);\r
- } \r
- public void toggleThumbnail(Boolean toggle) {\r
- Global.saveColumnVisible("thumbnail", toggle);\r
- int size;\r
- if (!toggle) {\r
- QFontMetrics f = QApplication.fontMetrics();\r
- size = f.height();\r
- verticalHeader().setDefaultSectionSize(f.height());\r
- } else\r
- size = Global.smallThumbnailSize.height();\r
- for (int i=0; i<runner.getNoteTableModel().rowCount(); i++) {\r
- setRowHeight(i, size);\r
- }\r
- \r
- setColumnHidden(Global.noteTableThumbnailPosition, !toggle);\r
- }\r
- \r
-}\r
+/*
+ * This file is part of NixNote
+ * Copyright 2009 Randy Baumgarte
+ *
+ * This file may be licensed under the terms of of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+*/
+package cx.fbn.nevernote.gui;
+
+import java.util.List;
+import java.util.SortedMap;
+
+import com.evernote.edam.type.Note;
+import com.trolltech.qt.core.QByteArray;
+import com.trolltech.qt.core.QModelIndex;
+import com.trolltech.qt.core.Qt;
+import com.trolltech.qt.core.Qt.Orientation;
+import com.trolltech.qt.core.Qt.SortOrder;
+import com.trolltech.qt.gui.QAbstractItemView;
+import com.trolltech.qt.gui.QAction;
+import com.trolltech.qt.gui.QApplication;
+import com.trolltech.qt.gui.QColor;
+import com.trolltech.qt.gui.QContextMenuEvent;
+import com.trolltech.qt.gui.QDragEnterEvent;
+import com.trolltech.qt.gui.QDropEvent;
+import com.trolltech.qt.gui.QFontMetrics;
+import com.trolltech.qt.gui.QKeyEvent;
+import com.trolltech.qt.gui.QKeySequence.StandardKey;
+import com.trolltech.qt.gui.QTableView;
+
+import cx.fbn.nevernote.Global;
+import cx.fbn.nevernote.NeverNote;
+import cx.fbn.nevernote.evernote.NoteMetadata;
+import cx.fbn.nevernote.filters.NoteSortFilterProxyModel;
+import cx.fbn.nevernote.signals.NoteSignal;
+import cx.fbn.nevernote.utilities.ApplicationLogger;
+import cx.fbn.nevernote.utilities.ListManager;
+
+public class TableView extends QTableView {
+ private final ListManager runner;
+ private final ApplicationLogger logger;
+ public NoteSortFilterProxyModel proxyModel; // note sort model
+ private QAction deleteAction;
+ private QAction addAction;
+ private QAction restoreAction;
+ private QAction noteHistoryAction;
+ private QAction duplicateAction;
+ private QAction mergeNotesAction;
+ // ICHANGED
+ private QAction openNewTabAction;
+ private QAction addNoteNewTabAction;
+
+ // Note title colors
+ private QAction noteTitleColorWhite;
+ private QAction noteTitleColorRed;
+ private QAction noteTitleColorBlue;
+ private QAction noteTitleColorGreen;
+ private QAction noteTitleColorYellow;
+ private QAction noteTitleColorBlack;
+ private QAction noteTitleColorGray;
+ private QAction noteTitleColorCyan;
+ private QAction noteTitleColorMagenta;
+ private QAction notePinned;
+ private QAction copyAsUrlAction;
+
+
+
+ public TableViewHeader header;
+ int fontHeight;
+ public Signal1<String> rowChanged;
+ public Signal0 resetViewport;
+ public NoteSignal noteSignal;
+
+ // ICHANGED
+ private final NeverNote parent;
+
+ // ICHANGED parent引数を追加
+ public TableView(ApplicationLogger l, ListManager m, NeverNote parent) {
+ // ICHANGED
+ this.parent = parent;
+
+ logger = l;
+ header = new TableViewHeader(Orientation.Horizontal,this);
+ setHorizontalHeader(header);
+ header.setMovable(true);
+ header.subjectDateAction.toggled.connect(this, "toggleSubjectDate(Boolean)");
+ header.createdDateAction.toggled.connect(this, "toggleCreationDate(Boolean)");
+ header.changedDateAction.toggled.connect(this, "toggleChangedDate(Boolean)");
+ header.authorAction.toggled.connect(this, "toggleAuthor(Boolean)");
+ header.urlAction.toggled.connect(this, "toggleSourceUrl(Boolean)");
+ header.pinnedAction.toggled.connect(this, "togglePinned(Boolean)");
+ header.tagsAction.toggled.connect(this, "toggleTags(Boolean)");
+ header.notebookAction.toggled.connect(this, "toggleNotebook(Boolean)");
+ header.synchronizedAction.toggled.connect(this, "toggleSynchronized(Boolean)");
+ header.guidAction.toggled.connect(this, "toggleGuid(Boolean)");
+ header.thumbnailAction.toggled.connect(this, "toggleThumbnail(Boolean)");
+ header.titleAction.toggled.connect(this, "toggleTitle(Boolean)");
+
+ noteSignal = new NoteSignal();
+ setAcceptDrops(true);
+ setDragEnabled(true);
+ setDragDropMode(QAbstractItemView.DragDropMode.DragDrop);
+ setDropIndicatorShown(false);
+
+ runner = m;
+
+ runner.getNoteTableModel().setHeaderData(Global.noteTableCreationPosition, Qt.Orientation.Horizontal, tr("Date Created"), Qt.ItemDataRole.DisplayRole);
+ runner.getNoteTableModel().setHeaderData(Global.noteTableTagPosition, Qt.Orientation.Horizontal, tr("Tags"), Qt.ItemDataRole.DisplayRole);
+ runner.getNoteTableModel().setHeaderData(Global.noteTableGuidPosition, Qt.Orientation.Horizontal, tr("Guid"), Qt.ItemDataRole.DisplayRole);
+ runner.getNoteTableModel().setHeaderData(Global.noteTableNotebookPosition, Qt.Orientation.Horizontal, tr("Notebook"), Qt.ItemDataRole.DisplayRole);
+ runner.getNoteTableModel().setHeaderData(Global.noteTableTitlePosition, Qt.Orientation.Horizontal, tr("Title"), Qt.ItemDataRole.DisplayRole);
+ runner.getNoteTableModel().setHeaderData(Global.noteTableChangedPosition, Qt.Orientation.Horizontal, tr("Date Changed"), Qt.ItemDataRole.DisplayRole);
+ runner.getNoteTableModel().setHeaderData(Global.noteTableAuthorPosition, Qt.Orientation.Horizontal, tr("Author"), Qt.ItemDataRole.DisplayRole);
+ runner.getNoteTableModel().setHeaderData(Global.noteTableSourceUrlPosition, Qt.Orientation.Horizontal, tr("Source Url"), Qt.ItemDataRole.DisplayRole);
+ runner.getNoteTableModel().setHeaderData(Global.noteTableSubjectDatePosition, Qt.Orientation.Horizontal, tr("Subject Date"), Qt.ItemDataRole.DisplayRole);
+ runner.getNoteTableModel().setHeaderData(Global.noteTableSynchronizedPosition, Qt.Orientation.Horizontal, tr("Sync"), Qt.ItemDataRole.DisplayRole);
+ runner.getNoteTableModel().setHeaderData(Global.noteTablePinnedPosition, Qt.Orientation.Horizontal, tr("Pinned"), Qt.ItemDataRole.DisplayRole);
+ runner.getNoteTableModel().setHeaderData(Global.noteTableThumbnailPosition, Qt.Orientation.Horizontal, tr("Thumbnail"), Qt.ItemDataRole.DisplayRole);
+ header.sortIndicatorChanged.connect(this, "resetViewport()");
+
+ proxyModel = new NoteSortFilterProxyModel(this);
+ proxyModel.setSourceModel(runner.getNoteTableModel());
+ setAlternatingRowColors(false);
+ setModel(proxyModel);
+ runner.getNoteTableModel().setSortProxyModel(proxyModel);
+
+ setSortingEnabled(true);
+ int sortCol = proxyModel.sortColumn();
+ SortOrder sortOrder = proxyModel.sortOrder();
+ sortByColumn(sortCol, sortOrder);
+
+ setSelectionBehavior(SelectionBehavior.SelectRows);
+ setSelectionMode(SelectionMode.SingleSelection);
+ verticalHeader().setVisible(false);
+ hideColumn(Global.noteTableGuidPosition); // Hide the guid column
+ setShowGrid(false);
+ setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers);
+
+ QFontMetrics f = QApplication.fontMetrics();
+ fontHeight = f.height();
+ rowChanged = new Signal1<String>();
+ resetViewport = new Signal0();
+
+ NoteTableDateDelegate dateDelegate = new NoteTableDateDelegate();
+ setItemDelegateForColumn(Global.noteTableCreationPosition, dateDelegate);
+ setItemDelegateForColumn(Global.noteTableChangedPosition, dateDelegate);
+ setItemDelegateForColumn(Global.noteTableSubjectDatePosition, dateDelegate);
+
+ }
+
+ // This should rescroll to the current item in the list when a column is
+ // sorted. Somehow I can't get this to work, but this part is correct.
+ @SuppressWarnings("unused")
+ private void resetViewport() {
+// if (currentIndex() == null)
+// return;
+
+// resetViewport.emit();
+ }
+
+
+ public void load(boolean reload) {
+ proxyModel.clear();
+ setSortingEnabled(false);
+ QFontMetrics f = QApplication.fontMetrics();
+ if (!Global.isColumnVisible("thumbnail"))
+ verticalHeader().setDefaultSectionSize(f.height());
+ else {
+ if (Global.getListView() == Global.View_List_Wide)
+ verticalHeader().setDefaultSectionSize(Global.smallThumbnailSize.height());
+ else
+ verticalHeader().setDefaultSectionSize(Global.largeThumbnailSize.height());
+ }
+ for (int i=0; i<runner.getNoteIndex().size(); i++) {
+ String guid = runner.getNoteIndex().get(i).getGuid();
+ NoteMetadata metaInfo = runner.getNoteMetadata().get(guid);
+ if (Global.showDeleted == true && !runner.getNoteIndex().get(i).isActive()) {
+ proxyModel.addGuid(guid, null);
+ }
+ if (!Global.showDeleted == true &&
+ (runner.getNoteIndex().get(i).isActive() ||
+ metaInfo.isPinned())) {
+ proxyModel.addGuid(guid, metaInfo);
+ }
+ }
+
+ if (!reload) {
+ logger.log(logger.EXTREME, "TableView.load() reload starting.");
+ proxyModel.filter();
+ setSortingEnabled(true);
+ logger.log(logger.EXTREME, "TableView.load() leaving reload.");
+ return;
+ }
+ logger.log(logger.EXTREME, "TableView.load() Filling table data from scratch");
+
+ for (int i=0; i<runner.getMasterNoteIndex().size(); i++) {
+ if (runner.getMasterNoteIndex().get(i) != null) {
+ Note note = runner.getMasterNoteIndex().get(i);
+ NoteMetadata meta = runner.getNoteMetadata().get(note.getGuid());
+ insertRow(runner.getMasterNoteIndex().get(i), meta, false, i);
+ }
+ }
+ proxyModel.invalidate();
+
+ resizeColumnWidths();
+ repositionColumns();
+
+ proxyModel.filter();
+
+ setSortingEnabled(true);
+ resetViewport.emit();
+ }
+
+ public void repositionColumns() {
+ int from = header.visualIndex(Global.noteTableCreationPosition);
+ int to = Global.getColumnPosition("noteTableCreationPosition");
+ if (to>=0) header.moveSection(from, to);
+
+ from = header.visualIndex(Global.noteTableTitlePosition);
+ to = Global.getColumnPosition("noteTableTitlePosition");
+ if (to>=0) header.moveSection(from, to);
+
+ from = header.visualIndex(Global.noteTableTagPosition);
+ to = Global.getColumnPosition("noteTableTagPosition");
+ if (to>=0) header.moveSection(from, to);
+
+ from = header.visualIndex(Global.noteTableNotebookPosition);
+ to = Global.getColumnPosition("noteTableNotebookPosition");
+ if (to>=0) header.moveSection(from, to);
+
+ from = header.visualIndex(Global.noteTableChangedPosition);
+ to = Global.getColumnPosition("noteTableChangedPosition");
+ if (to>=0) header.moveSection(from, to);
+
+ from = header.visualIndex(Global.noteTableSourceUrlPosition);
+ to = Global.getColumnPosition("noteTableSourceUrlPosition");
+ if (to>=0) header.moveSection(from, to);
+
+ from = header.visualIndex(Global.noteTableAuthorPosition);
+ to = Global.getColumnPosition("noteTableAuthorPosition");
+ if (to>=0) header.moveSection(from, to);
+
+ from = header.visualIndex(Global.noteTableSubjectDatePosition);
+ to = Global.getColumnPosition("noteTableSubjectDatePosition");
+ if (to>=0) header.moveSection(from, to);
+
+ from = header.visualIndex(Global.noteTableSynchronizedPosition);
+ to = Global.getColumnPosition("noteTableSynchronizedPosition");
+ if (to>=0) header.moveSection(from, to);
+
+ from = header.visualIndex(Global.noteTablePinnedPosition);
+ to = Global.getColumnPosition("noteTablePinnedPosition");
+ if (to>=0) header.moveSection(from, to);
+
+
+ from = header.visualIndex(Global.noteTableGuidPosition);
+ to = Global.getColumnPosition("noteTableGuidPosition");
+ if (to>=0) header.moveSection(from, to);
+
+
+ from = header.visualIndex(Global.noteTableThumbnailPosition);
+ to = Global.getColumnPosition("noteTableThumbnailPosition");
+ if (to>=0) header.moveSection(from, to);
+
+ }
+
+ public void resizeColumnWidths() {
+ int width;
+ width = Global.getColumnWidth("noteTableCreationPosition");
+ if (width>0) setColumnWidth(Global.noteTableCreationPosition, width);
+ width = Global.getColumnWidth("noteTableChangedPosition");
+ if (width>0) setColumnWidth(Global.noteTableChangedPosition, width);
+ width = Global.getColumnWidth("noteTableTitlePosition");
+ if (width>0) setColumnWidth(Global.noteTableTitlePosition, width);
+ width = Global.getColumnWidth("noteTableTagPosition");
+ if (width>0) setColumnWidth(Global.noteTableTagPosition, width);
+ width = Global.getColumnWidth("noteTableGuidPosition");
+ if (width>0) setColumnWidth(Global.noteTableGuidPosition, width);
+ width = Global.getColumnWidth("noteTableNotebookPosition");
+ if (width>0) setColumnWidth(Global.noteTableNotebookPosition, width);
+ width = Global.getColumnWidth("noteTableSourceUrlPosition");
+ if (width>0) setColumnWidth(Global.noteTableSourceUrlPosition, width);
+ width = Global.getColumnWidth("noteTableAuthorPosition");
+ if (width>0) setColumnWidth(Global.noteTableAuthorPosition, width);
+ width = Global.getColumnWidth("noteTableSubjectDatePosition");
+ if (width>0) setColumnWidth(Global.noteTableSubjectDatePosition, width);
+ width = Global.getColumnWidth("noteTableSynchronizedPosition");
+ if (width>0) setColumnWidth(Global.noteTableSynchronizedPosition, width);
+ width = Global.getColumnWidth("noteTableThumbnailPosition");
+ if (width>0) setColumnWidth(Global.noteTablePinnedPosition, width);
+ width = Global.getColumnWidth("noteTablePinnedPosition");
+ if (width>0) setColumnWidth(Global.noteTableThumbnailPosition, width);
+ width = Global.getColumnWidth("noteTableGuidPosition");
+ if (width>0) setColumnWidth(Global.noteTableGuidPosition, width);
+
+ }
+
+ public void resizeRowHeights() {
+ int height;
+ if (!Global.isColumnVisible("thumbnail") || !Global.enableThumbnails()) {
+ QFontMetrics f = QApplication.fontMetrics();
+ verticalHeader().setDefaultSectionSize(f.height());
+ height = fontHeight;
+ } else {
+ if (Global.getListView() == Global.View_List_Wide) {
+ verticalHeader().setDefaultSectionSize(Global.smallThumbnailSize.height());
+ height = Global.smallThumbnailSize.height();
+ } else {
+ verticalHeader().setDefaultSectionSize(Global.largeThumbnailSize.height());
+ height = Global.largeThumbnailSize.height();
+ }
+ }
+ for (int i=0; i<runner.getNoteTableModel().rowCount(); i++) {
+ setRowHeight(i, height);
+ }
+ }
+
+ public void insertRow(Note tempNote, NoteMetadata meta, boolean newNote, int row) {
+ if (newNote)
+ proxyModel.addGuid(tempNote.getGuid(), meta);
+ if (row > runner.getNoteTableModel().rowCount())
+ runner.getNoteTableModel().insertRow(0);
+
+ if (row < 0) {
+ row = runner.getNoteTableModel().rowCount();
+ runner.getNoteTableModel().insertRow(row);
+ }
+ if (newNote) {
+ resizeRowHeights();
+ }
+ }
+ protected boolean filterAcceptsRow(int sourceRow, QModelIndex sourceParent) {
+ return true;
+ }
+
+ public void setAddAction(QAction a) {
+ addAction = a;
+ }
+
+ public void setMergeNotesAction(QAction a) {
+ mergeNotesAction = a;
+ }
+
+ public void setCopyAsUrlAction(QAction a) {
+ copyAsUrlAction = a;
+ }
+
+ public void setNoteHistoryAction(QAction a) {
+ noteHistoryAction = a;
+ }
+
+ public void setDeleteAction(QAction d) {
+ deleteAction = d;
+ }
+
+ public void setRestoreAction(QAction r) {
+ restoreAction = r;
+ }
+ public void setNoteDuplicateAction(QAction d) {
+ duplicateAction = d;
+ }
+
+ // ICHANGED
+ public void setOpenNewTabAction(QAction t) {
+ openNewTabAction = t;
+ }
+
+ // ICHANGED
+ public void setAddNoteNewTabAction(QAction t) {
+ addNoteNewTabAction = t;
+ }
+
+ @Override
+ public void keyPressEvent(QKeyEvent e) {
+ if (e.matches(StandardKey.MoveToStartOfDocument)) {
+ if (runner.getNoteTableModel().rowCount() > 0) {
+ clearSelection();
+ selectRow(0);
+ }
+ }
+ if (e.matches(StandardKey.MoveToEndOfDocument)) {
+ if (runner.getNoteTableModel().rowCount() > 0) {
+ clearSelection();
+ selectRow(model().rowCount()-1);
+ }
+ }
+ super.keyPressEvent(e);
+ }
+
+ @Override
+ public void contextMenuEvent(QContextMenuEvent event) {
+ // ICHANGED QMenu から NoteTableContextMenu へ
+ NoteTableContextMenu menu = new NoteTableContextMenu(this);
+
+ // ICHANGED
+ menu.addAction(openNewTabAction);
+
+ // ICHANGED
+ menu.addSeparator();
+ if (Global.showDeleted) {
+ menu.addAction(restoreAction);
+ } else {
+ menu.addAction(addAction);
+ menu.addAction(addNoteNewTabAction);
+ }
+ menu.addSeparator();
+
+ menu.addAction(deleteAction);
+ menu.addSeparator();
+ menu.addAction(duplicateAction);
+ menu.addAction(copyAsUrlAction);
+ menu.addSeparator();
+ menu.addAction(noteHistoryAction);
+ menu.addAction(mergeNotesAction);
+
+ // ICHANGED QMenu から NoteTableContextMenu へ
+ NoteTableContextMenu titleColorMenu = new NoteTableContextMenu(this);
+
+ titleColorMenu.setTitle(tr("Title Color"));
+ menu.addMenu(titleColorMenu);
+ noteTitleColorWhite = new QAction(titleColorMenu);
+ noteTitleColorRed = new QAction(titleColorMenu);
+ noteTitleColorBlue = new QAction(titleColorMenu);
+ noteTitleColorGreen = new QAction(titleColorMenu);
+ noteTitleColorYellow = new QAction(titleColorMenu);
+ noteTitleColorBlack = new QAction(titleColorMenu);
+ noteTitleColorGray = new QAction(titleColorMenu);
+ noteTitleColorCyan = new QAction(titleColorMenu);
+ noteTitleColorMagenta = new QAction(titleColorMenu);
+
+ notePinned = new QAction(titleColorMenu);
+ menu.addAction(notePinned);
+
+ noteTitleColorWhite.setText(tr("White"));
+ noteTitleColorRed.setText(tr("Red"));
+ noteTitleColorBlue.setText(tr("Blue"));
+ noteTitleColorGreen.setText(tr("Green"));
+ noteTitleColorYellow.setText(tr("Yellow"));
+ noteTitleColorBlack.setText(tr("Black"));
+ noteTitleColorGray.setText(tr("Gray"));
+ noteTitleColorCyan.setText(tr("Cyan"));
+ noteTitleColorMagenta.setText(tr("Magenta"));
+ notePinned.setText(tr("Pin/Unpin"));
+
+ titleColorMenu.addAction(noteTitleColorWhite);
+ titleColorMenu.addAction(noteTitleColorRed);
+ titleColorMenu.addAction(noteTitleColorBlue);
+ titleColorMenu.addAction(noteTitleColorGreen);
+ titleColorMenu.addAction(noteTitleColorYellow);
+ titleColorMenu.addAction(noteTitleColorBlack);
+ titleColorMenu.addAction(noteTitleColorGray);
+ titleColorMenu.addAction(noteTitleColorCyan);
+ titleColorMenu.addAction(noteTitleColorMagenta);
+
+ noteTitleColorWhite.triggered.connect(this, "titleColorWhite()");
+
+ noteTitleColorWhite.triggered.connect(this, "titleColorWhite()");
+ noteTitleColorRed.triggered.connect(this, "titleColorRed()");
+ noteTitleColorBlue.triggered.connect(this, "titleColorBlue()");
+ noteTitleColorGreen.triggered.connect(this, "titleColorGreen()");
+ noteTitleColorYellow.triggered.connect(this, "titleColorYellow()");
+ noteTitleColorBlack.triggered.connect(this, "titleColorBlack()");
+ noteTitleColorGray.triggered.connect(this, "titleColorGray()");
+ noteTitleColorCyan.triggered.connect(this, "titleColorCyan()");
+ noteTitleColorMagenta.triggered.connect(this, "titleColorMagenta()");
+ notePinned.triggered.connect(this, "notePinned()");
+ menu.exec(event.globalPos());
+ }
+
+
+ @SuppressWarnings("unused")
+ private void titleColorWhite() {noteSignal.titleColorChanged.emit(QColor.white.rgb());}
+ @SuppressWarnings("unused")
+ private void titleColorRed() {noteSignal.titleColorChanged.emit(QColor.red.rgb());}
+ @SuppressWarnings("unused")
+ private void titleColorBlue() {noteSignal.titleColorChanged.emit(QColor.blue.rgb());}
+ @SuppressWarnings("unused")
+ private void titleColorGreen() {noteSignal.titleColorChanged.emit(QColor.green.rgb());}
+ @SuppressWarnings("unused")
+ private void titleColorYellow(){noteSignal.titleColorChanged.emit(QColor.yellow.rgb());}
+ @SuppressWarnings("unused")
+ private void titleColorBlack() {noteSignal.titleColorChanged.emit(QColor.black.rgb());}
+ @SuppressWarnings("unused")
+ private void titleColorGray() {noteSignal.titleColorChanged.emit(QColor.gray.rgb());}
+ @SuppressWarnings("unused")
+ private void titleColorCyan() {noteSignal.titleColorChanged.emit(QColor.cyan.rgb());}
+ @SuppressWarnings("unused")
+ private void titleColorMagenta() {noteSignal.titleColorChanged.emit(QColor.magenta.rgb());}
+ @SuppressWarnings("unused")
+ private void notePinned() {noteSignal.notePinned.emit();}
+
+
+ @Override
+ public void dragEnterEvent(QDragEnterEvent event) {
+ StringBuffer guid = new StringBuffer(1000);
+
+ showColumn(Global.noteTableGuidPosition);
+ List<QModelIndex> selections = selectionModel().selectedRows();
+ hideColumn(Global.noteTableGuidPosition);
+
+ if (selections.size() > 0) {
+ QModelIndex index;
+ for (int i=0; i<selections.size(); i++) {
+ int row = selections.get(i).row();
+ index = proxyModel.index(row, Global.noteTableGuidPosition);
+ SortedMap<Integer, Object> ix = proxyModel.itemData(index);
+ guid.append((String)ix.values().toArray()[0]);
+ guid.append(" ");
+ }
+ }
+ event.mimeData().setData("application/x-nevernote-note", new QByteArray(guid.toString()));
+ event.accept();
+
+ }
+
+ @Override
+ public void dropEvent(QDropEvent event) {
+ if (event.source() == this)
+ event.ignore();
+ }
+
+ // Return a column width
+ public int getColumnWidth(int col) {
+ return columnWidth(col);
+ }
+
+ public void toggleSubjectDate(Boolean toggle) {
+ Global.saveColumnVisible("dateSubject", toggle);
+ setColumnHidden(Global.noteTableSubjectDatePosition, !toggle);
+ }
+
+ public void toggleChangedDate(Boolean toggle) {
+ Global.saveColumnVisible("dateChanged", toggle);
+ setColumnHidden(Global.noteTableChangedPosition, !toggle);
+ }
+
+
+ public void toggleCreationDate(Boolean toggle) {
+ Global.saveColumnVisible("dateCreated", toggle);
+ setColumnHidden(Global.noteTableCreationPosition, !toggle);
+ }
+
+ public void toggleSourceUrl(Boolean toggle) {
+ Global.saveColumnVisible("sourceUrl", toggle);
+ setColumnHidden(Global.noteTableSourceUrlPosition, !toggle);
+ }
+
+ public void toggleAuthor(Boolean toggle) {
+ Global.saveColumnVisible("author", toggle);
+ setColumnHidden(Global.noteTableAuthorPosition, !toggle);
+ }
+
+ public void toggleNotebook(Boolean toggle) {
+ Global.saveColumnVisible("notebook", toggle);
+ setColumnHidden(Global.noteTableNotebookPosition, !toggle);
+ }
+
+ public void toggleTitle(Boolean toggle) {
+ Global.saveColumnVisible("title", toggle);
+ setColumnHidden(Global.noteTableTitlePosition, !toggle);
+ }
+
+ public void toggleTags(Boolean toggle) {
+ Global.saveColumnVisible("tags", toggle);
+ setColumnHidden(Global.noteTableTagPosition, !toggle);
+ }
+
+ public void toggleSynchronized(Boolean toggle) {
+ Global.saveColumnVisible("synchronized", toggle);
+ setColumnHidden(Global.noteTableSynchronizedPosition, !toggle);
+ }
+ public void togglePinned(Boolean toggle) {
+ Global.saveColumnVisible("pinned", toggle);
+ setColumnHidden(Global.noteTablePinnedPosition, !toggle);
+ }
+ public void toggleGuid(Boolean toggle) {
+ Global.saveColumnVisible("guid", toggle);
+ setColumnHidden(Global.noteTableGuidPosition, !toggle);
+ }
+ public void toggleThumbnail(Boolean toggle) {
+ Global.saveColumnVisible("thumbnail", toggle);
+ int size;
+ if (!toggle) {
+ QFontMetrics f = QApplication.fontMetrics();
+ size = f.height();
+ verticalHeader().setDefaultSectionSize(f.height());
+ } else
+ size = Global.smallThumbnailSize.height();
+ for (int i=0; i<runner.getNoteTableModel().rowCount(); i++) {
+ setRowHeight(i, size);
+ }
+
+ setColumnHidden(Global.noteTableThumbnailPosition, !toggle);
+ }
+
+ // ICHANGED
+ public void restoreSelectedNoteInfo(){
+ parent.restoreSelectedNoteInfo();
+ }
+
+}
event.mimeData().setData("application/x-nevernote-trash", new QByteArray(currentItem().text(1)));\r
event.accept();\r
}\r
+ \r
+ // ICHANGED\r
+ public QTreeWidgetItem getTrashItem() {\r
+ return trashItem;\r
+ }\r
}\r
--- /dev/null
+package cx.fbn.nevernote.neighbornote;
+
+import com.trolltech.qt.gui.QApplication;
+
+public class ClipBoardObserver {
+ private String SourceGuid;
+ private boolean internalFlg; // アプリケーション内コピーかどうかのフラグ
+
+ public ClipBoardObserver() {
+ SourceGuid = new String("");
+ internalFlg = false;
+ QApplication.clipboard().dataChanged.connect(this, "clipboardDataChanged()");
+ }
+
+ public void setCopySourceGuid(String guid, String text) {
+ if (!text.equals("")) {
+ SourceGuid = guid;
+ internalFlg = true;
+ }
+ }
+
+ public String getSourceGuid() {
+ if (SourceGuid.equals("")) {
+ return null;
+ }
+ return SourceGuid;
+ }
+
+ @SuppressWarnings("unused")
+ private void clipboardDataChanged() {
+ // 外部アプリケーションでコピー・カットが行われた時のための対処
+ if (!internalFlg) {
+ SourceGuid = "";
+ }
+ internalFlg = false;
+ }
+}
import cx.fbn.nevernote.utilities.ApplicationLogger;
public class OAuthWindow extends QDialog {
- private final static String consumerKey = "baumgarr";
- private final static String consumerSecret = "60d4cdedb074b0ac";
+ // ICHANGED 自分のキーに変更
+ private final static String consumerKey = "kimaira792";
+ private final static String consumerSecret = "c66706d41e06bf22";
+
public String response;
private final String temporaryCredUrl;
// Build the window
- setWindowTitle(tr("Please Grant Nixnote Access"));
+ setWindowTitle(tr("Please Grant NeighborNote Access"));
setWindowIcon(new QIcon(iconPath+"icons/password.png"));
grid = new QGridLayout();
setLayout(grid);
private InkImagesTable inkImagesTable;
private SyncTable syncTable;
private SystemIconTable systemIconTable;
+ // ICHANGED
+ private HistoryTable historyTable;
+ private ExcludedTable excludedTable;
+ private StaredTable staredTable;
+
private final ApplicationLogger logger;
private Connection conn;
private Connection indexConn;
private Connection resourceConn;
+ // ICHANGED
+ private Connection behaviorConn;
+
int throttle;
int id;
-
- public DatabaseConnection(ApplicationLogger l, String url, String iurl, String rurl, String userid, String password, String cypherPassword, int throttle) {
+ // ICHANGED String burlを追加
+ public DatabaseConnection(ApplicationLogger l, String url, String iurl, String rurl, String burl, String userid, String password, String cypherPassword, int throttle) {
logger = l;
this.throttle = throttle;
- dbSetup(url, iurl, rurl, userid, password, cypherPassword);
+ // ICHANGED burlを追加
+ dbSetup(url, iurl, rurl, burl, userid, password, cypherPassword);
}
private void setupTables() {
sharedNotebookTable = new SharedNotebookTable(logger, this);
systemIconTable = new SystemIconTable(logger, this);
inkImagesTable = new InkImagesTable(logger, this);
+ // ICHANGED
+ historyTable = new HistoryTable(logger, this);
+ excludedTable = new ExcludedTable(logger, this);
+ staredTable = new StaredTable(logger, this);
+
}
}
// Initialize the database connection
- public void dbSetup(String url,String indexUrl, String resourceUrl, String userid, String userPassword, String cypherPassword) {
+ // ICHANGED String behaviorUrlを追加
+ public void dbSetup(String url,String indexUrl, String resourceUrl, String behaviorUrl, String userid, String userPassword, String cypherPassword) {
logger.log(logger.HIGH, "Entering DatabaseConnection.dbSetup " +id);
boolean indexDbExists = f.exists();
f = Global.getFileManager().getDbDirFile(Global.resourceDatabaseName + ".h2.db");
boolean resourceDbExists = f.exists();
+ // ICHANGED
+ f = Global.getFileManager().getDbDirFile(Global.behaviorDatabaseName + ".h2.db");
+ boolean behaviorDbExists = f.exists();
logger.log(logger.HIGH, "Entering RDatabaseConnection.dbSetup");
}
indexConn = DriverManager.getConnection(indexUrl,userid,passwordString);
resourceConn = DriverManager.getConnection(resourceUrl,userid,passwordString);
+ // ICHANGED
+ behaviorConn = DriverManager.getConnection(behaviorUrl, userid, passwordString);
+
// conn = DriverManager.getConnection(url+";AUTO_SERVER=TRUE",userid,passwordString);
} catch (SQLException e) {
e.printStackTrace();
executeSql("Update note set indexneeded='true'");
}
+ // ICHANGED
+ // 操作履歴テーブルと除外ノートテーブルとスター付きノートテーブルを作る
+ if (!behaviorDbExists) {
+ createHistoryTables();
+ createExcludedTables();
+ createStaredTables();
+ }
+
// If we encrypted/decrypted it the last time, we need to reconnect the tables.
// if (Global.relinkTables) {
// NSqlQuery query = new NSqlQuery(conn);
noteTable.noteResourceTable.createTable();
}
+ // ICHANGED
+ public void createHistoryTables() {
+ historyTable.createTable();
+ }
+
+ // ICHANGED
+ public void createExcludedTables() {
+ excludedTable.createTable();
+ }
+
+ // ICHANGED
+ public void createStaredTables() {
+ staredTable.createTable();
+ }
+
public Connection getConnection() {
return conn;
}
return resourceConn;
}
+ // ICHANGED
+ public Connection getBehaviorConnection() {
+ return behaviorConn;
+ }
+
//***************************************************************
//* Table get methods
//***************************************************************
public InkImagesTable getInkImagesTable() {
return inkImagesTable;
}
+
+ // ICHANGED
+ public HistoryTable getHistoryTable() {
+ return historyTable;
+ }
+
+ // ICHANGED
+ public ExcludedTable getExcludedTable() {
+ return excludedTable;
+ }
+
+ // ICHANGED
+ public StaredTable getStaredTable() {
+ return staredTable;
+ }
//****************************************************************
//* Begin/End transactions
--- /dev/null
+// ICHANGED
+package cx.fbn.nevernote.sql;
+
+import cx.fbn.nevernote.sql.driver.NSqlQuery;
+import cx.fbn.nevernote.utilities.ApplicationLogger;
+
+public class ExcludedTable {
+ private final ApplicationLogger logger;
+ private final DatabaseConnection db;
+
+ // コンストラクタ
+ public ExcludedTable(ApplicationLogger l, DatabaseConnection d) {
+ logger = l;
+ db = d;
+ }
+
+ // テーブル作成
+ public void createTable() {
+ NSqlQuery query = new NSqlQuery(db.getBehaviorConnection());
+ logger.log(logger.HIGH, "ExcludedNotesテーブルを作成しています...");
+ if (!query.exec("Create table ExcludedNotes (id integer primary key auto_increment, guid1 varchar, guid2 varchar)"))
+ logger.log(logger.HIGH, "ExcludedNotesテーブル作成失敗!!!");
+ }
+
+ // テーブルをドロップ
+ public void dropTable() {
+ NSqlQuery query = new NSqlQuery(db.getBehaviorConnection());
+ query.exec("Drop table ExcludedNotes");
+ }
+
+ // ExcludedNotesテーブルにアイテムを1つ追加
+ public void addExclusion(String guid1, String guid2) {
+ NSqlQuery query = new NSqlQuery(db.getBehaviorConnection());
+ query.prepare("Insert Into ExcludedNotes (guid1, guid2) Values(:guid1, :guid2)");
+ query.bindValue(":guid1", guid1);
+ query.bindValue(":guid2", guid2);
+ if (!query.exec()) {
+ logger.log(logger.MEDIUM, "ExcludedNotesテーブルへのアイテム追加に失敗");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ }
+
+ // masterGuidとchildGuidをマージ
+ public void mergeHistoryGuid(String masterGuid, String childGuid) {
+ NSqlQuery excludedNotesQuery = new NSqlQuery(db.getBehaviorConnection());
+ boolean check = false;
+
+ // マージ後に重複してしまうデータを先に削除
+ excludedNotesQuery.prepare("Delete from ExcludedNotes where (guid1=:oldGuid1 and guid2=:newGuid1) or (guid1=:newGuid2 and guid2=:oldGuid2)");
+ excludedNotesQuery.bindValue(":oldGuid1", masterGuid);
+ excludedNotesQuery.bindValue(":newGuid1", childGuid);
+ excludedNotesQuery.bindValue(":oldGuid2", masterGuid);
+ excludedNotesQuery.bindValue(":newGuid2", childGuid);
+ check = excludedNotesQuery.exec();
+ if(!check){
+ logger.log(logger.MEDIUM, "excludedNotesテーブルの重複削除で失敗");
+ logger.log(logger.MEDIUM, excludedNotesQuery.lastError());
+ }
+
+ updateExcludedNoteGuid(masterGuid, childGuid);
+ }
+
+ // ExcludedNotesテーブルのGuidを更新
+ public void updateExcludedNoteGuid(String newGuid, String oldGuid){
+ NSqlQuery excludedNotesQuery = new NSqlQuery(db.getBehaviorConnection());
+ boolean check = false;
+
+ excludedNotesQuery.prepare("Update ExcludedNotes set guid1=:newGuid where guid1=:oldGuid");
+ excludedNotesQuery.bindValue(":newGuid", newGuid);
+ excludedNotesQuery.bindValue(":oldGuid", oldGuid);
+ check = excludedNotesQuery.exec();
+ if (!check) {
+ logger.log(logger.MEDIUM, "ExcludedNotesテーブルのguid1のところでguid更新失敗");
+ logger.log(logger.MEDIUM, excludedNotesQuery.lastError());
+ }
+ excludedNotesQuery.prepare("Update ExcludedNotes set guid2=:newGuid where guid2=:oldGuid");
+ excludedNotesQuery.bindValue(":newGuid", newGuid);
+ excludedNotesQuery.bindValue(":oldGuid", oldGuid);
+ check = excludedNotesQuery.exec();
+ if (!check) {
+ logger.log(logger.MEDIUM, "ExcludedNotesテーブルのguid2のところでguid更新失敗");
+ logger.log(logger.MEDIUM, excludedNotesQuery.lastError());
+ }
+ }
+
+ // ExcludedNotesテーブルに引数guidのノートが存在するか
+ public boolean existNote(String guid1, String guid2) {
+ NSqlQuery excludedNotesQuery = new NSqlQuery(db.getBehaviorConnection());
+
+ // 2つの引数guidを含むアイテムの存在確認
+ excludedNotesQuery.prepare("Select * from ExcludedNotes where Exists(Select * from ExcludedNotes where (guid1=:guid1_1 and guid2=:guid2_1) or (guid1=:guid2_2 and guid2=:guid1_2))");
+ excludedNotesQuery.bindValue(":guid1_1", guid1);
+ excludedNotesQuery.bindValue(":guid2_1", guid2);
+ excludedNotesQuery.bindValue(":guid1_2", guid1);
+ excludedNotesQuery.bindValue(":guid2_2", guid2);
+
+ if (!excludedNotesQuery.exec()) {
+ logger.log(logger.MEDIUM, "ExcludedNotesテーブルからguid1=" + guid1 + "かつguid2=" + guid2 + "(またはその逆)のアイテムの存在確認失敗");
+ logger.log(logger.MEDIUM, excludedNotesQuery.lastError());
+ }
+
+ if (excludedNotesQuery.next()) {
+ return true;
+ }
+
+ return false;
+ }
+
+ // oldGuidのノートの除外ノートをnewGuidのノートの除外ノートとして複製
+ public void duplicateExcludedNotes(String newGuid, String oldGuid) {
+ NSqlQuery excludedNotesQuery = new NSqlQuery(db.getBehaviorConnection());
+
+ // guid1 = oldGuidの除外ノートを取得
+ excludedNotesQuery.prepare("Select guid2 from ExcludedNotes where guid1=:oldGuid");
+ excludedNotesQuery.bindValue(":oldGuid", oldGuid);
+ if(!excludedNotesQuery.exec()){
+ logger.log(logger.MEDIUM, "ExcludedNotesテーブルからguid1=" + oldGuid + "のアイテム取得失敗");
+ logger.log(logger.MEDIUM, excludedNotesQuery.lastError());
+ }
+ // guid1 = newGuidの除外ノートとして複製
+ while(excludedNotesQuery.next()){
+ String guid2 = excludedNotesQuery.valueString(0);
+
+ addExclusion(newGuid, guid2);
+ }
+
+ // guid2 = oldGuidの除外ノートを取得
+ excludedNotesQuery.prepare("Select guid1 from ExcludedNotes where guid2=:oldGuid");
+ excludedNotesQuery.bindValue(":oldGuid", oldGuid);
+ if(!excludedNotesQuery.exec()){
+ logger.log(logger.MEDIUM, "ExcludedNotesテーブルからguid2=" + oldGuid + "のアイテム取得失敗");
+ logger.log(logger.MEDIUM, excludedNotesQuery.lastError());
+ }
+ // guid2 = newGuidの除外ノートとして複製
+ while(excludedNotesQuery.next()){
+ String guid1 = excludedNotesQuery.valueString(0);
+
+ addExclusion(guid1, newGuid);
+ }
+ }
+
+ // guidを含む列をExcludedNotesテーブルから削除
+ public void expungeExcludedNote(String guid) {
+ NSqlQuery query = new NSqlQuery(db.getBehaviorConnection());
+ boolean check;
+
+ query.prepare("Delete from ExcludedNotes where guid1=:guid1 or guid2=:guid2");
+ query.bindValue(":guid1", guid);
+ query.bindValue(":guid2", guid);
+
+ check = query.exec();
+ if(!check){
+ logger.log(logger.MEDIUM, "ExcludedNotesテーブルからguid=" + guid + "のデータ削除に失敗");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ }
+}
--- /dev/null
+// ICHANGED
+package cx.fbn.nevernote.sql;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import cx.fbn.nevernote.sql.driver.NSqlQuery;
+import cx.fbn.nevernote.utilities.ApplicationLogger;
+
+public class HistoryTable {
+ private final ApplicationLogger logger;
+ private final DatabaseConnection db;
+
+ // コンストラクタ
+ public HistoryTable(ApplicationLogger l, DatabaseConnection d) {
+ logger = l;
+ db = d;
+ }
+
+ // テーブル作成
+ public void createTable() {
+ NSqlQuery query = new NSqlQuery(db.getBehaviorConnection());
+ logger.log(logger.HIGH, "Historyテーブルを作成しています...");
+ if (!query
+ .exec("Create table History (id integer primary key auto_increment, behaviorType varchar,"
+ + "guid1 varchar, guid2 varchar)"))
+ logger.log(logger.HIGH, "Historyテーブル作成失敗!!!");
+ }
+
+ // テーブルをドロップ
+ public void dropTable() {
+ NSqlQuery query = new NSqlQuery(db.getBehaviorConnection());
+ query.exec("Drop table History");
+ }
+
+ // Historyテーブルにアイテムを1つ追加
+ public void addHistory(String behaviorType, String guid1, String guid2) {
+ NSqlQuery query = new NSqlQuery(db.getBehaviorConnection());
+ boolean excludedCheck = false;
+
+ if (behaviorType == null) {
+ return;
+ }
+ if (guid1 == null || guid1.equals("")) {
+ return;
+ }
+ if (guid2 == null || guid2.equals("")) {
+ return;
+ }
+ if (guid1.equals(guid2)) {
+ return;
+ }
+
+ // 除外ノートに指定されていないかチェックする
+ excludedCheck = db.getExcludedTable().existNote(guid1, guid2);
+
+ if (!excludedCheck) {
+ query.prepare("Insert Into History (behaviorType, guid1, guid2) Values(:behaviorType, :guid1, :guid2)");
+ query.bindValue(":behaviorType", behaviorType);
+ query.bindValue(":guid1", guid1);
+ query.bindValue(":guid2", guid2);
+ if (!query.exec()) {
+ logger.log(logger.MEDIUM, "Historyテーブルへのアイテム追加に失敗");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ }
+ }
+
+ // masterGuidとchildGuidをマージ
+ public void mergeHistoryGuid(String masterGuid, String childGuid) {
+ NSqlQuery histQuery = new NSqlQuery(db.getBehaviorConnection());
+ boolean check = false;
+
+ // マージ後に重複してしまうデータを先に削除
+ histQuery.prepare("Delete from history where (guid1=:oldGuid1 and guid2=:newGuid1) or (guid1=:newGuid2 and guid2=:oldGuid2)");
+ histQuery.bindValue(":oldGuid1", masterGuid);
+ histQuery.bindValue(":newGuid1", childGuid);
+ histQuery.bindValue(":oldGuid2", masterGuid);
+ histQuery.bindValue(":newGuid2", childGuid);
+ check = histQuery.exec();
+ if(!check){
+ logger.log(logger.MEDIUM, "historyテーブルの重複削除で失敗");
+ logger.log(logger.MEDIUM, histQuery.lastError());
+ }
+
+ updateHistoryGuid(masterGuid, childGuid);
+ }
+
+ // HistoryテーブルのGuidを更新
+ public void updateHistoryGuid(String newGuid, String oldGuid){
+ NSqlQuery histQuery = new NSqlQuery(db.getBehaviorConnection());
+ boolean check = false;
+
+ histQuery.prepare("Update history set guid1=:newGuid where guid1=:oldGuid");
+ histQuery.bindValue(":newGuid", newGuid);
+ histQuery.bindValue(":oldGuid", oldGuid);
+ check = histQuery.exec();
+ if (!check) {
+ logger.log(logger.MEDIUM, "historyテーブルのguid1のところでguid更新失敗");
+ logger.log(logger.MEDIUM, histQuery.lastError());
+ }
+ histQuery.prepare("Update history set guid2=:newGuid where guid2=:oldGuid");
+ histQuery.bindValue(":newGuid", newGuid);
+ histQuery.bindValue(":oldGuid", oldGuid);
+ check = histQuery.exec();
+ if (!check) {
+ logger.log(logger.MEDIUM, "historyテーブルのguid2のところでguid更新失敗");
+ logger.log(logger.MEDIUM, histQuery.lastError());
+ }
+ }
+
+ // Historyテーブルから引数ノートと関連のあるノートのguidと回数をゲット
+ public HashMap<String, Integer> getBehaviorHistory(String behaviorType, String guid) {
+ NSqlQuery query = new NSqlQuery(db.getBehaviorConnection());
+ HashMap<String, Integer> behaviorHist = new HashMap<String, Integer>();
+
+ // guid1=guidの履歴一覧を取得
+ query.prepare("Select guid2 from History where behaviorType=:behaviorType and guid1=:guid1");
+ query.bindValue(":behaviorType", behaviorType);
+ query.bindValue(":guid1", guid);
+ if (!query.exec()) {
+ logger.log(logger.MEDIUM,
+ "HistoryテーブルからbehaviorType=" + behaviorType + "かつguid1=" + guid + "のアイテム取得失敗");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ // HashMapに記録
+ while (query.next()) {
+ // すでにHashMapに登録されていたら、回数を+1
+ String key = query.valueString(0);
+ if (behaviorHist.containsKey(key)) {
+ behaviorHist.put(key, behaviorHist.get(key) + 1);
+ } else { // そうでないなら新規登録
+ behaviorHist.put(key, 1);
+ }
+ }
+
+ // guid2=guidの履歴一覧を取得
+ query.prepare("Select guid1 from History where behaviorType=:behaviorType and guid2=:guid2");
+ query.bindValue(":behaviorType", behaviorType);
+ query.bindValue(":guid2", guid);
+ if (!query.exec()) {
+ logger.log(logger.MEDIUM,
+ "HistoryテーブルからbehaviorType=" + behaviorType + "かつguid2=" + guid + "のアイテム取得失敗");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ // HashMapに記録
+ while (query.next()) {
+ // すでにHashMapに登録されていたら、回数を+1
+ String key = query.valueString(0);
+ if (behaviorHist.containsKey(key)) {
+ behaviorHist.put(key, behaviorHist.get(key) + 1);
+ } else { // そうでないなら新規登録
+ behaviorHist.put(key, 1);
+ }
+ }
+ return behaviorHist;
+ }
+
+ // oldGuidのノートの操作履歴をnewGuidのノートの操作履歴として複製
+ public void duplicateHistory(String newGuid, String oldGuid) {
+ NSqlQuery histQuery = new NSqlQuery(db.getBehaviorConnection());
+
+ // guid1 = oldGuidの履歴一覧を取得
+ histQuery.prepare("Select behaviorType, guid2 from History where guid1=:oldGuid");
+ histQuery.bindValue(":oldGuid", oldGuid);
+ if(!histQuery.exec()){
+ logger.log(logger.MEDIUM, "Historyテーブルからguid1=" + oldGuid + "のアイテム取得失敗");
+ logger.log(logger.MEDIUM, histQuery.lastError());
+ }
+ // guid1 = newGuidの履歴として複製
+ while(histQuery.next()){
+ String behaviorType = histQuery.valueString(0);
+ String guid2 = histQuery.valueString(1);
+
+ addHistory(behaviorType, newGuid, guid2);
+ }
+
+ // guid2 = oldGuidの履歴一覧を取得
+ histQuery.prepare("Select behaviorType, guid1 from History where guid2=:oldGuid");
+ histQuery.bindValue(":oldGuid", oldGuid);
+ if(!histQuery.exec()){
+ logger.log(logger.MEDIUM, "Historyテーブルからguid2=" + oldGuid + "のアイテム取得失敗");
+ logger.log(logger.MEDIUM, histQuery.lastError());
+ }
+ // guid2 = newGuidの履歴として複製
+ while(histQuery.next()){
+ String behaviorType = histQuery.valueString(0);
+ String guid1 = histQuery.valueString(1);
+
+ addHistory(behaviorType, guid1, newGuid);
+ }
+ }
+
+ // guidを含む列をHistoryテーブルから削除
+ public void expungeHistory(String guid) {
+ NSqlQuery query = new NSqlQuery(db.getBehaviorConnection());
+ boolean check;
+
+ query.prepare("Delete from History where guid1=:guid1 or guid2=:guid2");
+ query.bindValue(":guid1", guid);
+ query.bindValue(":guid2", guid);
+
+ check = query.exec();
+ if(!check){
+ logger.log(logger.MEDIUM, "historyテーブルからguid=" + guid + "のデータ削除に失敗");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ }
+
+ // guid1とguid2を指定してHistoryテーブルから削除
+ public void expungeHistory(String guid1, String guid2) {
+ NSqlQuery query = new NSqlQuery(db.getBehaviorConnection());
+ boolean check;
+
+ query.prepare("Delete from History where guid1=:guid1 and guid2=:guid2");
+ query.bindValue(":guid1", guid1);
+ query.bindValue(":guid2", guid2);
+
+ check = query.exec();
+ if(!check){
+ logger.log(logger.MEDIUM, "historyテーブルからguid1=" + guid1 + "かつguid2=" + guid2 + "のデータ削除に失敗");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+
+ // guid1とguid2が逆のパターンも削除
+ query.prepare("Delete from History where guid1=:guid1 and guid2=:guid2");
+ query.bindValue(":guid1", guid2);
+ query.bindValue(":guid2", guid1);
+
+ check = query.exec();
+ if(!check){
+ logger.log(logger.MEDIUM, "historyテーブルからguid1=" + guid2 + "かつguid2=" + guid1 + "のデータ削除に失敗");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ }
+
+ // 同じタグが付けられたノート間の履歴を登録
+ public void addSameTagHistory(String noteGuid, String tagGuid) {
+ if (noteGuid == null || noteGuid.equals("")) {
+ return;
+ }
+ if (tagGuid == null || tagGuid.equals("")) {
+ return;
+ }
+
+ // そのタグが新しいタグでないなら終了
+ List<String> prevTags = new ArrayList<String>(db.getNoteTable().noteTagsTable.getNoteTags(noteGuid));
+ for (int i = 0; i < prevTags.size(); i++) {
+ System.out.println(prevTags.get(i));
+ if (tagGuid.equals(prevTags.get(i))) {
+ return;
+ }
+ }
+
+ // すでにそのタグが付いているノートを取得
+ List<String> sameTagNoteGuids = new ArrayList<String>(db.getNoteTable().noteTagsTable.getTagNotes(tagGuid));
+
+ for (int i = 0; i < sameTagNoteGuids.size(); i++) {
+ String guid = sameTagNoteGuids.get(i);
+ addHistory("sameTag", noteGuid, guid);
+ }
+ }
+
+ // 同じノートブックに入れられたノート間の履歴を登録
+ public void addSameNotebookHistory(String noteGuid, String notebookGuid) {
+ if (noteGuid == null || noteGuid.equals("")) {
+ return;
+ }
+ if (notebookGuid == null || notebookGuid.equals("")) {
+ return;
+ }
+
+ // すでにそのノートブックに属しているノートを取得
+ List<String> sameNotebookNoteGuids = new ArrayList<String>(db.getNoteTable().getNotesByNotebook(notebookGuid));
+
+ for (int i = 0; i < sameNotebookNoteGuids.size(); i++) {
+ String guid = sameNotebookNoteGuids.get(i);
+ if (!noteGuid.equals(guid)) {
+ addHistory("sameNotebook", noteGuid, guid);
+ }
+ }
+ }
+}
-/*\r
- * This file is part of NixNote \r
- * Copyright 2009 Randy Baumgarte\r
- * \r
- * This file may be licensed under the terms of of the\r
- * GNU General Public License Version 2 (the ``GPL'').\r
- *\r
- * Software distributed under the License is distributed\r
- * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either\r
- * express or implied. See the GPL for the specific language\r
- * governing rights and limitations.\r
- *\r
- * You should have received a copy of the GPL along with this\r
- * program. If not, go to http://www.gnu.org/licenses/gpl.html\r
- * or write to the Free Software Foundation, Inc.,\r
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
- *\r
-*/\r
-\r
-\r
-package cx.fbn.nevernote.sql;\r
-\r
-import java.text.DateFormat;\r
-import java.text.ParseException;\r
-import java.text.SimpleDateFormat;\r
-import java.util.ArrayList;\r
-import java.util.HashMap;\r
-import java.util.List;\r
-\r
-import org.apache.commons.lang3.StringEscapeUtils;\r
-\r
-import com.evernote.edam.type.Note;\r
-import com.evernote.edam.type.NoteAttributes;\r
-import com.evernote.edam.type.Resource;\r
-import com.evernote.edam.type.Tag;\r
-import com.trolltech.qt.core.QByteArray;\r
-import com.trolltech.qt.core.QDateTime;\r
-import com.trolltech.qt.core.QTextCodec;\r
-import com.trolltech.qt.gui.QPixmap;\r
-\r
-import cx.fbn.nevernote.Global;\r
-import cx.fbn.nevernote.evernote.EnmlConverter;\r
-import cx.fbn.nevernote.evernote.NoteMetadata;\r
-import cx.fbn.nevernote.sql.driver.NSqlQuery;\r
-import cx.fbn.nevernote.utilities.ApplicationLogger;\r
-import cx.fbn.nevernote.utilities.Pair;\r
-\r
-public class NoteTable {\r
- private final ApplicationLogger logger;\r
- public final NoteTagsTable noteTagsTable;\r
- public NoteResourceTable noteResourceTable;\r
- private final DatabaseConnection db;\r
- int id;\r
-\r
- // Prepared Queries to improve speed\r
- private NSqlQuery getQueryWithContent;\r
- private NSqlQuery getQueryWithoutContent;\r
- private NSqlQuery getAllQueryWithoutContent;\r
- \r
- // Constructor\r
- public NoteTable(ApplicationLogger l, DatabaseConnection d) {\r
- logger = l;\r
- db = d;\r
- id = 0;\r
- noteResourceTable = new NoteResourceTable(logger, db);\r
- noteTagsTable = new NoteTagsTable(logger, db);\r
- getQueryWithContent = null;\r
- getQueryWithoutContent = null;\r
- }\r
- // Create the table\r
- public void createTable() {\r
- //getQueryWithContent = new NSqlQuery(db.getConnection());\r
- //getQueryWithoutContent = new NSqlQuery(db.getConnection());\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- logger.log(logger.HIGH, "Creating table Note...");\r
- if (!query.exec("Create table Note (guid varchar primary key, " +\r
- "updateSequenceNumber integer, title varchar, content varchar, contentHash varchar, "+\r
- "contentLength integer, created timestamp, updated timestamp, deleted timestamp, " \r
- +"active integer, notebookGuid varchar, attributeSubjectDate timestamp, "+\r
- "attributeLatitude double, attributeLongitude double, attributeAltitude double,"+\r
- "attributeAuthor varchar, attributeSource varchar, attributeSourceUrl varchar, "+\r
- "attributeSourceApplication varchar, indexNeeded boolean, isExpunged boolean, " +\r
- "isDirty boolean)")) \r
- logger.log(logger.HIGH, "Table Note creation FAILED!!!"); \r
- if (!query.exec("CREATE INDEX unindexed_notess on note (indexneeded desc, guid);"))\r
- logger.log(logger.HIGH, "Note unindexed_notes index creation FAILED!!!");\r
- if (!query.exec("CREATE INDEX unsynchronized_notes on note (isDirty desc, guid);"))\r
- logger.log(logger.HIGH, "note unsynchronized_notes index creation FAILED!!!"); \r
- noteTagsTable.createTable();\r
-// noteResourceTable.createTable(); \r
- }\r
- // Drop the table\r
- public void dropTable() {\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- query.exec("Drop table Note");\r
- noteTagsTable.dropTable();\r
- noteResourceTable.dropTable();\r
- }\r
- // Save Note List from Evernote \r
- public void addNote(Note n, boolean isDirty) {\r
- logger.log(logger.EXTREME, "Inside addNote");\r
- if (n == null)\r
- return;\r
- \r
- SimpleDateFormat simple = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");\r
-\r
- NSqlQuery query = new NSqlQuery(db.getConnection()); \r
- query.prepare("Insert Into Note ("\r
- +"guid, updateSequenceNumber, title, content, "\r
- +"contentHash, contentLength, created, updated, deleted, active, notebookGuid, "\r
- +"attributeSubjectDate, attributeLatitude, attributeLongitude, attributeAltitude, "\r
- +"attributeAuthor, attributeSource, attributeSourceUrl, attributeSourceApplication, "\r
- +"indexNeeded, isExpunged, isDirty, titlecolor, thumbnailneeded" \r
- +") Values("\r
- +":guid, :updateSequenceNumber, :title, :content, "\r
- +":contentHash, :contentLength, :created, :updated, :deleted, :active, :notebookGuid, "\r
- +":attributeSubjectDate, :attributeLatitude, :attributeLongitude, :attributeAltitude, "\r
- +":attributeAuthor, :attributeSource, :attributeSourceUrl, :attributeSourceApplication, "\r
- +":indexNeeded, :isExpunged, :isDirty, -1, true) ");\r
-\r
- StringBuilder created = new StringBuilder(simple.format(n.getCreated())); \r
- StringBuilder updated = new StringBuilder(simple.format(n.getUpdated())); \r
- StringBuilder deleted = new StringBuilder(simple.format(n.getDeleted()));\r
-\r
- \r
- \r
- query.bindValue(":guid", n.getGuid());\r
- query.bindValue(":updateSequenceNumber", n.getUpdateSequenceNum());\r
- query.bindValue(":title", n.getTitle());\r
- if (isDirty) {\r
- EnmlConverter enml = new EnmlConverter(logger);\r
- query.bindValue(":content", enml.fixEnXMLCrap(enml.fixEnMediaCrap(n.getContent())));\r
- }\r
- else\r
- query.bindValue(":content", n.getContent());\r
- query.bindValue(":contentHash", n.getContentHash());\r
- query.bindValue(":contentLength", n.getContentLength());\r
- query.bindValue(":created", created.toString());\r
- query.bindValue(":updated", updated.toString());\r
- query.bindValue(":deleted", deleted.toString());\r
- query.bindValue(":active", n.isActive());\r
- query.bindValue(":notebookGuid", n.getNotebookGuid());\r
- \r
- if (n.getAttributes() != null) {\r
- created = new StringBuilder(simple.format(n.getAttributes().getSubjectDate()));\r
- query.bindValue(":attributeSubjectDate", created.toString());\r
- query.bindValue(":attributeLatitude", n.getAttributes().getLatitude());\r
- query.bindValue(":attributeLongitude", n.getAttributes().getLongitude());\r
- query.bindValue(":attributeAltitude", n.getAttributes().getAltitude());\r
- query.bindValue(":attributeAuthor", n.getAttributes().getAuthor());\r
- query.bindValue(":attributeSource", n.getAttributes().getSource());\r
- query.bindValue(":attributeSourceUrl", n.getAttributes().getSourceURL());\r
- query.bindValue(":attributeSourceApplication", n.getAttributes().getSourceApplication());\r
- } else {\r
- created = new StringBuilder(simple.format(n.getCreated())); \r
- query.bindValue(":attributeSubjectDate", created.toString());\r
- query.bindValue(":attributeLatitude", 0.0);\r
- query.bindValue(":attributeLongitude", 0.0);\r
- query.bindValue(":attributeAltitude", 0.0);\r
- query.bindValue(":attributeAuthor", "");\r
- query.bindValue(":attributeSource", "");\r
- query.bindValue(":attributeSourceUrl", "");\r
- query.bindValue(":attributeSourceApplication", "");\r
- }\r
- query.bindValue(":indexNeeded", true);\r
- query.bindValue(":isExpunged", false);\r
- query.bindValue(":isDirty", isDirty);\r
-\r
- \r
- if (!query.exec())\r
- logger.log(logger.MEDIUM, query.lastError());\r
- \r
- // Save the note tags\r
- if (n.getTagGuids() != null) {\r
- for (int i=0; i<n.getTagGuids().size(); i++) \r
+/*
+ * This file is part of NixNote
+ * Copyright 2009 Randy Baumgarte
+ *
+ * This file may be licensed under the terms of of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+*/
+
+
+package cx.fbn.nevernote.sql;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.commons.lang3.StringEscapeUtils;
+
+import com.evernote.edam.type.Note;
+import com.evernote.edam.type.NoteAttributes;
+import com.evernote.edam.type.Resource;
+import com.evernote.edam.type.Tag;
+import com.trolltech.qt.core.QByteArray;
+import com.trolltech.qt.core.QDateTime;
+import com.trolltech.qt.core.QTextCodec;
+import com.trolltech.qt.gui.QPixmap;
+
+import cx.fbn.nevernote.Global;
+import cx.fbn.nevernote.evernote.EnmlConverter;
+import cx.fbn.nevernote.evernote.NoteMetadata;
+import cx.fbn.nevernote.sql.driver.NSqlQuery;
+import cx.fbn.nevernote.utilities.ApplicationLogger;
+import cx.fbn.nevernote.utilities.Pair;
+
+public class NoteTable {
+ private final ApplicationLogger logger;
+ public final NoteTagsTable noteTagsTable;
+ public NoteResourceTable noteResourceTable;
+ private final DatabaseConnection db;
+ int id;
+
+ // Prepared Queries to improve speed
+ private NSqlQuery getQueryWithContent;
+ private NSqlQuery getQueryWithoutContent;
+ private NSqlQuery getAllQueryWithoutContent;
+
+ // Constructor
+ public NoteTable(ApplicationLogger l, DatabaseConnection d) {
+ logger = l;
+ db = d;
+ id = 0;
+ noteResourceTable = new NoteResourceTable(logger, db);
+ noteTagsTable = new NoteTagsTable(logger, db);
+ getQueryWithContent = null;
+ getQueryWithoutContent = null;
+ }
+ // Create the table
+ public void createTable() {
+ //getQueryWithContent = new NSqlQuery(db.getConnection());
+ //getQueryWithoutContent = new NSqlQuery(db.getConnection());
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ logger.log(logger.HIGH, "Creating table Note...");
+ if (!query.exec("Create table Note (guid varchar primary key, " +
+ "updateSequenceNumber integer, title varchar, content varchar, contentHash varchar, "+
+ "contentLength integer, created timestamp, updated timestamp, deleted timestamp, "
+ +"active integer, notebookGuid varchar, attributeSubjectDate timestamp, "+
+ "attributeLatitude double, attributeLongitude double, attributeAltitude double,"+
+ "attributeAuthor varchar, attributeSource varchar, attributeSourceUrl varchar, "+
+ "attributeSourceApplication varchar, indexNeeded boolean, isExpunged boolean, " +
+ "isDirty boolean)"))
+ logger.log(logger.HIGH, "Table Note creation FAILED!!!");
+ if (!query.exec("CREATE INDEX unindexed_notess on note (indexneeded desc, guid);"))
+ logger.log(logger.HIGH, "Note unindexed_notes index creation FAILED!!!");
+ if (!query.exec("CREATE INDEX unsynchronized_notes on note (isDirty desc, guid);"))
+ logger.log(logger.HIGH, "note unsynchronized_notes index creation FAILED!!!");
+ noteTagsTable.createTable();
+// noteResourceTable.createTable();
+ }
+ // Drop the table
+ public void dropTable() {
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ query.exec("Drop table Note");
+ noteTagsTable.dropTable();
+ noteResourceTable.dropTable();
+ }
+ // Save Note List from Evernote
+ public void addNote(Note n, boolean isDirty) {
+ logger.log(logger.EXTREME, "Inside addNote");
+ if (n == null)
+ return;
+
+ SimpleDateFormat simple = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ query.prepare("Insert Into Note ("
+ +"guid, updateSequenceNumber, title, content, "
+ +"contentHash, contentLength, created, updated, deleted, active, notebookGuid, "
+ +"attributeSubjectDate, attributeLatitude, attributeLongitude, attributeAltitude, "
+ +"attributeAuthor, attributeSource, attributeSourceUrl, attributeSourceApplication, "
+ +"indexNeeded, isExpunged, isDirty, titlecolor, thumbnailneeded"
+ +") Values("
+ +":guid, :updateSequenceNumber, :title, :content, "
+ +":contentHash, :contentLength, :created, :updated, :deleted, :active, :notebookGuid, "
+ +":attributeSubjectDate, :attributeLatitude, :attributeLongitude, :attributeAltitude, "
+ +":attributeAuthor, :attributeSource, :attributeSourceUrl, :attributeSourceApplication, "
+ +":indexNeeded, :isExpunged, :isDirty, -1, true) ");
+
+ StringBuilder created = new StringBuilder(simple.format(n.getCreated()));
+ StringBuilder updated = new StringBuilder(simple.format(n.getUpdated()));
+ StringBuilder deleted = new StringBuilder(simple.format(n.getDeleted()));
+
+
+
+ query.bindValue(":guid", n.getGuid());
+ query.bindValue(":updateSequenceNumber", n.getUpdateSequenceNum());
+ query.bindValue(":title", n.getTitle());
+ if (isDirty) {
+ EnmlConverter enml = new EnmlConverter(logger);
+ query.bindValue(":content", enml.fixEnXMLCrap(enml.fixEnMediaCrap(n.getContent())));
+ }
+ else
+ query.bindValue(":content", n.getContent());
+ query.bindValue(":contentHash", n.getContentHash());
+ query.bindValue(":contentLength", n.getContentLength());
+ query.bindValue(":created", created.toString());
+ query.bindValue(":updated", updated.toString());
+ query.bindValue(":deleted", deleted.toString());
+ query.bindValue(":active", n.isActive());
+ query.bindValue(":notebookGuid", n.getNotebookGuid());
+
+ if (n.getAttributes() != null) {
+ created = new StringBuilder(simple.format(n.getAttributes().getSubjectDate()));
+ query.bindValue(":attributeSubjectDate", created.toString());
+ query.bindValue(":attributeLatitude", n.getAttributes().getLatitude());
+ query.bindValue(":attributeLongitude", n.getAttributes().getLongitude());
+ query.bindValue(":attributeAltitude", n.getAttributes().getAltitude());
+ query.bindValue(":attributeAuthor", n.getAttributes().getAuthor());
+ query.bindValue(":attributeSource", n.getAttributes().getSource());
+ query.bindValue(":attributeSourceUrl", n.getAttributes().getSourceURL());
+ query.bindValue(":attributeSourceApplication", n.getAttributes().getSourceApplication());
+ } else {
+ created = new StringBuilder(simple.format(n.getCreated()));
+ query.bindValue(":attributeSubjectDate", created.toString());
+ query.bindValue(":attributeLatitude", 0.0);
+ query.bindValue(":attributeLongitude", 0.0);
+ query.bindValue(":attributeAltitude", 0.0);
+ query.bindValue(":attributeAuthor", "");
+ query.bindValue(":attributeSource", "");
+ query.bindValue(":attributeSourceUrl", "");
+ query.bindValue(":attributeSourceApplication", "");
+ }
+ query.bindValue(":indexNeeded", true);
+ query.bindValue(":isExpunged", false);
+ query.bindValue(":isDirty", isDirty);
+
+
+ if (!query.exec())
+ logger.log(logger.MEDIUM, query.lastError());
+
+ // Save the note tags
+ if (n.getTagGuids() != null) {
+ for (int i=0; i<n.getTagGuids().size(); i++)
noteTagsTable.saveNoteTag(n.getGuid(), n.getTagGuids().get(i), isDirty);\r
- }\r
- logger.log(logger.EXTREME, "Leaving addNote");\r
- } \r
- // Setup queries for get to save time later\r
- private void prepareQueries() {\r
- if (getQueryWithContent == null) {\r
- getQueryWithContent = new NSqlQuery(db.getConnection());\r
- if (!getQueryWithContent.prepare("Select "\r
- +"guid, updateSequenceNumber, title, "\r
- +"created, updated, deleted, active, notebookGuid, "\r
- +"attributeSubjectDate, attributeLatitude, attributeLongitude, attributeAltitude, "\r
- +"attributeAuthor, attributeSource, attributeSourceUrl, attributeSourceApplication, "\r
- +"attributeContentClass, "\r
- +"content, contentHash, contentLength"\r
- +" from Note where guid=:guid and isExpunged=false")) {\r
- logger.log(logger.EXTREME, "Note SQL select prepare with content has failed.");\r
- logger.log(logger.MEDIUM, getQueryWithContent.lastError());\r
- }\r
- }\r
- \r
- if (getQueryWithoutContent == null) {\r
- getQueryWithoutContent = new NSqlQuery(db.getConnection());\r
- if (!getQueryWithoutContent.prepare("Select "\r
- +"guid, updateSequenceNumber, title, "\r
- +"created, updated, deleted, active, notebookGuid, "\r
- +"attributeSubjectDate, attributeLatitude, attributeLongitude, attributeAltitude, "\r
- +"attributeAuthor, attributeSource, attributeSourceUrl, attributeSourceApplication, "\r
- +"attributeContentClass"\r
- +" from Note where guid=:guid and isExpunged=false")) {\r
- logger.log(logger.EXTREME, "Note SQL select prepare without content has failed.");\r
- logger.log(logger.MEDIUM, getQueryWithoutContent.lastError());\r
- }\r
- }\r
- \r
- if (getAllQueryWithoutContent == null) {\r
- getAllQueryWithoutContent = new NSqlQuery(db.getConnection());\r
- \r
- if (!getAllQueryWithoutContent.prepare("Select "\r
- +"guid, updateSequenceNumber, title, "\r
- +"created, updated, deleted, active, notebookGuid, "\r
- +"attributeSubjectDate, attributeLatitude, attributeLongitude, attributeAltitude, "\r
- +"attributeAuthor, attributeSource, attributeSourceUrl, attributeSourceApplication, "\r
- +"attributeContentClass "\r
- +" from Note where isExpunged = false")) {\r
- logger.log(logger.EXTREME, "Note SQL select prepare without content has failed.");\r
- logger.log(logger.MEDIUM, getQueryWithoutContent.lastError());\r
- }\r
- }\r
- }\r
-\r
-\r
- // Get a note's content in blob format for index.\r
- public String getNoteContentNoUTFConversion(String guid) {\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- query.prepare("Select content from note where guid=:guid");\r
- query.bindValue(":guid", guid);\r
- query.exec(); \r
- query.next();\r
- return query.valueString(0);\r
- }\r
- // Get a note by Guid\r
- public Note getNote(String noteGuid, boolean loadContent, boolean loadResources, boolean loadRecognition, boolean loadBinary, boolean loadTags) {\r
-\r
-// extractMetadata("otherKey:{values};baumgarte:{titleColor=fff;pinned=true;};finalKey:{values1);");\r
- if (noteGuid == null)\r
- return null;\r
- if (noteGuid.trim().equals(""))\r
- return null;\r
-\r
- prepareQueries();\r
- NSqlQuery query;\r
- if (loadContent) {\r
- query = getQueryWithContent;\r
- } else {\r
- query = getQueryWithoutContent;\r
- }\r
- \r
- query.bindValue(":guid", noteGuid);\r
- if (!query.exec()) {\r
- logger.log(logger.EXTREME, "Note SQL select exec has failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- return null;\r
- }\r
- if (!query.next()) {\r
- logger.log(logger.EXTREME, "SQL Retrieve failed for note guid " +noteGuid + " in getNote()");\r
- logger.log(logger.EXTREME, " -> " +query.lastError().toString());\r
- logger.log(logger.EXTREME, " -> " +query.lastError());\r
- return null;\r
- }\r
- Note n = mapNoteFromQuery(query, loadContent, loadResources, loadRecognition, loadBinary, loadTags);\r
- n.setContent(fixCarriageReturn(n.getContent()));\r
- n.getAttributes().setContentClassIsSet(false);\r
- return n;\r
- }\r
- // Get a note by Guid\r
- public Note mapNoteFromQuery(NSqlQuery query, boolean loadContent, boolean loadResources, boolean loadRecognition, boolean loadBinary, boolean loadTags) {\r
- DateFormat indfm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");\r
-// indfm = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy");\r
-\r
- Note n = new Note();\r
- NoteAttributes na = new NoteAttributes();\r
- n.setAttributes(na);\r
- \r
- n.setGuid(query.valueString(0));\r
- n.setUpdateSequenceNum(new Integer(query.valueString(1)));\r
- n.setTitle(query.valueString(2));\r
-\r
- try {\r
- n.setCreated(indfm.parse(query.valueString(3)).getTime());\r
- n.setUpdated(indfm.parse(query.valueString(4)).getTime());\r
- n.setDeleted(indfm.parse(query.valueString(5)).getTime());\r
- } catch (ParseException e) {\r
- e.printStackTrace();\r
- }\r
-\r
- n.setActive(query.valueBoolean(6,true));\r
- n.setNotebookGuid(query.valueString(7));\r
- \r
- try {\r
- String attributeSubjectDate = query.valueString(8);\r
- if (!attributeSubjectDate.equals(""))\r
- na.setSubjectDate(indfm.parse(attributeSubjectDate).getTime());\r
- } catch (ParseException e) {\r
- e.printStackTrace();\r
- }\r
- na.setLatitude(new Float(query.valueString(9)));\r
- na.setLongitude(new Float(query.valueString(10)));\r
- na.setAltitude(new Float(query.valueString(11)));\r
- na.setAuthor(query.valueString(12));\r
- na.setSource(query.valueString(13));\r
- na.setSourceURL(query.valueString(14));\r
- na.setSourceApplication(query.valueString(15));\r
- na.setContentClass(query.valueString(16));\r
- \r
- if (loadTags) {\r
- List<String> tagGuids = noteTagsTable.getNoteTags(n.getGuid());\r
- List<String> tagNames = new ArrayList<String>();\r
- TagTable tagTable = db.getTagTable();\r
- for (int i=0; i<tagGuids.size(); i++) {\r
- String currentGuid = tagGuids.get(i);\r
- Tag tag = tagTable.getTag(currentGuid);\r
- if (tag.getName() != null)\r
- tagNames.add(tag.getName());\r
- else\r
- tagNames.add("");\r
- }\r
-\r
- n.setTagNames(tagNames);\r
- n.setTagGuids(tagGuids); \r
- }\r
- \r
- if (loadContent) {\r
- QTextCodec codec = QTextCodec.codecForLocale();\r
- codec = QTextCodec.codecForName("UTF-8");\r
- String unicode = codec.fromUnicode(query.valueString(17)).toString();\r
-\r
- // This is a hack. Basically I need to convert HTML Entities to "normal" text, but if I\r
- // convert the < character to < it will mess up the XML parsing. So, to get around this\r
- // I am "bit stuffing" the < to &< so StringEscapeUtils doesn't unescape it. After\r
- // I'm done I convert it back.\r
- StringBuffer buffer = new StringBuffer(unicode);\r
- if (Global.enableHTMLEntitiesFix && unicode.indexOf("&#") > 0) {\r
- unicode = query.valueString(17);\r
- //System.out.println(unicode);\r
- //unicode = unicode.replace("<", "&_lt;");\r
- //unicode = codec.fromUnicode(StringEscapeUtils.unescapeHtml(unicode)).toString();\r
- //unicode = unicode.replace("&_lt;", "<");\r
- //System.out.println("************************");\r
- int j=1;\r
- for (int i=buffer.indexOf("&#"); i != -1 && buffer.indexOf("&#", i)>0; i=buffer.indexOf("&#",i+1)) {\r
- j = buffer.indexOf(";",i)+1;\r
- if (i<j) {\r
- String entity = buffer.substring(i,j).toString();\r
- int len = entity.length()-1;\r
- String tempEntity = entity.substring(2, len);\r
- try {\r
- Integer.parseInt(tempEntity);\r
- entity = codec.fromUnicode(StringEscapeUtils.unescapeHtml4(entity)).toString();\r
- buffer.delete(i, j);\r
- buffer.insert(i, entity);\r
- } catch (Exception e){ }\r
- \r
- }\r
- } \r
- } \r
- \r
- n.setContent(unicode);\r
-// n.setContent(query.valueString(16).toString());\r
- \r
- String contentHash = query.valueString(18);\r
- if (contentHash != null)\r
- n.setContentHash(contentHash.getBytes());\r
- n.setContentLength(new Integer(query.valueString(19)));\r
- }\r
- if (loadResources)\r
- n.setResources(noteResourceTable.getNoteResources(n.getGuid(), loadBinary));\r
- if (loadRecognition) {\r
- if (n.getResources() == null) {\r
- List<Resource> resources = noteResourceTable.getNoteResourcesRecognition(n.getGuid());\r
- n.setResources(resources);\r
- } else {\r
- // We need to merge the recognition resources with the note resources retrieved earlier\r
- for (int i=0; i<n.getResources().size(); i++) {\r
- Resource r = noteResourceTable.getNoteResourceRecognition(n.getResources().get(i).getGuid());\r
- n.getResources().get(i).setRecognition(r.getRecognition());\r
- }\r
- }\r
- }\r
- n.setContent(fixCarriageReturn(n.getContent()));\r
- return n;\r
- }\r
- // Update a note's title\r
- public void updateNoteTitle(String guid, String title) {\r
- logger.log(logger.HIGH, "Entering NoteTable.updateNoteTitle");\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- boolean check = query.prepare("Update Note set title=:title, isDirty=true where guid=:guid");\r
- if (!check) {\r
- logger.log(logger.EXTREME, "Update note title sql prepare has failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- }\r
- query.bindValue(":title", title);\r
- query.bindValue(":guid", guid);\r
- check = query.exec();\r
- if (!check) {\r
- logger.log(logger.EXTREME, "Update note title has failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- }\r
- logger.log(logger.HIGH, "Leaving NoteTable.updateNoteTitle");\r
- }\r
- // Update a note's creation date\r
- public void updateNoteCreatedDate(String guid, QDateTime date) {\r
- logger.log(logger.HIGH, "Entering NoteTable.updateNoteCreatedDate");\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- boolean check = query.prepare("Update Note set created=:created, isDirty=true where guid=:guid");\r
- if (!check) {\r
- logger.log(logger.EXTREME, "Update note creation update sql prepare has failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- }\r
- \r
- query.bindValue(":created", date.toString("yyyy-MM-dd HH:mm:ss"));\r
- query.bindValue(":guid", guid);\r
- \r
- check = query.exec();\r
- if (!check) {\r
- logger.log(logger.EXTREME, "Update note creation date has failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- }\r
- logger.log(logger.HIGH, "Leaving NoteTable.updateNoteCreatedDate");\r
- }\r
- // Update a note's creation date\r
- public void updateNoteAlteredDate(String guid, QDateTime date) {\r
- logger.log(logger.HIGH, "Entering NoteTable.updateNoteAlteredDate");\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- boolean check = query.prepare("Update Note set updated=:altered, isDirty=true where guid=:guid");\r
- if (!check) {\r
- logger.log(logger.EXTREME, "Update note altered sql prepare has failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- }\r
- \r
- query.bindValue(":altered", date.toString("yyyy-MM-dd HH:mm:ss"));\r
- query.bindValue(":guid", guid);\r
- \r
- check = query.exec();\r
- if (!check) {\r
- logger.log(logger.EXTREME, "Update note altered date has failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- }\r
- logger.log(logger.HIGH, "Leaving NoteTable.updateNoteAlteredDate");\r
- }\r
- // Update a note's creation date\r
- public void updateNoteSubjectDate(String guid, QDateTime date) {\r
- logger.log(logger.HIGH, "Entering NoteTable.updateNoteSubjectDate");\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- boolean check = query.prepare("Update Note set attributeSubjectDate=:altered, isDirty=true where guid=:guid");\r
- if (!check) {\r
- logger.log(logger.EXTREME, "Update note subject date sql prepare has failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- }\r
- \r
- query.bindValue(":altered", date.toString("yyyy-MM-dd HH:mm:ss"));\r
- query.bindValue(":guid", guid);\r
- \r
- check = query.exec();\r
- if (!check) {\r
- logger.log(logger.EXTREME, "Update note subject date date has failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- }\r
- logger.log(logger.HIGH, "Leaving NoteTable.updateNoteSubjectDate");\r
- }\r
- // Update a note's creation date\r
- public void updateNoteAuthor(String guid, String author) {\r
- logger.log(logger.HIGH, "Entering NoteTable.updateNoteSubject");\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- boolean check = query.prepare("Update Note set attributeAuthor=:author, isDirty=true where guid=:guid");\r
- if (!check) {\r
- logger.log(logger.EXTREME, "Update note author sql prepare has failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- }\r
-\r
- query.bindValue(":author", author);\r
- query.bindValue(":guid", guid);\r
-\r
- check = query.exec();\r
- if (!check) {\r
- logger.log(logger.EXTREME, "Update note author has failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- }\r
- logger.log(logger.HIGH, "Leaving NoteTable.updateNoteSubject");\r
- }\r
- // Update a note's geo tags\r
- public void updateNoteGeoTags(String guid, Double lon, Double lat, Double alt) {\r
- logger.log(logger.HIGH, "Entering NoteTable.updateNoteGeoTags");\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- boolean check = query.prepare("Update Note set attributeLongitude=:longitude, "+\r
- "attributeLatitude=:latitude, attributeAltitude=:altitude, isDirty=true where guid=:guid");\r
- if (!check) {\r
- logger.log(logger.EXTREME, "Update note author sql prepare has failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- }\r
-\r
- query.bindValue(":longitude", lon);\r
- query.bindValue(":latitude", lat);\r
- query.bindValue(":altitude", alt);\r
- query.bindValue(":guid", guid);\r
-\r
- check = query.exec();\r
- if (!check) {\r
- logger.log(logger.EXTREME, "Update note geo tag has failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- }\r
- logger.log(logger.HIGH, "Leaving NoteTable.updateNoteGeoTags");\r
- \r
- }\r
- // Update a note's creation date\r
- public void updateNoteSourceUrl(String guid, String url) {\r
- logger.log(logger.HIGH, "Entering NoteTable.updateNoteSourceUrl");\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- boolean check = query.prepare("Update Note set attributeSourceUrl=:url, isDirty=true where guid=:guid");\r
- if (!check) {\r
- logger.log(logger.EXTREME, "Update note url sql prepare has failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- }\r
- \r
- query.bindValue(":url", url);\r
- query.bindValue(":guid", guid);\r
-\r
- check = query.exec();\r
- if (!check) {\r
- logger.log(logger.EXTREME, "Update note url has failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- }\r
- logger.log(logger.HIGH, "Leaving NoteTable.updateNoteSourceUrl");\r
- }\r
- // Update the notebook that a note is assigned to\r
- public void updateNoteNotebook(String guid, String notebookGuid, boolean expungeFromRemote) {\r
- logger.log(logger.HIGH, "Entering NoteTable.updateNoteNotebook");\r
- String currentNotebookGuid = new String("");\r
- \r
- \r
- // If we are going from a synchronized notebook to a local notebook, we\r
- // need to tell Evernote to purge the note online. However, if this is \r
- // conflicting change we move it to the local notebook without deleting it \r
- // or it would then delete the copy on the remote server.\r
- NotebookTable notebookTable = new NotebookTable(logger, db);\r
- DeletedTable deletedTable = new DeletedTable(logger, db);\r
- if (expungeFromRemote) {\r
- if (!notebookTable.isNotebookLocal(currentNotebookGuid) & notebookTable.isNotebookLocal(notebookGuid)) {\r
- deletedTable.addDeletedItem(guid, "NOTE");\r
- }\r
- }\r
- \r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- boolean check = query.prepare("Update Note set notebookGuid=:notebook, isDirty=true where guid=:guid");\r
- if (!check) {\r
- logger.log(logger.EXTREME, "Update note notebook sql prepare has failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- }\r
- query.bindValue(":notebook", notebookGuid);\r
- query.bindValue(":guid", guid);\r
- \r
- check = query.exec();\r
- if (!check) {\r
- logger.log(logger.EXTREME, "Update note notebook has failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- }\r
- logger.log(logger.HIGH, "Leaving NoteTable.updateNoteNotebook");\r
- }\r
- // Update a note's title\r
- public void updateNoteContent(String guid, String content) {\r
- logger.log(logger.HIGH, "Entering NoteTable.updateNoteContent");\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- boolean check = query.prepare("Update Note set content=:content, updated=CURRENT_TIMESTAMP(), isDirty=true, indexNeeded=true, " +\r
- " thumbnailneeded=true where guid=:guid");\r
- if (!check) {\r
- logger.log(logger.EXTREME, "Update note content sql prepare has failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- }\r
- \r
-// QTextCodec codec = QTextCodec.codecForLocale();\r
-// codec = QTextCodec.codecForName("UTF-8");\r
-// query.bindValue(":content", codec.fromUnicode(content).toString());\r
- query.bindValue(":content", content);\r
- query.bindValue(":guid", guid);\r
-\r
- check = query.exec();\r
- if (!check) {\r
- logger.log(logger.EXTREME, "Update note content has failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- }\r
- logger.log(logger.HIGH, "Leaving NoteTable.updateNoteContent");\r
- }\r
-\r
- // Delete a note\r
- public void deleteNote(String guid) {\r
- logger.log(logger.HIGH, "Entering NoteTable.deleteNote");\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- query.prepare("Update Note set deleted=CURRENT_TIMESTAMP(), active=false, isDirty=true where guid=:guid");\r
- query.bindValue(":guid", guid);\r
- if (!query.exec()) {\r
- logger.log(logger.MEDIUM, "Note delete failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- }\r
- logger.log(logger.HIGH, "Leaving NoteTable.deleteNote");\r
- }\r
- public void restoreNote(String guid) {\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- query.prepare("Update Note set deleted=:reset, active=true, isDirty=true where guid=:guid");\r
-// query.prepare("Update Note set deleted=0, active=true, isDirty=true where guid=:guid");\r
- query.bindValue(":guid", guid);\r
- query.bindValue(":reset", "1969-12-31 19:00:00");\r
- if (!query.exec()) {\r
- logger.log(logger.MEDIUM, "Note restore failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- }\r
- }\r
- // Purge a note (actually delete it instead of just marking it deleted)\r
- public void expungeNote(String guid, boolean permanentExpunge, boolean needsSync) {\r
- logger.log(logger.HIGH, "Entering NoteTable.expungeNote");\r
- \r
- if (!permanentExpunge) {\r
- hideExpungedNote(guid, needsSync);\r
- return;\r
- }\r
- \r
- \r
- NSqlQuery note = new NSqlQuery(db.getConnection());\r
- NSqlQuery resources = new NSqlQuery(db.getResourceConnection());\r
- NSqlQuery tags = new NSqlQuery(db.getConnection());\r
- NSqlQuery words = new NSqlQuery(db.getIndexConnection());\r
- \r
- note.prepare("Delete from Note where guid=:guid");\r
- resources.prepare("Delete from NoteResources where noteGuid=:guid");\r
- tags.prepare("Delete from NoteTags where noteGuid=:guid");\r
- words.prepare("Delete from words where guid=:guid");\r
-\r
- note.bindValue(":guid", guid);\r
- resources.bindValue(":guid", guid);\r
- tags.bindValue(":guid", guid);\r
- words.bindValue(":guid", guid);\r
- \r
- // Start purging notes.\r
- if (!note.exec()) {\r
- logger.log(logger.MEDIUM, "Purge from note failed.");\r
- logger.log(logger.MEDIUM, note.lastError());\r
- }\r
- if (!resources.exec()) {\r
- logger.log(logger.MEDIUM, "Purge from resources failed.");\r
- logger.log(logger.MEDIUM, resources.lastError());\r
- }\r
- if (!tags.exec()) {\r
- logger.log(logger.MEDIUM, "Note tags delete failed.");\r
- logger.log(logger.MEDIUM, tags.lastError());\r
- }\r
-\r
- if (!words.exec()) {\r
- logger.log(logger.MEDIUM, "Word delete failed.");\r
- logger.log(logger.MEDIUM, words.lastError());\r
- }\r
- if (needsSync) {\r
- DeletedTable deletedTable = new DeletedTable(logger, db);\r
- deletedTable.addDeletedItem(guid, "Note");\r
- }\r
- logger.log(logger.HIGH, "Leaving NoteTable.expungeNote");\r
- }\r
- // Purge a bunch of notes based upon the notebook\r
- public void expungeNotesByNotebook(String notebookGuid, boolean permanentExpunge, boolean needsSync) {\r
- List<String> notes = getNotesByNotebook(notebookGuid);\r
- for (int i=0; i<notes.size(); i++) {\r
- expungeNote(notes.get(i), permanentExpunge, needsSync);\r
- }\r
- }\r
-\r
- // Purge a note (actually delete it instead of just marking it deleted)\r
- public void hideExpungedNote(String guid, boolean needsSync) {\r
- NSqlQuery note = new NSqlQuery(db.getConnection());\r
- NSqlQuery resources = new NSqlQuery(db.getResourceConnection());\r
- NSqlQuery tags = new NSqlQuery(db.getConnection());\r
- NSqlQuery words = new NSqlQuery(db.getIndexConnection());\r
- \r
- note.prepare("Update Note set isExpunged=true where guid=:guid");\r
- resources.prepare("Delete from NoteResources where noteGuid=:guid");\r
- tags.prepare("Delete from NoteTags where noteGuid=:guid");\r
-// words.prepare("Delete from words where guid=:guid");\r
-\r
- note.bindValue(":guid", guid);\r
- resources.bindValue(":guid", guid);\r
- tags.bindValue(":guid", guid);\r
- words.bindValue(":guid", guid);\r
-\r
- // Start purging notes.\r
- if (!note.exec()) {\r
- logger.log(logger.MEDIUM, "Purge from note failed.");\r
- logger.log(logger.MEDIUM, note.lastError());\r
- }\r
- if (!resources.exec()) {\r
- logger.log(logger.MEDIUM, "Purge from resources failed.");\r
- logger.log(logger.MEDIUM, resources.lastError());\r
- }\r
- if (!tags.exec()) {\r
- logger.log(logger.MEDIUM, "Note tags delete failed.");\r
- logger.log(logger.MEDIUM, tags.lastError());\r
- }\r
-// System.out.println("Hiding Note: Deleting words");\r
-// if (!words.exec()) {\r
-// logger.log(logger.MEDIUM, "Word delete failed.");\r
-// logger.log(logger.MEDIUM, words.lastError());\r
-// }\r
- if (needsSync) {\r
- DeletedTable deletedTable = new DeletedTable(logger, db);\r
- deletedTable.addDeletedItem(guid, "Note");\r
- }\r
- }\r
-\r
- \r
- // Purge all deleted notes;\r
- public void expungeAllDeletedNotes() {\r
- logger.log(logger.HIGH, "Entering NoteTable.expungeAllDeletedNotes");\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- query.exec("select guid, updateSequenceNumber from note where active = false");\r
- List<String> guids = new ArrayList<String>();\r
- List<Integer> usns = new ArrayList<Integer>();\r
- while (query.next()) {\r
- guids.add(query.valueString(0));\r
- Integer usn = new Integer(query.valueString(1));\r
- usns.add(usn);\r
- }\r
- \r
- for (int i=0; i<guids.size(); i++) {\r
- Integer usn = usns.get(i);\r
- String guid = guids.get(i);\r
- if (usn == 0)\r
- expungeNote(guid, true, false);\r
- else\r
- expungeNote(guid, false, true);\r
- }\r
- logger.log(logger.HIGH, "Leaving NoteTable.expungeAllDeletedNotes");\r
- }\r
- // Update the note sequence number\r
- public void updateNoteSequence(String guid, int sequence) {\r
- logger.log(logger.HIGH, "Entering NoteTable.updateNoteSequence");\r
- boolean check;\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- check = query.prepare("Update Note set updateSequenceNumber=:sequence where guid=:guid");\r
-\r
- query.bindValue(":sequence", sequence);\r
- query.bindValue(":guid", guid);\r
- \r
- query.exec();\r
- if (!check) {\r
- logger.log(logger.MEDIUM, "Note sequence update failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- } \r
- logger.log(logger.HIGH, "Leaving NoteTable.updateNoteSequence");\r
- }\r
- // Update the note Guid\r
- public void updateNoteGuid(String oldGuid, String newGuid) {\r
- logger.log(logger.HIGH, "Entering NoteTable.updateNoteGuid");\r
- boolean check;\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- NSqlQuery resQuery = new NSqlQuery(db.getResourceConnection());\r
- NSqlQuery wordQuery = new NSqlQuery(db.getIndexConnection());\r
- query.prepare("Update Note set guid=:newGuid, original_guid=:original_guid where guid=:oldGuid");\r
-\r
- query.bindValue(":original_guid", oldGuid);\r
- query.bindValue(":newGuid", newGuid);\r
- query.bindValue(":oldGuid", oldGuid);\r
-\r
- check = query.exec();\r
- if (!check) {\r
- logger.log(logger.MEDIUM, "Note Guid update failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- } \r
- \r
- query.prepare("Update NoteTags set noteGuid=:newGuid where noteGuid=:oldGuid");\r
- query.bindValue(":newGuid", newGuid);\r
- query.bindValue(":oldGuid", oldGuid);\r
- check = query.exec();\r
- if (!check) {\r
- logger.log(logger.MEDIUM, "Note guid update failed for NoteTags.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- }\r
- \r
- wordQuery.prepare("Update words set guid=:newGuid where guid=:oldGuid");\r
- wordQuery.bindValue(":newGuid", newGuid);\r
- wordQuery.bindValue(":oldGuid", oldGuid);\r
- wordQuery.exec();\r
- if (!check) {\r
- logger.log(logger.MEDIUM, "Note guid update failed for Words.");\r
- logger.log(logger.MEDIUM, wordQuery.lastError());\r
- }\r
- resQuery.prepare("Update noteresources set noteguid=:newGuid where noteguid=:oldGuid");\r
- resQuery.bindValue(":newGuid", newGuid);\r
- resQuery.bindValue(":oldGuid", oldGuid);\r
- resQuery.exec();\r
- if (!check) {\r
- logger.log(logger.MEDIUM, "Note guid update failed for noteresources.");\r
- logger.log(logger.MEDIUM, resQuery.lastError());\r
- }\r
- logger.log(logger.HIGH, "Leaving NoteTable.updateNoteGuid");\r
- }\r
- // Update a note\r
- public void updateNote(Note n) {\r
- logger.log(logger.HIGH, "Entering NoteTable.updateNote");\r
- NoteMetadata meta = getNoteMetaInformation(n.getGuid());\r
- String originalGuid = findAlternateGuid(n.getGuid());\r
- expungeNote(n.getGuid(), true, false);\r
- addNote(n, false);\r
- if (n!=null) {\r
- updateNoteMetadata(meta);\r
- }\r
- if (originalGuid != null) {\r
- updateNoteGuid(n.getGuid(), originalGuid);\r
- updateNoteGuid(originalGuid, n.getGuid());\r
- }\r
- logger.log(logger.HIGH, "Leaving NoteTable.updateNote");\r
- }\r
- // Does a note exist?\r
- public boolean exists(String guid) {\r
- if (guid == null)\r
- return false;\r
- if (guid.trim().equals(""))\r
- return false;\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- query.prepare("Select guid from note where guid=:guid");\r
- query.bindValue(":guid", guid);\r
- if (!query.exec())\r
- logger.log(logger.EXTREME, "note.exists SQL retrieve has failed.");\r
- boolean retVal = query.next();\r
- return retVal;\r
- }\r
- // Does a note exist?\r
- public boolean isNoteExpunged(String guid) {\r
- if (guid == null)\r
- return false;\r
- if (guid.trim().equals(""))\r
- return false;\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- query.prepare("Select isExpunged from note where guid=:guid and isExpunged = true");\r
- query.bindValue(":guid", guid);\r
- if (!query.exec())\r
- logger.log(logger.EXTREME, "note.isNoteExpunged SQL retrieve has failed.");\r
- boolean retVal = query.next();\r
- return retVal;\r
- }\r
- // This is a convenience method to check if a note exists & update/create based upon it\r
- public void syncNote(Note note) {\r
- logger.log(logger.HIGH, "Entering NoteTable.syncNote");\r
- // If we got the note from Evernote we use its \r
- // metadata instead of the local copy.\r
- NoteMetadata meta = null;\r
- if (note.getAttributes() != null && note.getAttributes().getSourceApplication() != null) {\r
- meta = extractMetadata(note.getAttributes().getSourceApplication());\r
- } else \r
- meta = getNoteMetaInformation(note.getGuid());\r
- \r
- // Now, if the note exists we simply update it. Otherwise we\r
- // add a new note.\r
- if (exists(note.getGuid())) {\r
- updateNote(note);\r
- }\r
- else\r
- addNote(note, false);\r
- \r
- // If we have metadata, we write it out.\r
- if (meta != null) {\r
- meta.setGuid(note.getGuid());\r
- updateNoteMetadata(meta);\r
- }\r
- logger.log(logger.HIGH, "Leaving NoteTable.syncNote");\r
- }\r
- // Get a list of notes that need to be updated\r
- public List <Note> getDirty() {\r
- String guid;\r
- Note tempNote;\r
- List<Note> notes = new ArrayList<Note>();\r
- List<String> index = new ArrayList<String>();\r
- \r
- boolean check; \r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- \r
- check = query.exec("Select guid from Note where isDirty = true and isExpunged = false and notebookGuid not in (select guid from notebook where local = true or linked = true)");\r
- if (!check) \r
- logger.log(logger.EXTREME, "Note SQL retrieve has failed: " +query.lastError().toString());\r
- \r
- // Get a list of the notes\r
- while (query.next()) {\r
- guid = new String();\r
- guid = query.valueString(0);\r
- index.add(guid); \r
- } \r
- \r
- // Start getting notes\r
- for (int i=0; i<index.size(); i++) {\r
- tempNote = getNote(index.get(i), true,true,false,true,true);\r
- notes.add(tempNote);\r
- }\r
- logger.log(logger.LOW, "Dirty local notes: " +new Integer(notes.size()).toString());\r
- return notes; \r
- }\r
- // Get a list of notes that need to be updated\r
- public List <Note> getDirtyLinkedNotes() {\r
- String guid;\r
- Note tempNote;\r
- List<Note> notes = new ArrayList<Note>();\r
- List<String> index = new ArrayList<String>();\r
- \r
- boolean check; \r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- \r
- check = query.exec("Select guid from Note where isDirty = true and isExpunged = false and notebookGuid in (select guid from notebook where linked = true)");\r
- if (!check) \r
- logger.log(logger.EXTREME, "Note SQL retrieve has failed: " +query.lastError().toString());\r
- \r
- // Get a list of the notes\r
- while (query.next()) {\r
- guid = new String();\r
- guid = query.valueString(0);\r
- index.add(guid); \r
- } \r
- \r
- // Start getting notes\r
- for (int i=0; i<index.size(); i++) {\r
- tempNote = getNote(index.get(i), true,true,false,true,true);\r
- notes.add(tempNote);\r
- }\r
- logger.log(logger.LOW, "Dirty linked local notes: " +new Integer(notes.size()).toString());\r
- return notes; \r
- }\r
- // Get a list of notes that need to be updated\r
- public List <Note> getDirtyLinked(String notebookGuid) {\r
- String guid;\r
- Note tempNote;\r
- List<Note> notes = new ArrayList<Note>();\r
- List<String> index = new ArrayList<String>();\r
- \r
- boolean check; \r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- \r
- query.prepare("Select guid from Note where isDirty = true and isExpunged = false and notebookGuid=:notebookGuid");\r
- query.bindValue(":notebookGuid", notebookGuid);\r
- check = query.exec();\r
- if (!check) \r
- logger.log(logger.EXTREME, "Note SQL retrieve has failed getting dirty linked notes: " +query.lastError().toString());\r
- \r
- // Get a list of the notes\r
- while (query.next()) {\r
- guid = new String();\r
- guid = query.valueString(0);\r
- index.add(guid); \r
- } \r
- \r
- // Start getting notes\r
- for (int i=0; i<index.size(); i++) {\r
- tempNote = getNote(index.get(i), true,true,false,true,true);\r
- notes.add(tempNote);\r
- }\r
- logger.log(logger.LOW, "Dirty local notes for notebook " +notebookGuid +": " +new Integer(notes.size()).toString());\r
- return notes; \r
- }\r
- // Get a list of notes that need to be updated\r
- public List <String> getNotesByNotebook(String notebookGuid) {\r
- List<String> notes = new ArrayList<String>();\r
- List<String> index = new ArrayList<String>();\r
- \r
- boolean check; \r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- \r
- check = query.prepare("Select guid from Note where notebookguid=:notebookguid");\r
- if (!check) \r
- logger.log(logger.EXTREME, "Note SQL retrieve has failed: " +query.lastError().toString());\r
- query.bindValue(":notebookguid", notebookGuid);\r
- query. exec();\r
- \r
- // Get a list of the notes\r
- while (query.next()) {\r
- index.add(query.valueString(0)); \r
- } \r
- \r
- return notes; \r
- }\r
- // Get a list of notes that need to be updated\r
- public boolean isNoteDirty(String guid) {\r
- \r
- boolean check; \r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- \r
- check = query.prepare("Select guid from Note where isDirty = true and guid=:guid");\r
- query.bindValue(":guid", guid);\r
- check = query.exec();\r
- if (!check) \r
- logger.log(logger.EXTREME, "Note SQL retrieve has failed: " +query.lastError().toString());\r
- \r
- boolean returnValue;\r
- // Get a list of the notes\r
- if (query.next()) \r
- returnValue = true; \r
- else\r
- returnValue = false;\r
-\r
- return returnValue; \r
- }\r
-\r
- // Reset the dirty bit\r
- public void resetDirtyFlag(String guid) {\r
- logger.log(logger.LOW, "Resetting dirty flag for " +guid);\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- \r
- query.prepare("Update note set isdirty=false where guid=:guid");\r
- query.bindValue(":guid", guid);\r
- if (!query.exec())\r
- logger.log(logger.EXTREME, "Error resetting note dirty field.");\r
- }\r
- // Get all notes\r
- public List<String> getAllGuids() {\r
- List<String> notes = new ArrayList<String>();\r
- \r
- boolean check; \r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- \r
- check = query.exec("Select guid from Note");\r
- if (!check)\r
- logger.log(logger.EXTREME, "Notebook SQL retrieve has failed: "+query.lastError());\r
-\r
- // Get a list of the notes\r
- while (query.next()) {\r
- notes.add(new String(query.valueString(0))); \r
- }\r
- return notes;\r
- }\r
- // Get all notes\r
- public List<Note> getAllNotes() {\r
- List<Note> notes = new ArrayList<Note>();\r
- prepareQueries();\r
- boolean check; \r
- if (getAllQueryWithoutContent == null) \r
- prepareQueries();\r
- NSqlQuery query = getAllQueryWithoutContent;\r
- check = query.exec();\r
- if (!check)\r
- logger.log(logger.EXTREME, "Notebook SQL retrieve has failed: "+query.lastError());\r
- // Get a list of the notes\r
- while (query.next()) {\r
- notes.add(mapNoteFromQuery(query, false, false, false, false, true));\r
- }\r
- return notes;\r
- }\r
- // Count unindexed notes\r
- public int getUnindexedCount() {\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- query.exec("select count(*) from note where indexneeded=true and isExpunged = false");\r
- query.next(); \r
- int returnValue = new Integer(query.valueString(0));\r
- return returnValue;\r
- }\r
- // Count unsynchronized notes\r
- public int getDirtyCount() {\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- query.exec("select count(guid) from note where isDirty=true and isExpunged = false");\r
- query.next(); \r
- int returnValue = new Integer(query.valueString(0));\r
- logger.log(logger.LOW, "dirty count: " +returnValue);\r
- //query.exec("select count(guid) from note where isDirty=true and Active = 0 and isExpunged = false");\r
- //query.next(); \r
- //logger.log(logger.LOW, "dirty count (active only): " +query.valueString(0));\r
- //query.exec("Select count(guid) from Note where isDirty = true and isExpunged = false and notebookGuid not in (select guid from notebook where local = true or linked = true)");\r
- //query.next(); \r
- //logger.log(logger.LOW, "dirty count (no l&l notebooks): " +query.valueString(0));\r
- //logger.log(logger.LOW, "Beginning stack trace");\r
- //logger.log(logger.LOW, Thread.currentThread().getStackTrace());\r
-\r
- //logger.log(logger.LOW, "*************************");\r
- //logger.log(logger.LOW, "*** DIRTY RECORD DUMP ***");\r
- //logger.log(logger.LOW, "*************************");\r
- //List<Note> recs = getDirty();\r
- //for (int i=0; i<recs.size(); i++) {\r
- //Note n = getNote(recs.get(i).getGuid(), true, true, true, false, true);\r
- //logger.log(logger.LOW, "-- Begin Record ---");\r
- //logger.log(logger.LOW, "Guid: " +n.getGuid());\r
- //logger.log(logger.LOW, "Title: " +n.getTitle());\r
- //logger.log(logger.LOW, "Active: " +n.isActive());\r
- //logger.log(logger.LOW, "USN: " +n.getUpdateSequenceNum());\r
- //logger.log(logger.LOW, "Date Created: " +n.getCreated());\r
- //logger.log(logger.LOW, "Date Updated: " +n.getUpdated());\r
- //logger.log(logger.LOW, "Date Deleted: " +n.getDeleted());\r
- //logger.log(logger.LOW, "Resource Count: " +n.getResourcesSize());\r
- //for (int j=0; j<n.getResourcesSize(); j++) {\r
- //Resource r = n.getResources().get(j);\r
- //logger.log(logger.LOW, "Resource " +j +": " +r.getGuid());\r
- //logger.log(logger.LOW, "Active: " +r.isActive());\r
- //logger.log(logger.LOW, "USN: " +r.getUpdateSequenceNum());\r
- //}\r
- //logger.log(logger.LOW, "-- End Record ---");\r
- //}\r
- //logger.log(logger.LOW, "*****************************");\r
- //logger.log(logger.LOW, "*** End DIRTY RECORD DUMP ***");\r
- //logger.log(logger.LOW, "*****************************");\r
- return returnValue;\r
- }\r
- // Count notes\r
- public int getNoteCount() {\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- query.exec("select count(*) from note where isExpunged = false");\r
- query.next(); \r
- int returnValue = new Integer(query.valueString(0));\r
- return returnValue;\r
- }\r
- // Count deleted notes\r
- public int getDeletedCount() {\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- query.exec("select count(*) from note where isExpunged = false and active = false");\r
- if (!query.next()) \r
- return 0;\r
- int returnValue = new Integer(query.valueString(0));\r
- return returnValue;\r
- }\r
- // Reset a note sequence number to zero. This is useful for moving conflicting notes\r
- public void resetNoteSequence(String guid) {\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- boolean check = query.prepare("Update Note set updateSequenceNumber=0, isDirty=true where guid=:guid");\r
- if (!check) {\r
- logger.log(logger.EXTREME, "Update note ResetSequence sql prepare has failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- }\r
- query.bindValue(":guid", guid);\r
- check = query.exec();\r
- if (!check) {\r
- logger.log(logger.EXTREME, "Update note sequence number has failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- }\r
- }\r
- \r
- \r
- // Update a note resource by the hash\r
- public void updateNoteResourceGuidbyHash(String noteGuid, String resGuid, String hash) {\r
- NSqlQuery query = new NSqlQuery(db.getResourceConnection());\r
-/* query.prepare("Select guid from NoteResources where noteGuid=:noteGuid and datahash=:hex");\r
- query.bindValue(":noteGuid", noteGuid);\r
- query.bindValue(":hex", hash);\r
- query.exec();\r
- if (!query.next()) {\r
- logger.log(logger.LOW, "Error finding note resource in RNoteTable.updateNoteResourceGuidbyHash. GUID="+noteGuid +" resGuid="+ resGuid+" hash="+hash);\r
- return;\r
- }\r
- String guid = query.valueString(0);\r
-*/ \r
- query.prepare("update noteresources set guid=:guid where noteGuid=:noteGuid and datahash=:hex");\r
- query.bindValue(":guid", resGuid);\r
- query.bindValue(":noteGuid", noteGuid);\r
- query.bindValue(":hex", hash);\r
- if (!query.exec()) {\r
- logger.log(logger.EXTREME, "Note Resource Update by Hash failed");\r
- logger.log(logger.EXTREME, query.lastError().toString());\r
- }\r
- }\r
-\r
- // Fix CRLF problem that is on some notes\r
- private String fixCarriageReturn(String note) {\r
- if (note == null || !Global.enableCarriageReturnFix)\r
- return note;\r
- QByteArray a0Hex = new QByteArray("a0");\r
- String a0 = QByteArray.fromHex(a0Hex).toString();\r
- note = note.replace("<div>"+a0+"</div>", "<div> </div>");\r
- return note.replace("<div/>", "<div> </div>");\r
- }\r
- \r
- // Expunge notes that we don't want to synchronize\r
- public List<String> expungeIgnoreSynchronizedNotes(List<String> notebooks, List<String>tags, List<String> linked) {\r
- \r
- List<String> noteGuids = new ArrayList<String>();\r
- for (int i=0; i<notebooks.size(); i++) {\r
- List<String> notes = findNotesByNotebook(notebooks.get(i));\r
- for (int j=0; j<notes.size(); j++) {\r
- if (!isNoteDirty(notes.get(j))) {\r
- expungeNote(notes.get(j), true, false);\r
- noteGuids.add(notes.get(j));\r
- }\r
- }\r
- }\r
- \r
- for (int i=0; i<tags.size(); i++) {\r
- List<String> notes = findNotesByTag(tags.get(i));\r
- for (int j=0; j<notes.size(); j++) {\r
- if (!isNoteDirty(notes.get(j))) {\r
- expungeNote(notes.get(j), true, false);\r
- noteGuids.add(notes.get(j));\r
- }\r
- }\r
- }\r
- \r
- for (int i=0; i<linked.size(); i++) {\r
- String notebookGuid = db.getLinkedNotebookTable().getNotebookGuid(linked.get(i));\r
- if (notebookGuid != null && !notebookGuid.trim().equals("")) {\r
- List<Tag> linkedTags = db.getTagTable().getTagsForNotebook(notebookGuid);\r
- for (int j=0; j<linkedTags.size(); j++)\r
- db.getTagTable().expungeTag(linkedTags.get(j).getGuid(), false);\r
- \r
- List<String> notes = findNotesByNotebook(notebookGuid);\r
- for (int j=0; j<notes.size(); j++) {\r
- if (!isNoteDirty(notes.get(j))) {\r
- expungeNote(notes.get(j), true, false);\r
- noteGuids.add(notes.get(j));\r
- }\r
- }\r
- }\r
- }\r
- return noteGuids;\r
- }\r
- \r
- // Find a note by its notebook\r
- // Expunge notes that we don't want to synchronize\r
- public List<String> findNotesByNotebook(String notebook) {\r
- List<String> values = new ArrayList<String>();\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- query.prepare("Select guid from note where notebookguid=:notebook");\r
-\r
- query.bindValue(":notebook", notebook);\r
- query.exec();\r
- while (query.next()) {\r
- values.add(query.valueString(0));\r
- }\r
- return values;\r
- }\r
- \r
- public List<String> findNotesByTag(String tag) {\r
- List<String> values = new ArrayList<String>();\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- query.prepare("Select distinct noteguid from notetags where tagguid=:tag");\r
-\r
- query.bindValue(":tag", tag);\r
- query.exec();\r
- while (query.next()) {\r
- values.add(query.valueString(0));\r
- }\r
- return values;\r
- }\r
- \r
- // Find a note based upon its title.\r
- public List<Pair<String,String>> findNotesByTitle(String text) {\r
- List<Pair<String,String>> results = new ArrayList<Pair<String,String>>();\r
- boolean check; \r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- \r
- check = query.prepare("Select guid,title from Note where lower(title) like :title");\r
- if (!check) \r
- logger.log(logger.EXTREME, "Note SQL prepare for search by title has failed: " +query.lastError().toString());\r
- \r
- query.bindValue(":title", "%"+text.toLowerCase()+"%");\r
- query.exec();\r
- // Get a list of the notes\r
- while (query.next()) {\r
- Pair<String,String> p = new Pair<String,String>();\r
- p.setFirst(query.valueString(0));\r
- p.setSecond(query.valueString(1)); \r
- results.add(p); \r
- } \r
- return results;\r
- }\r
-\r
- \r
- \r
- //********************************************************************************\r
- //********************************************************************************\r
- //* Indexing Functions\r
- //********************************************************************************\r
- //********************************************************************************\r
- // set/unset a note to be reindexed\r
- public void setIndexNeeded(String guid, Boolean flag) {\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- query.prepare("Update Note set indexNeeded=:flag where guid=:guid");\r
-\r
- if (flag)\r
- query.bindValue(":flag", 1);\r
- else\r
- query.bindValue(":flag", 0);\r
- query.bindValue(":guid", guid);\r
- if (!query.exec()) {\r
- logger.log(logger.MEDIUM, "Note indexNeeded update failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- } \r
- List<Resource> r = noteResourceTable.getNoteResources(guid, false);\r
- for (int i=0; r!= null && i<r.size(); i++) {\r
- noteResourceTable.setIndexNeeded(r.get(i).getGuid(), true);\r
- }\r
- }\r
- // Set all notes to be reindexed\r
- public void reindexAllNotes() {\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- if (!query.exec("Update Note set indexNeeded=true")) {\r
- logger.log(logger.MEDIUM, "Note reindexAllNotes update failed.");\r
- logger.log(logger.MEDIUM, query.lastError());\r
- } \r
- }\r
-\r
- // Get all unindexed notes\r
- public List <String> getUnindexed() {\r
- String guid;\r
- List<String> index = new ArrayList<String>();\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- \r
- if (!query.exec("Select guid from Note where isExpunged = false and indexNeeded = true and DATEDIFF('MINUTE',updated,CURRENT_TIMESTAMP)>5"))\r
- logger.log(logger.EXTREME, "Note SQL retrieve has failed on getUnindexed().");\r
-\r
- // Get a list of the notes\r
- while (query.next()) {\r
- guid = new String();\r
- guid = query.valueString(0);\r
- index.add(guid); \r
- } \r
- return index; \r
- }\r
- public List<String> getNextUnindexed(int limit) {\r
- List<String> guids = new ArrayList<String>();\r
- \r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- \r
- if (!query.exec("Select guid from Note where isExpunged = false and indexNeeded = true and DATEDIFF('MINUTE',Updated,CURRENT_TIMESTAMP)>5 limit " +limit))\r
- logger.log(logger.EXTREME, "Note SQL retrieve has failed on getUnindexed().");\r
- \r
- // Get a list of the notes\r
- String guid;\r
- while (query.next()) {\r
- guid = new String();\r
- guid = query.valueString(0);\r
- guids.add(guid);\r
- } \r
- return guids; \r
- }\r
-\r
- \r
- // Get note meta information\r
- public void updateNoteMetadata(NoteMetadata meta) {\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- if (!query.prepare("Update Note set titleColor=:color, pinned=:pinned, attributeSourceApplication=:metaString where guid=:guid"))\r
- logger.log(logger.EXTREME, "Note SQL prepare has failed on updateNoteMetadata.");\r
- query.bindValue(":color", meta.getColor());\r
- query.bindValue(":pinned", meta.isPinned());\r
- query.bindValue(":guid", meta.getGuid());\r
- query.bindValue(":metaString", buildMetadataString(meta));\r
- if (!query.exec()) \r
- logger.log(logger.EXTREME, "Note SQL exec has failed on updateNoteMetadata.");\r
- return;\r
- }\r
- \r
- // Get all note meta information\r
- public HashMap<String, NoteMetadata> getNotesMetaInformation() {\r
- HashMap<String, NoteMetadata> returnValue = new HashMap<String, NoteMetadata>();\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- \r
- if (!query.exec("Select guid,titleColor, isDirty, pinned from Note"))\r
- logger.log(logger.EXTREME, "Note SQL retrieve has failed on getNoteMetaInformation.");\r
-\r
- // Get a list of the notes\r
- while (query.next()) {\r
- NoteMetadata note = new NoteMetadata();\r
- note.setGuid(query.valueString(0));\r
- note.setColor(query.valueInteger(1));\r
- note.setDirty(query.valueBoolean(2, false));\r
- int pinned = query.valueInteger(3);\r
- if (pinned > 0) \r
- note.setPinned(true);\r
- returnValue.put(note.getGuid(), note); \r
- } \r
-\r
- return returnValue;\r
- }\r
- // Get note meta information\r
- public NoteMetadata getNoteMetaInformation(String guid) {\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- \r
- if (!query.prepare("Select guid,titleColor, isDirty, pinned from Note where guid=:guid")) {\r
- logger.log(logger.EXTREME, "Note SQL retrieve has failed on getNoteMetaInformation.");\r
- return null;\r
- }\r
- query.bindValue(":guid", guid);\r
- query.exec();\r
-\r
- // Get a list of the notes\r
- while (query.next()) {\r
- NoteMetadata note = new NoteMetadata();\r
- note.setGuid(query.valueString(0));\r
- note.setColor(query.valueInteger(1));\r
- note.setDirty(query.valueBoolean(2, false));\r
- int pinned = query.valueInteger(3);\r
- if (pinned > 0) \r
- note.setPinned(true);\r
- return note;\r
- } \r
-\r
- return null;\r
- }\r
- \r
- \r
- //**********************************************************************************\r
- //* Thumbnail functions\r
- //**********************************************************************************\r
- // Set if a new thumbnail is needed\r
- public void setThumbnailNeeded(String guid, boolean needed) {\r
- \r
- boolean check; \r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- \r
- check = query.prepare("Update note set thumbnailneeded = :needed where guid=:guid");\r
- query.bindValue(":guid", guid);\r
- query.bindValue(":needed", needed);\r
- check = query.exec();\r
- if (!check) \r
- logger.log(logger.EXTREME, "Note SQL set thumbail needed failed: " +query.lastError().toString());\r
-\r
- }\r
- // Is a thumbail needed for this guid?\r
- public boolean isThumbnailNeeded(String guid) {\r
- \r
- boolean check; \r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- \r
- check = query.prepare("select thumbnailneeded from note where guid=:guid");\r
- query.bindValue(":guid", guid);\r
- check = query.exec();\r
- if (!check) \r
- logger.log(logger.EXTREME, "Note SQL isThumbnailNeeded query failed: " +query.lastError().toString());\r
- \r
- boolean returnValue;\r
- // Get a list of the notes\r
- if (query.next()) \r
- returnValue = query.valueBoolean(0, false); \r
- else\r
- returnValue = false;\r
-\r
- return returnValue; \r
- }\r
- // Set if a new thumbnail is needed\r
- public void setThumbnail(String guid, QByteArray thumbnail) {\r
- \r
- boolean check; \r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- \r
- check = query.prepare("Update note set thumbnail = :thumbnail where guid=:guid");\r
- query.bindValue(":guid", guid);\r
- query.bindValue(":thumbnail", thumbnail.toByteArray());\r
- check = query.exec();\r
- if (!check) \r
- logger.log(logger.EXTREME, "Note SQL set thumbail failed: " +query.lastError().toString());\r
-\r
- }\r
- // Set if a new thumbnail is needed\r
- public QByteArray getThumbnail(String guid) {\r
- \r
- boolean check; \r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- \r
- check = query.prepare("Select thumbnail from note where guid=:guid");\r
- query.bindValue(":guid", guid);\r
- check = query.exec();\r
- if (!check) \r
- logger.log(logger.EXTREME, "Note SQL get thumbail failed: " +query.lastError().toString());\r
- // Get a list of the notes\r
- if (query.next()) {\r
- try {\r
- if (query.getBlob(0) != null) {\r
- return new QByteArray(query.getBlob(0)); \r
- }\r
- } catch (java.lang.IllegalArgumentException e) {\r
- return null;\r
- }\r
- }\r
- return null;\r
- }\r
- // Get all thumbnails\r
- public HashMap<String, QPixmap> getThumbnails() {\r
- boolean check; \r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- HashMap<String, QPixmap> map = new HashMap<String,QPixmap>();\r
- \r
- check = query.prepare("Select guid,thumbnail from note where thumbnailneeded=false and isExpunged=false");\r
- check = query.exec();\r
- if (!check) \r
- logger.log(logger.EXTREME, "Note SQL get thumbail failed: " +query.lastError().toString());\r
- // Get a list of the notes\r
- while (query.next()) {\r
- try {\r
- if (query.getBlob(1) != null) {\r
- QByteArray data = new QByteArray(query.getBlob(1));\r
- QPixmap img = new QPixmap();\r
- if (img.loadFromData(data)) {\r
- img = img.scaled(Global.largeThumbnailSize);\r
- map.put(query.valueString(0), img);\r
- }\r
- } \r
- } catch (java.lang.IllegalArgumentException e) {\r
- logger.log(logger.HIGH, "Error retrieving thumbnail " +e.getMessage());\r
- }\r
- }\r
- return map;\r
- }\r
- // Get a list of notes that need thumbnails\r
- public List<String> findThumbnailsNeeded() {\r
- \r
- boolean check;\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- \r
- check = query.prepare("select guid from note where thumbnailneeded=true and isExpunged=false and DATEDIFF('MINUTE',updated,CURRENT_TIMESTAMP)>5 limit 5");\r
- check = query.exec();\r
- if (!check) \r
- logger.log(logger.EXTREME, "Note SQL findThumbnailsNeeded query failed: " +query.lastError().toString());\r
- \r
-\r
- // Get a list of the notes\r
- List<String> values = new ArrayList<String>();\r
- while (query.next()) {\r
- values.add(query.valueString(0)); \r
- }\r
-\r
- return values; \r
- }\r
- // Get a count of thumbnails needed\r
- public int getThumbnailNeededCount() {\r
- \r
- boolean check;\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- \r
- check = query.prepare("select count(guid) from note where thumbnailneeded=true and isExpunged=false and DATEDIFF('MINUTE',updated,CURRENT_TIMESTAMP)>5 limit 2");\r
- check = query.exec();\r
- if (!check) \r
- logger.log(logger.EXTREME, "Note SQL findThumbnailNeededCount query failed: " +query.lastError().toString());\r
- \r
- if (query.next()) {\r
- return query.valueInteger(0); \r
- }\r
-\r
- return 0; \r
- }\r
-\r
- //***********************************************************************************\r
- public String findAlternateGuid(String guid) {\r
- boolean check;\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- \r
- check = query.prepare("select guid from note where original_guid=:guid");\r
- query.bindValue(":guid", guid);\r
- check = query.exec();\r
- if (!check) \r
- logger.log(logger.EXTREME, "Note SQL findAlternateguid query failed: " +query.lastError().toString());\r
- \r
- if (query.next()) {\r
- return query.valueString(0); \r
- }\r
-\r
- return null; \r
- }\r
- \r
- //* Check if a note guid exists\r
- public boolean guidExists(String guid) {\r
- boolean check;\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- \r
- check = query.prepare("select guid from note where guid=:guid");\r
- query.bindValue(":guid", guid);\r
- check = query.exec();\r
- if (!check) \r
- logger.log(logger.EXTREME, "Note SQL guidExists query failed: " +query.lastError().toString());\r
- \r
- if (query.next()) {\r
- return true; \r
- }\r
-\r
- return false; \r
- }\r
- \r
- // Update a note content's hash. This happens if a resource is edited outside of NN\r
- public void updateResourceContentHash(String guid, String oldHash, String newHash) {\r
- Note n = getNote(guid, true, false, false, false,false);\r
- int position = n.getContent().indexOf("<en-media");\r
- int endPos;\r
- for (;position>-1;) {\r
- endPos = n.getContent().indexOf(">", position+1);\r
- String oldSegment = n.getContent().substring(position,endPos);\r
- int hashPos = oldSegment.indexOf("hash=\"");\r
- int hashEnd = oldSegment.indexOf("\"", hashPos+7);\r
- String hash = oldSegment.substring(hashPos+6, hashEnd);\r
- if (hash.equalsIgnoreCase(oldHash)) {\r
- String newSegment = oldSegment.replace(oldHash, newHash);\r
- String content = n.getContent().substring(0,position) +\r
- newSegment +\r
- n.getContent().substring(endPos);\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- query.prepare("update note set isdirty=true, thumbnailneeded=true, content=:content where guid=:guid");\r
- query.bindValue(":content", content);\r
- query.bindValue(":guid", n.getGuid());\r
- query.exec();\r
- }\r
- \r
- position = n.getContent().indexOf("<en-media", position+1);\r
- }\r
- }\r
-\r
- // Extract metadata from a note's Note.attributes.sourceApplication\r
- private NoteMetadata extractMetadata(String sourceApplication) {\r
- String consumerKey = "baumgarte:{";\r
- int startPos = sourceApplication.indexOf(consumerKey);\r
- if (startPos < 0 )\r
- return null;\r
- \r
- NoteMetadata meta = new NoteMetadata();\r
- startPos = startPos+consumerKey.length();\r
- \r
-// String startString = sourceApplication.substring(0,startPos);\r
- String metaString = sourceApplication.substring(startPos);\r
-// String endString = metaString.substring(metaString.indexOf("};"));\r
- int endPos = metaString.indexOf("};");\r
- if (endPos > 0)\r
- metaString = metaString.substring(0,endPos);\r
- \r
- String value = parseMetaString(metaString, "titleColor");\r
- if (value != null)\r
- meta.setColor(Integer.parseInt(value));\r
- \r
- value = parseMetaString(metaString, "pinned");\r
- if (value != null && value.equals(true))\r
- meta.setPinned(true);\r
- \r
- return meta;\r
- }\r
- \r
- // Given a metadata string from attribute.sourceApplication, we\r
- // extract the information for a given key.\r
- private String parseMetaString(String metaString, String key) {\r
- int startPos = metaString.indexOf(key);\r
- if (startPos < 0)\r
- return null;\r
- \r
- String value = metaString.substring(startPos+key.length()+1);\r
- int endPos = value.indexOf(";");\r
- if (endPos > 0)\r
- value = value.substring(0,endPos);\r
- \r
- return value;\r
- }\r
- \r
- // Given a set of metadata, we build a string that can be inserted\r
- // into the attribute.sourceApplication string.\r
- private String buildMetadataString(NoteMetadata meta) {\r
- StringBuffer value = new StringBuffer(removeExistingMetaString(meta.getGuid()));\r
- StringBuffer metaString = new StringBuffer();\r
- \r
- if (meta.isPinned()) {\r
- metaString.append("pinned=true;");\r
- }\r
- if (meta.getColor() != -1) {\r
- metaString.append("titleColor=" +new Integer(meta.getColor()).toString()+";");\r
- }\r
- if (metaString.length()>0) {\r
- \r
- // Adda any missing ";" or " " at the end of the existing \r
- // string.\r
- if (value.length()>1 && (!value.toString().trim().endsWith(";") || !value.toString().trim().endsWith(";"))) \r
- value.append("; ");\r
- \r
- value.append("baumgarte:{");\r
- value.append(metaString);\r
- value.append("};");\r
- return value.toString();\r
- }\r
- return null;\r
- }\r
-\r
- // This will remove the existing metadata string from the attribute.sourceApplication string.\r
- private String removeExistingMetaString(String guid) {\r
- NSqlQuery query = new NSqlQuery(db.getConnection());\r
- \r
- if (!query.prepare("Select attributeSourceApplication from Note where guid=:guid")) {\r
- logger.log(logger.EXTREME, "Note SQL retrieve has failed in removeExistingMetaString.");\r
- return null;\r
- }\r
- query.bindValue(":guid", guid);\r
- query.exec();\r
-\r
- // Get the application source string\r
- String sourceApplication = null;\r
- while (query.next()) {\r
- sourceApplication = query.valueString(0);\r
- }\r
- if (sourceApplication == null) \r
- return "";\r
- \r
- String consumerKey = "baumgarte:{";\r
- int startPos = sourceApplication.indexOf(consumerKey);\r
- if (startPos < 0 )\r
- return sourceApplication;\r
- String startString = sourceApplication.substring(0,startPos);\r
- String metaString = sourceApplication.substring(startPos);\r
- String endString = metaString.substring(metaString.indexOf("};")+2);\r
-\r
- return startString+endString;\r
- }\r
-\r
+ }
+ logger.log(logger.EXTREME, "Leaving addNote");
+ }
+ // Setup queries for get to save time later
+ private void prepareQueries() {
+ if (getQueryWithContent == null) {
+ getQueryWithContent = new NSqlQuery(db.getConnection());
+ if (!getQueryWithContent.prepare("Select "
+ +"guid, updateSequenceNumber, title, "
+ +"created, updated, deleted, active, notebookGuid, "
+ +"attributeSubjectDate, attributeLatitude, attributeLongitude, attributeAltitude, "
+ +"attributeAuthor, attributeSource, attributeSourceUrl, attributeSourceApplication, "
+ +"attributeContentClass, "
+ +"content, contentHash, contentLength"
+ +" from Note where guid=:guid and isExpunged=false")) {
+ logger.log(logger.EXTREME, "Note SQL select prepare with content has failed.");
+ logger.log(logger.MEDIUM, getQueryWithContent.lastError());
+ }
+ }
+
+ if (getQueryWithoutContent == null) {
+ getQueryWithoutContent = new NSqlQuery(db.getConnection());
+ if (!getQueryWithoutContent.prepare("Select "
+ +"guid, updateSequenceNumber, title, "
+ +"created, updated, deleted, active, notebookGuid, "
+ +"attributeSubjectDate, attributeLatitude, attributeLongitude, attributeAltitude, "
+ +"attributeAuthor, attributeSource, attributeSourceUrl, attributeSourceApplication, "
+ +"attributeContentClass"
+ +" from Note where guid=:guid and isExpunged=false")) {
+ logger.log(logger.EXTREME, "Note SQL select prepare without content has failed.");
+ logger.log(logger.MEDIUM, getQueryWithoutContent.lastError());
+ }
+ }
+
+ if (getAllQueryWithoutContent == null) {
+ getAllQueryWithoutContent = new NSqlQuery(db.getConnection());
+
+ if (!getAllQueryWithoutContent.prepare("Select "
+ +"guid, updateSequenceNumber, title, "
+ +"created, updated, deleted, active, notebookGuid, "
+ +"attributeSubjectDate, attributeLatitude, attributeLongitude, attributeAltitude, "
+ +"attributeAuthor, attributeSource, attributeSourceUrl, attributeSourceApplication, "
+ +"attributeContentClass "
+ +" from Note where isExpunged = false")) {
+ logger.log(logger.EXTREME, "Note SQL select prepare without content has failed.");
+ logger.log(logger.MEDIUM, getQueryWithoutContent.lastError());
+ }
+ }
+ }
+
+
+ // Get a note's content in blob format for index.
+ public String getNoteContentNoUTFConversion(String guid) {
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ query.prepare("Select content from note where guid=:guid");
+ query.bindValue(":guid", guid);
+ query.exec();
+ query.next();
+ return query.valueString(0);
+ }
+ // Get a note by Guid
+ public Note getNote(String noteGuid, boolean loadContent, boolean loadResources, boolean loadRecognition, boolean loadBinary, boolean loadTags) {
+
+ // ICHANGED 自分のキーに変更
+// extractMetadata("otherKey:{values};kimaira792:{titleColor=fff;pinned=true;};finalKey:{values1);");
+ if (noteGuid == null)
+ return null;
+ if (noteGuid.trim().equals(""))
+ return null;
+
+ prepareQueries();
+ NSqlQuery query;
+ if (loadContent) {
+ query = getQueryWithContent;
+ } else {
+ query = getQueryWithoutContent;
+ }
+
+ query.bindValue(":guid", noteGuid);
+ if (!query.exec()) {
+ logger.log(logger.EXTREME, "Note SQL select exec has failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ return null;
+ }
+ if (!query.next()) {
+ logger.log(logger.EXTREME, "SQL Retrieve failed for note guid " +noteGuid + " in getNote()");
+ logger.log(logger.EXTREME, " -> " +query.lastError().toString());
+ logger.log(logger.EXTREME, " -> " +query.lastError());
+ return null;
+ }
+ Note n = mapNoteFromQuery(query, loadContent, loadResources, loadRecognition, loadBinary, loadTags);
+ n.setContent(fixCarriageReturn(n.getContent()));
+ n.getAttributes().setContentClassIsSet(false);
+ return n;
+ }
+ // Get a note by Guid
+ public Note mapNoteFromQuery(NSqlQuery query, boolean loadContent, boolean loadResources, boolean loadRecognition, boolean loadBinary, boolean loadTags) {
+ DateFormat indfm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
+// indfm = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy");
+
+ Note n = new Note();
+ NoteAttributes na = new NoteAttributes();
+ n.setAttributes(na);
+
+ n.setGuid(query.valueString(0));
+ n.setUpdateSequenceNum(new Integer(query.valueString(1)));
+ n.setTitle(query.valueString(2));
+
+ try {
+ n.setCreated(indfm.parse(query.valueString(3)).getTime());
+ n.setUpdated(indfm.parse(query.valueString(4)).getTime());
+ n.setDeleted(indfm.parse(query.valueString(5)).getTime());
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+
+ n.setActive(query.valueBoolean(6,true));
+ n.setNotebookGuid(query.valueString(7));
+
+ try {
+ String attributeSubjectDate = query.valueString(8);
+ if (!attributeSubjectDate.equals(""))
+ na.setSubjectDate(indfm.parse(attributeSubjectDate).getTime());
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ na.setLatitude(new Float(query.valueString(9)));
+ na.setLongitude(new Float(query.valueString(10)));
+ na.setAltitude(new Float(query.valueString(11)));
+ na.setAuthor(query.valueString(12));
+ na.setSource(query.valueString(13));
+ na.setSourceURL(query.valueString(14));
+ na.setSourceApplication(query.valueString(15));
+ na.setContentClass(query.valueString(16));
+
+ if (loadTags) {
+ List<String> tagGuids = noteTagsTable.getNoteTags(n.getGuid());
+ List<String> tagNames = new ArrayList<String>();
+ TagTable tagTable = db.getTagTable();
+ for (int i=0; i<tagGuids.size(); i++) {
+ String currentGuid = tagGuids.get(i);
+ Tag tag = tagTable.getTag(currentGuid);
+ if (tag.getName() != null)
+ tagNames.add(tag.getName());
+ else
+ tagNames.add("");
+ }
+
+ n.setTagNames(tagNames);
+ n.setTagGuids(tagGuids);
+ }
+
+ if (loadContent) {
+ QTextCodec codec = QTextCodec.codecForLocale();
+ codec = QTextCodec.codecForName("UTF-8");
+ String unicode = codec.fromUnicode(query.valueString(17)).toString();
+
+ // This is a hack. Basically I need to convert HTML Entities to "normal" text, but if I
+ // convert the < character to < it will mess up the XML parsing. So, to get around this
+ // I am "bit stuffing" the < to &< so StringEscapeUtils doesn't unescape it. After
+ // I'm done I convert it back.
+ StringBuffer buffer = new StringBuffer(unicode);
+ if (Global.enableHTMLEntitiesFix && unicode.indexOf("&#") > 0) {
+ unicode = query.valueString(17);
+ //System.out.println(unicode);
+ //unicode = unicode.replace("<", "&_lt;");
+ //unicode = codec.fromUnicode(StringEscapeUtils.unescapeHtml(unicode)).toString();
+ //unicode = unicode.replace("&_lt;", "<");
+ //System.out.println("************************");
+ int j=1;
+ for (int i=buffer.indexOf("&#"); i != -1 && buffer.indexOf("&#", i)>0; i=buffer.indexOf("&#",i+1)) {
+ j = buffer.indexOf(";",i)+1;
+ if (i<j) {
+ String entity = buffer.substring(i,j).toString();
+ int len = entity.length()-1;
+ String tempEntity = entity.substring(2, len);
+ try {
+ Integer.parseInt(tempEntity);
+ entity = codec.fromUnicode(StringEscapeUtils.unescapeHtml4(entity)).toString();
+ buffer.delete(i, j);
+ buffer.insert(i, entity);
+ } catch (Exception e){ }
+
+ }
+ }
+ }
+
+ n.setContent(unicode);
+// n.setContent(query.valueString(16).toString());
+
+ String contentHash = query.valueString(18);
+ if (contentHash != null)
+ n.setContentHash(contentHash.getBytes());
+ n.setContentLength(new Integer(query.valueString(19)));
+ }
+ if (loadResources)
+ n.setResources(noteResourceTable.getNoteResources(n.getGuid(), loadBinary));
+ if (loadRecognition) {
+ if (n.getResources() == null) {
+ List<Resource> resources = noteResourceTable.getNoteResourcesRecognition(n.getGuid());
+ n.setResources(resources);
+ } else {
+ // We need to merge the recognition resources with the note resources retrieved earlier
+ for (int i=0; i<n.getResources().size(); i++) {
+ Resource r = noteResourceTable.getNoteResourceRecognition(n.getResources().get(i).getGuid());
+ n.getResources().get(i).setRecognition(r.getRecognition());
+ }
+ }
+ }
+ n.setContent(fixCarriageReturn(n.getContent()));
+ return n;
+ }
+ // Update a note's title
+ public void updateNoteTitle(String guid, String title) {
+ logger.log(logger.HIGH, "Entering NoteTable.updateNoteTitle");
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ boolean check = query.prepare("Update Note set title=:title, isDirty=true where guid=:guid");
+ if (!check) {
+ logger.log(logger.EXTREME, "Update note title sql prepare has failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ query.bindValue(":title", title);
+ query.bindValue(":guid", guid);
+ check = query.exec();
+ if (!check) {
+ logger.log(logger.EXTREME, "Update note title has failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ logger.log(logger.HIGH, "Leaving NoteTable.updateNoteTitle");
+ }
+ // Update a note's creation date
+ public void updateNoteCreatedDate(String guid, QDateTime date) {
+ logger.log(logger.HIGH, "Entering NoteTable.updateNoteCreatedDate");
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ boolean check = query.prepare("Update Note set created=:created, isDirty=true where guid=:guid");
+ if (!check) {
+ logger.log(logger.EXTREME, "Update note creation update sql prepare has failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+
+ query.bindValue(":created", date.toString("yyyy-MM-dd HH:mm:ss"));
+ query.bindValue(":guid", guid);
+
+ check = query.exec();
+ if (!check) {
+ logger.log(logger.EXTREME, "Update note creation date has failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ logger.log(logger.HIGH, "Leaving NoteTable.updateNoteCreatedDate");
+ }
+ // Update a note's creation date
+ public void updateNoteAlteredDate(String guid, QDateTime date) {
+ logger.log(logger.HIGH, "Entering NoteTable.updateNoteAlteredDate");
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ boolean check = query.prepare("Update Note set updated=:altered, isDirty=true where guid=:guid");
+ if (!check) {
+ logger.log(logger.EXTREME, "Update note altered sql prepare has failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+
+ query.bindValue(":altered", date.toString("yyyy-MM-dd HH:mm:ss"));
+ query.bindValue(":guid", guid);
+
+ check = query.exec();
+ if (!check) {
+ logger.log(logger.EXTREME, "Update note altered date has failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ logger.log(logger.HIGH, "Leaving NoteTable.updateNoteAlteredDate");
+ }
+ // Update a note's creation date
+ public void updateNoteSubjectDate(String guid, QDateTime date) {
+ logger.log(logger.HIGH, "Entering NoteTable.updateNoteSubjectDate");
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ boolean check = query.prepare("Update Note set attributeSubjectDate=:altered, isDirty=true where guid=:guid");
+ if (!check) {
+ logger.log(logger.EXTREME, "Update note subject date sql prepare has failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+
+ query.bindValue(":altered", date.toString("yyyy-MM-dd HH:mm:ss"));
+ query.bindValue(":guid", guid);
+
+ check = query.exec();
+ if (!check) {
+ logger.log(logger.EXTREME, "Update note subject date date has failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ logger.log(logger.HIGH, "Leaving NoteTable.updateNoteSubjectDate");
+ }
+ // Update a note's creation date
+ public void updateNoteAuthor(String guid, String author) {
+ logger.log(logger.HIGH, "Entering NoteTable.updateNoteSubject");
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ boolean check = query.prepare("Update Note set attributeAuthor=:author, isDirty=true where guid=:guid");
+ if (!check) {
+ logger.log(logger.EXTREME, "Update note author sql prepare has failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+
+ query.bindValue(":author", author);
+ query.bindValue(":guid", guid);
+
+ check = query.exec();
+ if (!check) {
+ logger.log(logger.EXTREME, "Update note author has failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ logger.log(logger.HIGH, "Leaving NoteTable.updateNoteSubject");
+ }
+ // Update a note's geo tags
+ public void updateNoteGeoTags(String guid, Double lon, Double lat, Double alt) {
+ logger.log(logger.HIGH, "Entering NoteTable.updateNoteGeoTags");
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ boolean check = query.prepare("Update Note set attributeLongitude=:longitude, "+
+ "attributeLatitude=:latitude, attributeAltitude=:altitude, isDirty=true where guid=:guid");
+ if (!check) {
+ logger.log(logger.EXTREME, "Update note author sql prepare has failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+
+ query.bindValue(":longitude", lon);
+ query.bindValue(":latitude", lat);
+ query.bindValue(":altitude", alt);
+ query.bindValue(":guid", guid);
+
+ check = query.exec();
+ if (!check) {
+ logger.log(logger.EXTREME, "Update note geo tag has failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ logger.log(logger.HIGH, "Leaving NoteTable.updateNoteGeoTags");
+
+ }
+ // Update a note's creation date
+ public void updateNoteSourceUrl(String guid, String url) {
+ logger.log(logger.HIGH, "Entering NoteTable.updateNoteSourceUrl");
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ boolean check = query.prepare("Update Note set attributeSourceUrl=:url, isDirty=true where guid=:guid");
+ if (!check) {
+ logger.log(logger.EXTREME, "Update note url sql prepare has failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+
+ query.bindValue(":url", url);
+ query.bindValue(":guid", guid);
+
+ check = query.exec();
+ if (!check) {
+ logger.log(logger.EXTREME, "Update note url has failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ logger.log(logger.HIGH, "Leaving NoteTable.updateNoteSourceUrl");
+ }
+ // Update the notebook that a note is assigned to
+ public void updateNoteNotebook(String guid, String notebookGuid, boolean expungeFromRemote) {
+ logger.log(logger.HIGH, "Entering NoteTable.updateNoteNotebook");
+ String currentNotebookGuid = new String("");
+
+
+ // If we are going from a synchronized notebook to a local notebook, we
+ // need to tell Evernote to purge the note online. However, if this is
+ // conflicting change we move it to the local notebook without deleting it
+ // or it would then delete the copy on the remote server.
+ NotebookTable notebookTable = new NotebookTable(logger, db);
+ DeletedTable deletedTable = new DeletedTable(logger, db);
+ if (expungeFromRemote) {
+ if (!notebookTable.isNotebookLocal(currentNotebookGuid) & notebookTable.isNotebookLocal(notebookGuid)) {
+ deletedTable.addDeletedItem(guid, "NOTE");
+ }
+ }
+
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ boolean check = query.prepare("Update Note set notebookGuid=:notebook, isDirty=true where guid=:guid");
+ if (!check) {
+ logger.log(logger.EXTREME, "Update note notebook sql prepare has failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ query.bindValue(":notebook", notebookGuid);
+ query.bindValue(":guid", guid);
+
+ check = query.exec();
+ if (!check) {
+ logger.log(logger.EXTREME, "Update note notebook has failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ logger.log(logger.HIGH, "Leaving NoteTable.updateNoteNotebook");
+ }
+ // Update a note's title
+ public void updateNoteContent(String guid, String content) {
+ logger.log(logger.HIGH, "Entering NoteTable.updateNoteContent");
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ boolean check = query.prepare("Update Note set content=:content, updated=CURRENT_TIMESTAMP(), isDirty=true, indexNeeded=true, " +
+ " thumbnailneeded=true where guid=:guid");
+ if (!check) {
+ logger.log(logger.EXTREME, "Update note content sql prepare has failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+
+// QTextCodec codec = QTextCodec.codecForLocale();
+// codec = QTextCodec.codecForName("UTF-8");
+// query.bindValue(":content", codec.fromUnicode(content).toString());
+ query.bindValue(":content", content);
+ query.bindValue(":guid", guid);
+
+ check = query.exec();
+ if (!check) {
+ logger.log(logger.EXTREME, "Update note content has failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ logger.log(logger.HIGH, "Leaving NoteTable.updateNoteContent");
+ }
+
+ // Delete a note
+ public void deleteNote(String guid) {
+ logger.log(logger.HIGH, "Entering NoteTable.deleteNote");
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ query.prepare("Update Note set deleted=CURRENT_TIMESTAMP(), active=false, isDirty=true where guid=:guid");
+ query.bindValue(":guid", guid);
+ if (!query.exec()) {
+ logger.log(logger.MEDIUM, "Note delete failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ logger.log(logger.HIGH, "Leaving NoteTable.deleteNote");
+ }
+ public void restoreNote(String guid) {
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ query.prepare("Update Note set deleted=:reset, active=true, isDirty=true where guid=:guid");
+// query.prepare("Update Note set deleted=0, active=true, isDirty=true where guid=:guid");
+ query.bindValue(":guid", guid);
+ query.bindValue(":reset", "1969-12-31 19:00:00");
+ if (!query.exec()) {
+ logger.log(logger.MEDIUM, "Note restore failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ }
+ // Purge a note (actually delete it instead of just marking it deleted)
+ public void expungeNote(String guid, boolean permanentExpunge, boolean needsSync) {
+ logger.log(logger.HIGH, "Entering NoteTable.expungeNote");
+
+ if (!permanentExpunge) {
+ hideExpungedNote(guid, needsSync);
+ return;
+ }
+
+
+ NSqlQuery note = new NSqlQuery(db.getConnection());
+ NSqlQuery resources = new NSqlQuery(db.getResourceConnection());
+ NSqlQuery tags = new NSqlQuery(db.getConnection());
+ NSqlQuery words = new NSqlQuery(db.getIndexConnection());
+
+ note.prepare("Delete from Note where guid=:guid");
+ resources.prepare("Delete from NoteResources where noteGuid=:guid");
+ tags.prepare("Delete from NoteTags where noteGuid=:guid");
+ words.prepare("Delete from words where guid=:guid");
+
+ note.bindValue(":guid", guid);
+ resources.bindValue(":guid", guid);
+ tags.bindValue(":guid", guid);
+ words.bindValue(":guid", guid);
+
+ // Start purging notes.
+ if (!note.exec()) {
+ logger.log(logger.MEDIUM, "Purge from note failed.");
+ logger.log(logger.MEDIUM, note.lastError());
+ }
+ if (!resources.exec()) {
+ logger.log(logger.MEDIUM, "Purge from resources failed.");
+ logger.log(logger.MEDIUM, resources.lastError());
+ }
+ if (!tags.exec()) {
+ logger.log(logger.MEDIUM, "Note tags delete failed.");
+ logger.log(logger.MEDIUM, tags.lastError());
+ }
+
+ if (!words.exec()) {
+ logger.log(logger.MEDIUM, "Word delete failed.");
+ logger.log(logger.MEDIUM, words.lastError());
+ }
+ if (needsSync) {
+ DeletedTable deletedTable = new DeletedTable(logger, db);
+ deletedTable.addDeletedItem(guid, "Note");
+ }
+ logger.log(logger.HIGH, "Leaving NoteTable.expungeNote");
+ }
+ // Purge a bunch of notes based upon the notebook
+ public void expungeNotesByNotebook(String notebookGuid, boolean permanentExpunge, boolean needsSync) {
+ List<String> notes = getNotesByNotebook(notebookGuid);
+ for (int i=0; i<notes.size(); i++) {
+ expungeNote(notes.get(i), permanentExpunge, needsSync);
+ }
+ }
+
+ // Purge a note (actually delete it instead of just marking it deleted)
+ public void hideExpungedNote(String guid, boolean needsSync) {
+ NSqlQuery note = new NSqlQuery(db.getConnection());
+ NSqlQuery resources = new NSqlQuery(db.getResourceConnection());
+ NSqlQuery tags = new NSqlQuery(db.getConnection());
+ NSqlQuery words = new NSqlQuery(db.getIndexConnection());
+
+ note.prepare("Update Note set isExpunged=true where guid=:guid");
+ resources.prepare("Delete from NoteResources where noteGuid=:guid");
+ tags.prepare("Delete from NoteTags where noteGuid=:guid");
+// words.prepare("Delete from words where guid=:guid");
+
+ note.bindValue(":guid", guid);
+ resources.bindValue(":guid", guid);
+ tags.bindValue(":guid", guid);
+ words.bindValue(":guid", guid);
+
+ // Start purging notes.
+ if (!note.exec()) {
+ logger.log(logger.MEDIUM, "Purge from note failed.");
+ logger.log(logger.MEDIUM, note.lastError());
+ }
+ if (!resources.exec()) {
+ logger.log(logger.MEDIUM, "Purge from resources failed.");
+ logger.log(logger.MEDIUM, resources.lastError());
+ }
+ if (!tags.exec()) {
+ logger.log(logger.MEDIUM, "Note tags delete failed.");
+ logger.log(logger.MEDIUM, tags.lastError());
+ }
+// System.out.println("Hiding Note: Deleting words");
+// if (!words.exec()) {
+// logger.log(logger.MEDIUM, "Word delete failed.");
+// logger.log(logger.MEDIUM, words.lastError());
+// }
+ if (needsSync) {
+ DeletedTable deletedTable = new DeletedTable(logger, db);
+ deletedTable.addDeletedItem(guid, "Note");
+ }
+ }
+
+
+ // Purge all deleted notes;
+ public void expungeAllDeletedNotes() {
+ logger.log(logger.HIGH, "Entering NoteTable.expungeAllDeletedNotes");
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ query.exec("select guid, updateSequenceNumber from note where active = false");
+ List<String> guids = new ArrayList<String>();
+ List<Integer> usns = new ArrayList<Integer>();
+ while (query.next()) {
+ guids.add(query.valueString(0));
+ Integer usn = new Integer(query.valueString(1));
+ usns.add(usn);
+ }
+
+ for (int i=0; i<guids.size(); i++) {
+ Integer usn = usns.get(i);
+ String guid = guids.get(i);
+ if (usn == 0)
+ expungeNote(guid, true, false);
+ else
+ expungeNote(guid, false, true);
+ }
+ logger.log(logger.HIGH, "Leaving NoteTable.expungeAllDeletedNotes");
+ }
+ // Update the note sequence number
+ public void updateNoteSequence(String guid, int sequence) {
+ logger.log(logger.HIGH, "Entering NoteTable.updateNoteSequence");
+ boolean check;
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ check = query.prepare("Update Note set updateSequenceNumber=:sequence where guid=:guid");
+
+ query.bindValue(":sequence", sequence);
+ query.bindValue(":guid", guid);
+
+ query.exec();
+ if (!check) {
+ logger.log(logger.MEDIUM, "Note sequence update failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ logger.log(logger.HIGH, "Leaving NoteTable.updateNoteSequence");
+ }
+ // Update the note Guid
+ public void updateNoteGuid(String oldGuid, String newGuid) {
+ logger.log(logger.HIGH, "Entering NoteTable.updateNoteGuid");
+ boolean check;
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ NSqlQuery resQuery = new NSqlQuery(db.getResourceConnection());
+ NSqlQuery wordQuery = new NSqlQuery(db.getIndexConnection());
+
+ query.prepare("Update Note set guid=:newGuid, original_guid=:original_guid where guid=:oldGuid");
+
+ query.bindValue(":original_guid", oldGuid);
+ query.bindValue(":newGuid", newGuid);
+ query.bindValue(":oldGuid", oldGuid);
+
+ check = query.exec();
+ if (!check) {
+ logger.log(logger.MEDIUM, "Note Guid update failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+
+ query.prepare("Update NoteTags set noteGuid=:newGuid where noteGuid=:oldGuid");
+ query.bindValue(":newGuid", newGuid);
+ query.bindValue(":oldGuid", oldGuid);
+ check = query.exec();
+ if (!check) {
+ logger.log(logger.MEDIUM, "Note guid update failed for NoteTags.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+
+ wordQuery.prepare("Update words set guid=:newGuid where guid=:oldGuid");
+ wordQuery.bindValue(":newGuid", newGuid);
+ wordQuery.bindValue(":oldGuid", oldGuid);
+ // IFIXED check = が抜けていたので修正
+ check = wordQuery.exec();
+ if (!check) {
+ logger.log(logger.MEDIUM, "Note guid update failed for Words.");
+ logger.log(logger.MEDIUM, wordQuery.lastError());
+ }
+ resQuery.prepare("Update noteresources set noteguid=:newGuid where noteguid=:oldGuid");
+ resQuery.bindValue(":newGuid", newGuid);
+ resQuery.bindValue(":oldGuid", oldGuid);
+ // IFIXED check = が抜けていたので修正
+ check = resQuery.exec();
+ if (!check) {
+ logger.log(logger.MEDIUM, "Note guid update failed for noteresources.");
+ logger.log(logger.MEDIUM, resQuery.lastError());
+ }
+
+ // ICHANGED 操作履歴テーブルのguidを更新
+ db.getHistoryTable().updateHistoryGuid(newGuid, oldGuid);
+
+ // ICHANGED 除外ノートテーブルのguidを更新
+ db.getExcludedTable().updateExcludedNoteGuid(newGuid, oldGuid);
+
+ // ICHANGED スター付きノートテーブルのguidを更新
+ db.getStaredTable().updateStaredNoteGuid(newGuid, oldGuid);
+ }
+ // Update a note
+ public void updateNote(Note n) {
+ logger.log(logger.HIGH, "Entering NoteTable.updateNote");
+ NoteMetadata meta = getNoteMetaInformation(n.getGuid());
+ String originalGuid = findAlternateGuid(n.getGuid());
+ expungeNote(n.getGuid(), true, false);
+ addNote(n, false);
+ if (n!=null) {
+ updateNoteMetadata(meta);
+ }
+ if (originalGuid != null) {
+ updateNoteGuid(n.getGuid(), originalGuid);
+ updateNoteGuid(originalGuid, n.getGuid());
+ }
+ logger.log(logger.HIGH, "Leaving NoteTable.updateNote");
+ }
+ // Does a note exist?
+ public boolean exists(String guid) {
+ if (guid == null)
+ return false;
+ if (guid.trim().equals(""))
+ return false;
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ query.prepare("Select guid from note where guid=:guid");
+ query.bindValue(":guid", guid);
+ if (!query.exec())
+ logger.log(logger.EXTREME, "note.exists SQL retrieve has failed.");
+ boolean retVal = query.next();
+ return retVal;
+ }
+ // Does a note exist?
+ public boolean isNoteExpunged(String guid) {
+ if (guid == null)
+ return false;
+ if (guid.trim().equals(""))
+ return false;
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ query.prepare("Select isExpunged from note where guid=:guid and isExpunged = true");
+ query.bindValue(":guid", guid);
+ if (!query.exec())
+ logger.log(logger.EXTREME, "note.isNoteExpunged SQL retrieve has failed.");
+ boolean retVal = query.next();
+ return retVal;
+ }
+ // This is a convenience method to check if a note exists & update/create based upon it
+ public void syncNote(Note note) {
+ logger.log(logger.HIGH, "Entering NoteTable.syncNote");
+ // If we got the note from Evernote we use its
+ // metadata instead of the local copy.
+ NoteMetadata meta = null;
+ if (note.getAttributes() != null && note.getAttributes().getSourceApplication() != null) {
+ meta = extractMetadata(note.getAttributes().getSourceApplication());
+ } else
+ meta = getNoteMetaInformation(note.getGuid());
+
+ // Now, if the note exists we simply update it. Otherwise we
+ // add a new note.
+ if (exists(note.getGuid())) {
+ updateNote(note);
+ }
+ else
+ addNote(note, false);
+
+ // If we have metadata, we write it out.
+ if (meta != null) {
+ meta.setGuid(note.getGuid());
+ updateNoteMetadata(meta);
+ }
+ logger.log(logger.HIGH, "Leaving NoteTable.syncNote");
+ }
+ // Get a list of notes that need to be updated
+ public List <Note> getDirty() {
+ String guid;
+ Note tempNote;
+ List<Note> notes = new ArrayList<Note>();
+ List<String> index = new ArrayList<String>();
+
+ boolean check;
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+
+ check = query.exec("Select guid from Note where isDirty = true and isExpunged = false and notebookGuid not in (select guid from notebook where local = true or linked = true)");
+ if (!check)
+ logger.log(logger.EXTREME, "Note SQL retrieve has failed: " +query.lastError().toString());
+
+ // Get a list of the notes
+ while (query.next()) {
+ guid = new String();
+ guid = query.valueString(0);
+ index.add(guid);
+ }
+
+ // Start getting notes
+ for (int i=0; i<index.size(); i++) {
+ tempNote = getNote(index.get(i), true,true,false,true,true);
+ notes.add(tempNote);
+ }
+ logger.log(logger.LOW, "Dirty local notes: " +new Integer(notes.size()).toString());
+ return notes;
+ }
+ // Get a list of notes that need to be updated
+ public List <Note> getDirtyLinkedNotes() {
+ String guid;
+ Note tempNote;
+ List<Note> notes = new ArrayList<Note>();
+ List<String> index = new ArrayList<String>();
+
+ boolean check;
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+
+ check = query.exec("Select guid from Note where isDirty = true and isExpunged = false and notebookGuid in (select guid from notebook where linked = true)");
+ if (!check)
+ logger.log(logger.EXTREME, "Note SQL retrieve has failed: " +query.lastError().toString());
+
+ // Get a list of the notes
+ while (query.next()) {
+ guid = new String();
+ guid = query.valueString(0);
+ index.add(guid);
+ }
+
+ // Start getting notes
+ for (int i=0; i<index.size(); i++) {
+ tempNote = getNote(index.get(i), true,true,false,true,true);
+ notes.add(tempNote);
+ }
+ logger.log(logger.LOW, "Dirty linked local notes: " +new Integer(notes.size()).toString());
+ return notes;
+ }
+ // Get a list of notes that need to be updated
+ public List <Note> getDirtyLinked(String notebookGuid) {
+ String guid;
+ Note tempNote;
+ List<Note> notes = new ArrayList<Note>();
+ List<String> index = new ArrayList<String>();
+
+ boolean check;
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+
+ query.prepare("Select guid from Note where isDirty = true and isExpunged = false and notebookGuid=:notebookGuid");
+ query.bindValue(":notebookGuid", notebookGuid);
+ check = query.exec();
+ if (!check)
+ logger.log(logger.EXTREME, "Note SQL retrieve has failed getting dirty linked notes: " +query.lastError().toString());
+
+ // Get a list of the notes
+ while (query.next()) {
+ guid = new String();
+ guid = query.valueString(0);
+ index.add(guid);
+ }
+
+ // Start getting notes
+ for (int i=0; i<index.size(); i++) {
+ tempNote = getNote(index.get(i), true,true,false,true,true);
+ notes.add(tempNote);
+ }
+ logger.log(logger.LOW, "Dirty local notes for notebook " +notebookGuid +": " +new Integer(notes.size()).toString());
+ return notes;
+ }
+ // Get a list of notes that need to be updated
+ // IFIXED バグで空のリストを返すだけのメソッドになっていたのを修正
+ public List <String> getNotesByNotebook(String notebookGuid) {
+ List<String> notes = new ArrayList<String>();
+ // IFIXED List<String> index = new ArrayList<String>();
+
+ boolean check;
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+
+ check = query.prepare("Select guid from Note where notebookguid=:notebookguid");
+ if (!check)
+ logger.log(logger.EXTREME, "Note SQL retrieve has failed: " +query.lastError().toString());
+ query.bindValue(":notebookguid", notebookGuid);
+ query. exec();
+
+ // Get a list of the notes
+ while (query.next()) {
+ // IFIXED index.add(query.valueString(0));
+ notes.add(query.valueString(0));
+ }
+
+ return notes;
+ }
+ // Get a list of notes that need to be updated
+ public boolean isNoteDirty(String guid) {
+
+ boolean check;
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+
+ check = query.prepare("Select guid from Note where isDirty = true and guid=:guid");
+ query.bindValue(":guid", guid);
+ check = query.exec();
+ if (!check)
+ logger.log(logger.EXTREME, "Note SQL retrieve has failed: " +query.lastError().toString());
+
+ boolean returnValue;
+ // Get a list of the notes
+ if (query.next())
+ returnValue = true;
+ else
+ returnValue = false;
+
+ return returnValue;
+ }
+
+ // Reset the dirty bit
+ public void resetDirtyFlag(String guid) {
+ logger.log(logger.LOW, "Resetting dirty flag for " +guid);
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+
+ query.prepare("Update note set isdirty=false where guid=:guid");
+ query.bindValue(":guid", guid);
+ if (!query.exec())
+ logger.log(logger.EXTREME, "Error resetting note dirty field.");
+ }
+ // Get all notes
+ public List<String> getAllGuids() {
+ List<String> notes = new ArrayList<String>();
+
+ boolean check;
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+
+ check = query.exec("Select guid from Note");
+ if (!check)
+ logger.log(logger.EXTREME, "Notebook SQL retrieve has failed: "+query.lastError());
+
+ // Get a list of the notes
+ while (query.next()) {
+ notes.add(new String(query.valueString(0)));
+ }
+ return notes;
+ }
+ // Get all notes
+ public List<Note> getAllNotes() {
+ List<Note> notes = new ArrayList<Note>();
+ prepareQueries();
+ boolean check;
+ if (getAllQueryWithoutContent == null)
+ prepareQueries();
+ NSqlQuery query = getAllQueryWithoutContent;
+ check = query.exec();
+ if (!check)
+ logger.log(logger.EXTREME, "Notebook SQL retrieve has failed: "+query.lastError());
+ // Get a list of the notes
+ while (query.next()) {
+ notes.add(mapNoteFromQuery(query, false, false, false, false, true));
+ }
+ return notes;
+ }
+ // Count unindexed notes
+ public int getUnindexedCount() {
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ query.exec("select count(*) from note where indexneeded=true and isExpunged = false");
+ query.next();
+ int returnValue = new Integer(query.valueString(0));
+ return returnValue;
+ }
+ // Count unsynchronized notes
+ public int getDirtyCount() {
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ query.exec("select count(guid) from note where isDirty=true and isExpunged = false");
+ query.next();
+ int returnValue = new Integer(query.valueString(0));
+ logger.log(logger.LOW, "dirty count: " +returnValue);
+ //query.exec("select count(guid) from note where isDirty=true and Active = 0 and isExpunged = false");
+ //query.next();
+ //logger.log(logger.LOW, "dirty count (active only): " +query.valueString(0));
+ //query.exec("Select count(guid) from Note where isDirty = true and isExpunged = false and notebookGuid not in (select guid from notebook where local = true or linked = true)");
+ //query.next();
+ //logger.log(logger.LOW, "dirty count (no l&l notebooks): " +query.valueString(0));
+ //logger.log(logger.LOW, "Beginning stack trace");
+ //logger.log(logger.LOW, Thread.currentThread().getStackTrace());
+
+ //logger.log(logger.LOW, "*************************");
+ //logger.log(logger.LOW, "*** DIRTY RECORD DUMP ***");
+ //logger.log(logger.LOW, "*************************");
+ //List<Note> recs = getDirty();
+ //for (int i=0; i<recs.size(); i++) {
+ //Note n = getNote(recs.get(i).getGuid(), true, true, true, false, true);
+ //logger.log(logger.LOW, "-- Begin Record ---");
+ //logger.log(logger.LOW, "Guid: " +n.getGuid());
+ //logger.log(logger.LOW, "Title: " +n.getTitle());
+ //logger.log(logger.LOW, "Active: " +n.isActive());
+ //logger.log(logger.LOW, "USN: " +n.getUpdateSequenceNum());
+ //logger.log(logger.LOW, "Date Created: " +n.getCreated());
+ //logger.log(logger.LOW, "Date Updated: " +n.getUpdated());
+ //logger.log(logger.LOW, "Date Deleted: " +n.getDeleted());
+ //logger.log(logger.LOW, "Resource Count: " +n.getResourcesSize());
+ //for (int j=0; j<n.getResourcesSize(); j++) {
+ //Resource r = n.getResources().get(j);
+ //logger.log(logger.LOW, "Resource " +j +": " +r.getGuid());
+ //logger.log(logger.LOW, "Active: " +r.isActive());
+ //logger.log(logger.LOW, "USN: " +r.getUpdateSequenceNum());
+ //}
+ //logger.log(logger.LOW, "-- End Record ---");
+ //}
+ //logger.log(logger.LOW, "*****************************");
+ //logger.log(logger.LOW, "*** End DIRTY RECORD DUMP ***");
+ //logger.log(logger.LOW, "*****************************");
+ return returnValue;
+ }
+ // Count notes
+ public int getNoteCount() {
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ query.exec("select count(*) from note where isExpunged = false");
+ query.next();
+ int returnValue = new Integer(query.valueString(0));
+ return returnValue;
+ }
+ // Count deleted notes
+ public int getDeletedCount() {
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ query.exec("select count(*) from note where isExpunged = false and active = false");
+ if (!query.next())
+ return 0;
+ int returnValue = new Integer(query.valueString(0));
+ return returnValue;
+ }
+ // Reset a note sequence number to zero. This is useful for moving conflicting notes
+ public void resetNoteSequence(String guid) {
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ boolean check = query.prepare("Update Note set updateSequenceNumber=0, isDirty=true where guid=:guid");
+ if (!check) {
+ logger.log(logger.EXTREME, "Update note ResetSequence sql prepare has failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ query.bindValue(":guid", guid);
+ check = query.exec();
+ if (!check) {
+ logger.log(logger.EXTREME, "Update note sequence number has failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ }
+
+
+ // Update a note resource by the hash
+ public void updateNoteResourceGuidbyHash(String noteGuid, String resGuid, String hash) {
+ NSqlQuery query = new NSqlQuery(db.getResourceConnection());
+/* query.prepare("Select guid from NoteResources where noteGuid=:noteGuid and datahash=:hex");
+ query.bindValue(":noteGuid", noteGuid);
+ query.bindValue(":hex", hash);
+ query.exec();
+ if (!query.next()) {
+ logger.log(logger.LOW, "Error finding note resource in RNoteTable.updateNoteResourceGuidbyHash. GUID="+noteGuid +" resGuid="+ resGuid+" hash="+hash);
+ return;
+ }
+ String guid = query.valueString(0);
+*/
+ query.prepare("update noteresources set guid=:guid where noteGuid=:noteGuid and datahash=:hex");
+ query.bindValue(":guid", resGuid);
+ query.bindValue(":noteGuid", noteGuid);
+ query.bindValue(":hex", hash);
+ if (!query.exec()) {
+ logger.log(logger.EXTREME, "Note Resource Update by Hash failed");
+ logger.log(logger.EXTREME, query.lastError().toString());
+ }
+ }
+
+ // Fix CRLF problem that is on some notes
+ private String fixCarriageReturn(String note) {
+ if (note == null || !Global.enableCarriageReturnFix)
+ return note;
+ QByteArray a0Hex = new QByteArray("a0");
+ String a0 = QByteArray.fromHex(a0Hex).toString();
+ note = note.replace("<div>"+a0+"</div>", "<div> </div>");
+ return note.replace("<div/>", "<div> </div>");
+ }
+
+ // Expunge notes that we don't want to synchronize
+ public List<String> expungeIgnoreSynchronizedNotes(List<String> notebooks, List<String>tags, List<String> linked) {
+
+ List<String> noteGuids = new ArrayList<String>();
+ for (int i=0; i<notebooks.size(); i++) {
+ List<String> notes = findNotesByNotebook(notebooks.get(i));
+ for (int j=0; j<notes.size(); j++) {
+ if (!isNoteDirty(notes.get(j))) {
+ expungeNote(notes.get(j), true, false);
+ noteGuids.add(notes.get(j));
+ }
+ }
+ }
+
+ for (int i=0; i<tags.size(); i++) {
+ List<String> notes = findNotesByTag(tags.get(i));
+ for (int j=0; j<notes.size(); j++) {
+ if (!isNoteDirty(notes.get(j))) {
+ expungeNote(notes.get(j), true, false);
+ noteGuids.add(notes.get(j));
+ }
+ }
+ }
+
+ for (int i=0; i<linked.size(); i++) {
+ String notebookGuid = db.getLinkedNotebookTable().getNotebookGuid(linked.get(i));
+ if (notebookGuid != null && !notebookGuid.trim().equals("")) {
+ List<Tag> linkedTags = db.getTagTable().getTagsForNotebook(notebookGuid);
+ for (int j=0; j<linkedTags.size(); j++)
+ db.getTagTable().expungeTag(linkedTags.get(j).getGuid(), false);
+
+ List<String> notes = findNotesByNotebook(notebookGuid);
+ for (int j=0; j<notes.size(); j++) {
+ if (!isNoteDirty(notes.get(j))) {
+ expungeNote(notes.get(j), true, false);
+ noteGuids.add(notes.get(j));
+ }
+ }
+ }
+ }
+ return noteGuids;
+ }
+
+ // Find a note by its notebook
+ // Expunge notes that we don't want to synchronize
+ public List<String> findNotesByNotebook(String notebook) {
+ List<String> values = new ArrayList<String>();
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ query.prepare("Select guid from note where notebookguid=:notebook");
+
+ query.bindValue(":notebook", notebook);
+ query.exec();
+ while (query.next()) {
+ values.add(query.valueString(0));
+ }
+ return values;
+ }
+
+ public List<String> findNotesByTag(String tag) {
+ List<String> values = new ArrayList<String>();
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ query.prepare("Select distinct noteguid from notetags where tagguid=:tag");
+
+ query.bindValue(":tag", tag);
+ query.exec();
+ while (query.next()) {
+ values.add(query.valueString(0));
+ }
+ return values;
+ }
+
+ // Find a note based upon its title.
+ public List<Pair<String,String>> findNotesByTitle(String text) {
+ List<Pair<String,String>> results = new ArrayList<Pair<String,String>>();
+ boolean check;
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+
+ check = query.prepare("Select guid,title from Note where lower(title) like :title");
+ if (!check)
+ logger.log(logger.EXTREME, "Note SQL prepare for search by title has failed: " +query.lastError().toString());
+
+ query.bindValue(":title", "%"+text.toLowerCase()+"%");
+ query.exec();
+ // Get a list of the notes
+ while (query.next()) {
+ Pair<String,String> p = new Pair<String,String>();
+ p.setFirst(query.valueString(0));
+ p.setSecond(query.valueString(1));
+ results.add(p);
+ }
+ return results;
+ }
+
+
+
+ //********************************************************************************
+ //********************************************************************************
+ //* Indexing Functions
+ //********************************************************************************
+ //********************************************************************************
+ // set/unset a note to be reindexed
+ public void setIndexNeeded(String guid, Boolean flag) {
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ query.prepare("Update Note set indexNeeded=:flag where guid=:guid");
+
+ if (flag)
+ query.bindValue(":flag", 1);
+ else
+ query.bindValue(":flag", 0);
+ query.bindValue(":guid", guid);
+ if (!query.exec()) {
+ logger.log(logger.MEDIUM, "Note indexNeeded update failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ List<Resource> r = noteResourceTable.getNoteResources(guid, false);
+ for (int i=0; r!= null && i<r.size(); i++) {
+ noteResourceTable.setIndexNeeded(r.get(i).getGuid(), true);
+ }
+ }
+ // Set all notes to be reindexed
+ public void reindexAllNotes() {
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ if (!query.exec("Update Note set indexNeeded=true")) {
+ logger.log(logger.MEDIUM, "Note reindexAllNotes update failed.");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ }
+
+ // Get all unindexed notes
+ public List <String> getUnindexed() {
+ String guid;
+ List<String> index = new ArrayList<String>();
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+
+ if (!query.exec("Select guid from Note where isExpunged = false and indexNeeded = true and DATEDIFF('MINUTE',updated,CURRENT_TIMESTAMP)>5"))
+ logger.log(logger.EXTREME, "Note SQL retrieve has failed on getUnindexed().");
+
+ // Get a list of the notes
+ while (query.next()) {
+ guid = new String();
+ guid = query.valueString(0);
+ index.add(guid);
+ }
+ return index;
+ }
+ public List<String> getNextUnindexed(int limit) {
+ List<String> guids = new ArrayList<String>();
+
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+
+ if (!query.exec("Select guid from Note where isExpunged = false and indexNeeded = true and DATEDIFF('MINUTE',Updated,CURRENT_TIMESTAMP)>5 limit " +limit))
+ logger.log(logger.EXTREME, "Note SQL retrieve has failed on getUnindexed().");
+
+ // Get a list of the notes
+ String guid;
+ while (query.next()) {
+ guid = new String();
+ guid = query.valueString(0);
+ guids.add(guid);
+ }
+ return guids;
+ }
+
+
+ // Get note meta information
+ public void updateNoteMetadata(NoteMetadata meta) {
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ if (!query.prepare("Update Note set titleColor=:color, pinned=:pinned, attributeSourceApplication=:metaString where guid=:guid"))
+ logger.log(logger.EXTREME, "Note SQL prepare has failed on updateNoteMetadata.");
+ query.bindValue(":color", meta.getColor());
+ query.bindValue(":pinned", meta.isPinned());
+ query.bindValue(":guid", meta.getGuid());
+ query.bindValue(":metaString", buildMetadataString(meta));
+ if (!query.exec())
+ logger.log(logger.EXTREME, "Note SQL exec has failed on updateNoteMetadata.");
+ return;
+ }
+
+ // Get all note meta information
+ public HashMap<String, NoteMetadata> getNotesMetaInformation() {
+ HashMap<String, NoteMetadata> returnValue = new HashMap<String, NoteMetadata>();
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+
+ if (!query.exec("Select guid,titleColor, isDirty, pinned from Note"))
+ logger.log(logger.EXTREME, "Note SQL retrieve has failed on getNoteMetaInformation.");
+
+ // Get a list of the notes
+ while (query.next()) {
+ NoteMetadata note = new NoteMetadata();
+ note.setGuid(query.valueString(0));
+ note.setColor(query.valueInteger(1));
+ note.setDirty(query.valueBoolean(2, false));
+ int pinned = query.valueInteger(3);
+ if (pinned > 0)
+ note.setPinned(true);
+ returnValue.put(note.getGuid(), note);
+ }
+
+ return returnValue;
+ }
+ // Get note meta information
+ public NoteMetadata getNoteMetaInformation(String guid) {
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+
+ if (!query.prepare("Select guid,titleColor, isDirty, pinned from Note where guid=:guid")) {
+ logger.log(logger.EXTREME, "Note SQL retrieve has failed on getNoteMetaInformation.");
+ return null;
+ }
+ query.bindValue(":guid", guid);
+ query.exec();
+
+ // Get a list of the notes
+ while (query.next()) {
+ NoteMetadata note = new NoteMetadata();
+ note.setGuid(query.valueString(0));
+ note.setColor(query.valueInteger(1));
+ note.setDirty(query.valueBoolean(2, false));
+ int pinned = query.valueInteger(3);
+ if (pinned > 0)
+ note.setPinned(true);
+ return note;
+ }
+
+ return null;
+ }
+
+
+ //**********************************************************************************
+ //* Thumbnail functions
+ //**********************************************************************************
+ // Set if a new thumbnail is needed
+ public void setThumbnailNeeded(String guid, boolean needed) {
+
+ boolean check;
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+
+ check = query.prepare("Update note set thumbnailneeded = :needed where guid=:guid");
+ query.bindValue(":guid", guid);
+ query.bindValue(":needed", needed);
+ check = query.exec();
+ if (!check)
+ logger.log(logger.EXTREME, "Note SQL set thumbail needed failed: " +query.lastError().toString());
+
+ }
+ // Is a thumbail needed for this guid?
+ public boolean isThumbnailNeeded(String guid) {
+
+ boolean check;
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+
+ check = query.prepare("select thumbnailneeded from note where guid=:guid");
+ query.bindValue(":guid", guid);
+ check = query.exec();
+ if (!check)
+ logger.log(logger.EXTREME, "Note SQL isThumbnailNeeded query failed: " +query.lastError().toString());
+
+ boolean returnValue;
+ // Get a list of the notes
+ if (query.next())
+ returnValue = query.valueBoolean(0, false);
+ else
+ returnValue = false;
+
+ return returnValue;
+ }
+ // Set if a new thumbnail is needed
+ public void setThumbnail(String guid, QByteArray thumbnail) {
+
+ boolean check;
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+
+ check = query.prepare("Update note set thumbnail = :thumbnail where guid=:guid");
+ query.bindValue(":guid", guid);
+ query.bindValue(":thumbnail", thumbnail.toByteArray());
+ check = query.exec();
+ if (!check)
+ logger.log(logger.EXTREME, "Note SQL set thumbail failed: " +query.lastError().toString());
+
+ }
+ // Set if a new thumbnail is needed
+ public QByteArray getThumbnail(String guid) {
+
+ boolean check;
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+
+ check = query.prepare("Select thumbnail from note where guid=:guid");
+ query.bindValue(":guid", guid);
+ check = query.exec();
+ if (!check)
+ logger.log(logger.EXTREME, "Note SQL get thumbail failed: " +query.lastError().toString());
+ // Get a list of the notes
+ if (query.next()) {
+ try {
+ if (query.getBlob(0) != null) {
+ return new QByteArray(query.getBlob(0));
+ }
+ } catch (java.lang.IllegalArgumentException e) {
+ return null;
+ }
+ }
+ return null;
+ }
+ // Get all thumbnails
+ public HashMap<String, QPixmap> getThumbnails() {
+ boolean check;
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ HashMap<String, QPixmap> map = new HashMap<String,QPixmap>();
+
+ check = query.prepare("Select guid,thumbnail from note where thumbnailneeded=false and isExpunged=false");
+ check = query.exec();
+ if (!check)
+ logger.log(logger.EXTREME, "Note SQL get thumbail failed: " +query.lastError().toString());
+ // Get a list of the notes
+ while (query.next()) {
+ try {
+ if (query.getBlob(1) != null) {
+ QByteArray data = new QByteArray(query.getBlob(1));
+ QPixmap img = new QPixmap();
+ if (img.loadFromData(data)) {
+ img = img.scaled(Global.largeThumbnailSize);
+ map.put(query.valueString(0), img);
+ }
+ }
+ } catch (java.lang.IllegalArgumentException e) {
+ logger.log(logger.HIGH, "Error retrieving thumbnail " +e.getMessage());
+ }
+ }
+ return map;
+ }
+ // Get a list of notes that need thumbnails
+ public List<String> findThumbnailsNeeded() {
+
+ boolean check;
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+
+ check = query.prepare("select guid from note where thumbnailneeded=true and isExpunged=false and DATEDIFF('MINUTE',updated,CURRENT_TIMESTAMP)>5 limit 5");
+ check = query.exec();
+ if (!check)
+ logger.log(logger.EXTREME, "Note SQL findThumbnailsNeeded query failed: " +query.lastError().toString());
+
+
+ // Get a list of the notes
+ List<String> values = new ArrayList<String>();
+ while (query.next()) {
+ values.add(query.valueString(0));
+ }
+
+ return values;
+ }
+ // Get a count of thumbnails needed
+ public int getThumbnailNeededCount() {
+
+ boolean check;
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+
+ check = query.prepare("select count(guid) from note where thumbnailneeded=true and isExpunged=false and DATEDIFF('MINUTE',updated,CURRENT_TIMESTAMP)>5 limit 2");
+ check = query.exec();
+ if (!check)
+ logger.log(logger.EXTREME, "Note SQL findThumbnailNeededCount query failed: " +query.lastError().toString());
+
+ if (query.next()) {
+ return query.valueInteger(0);
+ }
+
+ return 0;
+ }
+
+ //***********************************************************************************
+ public String findAlternateGuid(String guid) {
+ boolean check;
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+
+ check = query.prepare("select guid from note where original_guid=:guid");
+ query.bindValue(":guid", guid);
+ check = query.exec();
+ if (!check)
+ logger.log(logger.EXTREME, "Note SQL findAlternateguid query failed: " +query.lastError().toString());
+
+ if (query.next()) {
+ return query.valueString(0);
+ }
+
+ return null;
+ }
+
+ //* Check if a note guid exists
+ public boolean guidExists(String guid) {
+ boolean check;
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+
+ check = query.prepare("select guid from note where guid=:guid");
+ query.bindValue(":guid", guid);
+ check = query.exec();
+ if (!check)
+ logger.log(logger.EXTREME, "Note SQL guidExists query failed: " +query.lastError().toString());
+
+ if (query.next()) {
+ return true;
+ }
+
+ return false;
+ }
+
+ // Update a note content's hash. This happens if a resource is edited outside of NN
+ public void updateResourceContentHash(String guid, String oldHash, String newHash) {
+ Note n = getNote(guid, true, false, false, false,false);
+ int position = n.getContent().indexOf("<en-media");
+ int endPos;
+ for (;position>-1;) {
+ endPos = n.getContent().indexOf(">", position+1);
+ String oldSegment = n.getContent().substring(position,endPos);
+ int hashPos = oldSegment.indexOf("hash=\"");
+ int hashEnd = oldSegment.indexOf("\"", hashPos+7);
+ String hash = oldSegment.substring(hashPos+6, hashEnd);
+ if (hash.equalsIgnoreCase(oldHash)) {
+ String newSegment = oldSegment.replace(oldHash, newHash);
+ String content = n.getContent().substring(0,position) +
+ newSegment +
+ n.getContent().substring(endPos);
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ query.prepare("update note set isdirty=true, thumbnailneeded=true, content=:content where guid=:guid");
+ query.bindValue(":content", content);
+ query.bindValue(":guid", n.getGuid());
+ query.exec();
+ }
+
+ position = n.getContent().indexOf("<en-media", position+1);
+ }
+ }
+
+ // Extract metadata from a note's Note.attributes.sourceApplication
+ private NoteMetadata extractMetadata(String sourceApplication) {
+ // ICHANGED 自分のキーに変更
+ String consumerKey = "kimaira792:{";
+
+ int startPos = sourceApplication.indexOf(consumerKey);
+ if (startPos < 0 )
+ return null;
+
+ NoteMetadata meta = new NoteMetadata();
+ startPos = startPos+consumerKey.length();
+
+// String startString = sourceApplication.substring(0,startPos);
+ String metaString = sourceApplication.substring(startPos);
+// String endString = metaString.substring(metaString.indexOf("};"));
+ int endPos = metaString.indexOf("};");
+ if (endPos > 0)
+ metaString = metaString.substring(0,endPos);
+
+ String value = parseMetaString(metaString, "titleColor");
+ if (value != null)
+ meta.setColor(Integer.parseInt(value));
+
+ value = parseMetaString(metaString, "pinned");
+ if (value != null && value.equals(true))
+ meta.setPinned(true);
+
+ return meta;
+ }
+
+ // Given a metadata string from attribute.sourceApplication, we
+ // extract the information for a given key.
+ private String parseMetaString(String metaString, String key) {
+ int startPos = metaString.indexOf(key);
+ if (startPos < 0)
+ return null;
+
+ String value = metaString.substring(startPos+key.length()+1);
+ int endPos = value.indexOf(";");
+ if (endPos > 0)
+ value = value.substring(0,endPos);
+
+ return value;
+ }
+
+ // Given a set of metadata, we build a string that can be inserted
+ // into the attribute.sourceApplication string.
+ private String buildMetadataString(NoteMetadata meta) {
+ StringBuffer value = new StringBuffer(removeExistingMetaString(meta.getGuid()));
+ StringBuffer metaString = new StringBuffer();
+
+ if (meta.isPinned()) {
+ metaString.append("pinned=true;");
+ }
+ if (meta.getColor() != -1) {
+ metaString.append("titleColor=" +new Integer(meta.getColor()).toString()+";");
+ }
+ if (metaString.length()>0) {
+
+ // Adda any missing ";" or " " at the end of the existing
+ // string.
+ if (value.length()>1 && (!value.toString().trim().endsWith(";") || !value.toString().trim().endsWith(";")))
+ value.append("; ");
+
+ // ICHANGED 自分のキーに変更
+ value.append("kimaira792:{");
+ value.append(metaString);
+ value.append("};");
+ return value.toString();
+ }
+ return null;
+ }
+
+ // This will remove the existing metadata string from the attribute.sourceApplication string.
+ private String removeExistingMetaString(String guid) {
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+
+ if (!query.prepare("Select attributeSourceApplication from Note where guid=:guid")) {
+ logger.log(logger.EXTREME, "Note SQL retrieve has failed in removeExistingMetaString.");
+ return null;
+ }
+ query.bindValue(":guid", guid);
+ query.exec();
+
+ // Get the application source string
+ String sourceApplication = null;
+ while (query.next()) {
+ sourceApplication = query.valueString(0);
+ }
+ if (sourceApplication == null)
+ return "";
+
+ // ICHANGED 自分のキーに変更
+ String consumerKey = "kimaira792:{";
+ int startPos = sourceApplication.indexOf(consumerKey);
+ if (startPos < 0 )
+ return sourceApplication;
+ String startString = sourceApplication.substring(0,startPos);
+ String metaString = sourceApplication.substring(startPos);
+ String endString = metaString.substring(metaString.indexOf("};")+2);
+
+ return startString+endString;
+ }
+
public void dumpDirtyNotes() {\r
logger.log(logger.LOW, "Dirty Notes: ");\r
List<Note> noteList = this.getDirty();\r
for (int i=0; i<noteList.size();i++) {\r
logger.log(logger.LOW, i +" : " +noteList.get(i).getGuid() + " : " +noteList.get(i).getTitle() );\r
}\r
- }\r
- \r
-} \r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
+ }
+
+ // ICHANGED
+ // guidからノートのタイトルをゲット
+ public String getNoteTitle(String noteGuid) {
+
+ if (noteGuid == null)
+ return null;
+ if (noteGuid.trim().equals(""))
+ return null;
+
+ NSqlQuery query = new NSqlQuery(db.getConnection());
+ query.prepare("Select title from Note where guid=:guid and isExpunged=false");
+ query.bindValue(":guid", noteGuid);
+ if (!query.exec()) {
+ logger.log(logger.MEDIUM, "Noteテーブルからタイトルの取得失敗");
+ logger.log(logger.MEDIUM, query.lastError());
+ return null;
+ }
+ if (!query.next()) {
+ logger.log(logger.EXTREME, "SQL Retrieve failed for note guid "
+ + noteGuid + " in getNoteTitle()");
+ logger.log(logger.EXTREME, " -> " + query.lastError().toString());
+ logger.log(logger.EXTREME, " -> " + query.lastError());
+ return null;
+ }
+
+ String noteTitle = query.valueString(0);
+
+ return noteTitle;
+ }
+
+ /*
+ * // ICHANGED // ノートがアクティブかどうか調べる public boolean isNoteActive(String guid){
+ * if(guid == null) return false; if(guid.trim().equals("")) return false;
+ *
+ * NSqlQuery query = new NSqlQuery(db.getConnection());
+ * query.prepare("Select active from Note where guid=:guid");
+ * query.bindValue(":guid", guid); if(!query.exec()){
+ * logger.log(logger.EXTREME, "note.isNoteActive SQL retrieve has failed.");
+ * return false; } if(!query.next()){ logger.log(logger.EXTREME,
+ * "SQL Retrieve failed for note guid " +guid + " in isNoteActive()");
+ * return false; }
+ *
+ * boolean retVal = query.valueBoolean(0, false); return retVal; }
+ */
+
+}
+
+
+
+
+
--- /dev/null
+/*
+ * クラスを現在作成中。インスタンスの生成および呼び出し部分は未着手。
+ */
+
+package cx.fbn.nevernote.sql;
+
+import cx.fbn.nevernote.sql.driver.NSqlQuery;
+import cx.fbn.nevernote.utilities.ApplicationLogger;
+
+public class StaredTable {
+ private final ApplicationLogger logger;
+ private final DatabaseConnection db;
+
+ // コンストラクタ
+ public StaredTable(ApplicationLogger l, DatabaseConnection d) {
+ logger = l;
+ db = d;
+ }
+
+ // テーブル作成
+ public void createTable() {
+ NSqlQuery query = new NSqlQuery(db.getBehaviorConnection());
+ logger.log(logger.HIGH, "StaredNotesテーブルを作成しています...");
+ if (!query.exec("Create table StaredNotes (id integer primary key auto_increment, masterGuid varchar, staredGuid varchar)"))
+ logger.log(logger.HIGH, "StaredNotesテーブル作成失敗!!!");
+ }
+
+ // テーブルをドロップ
+ public void dropTable() {
+ NSqlQuery query = new NSqlQuery(db.getBehaviorConnection());
+ query.exec("Drop table StaredNotes");
+ }
+
+ // StaredNotesテーブルにアイテムを1つ追加
+ public void addStaredItem(String masterGuid, String staredGuid) {
+ NSqlQuery query = new NSqlQuery(db.getBehaviorConnection());
+ query.prepare("Insert Into StaredNotes (masterGuid, staredGuid) Values(:masterGuid, :staredGuid)");
+ query.bindValue(":masterGuid", masterGuid);
+ query.bindValue(":staredGuid", staredGuid);
+ if (!query.exec()) {
+ logger.log(logger.MEDIUM, "StaredNotesテーブルへのアイテム追加に失敗");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ }
+
+ // StaredNotesテーブルからアイテムを1つ削除
+ public void removeStaredItem(String masterGuid, String staredGuid) {
+ NSqlQuery query = new NSqlQuery(db.getBehaviorConnection());
+ query.prepare("Delete from StaredNotes where (masterGuid=:masterGuid and staredGuid=:staredGuid)");
+ query.bindValue(":masterGuid", masterGuid);
+ query.bindValue(":staredGuid", staredGuid);
+ if (!query.exec()) {
+ logger.log(logger.MEDIUM, "StaredNotesテーブルからのアイテム削除に失敗");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ }
+
+ // guidを含む列をStaredNotesテーブルから削除
+ public void expungeStaredNote(String guid) {
+ NSqlQuery query = new NSqlQuery(db.getBehaviorConnection());
+ boolean check;
+
+ query.prepare("Delete from StaredNotes where masterGuid=:masterGuid or staredGuid=:staredGuid");
+ query.bindValue(":masterGuid", guid);
+ query.bindValue(":staredGuid", guid);
+
+ check = query.exec();
+ if(!check){
+ logger.log(logger.MEDIUM, "StaredNotesテーブルからguid=" + guid + "のデータ削除に失敗");
+ logger.log(logger.MEDIUM, query.lastError());
+ }
+ }
+
+ // masterGuidとchildGuidをマージ
+ public void mergeHistoryGuid(String masterGuid, String childGuid) {
+ NSqlQuery staredNotesQuery = new NSqlQuery(db.getBehaviorConnection());
+ boolean check = false;
+
+ // マージ後に重複してしまうデータを先に削除
+ staredNotesQuery.prepare("Delete from StaredNotes where (masterGuid=:masterGuid1 and staredGuid=:staredGuid1) or (masterGuid=:masterGuid2 and staredGuid=:staredGuid2)");
+ staredNotesQuery.bindValue(":masterGuid1", masterGuid);
+ staredNotesQuery.bindValue(":childGuid1", childGuid);
+ staredNotesQuery.bindValue(":masterGuid2", childGuid);
+ staredNotesQuery.bindValue(":staredGuid2", masterGuid);
+ check = staredNotesQuery.exec();
+ if(!check){
+ logger.log(logger.MEDIUM, "staredNotesテーブルの重複削除で失敗");
+ logger.log(logger.MEDIUM, staredNotesQuery.lastError());
+ }
+
+ updateStaredNoteGuid(masterGuid, childGuid);
+ }
+
+ // StaredNotesテーブルのGuidを更新
+ public void updateStaredNoteGuid(String newGuid, String oldGuid){
+ NSqlQuery staredNotesQuery = new NSqlQuery(db.getBehaviorConnection());
+ boolean check = false;
+
+ staredNotesQuery.prepare("Update StaredNotes set masterGuid=:newGuid where masterGuid=:oldGuid");
+ staredNotesQuery.bindValue(":newGuid", newGuid);
+ staredNotesQuery.bindValue(":oldGuid", oldGuid);
+ check = staredNotesQuery.exec();
+ if (!check) {
+ logger.log(logger.MEDIUM, "StaredNotesテーブルのmasterGuidのところでguid更新失敗");
+ logger.log(logger.MEDIUM, staredNotesQuery.lastError());
+ }
+ staredNotesQuery.prepare("Update StaredNotes set staredGuid=:newGuid where staredGuid=:oldGuid");
+ staredNotesQuery.bindValue(":newGuid", newGuid);
+ staredNotesQuery.bindValue(":oldGuid", oldGuid);
+ check = staredNotesQuery.exec();
+ if (!check) {
+ logger.log(logger.MEDIUM, "StaredNotesテーブルのstaredGuidのところでguid更新失敗");
+ logger.log(logger.MEDIUM, staredNotesQuery.lastError());
+ }
+ }
+
+ // StaredNotesテーブルに引数guidのノートが存在するか
+ public boolean existNote(String masterGuid, String staredGuid) {
+ NSqlQuery staredNotesQuery = new NSqlQuery(db.getBehaviorConnection());
+
+ // 2つの引数guidを含むアイテムの存在確認
+ staredNotesQuery.prepare("Select * from StaredNotes where Exists(Select * from StaredNotes where (masterGuid=:masterGuid1 and staredGuid=:staredGuid1) or (masterGuid=:masterGuid2 and staredGuid=:staredGuid2))");
+ staredNotesQuery.bindValue(":masterGuid1", masterGuid);
+ staredNotesQuery.bindValue(":staredGuid1", staredGuid);
+ staredNotesQuery.bindValue(":masterGuid2", masterGuid);
+ staredNotesQuery.bindValue(":staredGuid2", staredGuid);
+
+ if (!staredNotesQuery.exec()) {
+ logger.log(logger.MEDIUM, "StaredNotesテーブルからmasterGuid=" + masterGuid + "かつstaredGuid=" + staredGuid + "(またはその逆)のアイテムの存在確認失敗");
+ logger.log(logger.MEDIUM, staredNotesQuery.lastError());
+ }
+
+ if (staredNotesQuery.next()) {
+ return true;
+ }
+
+ return false;
+ }
+
+ // oldGuidのノートの除外ノートをnewGuidのノートの除外ノートとして複製
+ public void duplicateStaredNotes(String newGuid, String oldGuid) {
+ NSqlQuery staredNotesQuery = new NSqlQuery(db.getBehaviorConnection());
+
+ // masterGuid = oldGuidのスター付きノートを取得
+ staredNotesQuery.prepare("Select staredGuid from StaredNotes where masterGuid=:oldGuid");
+ staredNotesQuery.bindValue(":oldGuid", oldGuid);
+ if(!staredNotesQuery.exec()){
+ logger.log(logger.MEDIUM, "StaredNotesテーブルからmasterGuid=" + oldGuid + "のアイテム取得失敗");
+ logger.log(logger.MEDIUM, staredNotesQuery.lastError());
+ }
+ // masterGuid = newGuidのスター付きノートとして複製
+ while(staredNotesQuery.next()){
+ String staredGuid = staredNotesQuery.valueString(0);
+
+ addStaredItem(newGuid, staredGuid);
+ }
+
+ // staredGuid = oldGuidの除外ノートを取得
+ staredNotesQuery.prepare("Select masterGuid from StaredNotes where staredGuid=:oldGuid");
+ staredNotesQuery.bindValue(":oldGuid", oldGuid);
+ if(!staredNotesQuery.exec()){
+ logger.log(logger.MEDIUM, "StaredNotesテーブルからstaredGuid=" + oldGuid + "のアイテム取得失敗");
+ logger.log(logger.MEDIUM, staredNotesQuery.lastError());
+ }
+ // staredGuid = newGuidの除外ノートとして複製
+ while(staredNotesQuery.next()){
+ String masterGuid = staredNotesQuery.valueString(0);
+
+ addStaredItem(masterGuid, newGuid);
+ }
+ }
+}
-/*\r
- * This file is part of NixNote \r
- * Copyright 2009 Randy Baumgarte\r
- * \r
- * This file may be licensed under the terms of of the\r
- * GNU General Public License Version 2 (the ``GPL'').\r
- *\r
- * Software distributed under the License is distributed\r
- * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either\r
- * express or implied. See the GPL for the specific language\r
- * governing rights and limitations.\r
- *\r
- * You should have received a copy of the GPL along with this\r
- * program. If not, go to http://www.gnu.org/licenses/gpl.html\r
- * or write to the Free Software Foundation, Inc.,\r
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
- *\r
-*/\r
-\r
-package cx.fbn.nevernote.threads;\r
-\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-import java.util.Vector;\r
-import java.util.concurrent.LinkedBlockingQueue;\r
-\r
-import com.evernote.edam.type.Note;\r
-import com.trolltech.qt.core.QMutex;\r
-import com.trolltech.qt.core.QObject;\r
-\r
-import cx.fbn.nevernote.filters.NotebookCounter;\r
-import cx.fbn.nevernote.filters.TagCounter;\r
-import cx.fbn.nevernote.signals.NotebookSignal;\r
-import cx.fbn.nevernote.signals.TagSignal;\r
-import cx.fbn.nevernote.signals.TrashSignal;\r
-import cx.fbn.nevernote.sql.DatabaseConnection;\r
-import cx.fbn.nevernote.utilities.ApplicationLogger;\r
-\r
-public class CounterRunner extends QObject implements Runnable {\r
- \r
- private class NoteRecord {\r
- public String notebookGuid;\r
- public Vector<String> tags;\r
- public boolean active;\r
- \r
- public NoteRecord() {\r
- tags = new Vector<String>();\r
- }\r
- }\r
- private final ApplicationLogger logger;\r
- private volatile boolean keepRunning;\r
- public int ID;\r
- public volatile NotebookSignal notebookSignal;\r
- public volatile TrashSignal trashSignal;\r
- public volatile TagSignal tagSignal;\r
- private volatile Vector<NoteRecord> records;\r
- public int type;\r
- public QMutex threadLock;\r
- \r
- public static int EXIT=0;\r
- public static int NOTEBOOK=1;\r
- public static int TAG=2;\r
- public static int TRASH=3;\r
- \r
- public boolean ready = false;\r
- public boolean abortCount = false;\r
- private final DatabaseConnection conn;\r
-\r
- private volatile LinkedBlockingQueue<Integer> readyQueue = new LinkedBlockingQueue<Integer>();\r
- \r
- \r
- //*********************************************\r
- //* Constructor *\r
- //*********************************************\r
- public CounterRunner(String logname, int t, String u, String i, String r, String uid, String pswd, String cpswd) {\r
- type = t;\r
-\r
- threadLock = new QMutex();\r
- logger = new ApplicationLogger(logname);\r
-// setAutoDelete(false); \r
- conn = new DatabaseConnection(logger, u, i, r, uid, pswd, cpswd, 300);\r
- keepRunning = true;\r
- notebookSignal = new NotebookSignal();\r
- tagSignal = new TagSignal();\r
- trashSignal = new TrashSignal();\r
- \r
- records = new Vector<NoteRecord>();\r
- }\r
- \r
- \r
- \r
- //*********************************************\r
- //* Run unit *\r
- //*********************************************\r
- @Override\r
- public void run() {\r
- boolean keepRunning = true;\r
- \r
- thread().setPriority(Thread.MIN_PRIORITY);\r
- while(keepRunning) {\r
- ready = true;\r
- try {\r
- \r
- type = readyQueue.take();\r
- threadLock.lock();\r
- if (type == EXIT)\r
- keepRunning = false;\r
- if (type == NOTEBOOK)\r
- countNotebookResults();\r
- if (type == TAG)\r
- countTagResults();\r
- if (type == TRASH)\r
- countTrashResults();\r
- threadLock.unlock();\r
- } catch (InterruptedException e) {}\r
- }\r
- conn.dbShutdown();\r
- }\r
- \r
- \r
- \r
- public void setNoteIndex(List<Note> idx) {\r
- abortCount = true;\r
- threadLock.lock();\r
- abortCount = false;\r
- records.clear();\r
- if (idx != null) {\r
- for (int i=0; i<idx.size(); i++) {\r
- if (abortCount)\r
- return;\r
- NoteRecord record = new NoteRecord();\r
- record.notebookGuid = new String(idx.get(i).getNotebookGuid());\r
- record.active = idx.get(i).isActive();\r
- for (int j=0; j<idx.get(i).getTagGuidsSize(); j++) {\r
- if (abortCount)\r
- return;\r
- record.tags.add(new String(idx.get(i).getTagGuids().get(j)));\r
- }\r
- records.add(record);\r
- }\r
- }\r
- threadLock.unlock();\r
- }\r
- public void release(int type) {\r
- readyQueue.add(type);\r
- }\r
- \r
- //*********************************************\r
- //* Getter & Setter method to tell the thread *\r
- //* to keep running. *\r
- //*********************************************\r
- public void setKeepRunning(boolean b) {\r
- keepRunning = b;\r
- }\r
- public boolean keepRunning() {\r
- return keepRunning;\r
- }\r
- \r
- \r
- //*********************************************\r
- //* Do the actual counting *\r
- //*********************************************\r
- private void countNotebookResults() {\r
- logger.log(logger.EXTREME, "Entering ListManager.countNotebookResults"); \r
- if (abortCount)\r
- return;\r
- List<NotebookCounter> nCounter = new ArrayList<NotebookCounter>();\r
- for (int i=0; i<records.size(); i++) {\r
- if (abortCount)\r
- return;\r
- boolean found = false;\r
- for (int j=0; j<nCounter.size(); j++) {\r
- if (abortCount)\r
- return;\r
- if (records.get(i).active && nCounter.get(j).getGuid().equals(records.get(i).notebookGuid)) {\r
- nCounter.get(j).setCount(nCounter.get(j).getCount()+1);\r
- found = true;\r
- j=nCounter.size();\r
- }\r
- }\r
- if (!found && records.get(i).active) {\r
- NotebookCounter newCounter = new NotebookCounter();\r
- newCounter.setGuid(records.get(i).notebookGuid);\r
- newCounter.setCount(1);\r
- nCounter.add(newCounter);\r
- }\r
- }\r
- if (abortCount)\r
- return;\r
- notebookSignal.countsChanged.emit(nCounter);\r
- logger.log(logger.EXTREME, "Leaving ListManager.countNotebookResults()");\r
- }\r
- \r
- \r
- /*\r
- private void countTagResults() {\r
- logger.log(logger.EXTREME, "Entering ListManager.countTagResults"); \r
- List<TagCounter> counter = new ArrayList<TagCounter>();\r
- List<Tag> allTags = conn.getTagTable().getAll();\r
- \r
- if (abortCount) \r
- return;\r
- if (allTags == null)\r
- return;\r
- for (int k=0; k<allTags.size() && keepRunning; k++) {\r
- TagCounter newCounter = new TagCounter();\r
- newCounter.setGuid(allTags.get(k).getGuid());\r
- newCounter.setCount(0);\r
- counter.add(newCounter);\r
- }\r
- \r
- if (type == TAG_ALL) {\r
- List<Pair<String, Integer>> tagCounts = conn.getNoteTable().noteTagsTable.getTagCounts();\r
- if (abortCount)\r
- return;\r
- for (int i=0; tagCounts != null && i<tagCounts.size(); i++) {\r
- if (abortCount)\r
- return;\r
- for (int j=0; j<counter.size(); j++) {\r
- if (abortCount)\r
- return;\r
- if (tagCounts.get(i).getFirst().equals(counter.get(j).getGuid())) {\r
- if (abortCount)\r
- return;\r
- counter.get(j).setCount(tagCounts.get(i).getSecond());\r
- j=counter.size();\r
- }\r
- }\r
- }\r
- if (abortCount)\r
- return;\r
- tagSignal.countsChanged.emit(counter);\r
- return;\r
- }\r
- \r
- \r
- if (abortCount)\r
- return;\r
- List<cx.fbn.nevernote.sql.NoteTagsRecord> tags = conn.getNoteTable().noteTagsTable.getAllNoteTags();\r
- for (int i=noteIndex.size()-1; i>=0; i--) {\r
- if (abortCount)\r
- return;\r
- String note = noteIndex.get(i);\r
- for (int x=0; tags!= null && x<tags.size() && keepRunning; x++) {\r
- if (abortCount)\r
- return;\r
- String tag = tags.get(x).tagGuid;\r
- for (int j=0; j<counter.size() && keepRunning; j++) {\r
- if (abortCount)\r
- return;\r
- if (counter.get(j).getGuid().equals(tag) && note.equals(tags.get(x).noteGuid)) {\r
- int c = counter.get(j).getCount()+1;\r
- counter.get(j).setCount(c);\r
- }\r
- }\r
- }\r
- }\r
- if (abortCount)\r
- return;\r
- tagSignal.countsChanged.emit(counter);\r
- logger.log(logger.EXTREME, "Leaving ListManager.countTagResults()");\r
- } */\r
- private void countTagResults() {\r
- logger.log(logger.EXTREME, "Entering ListManager.countTagResults"); \r
- if (abortCount)\r
- return;\r
- List<TagCounter> tCounter = new ArrayList<TagCounter>();\r
- for (int i=0; i<records.size(); i++) {\r
- if (abortCount)\r
- return;\r
- \r
- // Loop through the list of tags so we can count them\r
- Vector<String> tags = records.get(i).tags;\r
- for (int z=0; z<tags.size(); z++) {\r
- boolean found = false;\r
- for (int j=0; j<tCounter.size(); j++) {\r
- if (abortCount)\r
- return;\r
- if (tCounter.get(j).getGuid().equals(tags.get(z))) {\r
- tCounter.get(j).setCount(tCounter.get(j).getCount()+1);\r
- found = true;\r
- j=tCounter.size();\r
- }\r
- }\r
- if (!found) {\r
- TagCounter newCounter = new TagCounter();\r
- newCounter.setGuid(tags.get(z));\r
- newCounter.setCount(1);\r
- tCounter.add(newCounter);\r
- }\r
- }\r
- }\r
- if (abortCount)\r
- return;\r
- tagSignal.countsChanged.emit(tCounter);\r
- logger.log(logger.EXTREME, "Leaving ListManager.countTagResults"); \r
- }\r
- \r
- \r
- private void countTrashResults() {\r
- logger.log(logger.EXTREME, "Entering CounterRunner.countTrashResults()"); \r
- if (abortCount)\r
- return;\r
-\r
- int tCounter = 0;\r
- for (int i=0; i<records.size(); i++) {\r
- if (abortCount)\r
- return;\r
- if (!records.get(i).active)\r
- tCounter++;\r
- }\r
- \r
- if (abortCount)\r
- return;\r
-\r
- trashSignal.countChanged.emit(tCounter);\r
- logger.log(logger.EXTREME, "Leaving CounterRunner.countTrashResults()");\r
- }\r
-\r
-}\r
+/*
+ * This file is part of NixNote
+ * Copyright 2009 Randy Baumgarte
+ *
+ * This file may be licensed under the terms of of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+*/
+
+package cx.fbn.nevernote.threads;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import com.evernote.edam.type.Note;
+import com.trolltech.qt.core.QMutex;
+import com.trolltech.qt.core.QObject;
+
+import cx.fbn.nevernote.filters.NotebookCounter;
+import cx.fbn.nevernote.filters.TagCounter;
+import cx.fbn.nevernote.signals.NotebookSignal;
+import cx.fbn.nevernote.signals.TagSignal;
+import cx.fbn.nevernote.signals.TrashSignal;
+import cx.fbn.nevernote.sql.DatabaseConnection;
+import cx.fbn.nevernote.utilities.ApplicationLogger;
+
+public class CounterRunner extends QObject implements Runnable {
+
+ private class NoteRecord {
+ public String notebookGuid;
+ public Vector<String> tags;
+ public boolean active;
+
+ public NoteRecord() {
+ tags = new Vector<String>();
+ }
+ }
+ private final ApplicationLogger logger;
+ private volatile boolean keepRunning;
+ public int ID;
+ public volatile NotebookSignal notebookSignal;
+ public volatile TrashSignal trashSignal;
+ public volatile TagSignal tagSignal;
+ private volatile Vector<NoteRecord> records;
+ public int type;
+ public QMutex threadLock;
+
+ public static int EXIT=0;
+ public static int NOTEBOOK=1;
+ public static int TAG=2;
+ public static int TRASH=3;
+
+ public boolean ready = false;
+ public boolean abortCount = false;
+ private final DatabaseConnection conn;
+
+ private volatile LinkedBlockingQueue<Integer> readyQueue = new LinkedBlockingQueue<Integer>();
+
+
+ //*********************************************
+ //* Constructor *
+ //*********************************************
+ // ICHANGED String bを追加
+ public CounterRunner(String logname, int t, String u, String i, String r, String b, String uid, String pswd, String cpswd) {
+ type = t;
+
+ threadLock = new QMutex();
+ logger = new ApplicationLogger(logname);
+// setAutoDelete(false);
+ // ICHANGED bを追加
+ conn = new DatabaseConnection(logger, u, i, r, b, uid, pswd, cpswd, 300);
+
+ keepRunning = true;
+ notebookSignal = new NotebookSignal();
+ tagSignal = new TagSignal();
+ trashSignal = new TrashSignal();
+
+ records = new Vector<NoteRecord>();
+ }
+
+
+
+ //*********************************************
+ //* Run unit *
+ //*********************************************
+ @Override
+ public void run() {
+ boolean keepRunning = true;
+
+ thread().setPriority(Thread.MIN_PRIORITY);
+ while(keepRunning) {
+ ready = true;
+ try {
+
+ type = readyQueue.take();
+ threadLock.lock();
+ if (type == EXIT)
+ keepRunning = false;
+ if (type == NOTEBOOK)
+ countNotebookResults();
+ if (type == TAG)
+ countTagResults();
+ if (type == TRASH)
+ countTrashResults();
+ threadLock.unlock();
+ } catch (InterruptedException e) {}
+ }
+ conn.dbShutdown();
+ }
+
+
+
+ public void setNoteIndex(List<Note> idx) {
+ abortCount = true;
+ threadLock.lock();
+ abortCount = false;
+ records.clear();
+ if (idx != null) {
+ for (int i=0; i<idx.size(); i++) {
+ if (abortCount)
+ return;
+ NoteRecord record = new NoteRecord();
+ record.notebookGuid = new String(idx.get(i).getNotebookGuid());
+ record.active = idx.get(i).isActive();
+ for (int j=0; j<idx.get(i).getTagGuidsSize(); j++) {
+ if (abortCount)
+ return;
+ record.tags.add(new String(idx.get(i).getTagGuids().get(j)));
+ }
+ records.add(record);
+ }
+ }
+ threadLock.unlock();
+ }
+ public void release(int type) {
+ readyQueue.add(type);
+ }
+
+ //*********************************************
+ //* Getter & Setter method to tell the thread *
+ //* to keep running. *
+ //*********************************************
+ public void setKeepRunning(boolean b) {
+ keepRunning = b;
+ }
+ public boolean keepRunning() {
+ return keepRunning;
+ }
+
+
+ //*********************************************
+ //* Do the actual counting *
+ //*********************************************
+ private void countNotebookResults() {
+ logger.log(logger.EXTREME, "Entering ListManager.countNotebookResults");
+ if (abortCount)
+ return;
+ List<NotebookCounter> nCounter = new ArrayList<NotebookCounter>();
+ for (int i=0; i<records.size(); i++) {
+ if (abortCount)
+ return;
+ boolean found = false;
+ for (int j=0; j<nCounter.size(); j++) {
+ if (abortCount)
+ return;
+ if (records.get(i).active && nCounter.get(j).getGuid().equals(records.get(i).notebookGuid)) {
+ nCounter.get(j).setCount(nCounter.get(j).getCount()+1);
+ found = true;
+ j=nCounter.size();
+ }
+ }
+ if (!found && records.get(i).active) {
+ NotebookCounter newCounter = new NotebookCounter();
+ newCounter.setGuid(records.get(i).notebookGuid);
+ newCounter.setCount(1);
+ nCounter.add(newCounter);
+ }
+ }
+ if (abortCount)
+ return;
+ notebookSignal.countsChanged.emit(nCounter);
+ logger.log(logger.EXTREME, "Leaving ListManager.countNotebookResults()");
+ }
+
+
+ /*
+ private void countTagResults() {
+ logger.log(logger.EXTREME, "Entering ListManager.countTagResults");
+ List<TagCounter> counter = new ArrayList<TagCounter>();
+ List<Tag> allTags = conn.getTagTable().getAll();
+
+ if (abortCount)
+ return;
+ if (allTags == null)
+ return;
+ for (int k=0; k<allTags.size() && keepRunning; k++) {
+ TagCounter newCounter = new TagCounter();
+ newCounter.setGuid(allTags.get(k).getGuid());
+ newCounter.setCount(0);
+ counter.add(newCounter);
+ }
+
+ if (type == TAG_ALL) {
+ List<Pair<String, Integer>> tagCounts = conn.getNoteTable().noteTagsTable.getTagCounts();
+ if (abortCount)
+ return;
+ for (int i=0; tagCounts != null && i<tagCounts.size(); i++) {
+ if (abortCount)
+ return;
+ for (int j=0; j<counter.size(); j++) {
+ if (abortCount)
+ return;
+ if (tagCounts.get(i).getFirst().equals(counter.get(j).getGuid())) {
+ if (abortCount)
+ return;
+ counter.get(j).setCount(tagCounts.get(i).getSecond());
+ j=counter.size();
+ }
+ }
+ }
+ if (abortCount)
+ return;
+ tagSignal.countsChanged.emit(counter);
+ return;
+ }
+
+
+ if (abortCount)
+ return;
+ List<cx.fbn.nevernote.sql.NoteTagsRecord> tags = conn.getNoteTable().noteTagsTable.getAllNoteTags();
+ for (int i=noteIndex.size()-1; i>=0; i--) {
+ if (abortCount)
+ return;
+ String note = noteIndex.get(i);
+ for (int x=0; tags!= null && x<tags.size() && keepRunning; x++) {
+ if (abortCount)
+ return;
+ String tag = tags.get(x).tagGuid;
+ for (int j=0; j<counter.size() && keepRunning; j++) {
+ if (abortCount)
+ return;
+ if (counter.get(j).getGuid().equals(tag) && note.equals(tags.get(x).noteGuid)) {
+ int c = counter.get(j).getCount()+1;
+ counter.get(j).setCount(c);
+ }
+ }
+ }
+ }
+ if (abortCount)
+ return;
+ tagSignal.countsChanged.emit(counter);
+ logger.log(logger.EXTREME, "Leaving ListManager.countTagResults()");
+ } */
+ private void countTagResults() {
+ logger.log(logger.EXTREME, "Entering ListManager.countTagResults");
+ if (abortCount)
+ return;
+ List<TagCounter> tCounter = new ArrayList<TagCounter>();
+ for (int i=0; i<records.size(); i++) {
+ if (abortCount)
+ return;
+
+ // Loop through the list of tags so we can count them
+ Vector<String> tags = records.get(i).tags;
+ for (int z=0; z<tags.size(); z++) {
+ boolean found = false;
+ for (int j=0; j<tCounter.size(); j++) {
+ if (abortCount)
+ return;
+ if (tCounter.get(j).getGuid().equals(tags.get(z))) {
+ tCounter.get(j).setCount(tCounter.get(j).getCount()+1);
+ found = true;
+ j=tCounter.size();
+ }
+ }
+ if (!found) {
+ TagCounter newCounter = new TagCounter();
+ newCounter.setGuid(tags.get(z));
+ newCounter.setCount(1);
+ tCounter.add(newCounter);
+ }
+ }
+ }
+ if (abortCount)
+ return;
+ tagSignal.countsChanged.emit(tCounter);
+ logger.log(logger.EXTREME, "Leaving ListManager.countTagResults");
+ }
+
+
+ private void countTrashResults() {
+ logger.log(logger.EXTREME, "Entering CounterRunner.countTrashResults()");
+ if (abortCount)
+ return;
+
+ int tCounter = 0;
+ for (int i=0; i<records.size(); i++) {
+ if (abortCount)
+ return;
+ if (!records.get(i).active)
+ tCounter++;
+ }
+
+ if (abortCount)
+ return;
+
+ trashSignal.countChanged.emit(tCounter);
+ logger.log(logger.EXTREME, "Leaving CounterRunner.countTrashResults()");
+ }
+
+}
-/*\r
- * This file is part of NixNote \r
- * Copyright 2009 Randy Baumgarte\r
- * \r
- * This file may be licensed under the terms of of the\r
- * GNU General Public License Version 2 (the ``GPL'').\r
- *\r
- * Software distributed under the License is distributed\r
- * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either\r
- * express or implied. See the GPL for the specific language\r
- * governing rights and limitations.\r
- *\r
- * You should have received a copy of the GPL along with this\r
- * program. If not, go to http://www.gnu.org/licenses/gpl.html\r
- * or write to the Free Software Foundation, Inc.,\r
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
- *\r
-*/\r
-\r
-package cx.fbn.nevernote.threads;\r
-\r
-import java.io.File;\r
-import java.io.FileInputStream;\r
-import java.io.FileNotFoundException;\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
-import java.util.List;\r
-import java.util.TreeSet;\r
-import java.util.concurrent.LinkedBlockingQueue;\r
-import java.util.concurrent.locks.LockSupport;\r
-\r
-import org.apache.commons.lang3.StringEscapeUtils;\r
-import org.apache.tika.exception.TikaException;\r
-import org.apache.tika.metadata.Metadata;\r
-import org.apache.tika.parser.ParseContext;\r
-import org.apache.tika.parser.microsoft.OfficeParser;\r
-import org.apache.tika.parser.microsoft.ooxml.OOXMLParser;\r
-import org.apache.tika.parser.odf.OpenDocumentParser;\r
-import org.apache.tika.parser.pdf.PDFParser;\r
-import org.apache.tika.parser.rtf.RTFParser;\r
-import org.apache.tika.sax.BodyContentHandler;\r
-import org.xml.sax.ContentHandler;\r
-import org.xml.sax.SAXException;\r
-\r
-import com.evernote.edam.type.Data;\r
-import com.evernote.edam.type.Note;\r
-import com.evernote.edam.type.Resource;\r
-import com.trolltech.qt.core.QByteArray;\r
-import com.trolltech.qt.core.QIODevice.OpenModeFlag;\r
-import com.trolltech.qt.core.QObject;\r
-import com.trolltech.qt.core.QTemporaryFile;\r
-import com.trolltech.qt.xml.QDomDocument;\r
-import com.trolltech.qt.xml.QDomElement;\r
-import com.trolltech.qt.xml.QDomNodeList;\r
-\r
-import cx.fbn.nevernote.Global;\r
-import cx.fbn.nevernote.signals.IndexSignal;\r
-import cx.fbn.nevernote.signals.NoteResourceSignal;\r
-import cx.fbn.nevernote.signals.NoteSignal;\r
-import cx.fbn.nevernote.sql.DatabaseConnection;\r
-import cx.fbn.nevernote.utilities.ApplicationLogger;\r
-\r
-public class IndexRunner extends QObject implements Runnable {\r
- \r
- private final ApplicationLogger logger;\r
- private String guid;\r
- private QByteArray resourceBinary;\r
- public volatile NoteSignal noteSignal;\r
- public volatile NoteResourceSignal resourceSignal;\r
- private int indexType;\r
- public final int SCAN=1; \r
- public final int REINDEXALL=2;\r
- public final int REINDEXNOTE=3;\r
- public boolean keepRunning;\r
- private final QDomDocument doc;\r
- private static String regex = Global.getWordRegex();\r
- public String specialIndexCharacters = "";\r
- public boolean indexNoteBody = true;\r
- public boolean indexNoteTitle = true;\r
- public boolean indexImageRecognition = true;\r
- private final DatabaseConnection conn;\r
- private volatile LinkedBlockingQueue<String> workQueue;\r
- private static int MAX_QUEUED_WAITING = 1000;\r
- public boolean interrupt;\r
- public boolean idle;\r
- public boolean indexAttachmentsLocally = true;\r
- public volatile IndexSignal signal;\r
- private final TreeSet<String> foundWords;\r
- int uncommittedCount = 0;\r
-\r
- \r
- public IndexRunner(String logname, String u, String i, String r, String uid, String pswd, String cpswd) {\r
- foundWords = new TreeSet<String>();\r
- logger = new ApplicationLogger(logname);\r
- conn = new DatabaseConnection(logger, u, i, r, uid, pswd, cpswd, 500);\r
- indexType = SCAN;\r
- guid = null;\r
- keepRunning = true;\r
- doc = new QDomDocument();\r
- workQueue=new LinkedBlockingQueue<String>(MAX_QUEUED_WAITING); \r
- }\r
- \r
- public void setIndexType(int t) {\r
- indexType = t;\r
- }\r
- \r
- \r
- @Override\r
- public void run() {\r
- thread().setPriority(Thread.MIN_PRIORITY);\r
- noteSignal = new NoteSignal();\r
- resourceSignal = new NoteResourceSignal();\r
- signal = new IndexSignal();\r
- logger.log(logger.EXTREME, "Starting index thread ");\r
- while (keepRunning) {\r
- idle=true;\r
- try {\r
- conn.commitTransaction();\r
- uncommittedCount = 0;\r
- String work = workQueue.take();\r
- idle=false;\r
- if (work.startsWith("SCAN")) {\r
- guid=null;\r
- interrupt = false;\r
- indexType = SCAN;\r
- }\r
- if (work.startsWith("REINDEXALL")) {\r
- guid = null;\r
- indexType=REINDEXALL;\r
- }\r
- if (work.startsWith("REINDEXNOTE")) {\r
- work = work.replace("REINDEXNOTE ", "");\r
- guid = work;\r
- indexType = REINDEXNOTE;\r
- }\r
- if (work.startsWith("STOP")) {\r
- keepRunning = false;\r
- guid = null;\r
- }\r
- logger.log(logger.EXTREME, "Type:" +indexType);\r
- if (indexType == SCAN && keepRunning) {\r
- logger.log(logger.MEDIUM, "Scanning for unindexed notes & resources");\r
- scanUnindexed();\r
- setIndexType(0);\r
- }\r
- if (indexType == REINDEXALL && keepRunning) {\r
- logger.log(logger.MEDIUM, "Marking all for reindex");\r
- reindexAll();\r
- setIndexType(0);\r
- }\r
- if (indexType == REINDEXNOTE && keepRunning) {\r
- reindexNote();\r
- }\r
- } catch (InterruptedException e) {\r
- logger.log(logger.LOW, "Thread interrupted exception: " +e.getMessage());\r
- }\r
- }\r
- logger.log(logger.EXTREME, "Shutting down database");\r
- conn.dbShutdown();\r
- logger.log(logger.EXTREME, "Database shut down. Exiting thread");\r
- }\r
- \r
- // Reindex a note\r
- public void indexNoteContent() {\r
- foundWords.clear();\r
- \r
- logger.log(logger.EXTREME, "Entering indexRunner.indexNoteContent()");\r
- \r
- logger.log(logger.EXTREME, "Getting note content");\r
- Note n = conn.getNoteTable().getNote(guid,true,false,true,true, true);\r
- String data;\r
- if (indexNoteBody) {\r
- data = n.getContent();\r
- data = conn.getNoteTable().getNoteContentNoUTFConversion(n.getGuid());\r
- \r
- logger.log(logger.EXTREME, "Removing any encrypted data");\r
- data = removeEnCrypt(data.toString());\r
- logger.log(logger.EXTREME, "Removing xml markups");\r
- } else\r
- data = "";\r
- String text;\r
- if (indexNoteTitle)\r
- text = removeTags(StringEscapeUtils.unescapeHtml4(data) +" "+ n.getTitle());\r
- else\r
- text = removeTags(StringEscapeUtils.unescapeHtml4(data));\r
- \r
- logger.log(logger.EXTREME, "Splitting words");\r
- String[] result = text.toString().split(regex);\r
- conn.commitTransaction();\r
- conn.beginTransaction();\r
- logger.log(logger.EXTREME, "Deleting existing words for note from index");\r
- conn.getWordsTable().expungeFromWordIndex(guid, "CONTENT");\r
- \r
- logger.log(logger.EXTREME, "Number of words found: " +result.length);\r
- for (int j=0; j<result.length && keepRunning; j++) {\r
- if (interrupt) {\r
- processInterrupt();\r
- }\r
- if (!result[j].trim().equals("")) {\r
- logger.log(logger.EXTREME, "Result word: " +result[j].trim());\r
- addToIndex(guid, result[j], "CONTENT");\r
- }\r
- }\r
- \r
- // Add tags\r
- for (int j=0; j<n.getTagNamesSize(); j++) {\r
- if (n.getTagNames() != null && n.getTagNames().get(j) != null && !n.getTagNames().get(j).trim().equals(""))\r
- addToIndex(guid, n.getTagNames().get(j), "CONTENT");\r
- }\r
- \r
- // If we were interrupted, we will reindex this note next time\r
- if (Global.keepRunning) {\r
- logger.log(logger.EXTREME, "Resetting note guid needed");\r
- conn.getNoteTable().setIndexNeeded(guid, false);\r
- } \r
- conn.commitTransaction();\r
- uncommittedCount = 0;\r
- logger.log(logger.EXTREME, "Leaving indexRunner.indexNoteContent()");\r
- }\r
- \r
- \r
- private String removeTags(String text) {\r
- StringBuffer buffer = new StringBuffer(text);\r
- boolean inTag = false;\r
- for (int i=buffer.length()-1; i>=0; i--) {\r
- if (buffer.charAt(i) == '>')\r
- inTag = true;\r
- if (buffer.charAt(i) == '<')\r
- inTag = false;\r
- if (inTag || buffer.charAt(i) == '<')\r
- buffer.deleteCharAt(i);\r
- }\r
- \r
- return buffer.toString();\r
- }\r
-\r
- \r
- public synchronized boolean addWork(String request) {\r
- if (workQueue.size() == 0) {\r
- workQueue.offer(request);\r
- return true;\r
- }\r
- return false;\r
- }\r
- \r
- public synchronized int getWorkQueueSize() {\r
- return workQueue.size();\r
- }\r
- \r
- public void indexResource() {\r
- \r
- if (guid == null)\r
- return;\r
- foundWords.clear();\r
- Resource r = conn.getNoteTable().noteResourceTable.getNoteResourceRecognition(guid);\r
- if (!indexImageRecognition || \r
- r == null || r.getRecognition() == null || \r
- r.getRecognition().getBody() == null || \r
- r.getRecognition().getBody().length == 0) \r
- resourceBinary = new QByteArray(" ");\r
- else\r
- resourceBinary = new QByteArray(r.getRecognition().getBody());\r
- \r
- conn.commitTransaction();\r
- conn.beginTransaction();\r
- conn.getWordsTable().expungeFromWordIndex(r.getNoteGuid(), "RESOURCE");\r
- // This is due to an old bug & can be removed at some point in the future 11/23/2010\r
- conn.getWordsTable().expungeFromWordIndex(guid, "RESOURCE"); \r
- conn.commitTransaction();\r
- uncommittedCount = 0;\r
- conn.beginTransaction();\r
- \r
- doc.setContent(resourceBinary);\r
- QDomElement docElem = doc.documentElement();\r
- \r
- // look for text tags\r
- QDomNodeList anchors = docElem.elementsByTagName("t");\r
- for (int i=0; i<anchors.length() && keepRunning; i++) {\r
- if (interrupt) {\r
- if (interrupt) {\r
- processInterrupt();\r
- }\r
- }\r
- QDomElement enmedia = anchors.at(i).toElement();\r
- String weight = new String(enmedia.attribute("w"));\r
- String text = new String(enmedia.text()).toLowerCase();\r
- if (!text.equals("")) {\r
- conn.getWordsTable().addWordToNoteIndex(r.getNoteGuid(), text, "RESOURCE", new Integer(weight));\r
- uncommittedCount++;\r
- if (uncommittedCount > 100) {\r
- conn.commitTransaction();\r
- uncommittedCount=0;\r
- }\r
- }\r
- }\r
- \r
- if (Global.keepRunning && indexAttachmentsLocally) {\r
- conn.commitTransaction();\r
- uncommittedCount = 0;\r
- conn.beginTransaction();\r
- indexResourceContent(guid);\r
- }\r
- \r
- if (Global.keepRunning)\r
- conn.getNoteTable().noteResourceTable.setIndexNeeded(guid,false);\r
- conn.commitTransaction();\r
- uncommittedCount = 0;\r
- }\r
- \r
- private void indexResourceContent(String guid) {\r
- Resource r = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);\r
- if (r != null && r.getMime() != null) {\r
- if (r.getMime().equalsIgnoreCase("application/pdf")) {\r
- indexResourcePDF(r);\r
- return;\r
- }\r
- if (r.getMime().equalsIgnoreCase("application/docx") || \r
- r.getMime().equalsIgnoreCase("application/xlsx") || \r
- r.getMime().equalsIgnoreCase("application/pptx")) {\r
- indexResourceOOXML(r);\r
- return;\r
- }\r
- if (r.getMime().equalsIgnoreCase("application/vsd") ||\r
- r.getMime().equalsIgnoreCase("application/ppt") ||\r
- r.getMime().equalsIgnoreCase("application/xls") ||\r
- r.getMime().equalsIgnoreCase("application/msg") ||\r
- r.getMime().equalsIgnoreCase("application/doc")) {\r
- indexResourceOffice(r);\r
- return;\r
- }\r
- if (r.getMime().equalsIgnoreCase("application/rtf")) {\r
- indexResourceRTF(r);\r
- return;\r
- }\r
- if (r.getMime().equalsIgnoreCase("application/odf") ||\r
- r.getMime().equalsIgnoreCase("application/odt") ||\r
- r.getMime().equalsIgnoreCase("application/odp") ||\r
- r.getMime().equalsIgnoreCase("application/odg") ||\r
- r.getMime().equalsIgnoreCase("application/odb") ||\r
- r.getMime().equalsIgnoreCase("application/ods")) {\r
- indexResourceODF(r);\r
- return;\r
- }\r
- }\r
- }\r
-\r
-\r
- private void indexResourceRTF(Resource r) {\r
-\r
- Data d = r.getData();\r
- for (int i=0; i<20 && d.getSize() == 0; i++)\r
- d = r.getData();\r
- if (d.getSize()== 0)\r
- return;\r
-\r
- QTemporaryFile f = writeResource(d);\r
- if (!keepRunning) {\r
- return;\r
- }\r
- \r
- InputStream input;\r
- try {\r
- input = new FileInputStream(new File(f.fileName()));\r
- ContentHandler textHandler = new BodyContentHandler(-1);\r
- Metadata metadata = new Metadata();\r
- RTFParser parser = new RTFParser(); \r
- ParseContext context = new ParseContext();\r
- parser.parse(input, textHandler, metadata, context);\r
- String[] result = textHandler.toString().split(regex);\r
- for (int i=0; i<result.length && keepRunning; i++) {\r
- addToIndex(r.getNoteGuid(), result[i], "RESOURCE");\r
- }\r
- input.close();\r
- \r
- f.close();\r
- } catch (java.lang.ClassCastException e) {\r
- logger.log(logger.LOW, "Cast exception: " +e.getMessage());\r
- } catch (FileNotFoundException e) {\r
- logger.log(logger.LOW, "FileNotFound exception: " +e.getMessage());\r
- } catch (IOException e) {\r
- logger.log(logger.LOW, "IO exception: " +e.getMessage());\r
- } catch (SAXException e) {\r
- logger.log(logger.LOW, "SAX exception: " +e.getMessage());\r
- } catch (TikaException e) {\r
- logger.log(logger.LOW, "Tika exception: " +e.getMessage());\r
- } catch (Exception e) {\r
- logger.log(logger.LOW, "Unknown exception: " +e.getMessage());\r
- } catch (java.lang.NoSuchMethodError e) {\r
- logger.log(logger.LOW, "NoSuchMethod error: " +e.getMessage());\r
- } catch (Error e) {\r
- logger.log(logger.LOW, "Unknown error: " +e.getMessage());\r
- }\r
- }\r
-\r
- \r
- private void indexResourceODF(Resource r) {\r
-\r
- Data d = r.getData();\r
- for (int i=0; i<20 && d.getSize() == 0; i++)\r
- d = r.getData();\r
- if (d.getSize()== 0)\r
- return;\r
- QTemporaryFile f = writeResource(d);\r
- if (!keepRunning) {\r
- return;\r
- }\r
- \r
- InputStream input;\r
- try {\r
- input = new FileInputStream(new File(f.fileName()));\r
- ContentHandler textHandler = new BodyContentHandler(-1);\r
- Metadata metadata = new Metadata();\r
- OpenDocumentParser parser = new OpenDocumentParser(); \r
- ParseContext context = new ParseContext();\r
- parser.parse(input, textHandler, metadata, context);\r
- String[] result = textHandler.toString().split(regex);\r
- for (int i=0; i<result.length && keepRunning; i++) {\r
- if (interrupt) {\r
- processInterrupt();\r
- }\r
- addToIndex(r.getNoteGuid(), result[i], "RESOURCE");\r
- }\r
- input.close();\r
- \r
- f.close();\r
- } catch (java.lang.ClassCastException e) {\r
- logger.log(logger.LOW, "Cast exception: " +e.getMessage());\r
- } catch (FileNotFoundException e) {\r
- logger.log(logger.LOW, "FileNotFound exception: " +e.getMessage());\r
- } catch (IOException e) {\r
- logger.log(logger.LOW, "IO exception: " +e.getMessage());\r
- } catch (SAXException e) {\r
- logger.log(logger.LOW, "SAX exception: " +e.getMessage());\r
- } catch (TikaException e) {\r
- logger.log(logger.LOW, "Tika exception: " +e.getMessage());\r
- } catch (Exception e) {\r
- logger.log(logger.LOW, "Unknown exception: " +e.getMessage());\r
- } catch (java.lang.NoSuchMethodError e) {\r
- logger.log(logger.LOW, "NoSuchMethod error: " +e.getMessage());\r
- } catch (Error e) {\r
- logger.log(logger.LOW, "Unknown error: " +e.getMessage());\r
- }\r
- }\r
-\r
- \r
- private void indexResourceOffice(Resource r) {\r
-\r
- Data d = r.getData();\r
- for (int i=0; i<20 && d.getSize() == 0; i++)\r
- d = r.getData();\r
- if (d.getSize()== 0)\r
- return;\r
- QTemporaryFile f = writeResource(d);\r
- if (!keepRunning) {\r
- return;\r
- }\r
- \r
- InputStream input;\r
- try {\r
- input = new FileInputStream(new File(f.fileName()));\r
- ContentHandler textHandler = new BodyContentHandler(-1);\r
- Metadata metadata = new Metadata();\r
- OfficeParser parser = new OfficeParser(); \r
- ParseContext context = new ParseContext();\r
- parser.parse(input, textHandler, metadata, context);\r
- String[] result = textHandler.toString().split(regex);\r
- for (int i=0; i<result.length && keepRunning; i++) {\r
- if (interrupt) {\r
- processInterrupt();\r
- }\r
- addToIndex(r.getNoteGuid(), result[i], "RESOURCE");\r
- }\r
- input.close();\r
- \r
- f.close();\r
- } catch (java.lang.ClassCastException e) {\r
- logger.log(logger.LOW, "Cast exception: " +e.getMessage());\r
- } catch (FileNotFoundException e) {\r
- logger.log(logger.LOW, "FileNotFound exception: " +e.getMessage());\r
- } catch (IOException e) {\r
- logger.log(logger.LOW, "IO exception: " +e.getMessage());\r
- } catch (SAXException e) {\r
- logger.log(logger.LOW, "SAX exception: " +e.getMessage());\r
- } catch (TikaException e) {\r
- logger.log(logger.LOW, "Tika exception: " +e.getMessage());\r
- } catch (Exception e) {\r
- logger.log(logger.LOW, "Unknown exception: " +e.getMessage());\r
- } catch (java.lang.NoSuchMethodError e) {\r
- logger.log(logger.LOW, "NoSuchMethod error: " +e.getMessage());\r
- } catch (Error e) {\r
- logger.log(logger.LOW, "Unknown error: " +e.getMessage());\r
- }\r
- }\r
-\r
- \r
- \r
- private void indexResourcePDF(Resource r) {\r
-\r
- Data d = r.getData();\r
- for (int i=0; i<20 && d.getSize() == 0; i++)\r
- d = r.getData();\r
- if (d.getSize()== 0)\r
- return;\r
- QTemporaryFile f = writeResource(d);\r
- if (!keepRunning) {\r
- return;\r
- }\r
- \r
- InputStream input;\r
- try { \r
- input = new FileInputStream(new File(f.fileName()));\r
- ContentHandler textHandler = new BodyContentHandler(-1);\r
- Metadata metadata = new Metadata();\r
- PDFParser parser = new PDFParser(); \r
- ParseContext context = new ParseContext();\r
- parser.parse(input, textHandler, metadata, context);\r
- String[] result = textHandler.toString().split(regex);\r
- for (int i=0; i<result.length && keepRunning; i++) {\r
- if (interrupt) {\r
- processInterrupt();\r
- }\r
- addToIndex(r.getNoteGuid(), result[i], "RESOURCE");\r
- }\r
- input.close();\r
- \r
- f.close();\r
- } catch (java.lang.ClassCastException e) {\r
- logger.log(logger.LOW, "Cast exception: " +e.getMessage());\r
- } catch (FileNotFoundException e) {\r
- logger.log(logger.LOW, "FileNotFound exception: " +e.getMessage());\r
- } catch (IOException e) {\r
- logger.log(logger.LOW, "IO exception: " +e.getMessage());\r
- } catch (SAXException e) {\r
- logger.log(logger.LOW, "SAX exception: " +e.getMessage());\r
- } catch (TikaException e) {\r
- logger.log(logger.LOW, "Tika exception: " +e.getMessage());\r
- } catch (Exception e) {\r
- logger.log(logger.LOW, "Unknown exception: " +e.getMessage());\r
- } catch (java.lang.NoSuchMethodError e) {\r
- logger.log(logger.LOW, "NoSuchMethod error: " +e.getMessage());\r
- } catch (Error e) {\r
- logger.log(logger.LOW, "Unknown error: " +e.getMessage());\r
- }\r
- }\r
- \r
- \r
- private void indexResourceOOXML(Resource r) {\r
-\r
- Data d = r.getData();\r
- for (int i=0; i<20 && d.getSize() == 0; i++)\r
- d = r.getData();\r
- if (d.getSize()== 0)\r
- return;\r
- QTemporaryFile f = writeResource(d);\r
- if (!keepRunning) {\r
- return;\r
- }\r
- \r
- InputStream input;\r
- try {\r
- input = new FileInputStream(new File(f.fileName()));\r
- ContentHandler textHandler = new BodyContentHandler(-1);\r
- Metadata metadata = new Metadata();\r
- OOXMLParser parser = new OOXMLParser(); \r
- ParseContext context = new ParseContext();\r
- parser.parse(input, textHandler, metadata, context);\r
- String[] result = textHandler.toString().split(regex);\r
- for (int i=0; i<result.length && keepRunning; i++) {\r
- if (interrupt) {\r
- processInterrupt();\r
- }\r
- addToIndex(r.getNoteGuid(), result[i], "RESOURCE");\r
- }\r
- input.close();\r
- \r
- f.close();\r
- } catch (java.lang.ClassCastException e) {\r
- logger.log(logger.LOW, "Cast exception: " +e.getMessage());\r
- } catch (FileNotFoundException e) {\r
- logger.log(logger.LOW, "FileNotFound exception: " +e.getMessage());\r
- } catch (IOException e) {\r
- logger.log(logger.LOW, "IO exception: " +e.getMessage());\r
- } catch (SAXException e) {\r
- logger.log(logger.LOW, "SAX exception: " +e.getMessage());\r
- } catch (TikaException e) {\r
- logger.log(logger.LOW, "Tika exception: " +e.getMessage());\r
- } catch (Exception e) {\r
- logger.log(logger.LOW, "Unknown exception: " +e.getMessage());\r
- } catch (java.lang.NoSuchMethodError e) {\r
- logger.log(logger.LOW, "NoSuchMethod error: " +e.getMessage());\r
- } catch (Error e) {\r
- logger.log(logger.LOW, "Unknown error: " +e.getMessage()); }\r
- }\r
- \r
-\r
- \r
- private QTemporaryFile writeResource(Data d) {\r
- QTemporaryFile newFile = new QTemporaryFile();\r
- newFile.open(OpenModeFlag.WriteOnly);\r
- newFile.write(d.getBody());\r
- newFile.close();\r
- return newFile;\r
- } \r
-\r
- \r
- private String removeEnCrypt(String content) {\r
- int index = content.indexOf("<en-crypt");\r
- int endPos;\r
- boolean tagFound = true;\r
- while (tagFound && keepRunning) {\r
- if (interrupt) {\r
- processInterrupt();\r
- }\r
- endPos = content.indexOf("</en-crypt>", index)+11;\r
- if (endPos > -1 && index > -1) {\r
- content = content.substring(0,index)+content.substring(endPos);\r
- index = content.indexOf("<en-crypt");\r
- } else {\r
- tagFound = false;\r
- }\r
- }\r
- return content;\r
- }\r
-\r
- \r
- private void addToIndex(String guid, String word, String type) {\r
- if (foundWords.contains(word))\r
- return;\r
- StringBuffer buffer = new StringBuffer(word.toLowerCase());\r
- for (int i=buffer.length()-1; i>=0; i--) {\r
- if (!Character.isLetterOrDigit(buffer.charAt(i)) && specialIndexCharacters.indexOf(buffer.charAt(i)) == -1)\r
- buffer.deleteCharAt(i);\r
- else\r
- break;\r
- }\r
- buffer = buffer.reverse();\r
- for (int i=buffer.length()-1; i>=0; i--) {\r
- if (!Character.isLetterOrDigit(buffer.charAt(i)))\r
- buffer.deleteCharAt(i);\r
- else\r
- break;\r
- }\r
- buffer = buffer.reverse();\r
- if (buffer.length() > 0) {\r
- // We have a good word, now let's trim off junk at the beginning or end\r
- if (!foundWords.contains(buffer.toString())) {\r
- foundWords.add(buffer.toString());\r
- foundWords.add(word);\r
- conn.getWordsTable().addWordToNoteIndex(guid, buffer.toString(), type, 100);\r
- uncommittedCount++;\r
- if (uncommittedCount > 100) {\r
- conn.commitTransaction();\r
- uncommittedCount=0;\r
- }\r
- }\r
- }\r
- return;\r
- }\r
- \r
- private void scanUnindexed() {\r
- List<String> notes = conn.getNoteTable().getUnindexed();\r
- guid = null;\r
- boolean started = false;\r
- if (notes.size() > 0) {\r
- signal.indexStarted.emit();\r
- started = true;\r
- }\r
- for (int i=0; i<notes.size() && keepRunning; i++) {\r
- if (interrupt) {\r
- processInterrupt();\r
- }\r
- guid = notes.get(i);\r
- if (guid != null && keepRunning) {\r
- indexNoteContent();\r
- }\r
- }\r
- \r
- List<String> unindexedResources = conn.getNoteTable().noteResourceTable.getUnindexed();\r
- if (unindexedResources.size() > 0 && !started) {\r
- signal.indexStarted.emit();\r
- started = true;\r
- }\r
- for (int i=0; i<unindexedResources.size()&& keepRunning; i++) {\r
- if (interrupt) {\r
- processInterrupt();\r
- }\r
- guid = unindexedResources.get(i);\r
- if (keepRunning) {\r
- indexResource();\r
- }\r
- }\r
- \r
- // Cleanup stuff that was deleted at some point\r
- List<String> guids = conn.getWordsTable().getGuidList();\r
- logger.log(logger.LOW, "GUIDS in index: " +guids.size());\r
- for (int i=0; i<guids.size() && keepRunning; i++) {\r
- if (!conn.getNoteTable().exists(guids.get(i))) {\r
- logger.log(logger.LOW, "Old GUID found: " +guids.get(i));\r
- conn.getWordsTable().expunge(guids.get(i));\r
- }\r
- }\r
- \r
- if (started && keepRunning) \r
- signal.indexFinished.emit();\r
- }\r
- \r
- private void reindexNote() {\r
- if (guid == null)\r
- return;\r
- conn.getNoteTable().setIndexNeeded(guid, true);\r
- }\r
- \r
- private void reindexAll() {\r
- conn.getNoteTable().reindexAllNotes();\r
- conn.getNoteTable().noteResourceTable.reindexAll(); \r
- }\r
-\r
- private void waitSeconds(int len) {\r
- long starttime = 0; // variable declared\r
- //...\r
- // for the first time, remember the timestamp\r
- starttime = System.currentTimeMillis();\r
- // the next timestamp we want to wake up\r
- starttime += (1000.0);\r
- // Wait until the desired next time arrives using nanosecond\r
- // accuracy timer (wait(time) isn't accurate enough on most platforms) \r
- LockSupport.parkNanos((Math.max(0, \r
- starttime - System.currentTimeMillis()) * 1000000));\r
- }\r
- \r
- private void processInterrupt() {\r
- conn.commitTransaction();\r
- waitSeconds(1);\r
- uncommittedCount = 0;\r
- conn.beginTransaction();\r
- interrupt = false;\r
- }\r
- \r
-}\r
+/*
+ * This file is part of NixNote
+ * Copyright 2009 Randy Baumgarte
+ *
+ * This file may be licensed under the terms of of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+*/
+
+package cx.fbn.nevernote.threads;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.TreeSet;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.locks.LockSupport;
+
+import org.apache.commons.lang3.StringEscapeUtils;
+import org.apache.tika.exception.TikaException;
+import org.apache.tika.metadata.Metadata;
+import org.apache.tika.parser.ParseContext;
+import org.apache.tika.parser.microsoft.OfficeParser;
+import org.apache.tika.parser.microsoft.ooxml.OOXMLParser;
+import org.apache.tika.parser.odf.OpenDocumentParser;
+import org.apache.tika.parser.pdf.PDFParser;
+import org.apache.tika.parser.rtf.RTFParser;
+import org.apache.tika.sax.BodyContentHandler;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+import com.evernote.edam.type.Data;
+import com.evernote.edam.type.Note;
+import com.evernote.edam.type.Resource;
+import com.trolltech.qt.core.QByteArray;
+import com.trolltech.qt.core.QIODevice.OpenModeFlag;
+import com.trolltech.qt.core.QObject;
+import com.trolltech.qt.core.QTemporaryFile;
+import com.trolltech.qt.xml.QDomDocument;
+import com.trolltech.qt.xml.QDomElement;
+import com.trolltech.qt.xml.QDomNodeList;
+
+import cx.fbn.nevernote.Global;
+import cx.fbn.nevernote.signals.IndexSignal;
+import cx.fbn.nevernote.signals.NoteResourceSignal;
+import cx.fbn.nevernote.signals.NoteSignal;
+import cx.fbn.nevernote.sql.DatabaseConnection;
+import cx.fbn.nevernote.utilities.ApplicationLogger;
+
+public class IndexRunner extends QObject implements Runnable {
+
+ private final ApplicationLogger logger;
+ private String guid;
+ private QByteArray resourceBinary;
+ public volatile NoteSignal noteSignal;
+ public volatile NoteResourceSignal resourceSignal;
+ private int indexType;
+ public final int SCAN=1;
+ public final int REINDEXALL=2;
+ public final int REINDEXNOTE=3;
+ public boolean keepRunning;
+ private final QDomDocument doc;
+ private static String regex = Global.getWordRegex();
+ public String specialIndexCharacters = "";
+ public boolean indexNoteBody = true;
+ public boolean indexNoteTitle = true;
+ public boolean indexImageRecognition = true;
+ private final DatabaseConnection conn;
+ private volatile LinkedBlockingQueue<String> workQueue;
+ private static int MAX_QUEUED_WAITING = 1000;
+ public boolean interrupt;
+ public boolean idle;
+ public boolean indexAttachmentsLocally = true;
+ public volatile IndexSignal signal;
+ private final TreeSet<String> foundWords;
+ int uncommittedCount = 0;
+
+ // ICHANGED String bを追加
+ public IndexRunner(String logname, String u, String i, String r, String b, String uid, String pswd, String cpswd) {
+ foundWords = new TreeSet<String>();
+ logger = new ApplicationLogger(logname);
+ // ICHANGED bを追加
+ conn = new DatabaseConnection(logger, u, i, r, b, uid, pswd, cpswd, 500);
+ indexType = SCAN;
+ guid = null;
+ keepRunning = true;
+ doc = new QDomDocument();
+ workQueue=new LinkedBlockingQueue<String>(MAX_QUEUED_WAITING);
+ }
+
+ public void setIndexType(int t) {
+ indexType = t;
+ }
+
+
+ @Override
+ public void run() {
+ thread().setPriority(Thread.MIN_PRIORITY);
+ noteSignal = new NoteSignal();
+ resourceSignal = new NoteResourceSignal();
+ signal = new IndexSignal();
+ logger.log(logger.EXTREME, "Starting index thread ");
+ while (keepRunning) {
+ idle=true;
+ try {
+ conn.commitTransaction();
+ uncommittedCount = 0;
+ String work = workQueue.take();
+ idle=false;
+ if (work.startsWith("SCAN")) {
+ guid=null;
+ interrupt = false;
+ indexType = SCAN;
+ }
+ if (work.startsWith("REINDEXALL")) {
+ guid = null;
+ indexType=REINDEXALL;
+ }
+ if (work.startsWith("REINDEXNOTE")) {
+ work = work.replace("REINDEXNOTE ", "");
+ guid = work;
+ indexType = REINDEXNOTE;
+ }
+ if (work.startsWith("STOP")) {
+ keepRunning = false;
+ guid = null;
+ }
+ logger.log(logger.EXTREME, "Type:" +indexType);
+ if (indexType == SCAN && keepRunning) {
+ logger.log(logger.MEDIUM, "Scanning for unindexed notes & resources");
+ scanUnindexed();
+ setIndexType(0);
+ }
+ if (indexType == REINDEXALL && keepRunning) {
+ logger.log(logger.MEDIUM, "Marking all for reindex");
+ reindexAll();
+ setIndexType(0);
+ }
+ if (indexType == REINDEXNOTE && keepRunning) {
+ reindexNote();
+ }
+ } catch (InterruptedException e) {
+ logger.log(logger.LOW, "Thread interrupted exception: " +e.getMessage());
+ }
+ }
+ logger.log(logger.EXTREME, "Shutting down database");
+ conn.dbShutdown();
+ logger.log(logger.EXTREME, "Database shut down. Exiting thread");
+ }
+
+ // Reindex a note
+ public void indexNoteContent() {
+ foundWords.clear();
+
+ logger.log(logger.EXTREME, "Entering indexRunner.indexNoteContent()");
+
+ logger.log(logger.EXTREME, "Getting note content");
+ Note n = conn.getNoteTable().getNote(guid,true,false,true,true, true);
+ String data;
+ if (indexNoteBody) {
+ data = n.getContent();
+ data = conn.getNoteTable().getNoteContentNoUTFConversion(n.getGuid());
+
+ logger.log(logger.EXTREME, "Removing any encrypted data");
+ data = removeEnCrypt(data.toString());
+ logger.log(logger.EXTREME, "Removing xml markups");
+ } else
+ data = "";
+ String text;
+ if (indexNoteTitle)
+ text = removeTags(StringEscapeUtils.unescapeHtml4(data) +" "+ n.getTitle());
+ else
+ text = removeTags(StringEscapeUtils.unescapeHtml4(data));
+
+ logger.log(logger.EXTREME, "Splitting words");
+ String[] result = text.toString().split(regex);
+ conn.commitTransaction();
+ conn.beginTransaction();
+ logger.log(logger.EXTREME, "Deleting existing words for note from index");
+ conn.getWordsTable().expungeFromWordIndex(guid, "CONTENT");
+
+ logger.log(logger.EXTREME, "Number of words found: " +result.length);
+ for (int j=0; j<result.length && keepRunning; j++) {
+ if (interrupt) {
+ processInterrupt();
+ }
+ if (!result[j].trim().equals("")) {
+ logger.log(logger.EXTREME, "Result word: " +result[j].trim());
+ addToIndex(guid, result[j], "CONTENT");
+ }
+ }
+
+ // Add tags
+ for (int j=0; j<n.getTagNamesSize(); j++) {
+ if (n.getTagNames() != null && n.getTagNames().get(j) != null && !n.getTagNames().get(j).trim().equals(""))
+ addToIndex(guid, n.getTagNames().get(j), "CONTENT");
+ }
+
+ // If we were interrupted, we will reindex this note next time
+ if (Global.keepRunning) {
+ logger.log(logger.EXTREME, "Resetting note guid needed");
+ conn.getNoteTable().setIndexNeeded(guid, false);
+ }
+ conn.commitTransaction();
+ uncommittedCount = 0;
+ logger.log(logger.EXTREME, "Leaving indexRunner.indexNoteContent()");
+ }
+
+
+ private String removeTags(String text) {
+ StringBuffer buffer = new StringBuffer(text);
+ boolean inTag = false;
+ for (int i=buffer.length()-1; i>=0; i--) {
+ if (buffer.charAt(i) == '>')
+ inTag = true;
+ if (buffer.charAt(i) == '<')
+ inTag = false;
+ if (inTag || buffer.charAt(i) == '<')
+ buffer.deleteCharAt(i);
+ }
+
+ return buffer.toString();
+ }
+
+
+ public synchronized boolean addWork(String request) {
+ if (workQueue.size() == 0) {
+ workQueue.offer(request);
+ return true;
+ }
+ return false;
+ }
+
+ public synchronized int getWorkQueueSize() {
+ return workQueue.size();
+ }
+
+ public void indexResource() {
+
+ if (guid == null)
+ return;
+ foundWords.clear();
+ Resource r = conn.getNoteTable().noteResourceTable.getNoteResourceRecognition(guid);
+ if (!indexImageRecognition ||
+ r == null || r.getRecognition() == null ||
+ r.getRecognition().getBody() == null ||
+ r.getRecognition().getBody().length == 0)
+ resourceBinary = new QByteArray(" ");
+ else
+ resourceBinary = new QByteArray(r.getRecognition().getBody());
+
+ conn.commitTransaction();
+ conn.beginTransaction();
+ conn.getWordsTable().expungeFromWordIndex(r.getNoteGuid(), "RESOURCE");
+ // This is due to an old bug & can be removed at some point in the future 11/23/2010
+ conn.getWordsTable().expungeFromWordIndex(guid, "RESOURCE");
+ conn.commitTransaction();
+ uncommittedCount = 0;
+ conn.beginTransaction();
+
+ doc.setContent(resourceBinary);
+ QDomElement docElem = doc.documentElement();
+
+ // look for text tags
+ QDomNodeList anchors = docElem.elementsByTagName("t");
+ for (int i=0; i<anchors.length() && keepRunning; i++) {
+ if (interrupt) {
+ if (interrupt) {
+ processInterrupt();
+ }
+ }
+ QDomElement enmedia = anchors.at(i).toElement();
+ String weight = new String(enmedia.attribute("w"));
+ String text = new String(enmedia.text()).toLowerCase();
+ if (!text.equals("")) {
+ conn.getWordsTable().addWordToNoteIndex(r.getNoteGuid(), text, "RESOURCE", new Integer(weight));
+ uncommittedCount++;
+ if (uncommittedCount > 100) {
+ conn.commitTransaction();
+ uncommittedCount=0;
+ }
+ }
+ }
+
+ if (Global.keepRunning && indexAttachmentsLocally) {
+ conn.commitTransaction();
+ uncommittedCount = 0;
+ conn.beginTransaction();
+ indexResourceContent(guid);
+ }
+
+ if (Global.keepRunning)
+ conn.getNoteTable().noteResourceTable.setIndexNeeded(guid,false);
+ conn.commitTransaction();
+ uncommittedCount = 0;
+ }
+
+ private void indexResourceContent(String guid) {
+ Resource r = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);
+ if (r != null && r.getMime() != null) {
+ if (r.getMime().equalsIgnoreCase("application/pdf")) {
+ indexResourcePDF(r);
+ return;
+ }
+ if (r.getMime().equalsIgnoreCase("application/docx") ||
+ r.getMime().equalsIgnoreCase("application/xlsx") ||
+ r.getMime().equalsIgnoreCase("application/pptx")) {
+ indexResourceOOXML(r);
+ return;
+ }
+ if (r.getMime().equalsIgnoreCase("application/vsd") ||
+ r.getMime().equalsIgnoreCase("application/ppt") ||
+ r.getMime().equalsIgnoreCase("application/xls") ||
+ r.getMime().equalsIgnoreCase("application/msg") ||
+ r.getMime().equalsIgnoreCase("application/doc")) {
+ indexResourceOffice(r);
+ return;
+ }
+ if (r.getMime().equalsIgnoreCase("application/rtf")) {
+ indexResourceRTF(r);
+ return;
+ }
+ if (r.getMime().equalsIgnoreCase("application/odf") ||
+ r.getMime().equalsIgnoreCase("application/odt") ||
+ r.getMime().equalsIgnoreCase("application/odp") ||
+ r.getMime().equalsIgnoreCase("application/odg") ||
+ r.getMime().equalsIgnoreCase("application/odb") ||
+ r.getMime().equalsIgnoreCase("application/ods")) {
+ indexResourceODF(r);
+ return;
+ }
+ }
+ }
+
+
+ private void indexResourceRTF(Resource r) {
+
+ Data d = r.getData();
+ for (int i=0; i<20 && d.getSize() == 0; i++)
+ d = r.getData();
+ if (d.getSize()== 0)
+ return;
+
+ QTemporaryFile f = writeResource(d);
+ if (!keepRunning) {
+ return;
+ }
+
+ InputStream input;
+ try {
+ input = new FileInputStream(new File(f.fileName()));
+ ContentHandler textHandler = new BodyContentHandler(-1);
+ Metadata metadata = new Metadata();
+ RTFParser parser = new RTFParser();
+ ParseContext context = new ParseContext();
+ parser.parse(input, textHandler, metadata, context);
+ String[] result = textHandler.toString().split(regex);
+ for (int i=0; i<result.length && keepRunning; i++) {
+ addToIndex(r.getNoteGuid(), result[i], "RESOURCE");
+ }
+ input.close();
+
+ f.close();
+ } catch (java.lang.ClassCastException e) {
+ logger.log(logger.LOW, "Cast exception: " +e.getMessage());
+ } catch (FileNotFoundException e) {
+ logger.log(logger.LOW, "FileNotFound exception: " +e.getMessage());
+ } catch (IOException e) {
+ logger.log(logger.LOW, "IO exception: " +e.getMessage());
+ } catch (SAXException e) {
+ logger.log(logger.LOW, "SAX exception: " +e.getMessage());
+ } catch (TikaException e) {
+ logger.log(logger.LOW, "Tika exception: " +e.getMessage());
+ } catch (Exception e) {
+ logger.log(logger.LOW, "Unknown exception: " +e.getMessage());
+ } catch (java.lang.NoSuchMethodError e) {
+ logger.log(logger.LOW, "NoSuchMethod error: " +e.getMessage());
+ } catch (Error e) {
+ logger.log(logger.LOW, "Unknown error: " +e.getMessage());
+ }
+ }
+
+
+ private void indexResourceODF(Resource r) {
+
+ Data d = r.getData();
+ for (int i=0; i<20 && d.getSize() == 0; i++)
+ d = r.getData();
+ if (d.getSize()== 0)
+ return;
+ QTemporaryFile f = writeResource(d);
+ if (!keepRunning) {
+ return;
+ }
+
+ InputStream input;
+ try {
+ input = new FileInputStream(new File(f.fileName()));
+ ContentHandler textHandler = new BodyContentHandler(-1);
+ Metadata metadata = new Metadata();
+ OpenDocumentParser parser = new OpenDocumentParser();
+ ParseContext context = new ParseContext();
+ parser.parse(input, textHandler, metadata, context);
+ String[] result = textHandler.toString().split(regex);
+ for (int i=0; i<result.length && keepRunning; i++) {
+ if (interrupt) {
+ processInterrupt();
+ }
+ addToIndex(r.getNoteGuid(), result[i], "RESOURCE");
+ }
+ input.close();
+
+ f.close();
+ } catch (java.lang.ClassCastException e) {
+ logger.log(logger.LOW, "Cast exception: " +e.getMessage());
+ } catch (FileNotFoundException e) {
+ logger.log(logger.LOW, "FileNotFound exception: " +e.getMessage());
+ } catch (IOException e) {
+ logger.log(logger.LOW, "IO exception: " +e.getMessage());
+ } catch (SAXException e) {
+ logger.log(logger.LOW, "SAX exception: " +e.getMessage());
+ } catch (TikaException e) {
+ logger.log(logger.LOW, "Tika exception: " +e.getMessage());
+ } catch (Exception e) {
+ logger.log(logger.LOW, "Unknown exception: " +e.getMessage());
+ } catch (java.lang.NoSuchMethodError e) {
+ logger.log(logger.LOW, "NoSuchMethod error: " +e.getMessage());
+ } catch (Error e) {
+ logger.log(logger.LOW, "Unknown error: " +e.getMessage());
+ }
+ }
+
+
+ private void indexResourceOffice(Resource r) {
+
+ Data d = r.getData();
+ for (int i=0; i<20 && d.getSize() == 0; i++)
+ d = r.getData();
+ if (d.getSize()== 0)
+ return;
+ QTemporaryFile f = writeResource(d);
+ if (!keepRunning) {
+ return;
+ }
+
+ InputStream input;
+ try {
+ input = new FileInputStream(new File(f.fileName()));
+ ContentHandler textHandler = new BodyContentHandler(-1);
+ Metadata metadata = new Metadata();
+ OfficeParser parser = new OfficeParser();
+ ParseContext context = new ParseContext();
+ parser.parse(input, textHandler, metadata, context);
+ String[] result = textHandler.toString().split(regex);
+ for (int i=0; i<result.length && keepRunning; i++) {
+ if (interrupt) {
+ processInterrupt();
+ }
+ addToIndex(r.getNoteGuid(), result[i], "RESOURCE");
+ }
+ input.close();
+
+ f.close();
+ } catch (java.lang.ClassCastException e) {
+ logger.log(logger.LOW, "Cast exception: " +e.getMessage());
+ } catch (FileNotFoundException e) {
+ logger.log(logger.LOW, "FileNotFound exception: " +e.getMessage());
+ } catch (IOException e) {
+ logger.log(logger.LOW, "IO exception: " +e.getMessage());
+ } catch (SAXException e) {
+ logger.log(logger.LOW, "SAX exception: " +e.getMessage());
+ } catch (TikaException e) {
+ logger.log(logger.LOW, "Tika exception: " +e.getMessage());
+ } catch (Exception e) {
+ logger.log(logger.LOW, "Unknown exception: " +e.getMessage());
+ } catch (java.lang.NoSuchMethodError e) {
+ logger.log(logger.LOW, "NoSuchMethod error: " +e.getMessage());
+ } catch (Error e) {
+ logger.log(logger.LOW, "Unknown error: " +e.getMessage());
+ }
+ }
+
+
+
+ private void indexResourcePDF(Resource r) {
+
+ Data d = r.getData();
+ for (int i=0; i<20 && d.getSize() == 0; i++)
+ d = r.getData();
+ if (d.getSize()== 0)
+ return;
+ QTemporaryFile f = writeResource(d);
+ if (!keepRunning) {
+ return;
+ }
+
+ InputStream input;
+ try {
+ input = new FileInputStream(new File(f.fileName()));
+ ContentHandler textHandler = new BodyContentHandler(-1);
+ Metadata metadata = new Metadata();
+ PDFParser parser = new PDFParser();
+ ParseContext context = new ParseContext();
+ parser.parse(input, textHandler, metadata, context);
+ String[] result = textHandler.toString().split(regex);
+ for (int i=0; i<result.length && keepRunning; i++) {
+ if (interrupt) {
+ processInterrupt();
+ }
+ addToIndex(r.getNoteGuid(), result[i], "RESOURCE");
+ }
+ input.close();
+
+ f.close();
+ } catch (java.lang.ClassCastException e) {
+ logger.log(logger.LOW, "Cast exception: " +e.getMessage());
+ } catch (FileNotFoundException e) {
+ logger.log(logger.LOW, "FileNotFound exception: " +e.getMessage());
+ } catch (IOException e) {
+ logger.log(logger.LOW, "IO exception: " +e.getMessage());
+ } catch (SAXException e) {
+ logger.log(logger.LOW, "SAX exception: " +e.getMessage());
+ } catch (TikaException e) {
+ logger.log(logger.LOW, "Tika exception: " +e.getMessage());
+ } catch (Exception e) {
+ logger.log(logger.LOW, "Unknown exception: " +e.getMessage());
+ } catch (java.lang.NoSuchMethodError e) {
+ logger.log(logger.LOW, "NoSuchMethod error: " +e.getMessage());
+ } catch (Error e) {
+ logger.log(logger.LOW, "Unknown error: " +e.getMessage());
+ }
+ }
+
+
+ private void indexResourceOOXML(Resource r) {
+
+ Data d = r.getData();
+ for (int i=0; i<20 && d.getSize() == 0; i++)
+ d = r.getData();
+ if (d.getSize()== 0)
+ return;
+ QTemporaryFile f = writeResource(d);
+ if (!keepRunning) {
+ return;
+ }
+
+ InputStream input;
+ try {
+ input = new FileInputStream(new File(f.fileName()));
+ ContentHandler textHandler = new BodyContentHandler(-1);
+ Metadata metadata = new Metadata();
+ OOXMLParser parser = new OOXMLParser();
+ ParseContext context = new ParseContext();
+ parser.parse(input, textHandler, metadata, context);
+ String[] result = textHandler.toString().split(regex);
+ for (int i=0; i<result.length && keepRunning; i++) {
+ if (interrupt) {
+ processInterrupt();
+ }
+ addToIndex(r.getNoteGuid(), result[i], "RESOURCE");
+ }
+ input.close();
+
+ f.close();
+ } catch (java.lang.ClassCastException e) {
+ logger.log(logger.LOW, "Cast exception: " +e.getMessage());
+ } catch (FileNotFoundException e) {
+ logger.log(logger.LOW, "FileNotFound exception: " +e.getMessage());
+ } catch (IOException e) {
+ logger.log(logger.LOW, "IO exception: " +e.getMessage());
+ } catch (SAXException e) {
+ logger.log(logger.LOW, "SAX exception: " +e.getMessage());
+ } catch (TikaException e) {
+ logger.log(logger.LOW, "Tika exception: " +e.getMessage());
+ } catch (Exception e) {
+ logger.log(logger.LOW, "Unknown exception: " +e.getMessage());
+ } catch (java.lang.NoSuchMethodError e) {
+ logger.log(logger.LOW, "NoSuchMethod error: " +e.getMessage());
+ } catch (Error e) {
+ logger.log(logger.LOW, "Unknown error: " +e.getMessage()); }
+ }
+
+
+
+ private QTemporaryFile writeResource(Data d) {
+ QTemporaryFile newFile = new QTemporaryFile();
+ newFile.open(OpenModeFlag.WriteOnly);
+ newFile.write(d.getBody());
+ newFile.close();
+ return newFile;
+ }
+
+
+ private String removeEnCrypt(String content) {
+ int index = content.indexOf("<en-crypt");
+ int endPos;
+ boolean tagFound = true;
+ while (tagFound && keepRunning) {
+ if (interrupt) {
+ processInterrupt();
+ }
+ endPos = content.indexOf("</en-crypt>", index)+11;
+ if (endPos > -1 && index > -1) {
+ content = content.substring(0,index)+content.substring(endPos);
+ index = content.indexOf("<en-crypt");
+ } else {
+ tagFound = false;
+ }
+ }
+ return content;
+ }
+
+
+ private void addToIndex(String guid, String word, String type) {
+ if (foundWords.contains(word))
+ return;
+ StringBuffer buffer = new StringBuffer(word.toLowerCase());
+ for (int i=buffer.length()-1; i>=0; i--) {
+ if (!Character.isLetterOrDigit(buffer.charAt(i)) && specialIndexCharacters.indexOf(buffer.charAt(i)) == -1)
+ buffer.deleteCharAt(i);
+ else
+ break;
+ }
+ buffer = buffer.reverse();
+ for (int i=buffer.length()-1; i>=0; i--) {
+ if (!Character.isLetterOrDigit(buffer.charAt(i)))
+ buffer.deleteCharAt(i);
+ else
+ break;
+ }
+ buffer = buffer.reverse();
+ if (buffer.length() > 0) {
+ // We have a good word, now let's trim off junk at the beginning or end
+ if (!foundWords.contains(buffer.toString())) {
+ foundWords.add(buffer.toString());
+ foundWords.add(word);
+ conn.getWordsTable().addWordToNoteIndex(guid, buffer.toString(), type, 100);
+ uncommittedCount++;
+ if (uncommittedCount > 100) {
+ conn.commitTransaction();
+ uncommittedCount=0;
+ }
+ }
+ }
+ return;
+ }
+
+ private void scanUnindexed() {
+ List<String> notes = conn.getNoteTable().getUnindexed();
+ guid = null;
+ boolean started = false;
+ if (notes.size() > 0) {
+ signal.indexStarted.emit();
+ started = true;
+ }
+ for (int i=0; i<notes.size() && keepRunning; i++) {
+ if (interrupt) {
+ processInterrupt();
+ }
+ guid = notes.get(i);
+ if (guid != null && keepRunning) {
+ indexNoteContent();
+ }
+ }
+
+ List<String> unindexedResources = conn.getNoteTable().noteResourceTable.getUnindexed();
+ if (unindexedResources.size() > 0 && !started) {
+ signal.indexStarted.emit();
+ started = true;
+ }
+ for (int i=0; i<unindexedResources.size()&& keepRunning; i++) {
+ if (interrupt) {
+ processInterrupt();
+ }
+ guid = unindexedResources.get(i);
+ if (keepRunning) {
+ indexResource();
+ }
+ }
+
+ // Cleanup stuff that was deleted at some point
+ List<String> guids = conn.getWordsTable().getGuidList();
+ logger.log(logger.LOW, "GUIDS in index: " +guids.size());
+ for (int i=0; i<guids.size() && keepRunning; i++) {
+ if (!conn.getNoteTable().exists(guids.get(i))) {
+ logger.log(logger.LOW, "Old GUID found: " +guids.get(i));
+ conn.getWordsTable().expunge(guids.get(i));
+ }
+ }
+
+ if (started && keepRunning)
+ signal.indexFinished.emit();
+ }
+
+ private void reindexNote() {
+ if (guid == null)
+ return;
+ conn.getNoteTable().setIndexNeeded(guid, true);
+ }
+
+ private void reindexAll() {
+ conn.getNoteTable().reindexAllNotes();
+ conn.getNoteTable().noteResourceTable.reindexAll();
+ }
+
+ private void waitSeconds(int len) {
+ long starttime = 0; // variable declared
+ //...
+ // for the first time, remember the timestamp
+ starttime = System.currentTimeMillis();
+ // the next timestamp we want to wake up
+ starttime += (1000.0);
+ // Wait until the desired next time arrives using nanosecond
+ // accuracy timer (wait(time) isn't accurate enough on most platforms)
+ LockSupport.parkNanos((Math.max(0,
+ starttime - System.currentTimeMillis()) * 1000000));
+ }
+
+ private void processInterrupt() {
+ conn.commitTransaction();
+ waitSeconds(1);
+ uncommittedCount = 0;
+ conn.beginTransaction();
+ interrupt = false;
+ }
+
+}
-/*\r
- * This file is part of NixNote \r
- * Copyright 2009 Randy Baumgarte\r
- * \r
- * This file may be licensed under the terms of of the\r
- * GNU General Public License Version 2 (the ``GPL'').\r
- *\r
- * Software distributed under the License is distributed\r
- * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either\r
- * express or implied. See the GPL for the specific language\r
- * governing rights and limitations.\r
- *\r
- * You should have received a copy of the GPL along with this\r
- * program. If not, go to http://www.gnu.org/licenses/gpl.html\r
- * or write to the Free Software Foundation, Inc.,\r
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
- *\r
-*/\r
-\r
-package cx.fbn.nevernote.threads;\r
-\r
-import java.util.GregorianCalendar;\r
-import java.util.List;\r
-import java.util.concurrent.LinkedBlockingQueue;\r
-\r
-import com.evernote.edam.type.Resource;\r
-import com.trolltech.qt.core.QMutex;\r
-import com.trolltech.qt.core.QObject;\r
-\r
-import cx.fbn.nevernote.Global;\r
-import cx.fbn.nevernote.evernote.EnmlConverter;\r
-import cx.fbn.nevernote.signals.NoteSignal;\r
-import cx.fbn.nevernote.sql.DatabaseConnection;\r
-import cx.fbn.nevernote.utilities.ApplicationLogger;\r
-import cx.fbn.nevernote.utilities.Pair;\r
-\r
-public class SaveRunner extends QObject implements Runnable {\r
- \r
- private final ApplicationLogger logger;\r
- public volatile boolean keepRunning;\r
- public QMutex threadLock;\r
- private final DatabaseConnection conn;\r
- private boolean idle;\r
- public NoteSignal noteSignals;\r
-\r
- private volatile LinkedBlockingQueue<Pair<String, String>> workQueue = new LinkedBlockingQueue<Pair<String, String>>();\r
- \r
- \r
- //*********************************************\r
- //* Constructor *\r
- //*********************************************\r
- public SaveRunner(String logname, String u, String i, String r, String uid, String pswd, String cpswd) {\r
- logger = new ApplicationLogger(logname);\r
- conn = new DatabaseConnection(logger, u, i, r, uid, pswd, cpswd, 0);\r
- threadLock = new QMutex();\r
- keepRunning = true;\r
- noteSignals = new NoteSignal();\r
- }\r
- \r
- public SaveRunner(ApplicationLogger l, DatabaseConnection c) {\r
- logger = l;\r
- conn = c;\r
- keepRunning = true;\r
- noteSignals = new NoteSignal();\r
- }\r
- \r
- \r
- \r
- //*********************************************\r
- //* Run unit *\r
- //*********************************************\r
- @Override\r
- public void run() {\r
- thread().setPriority(Thread.MIN_PRIORITY);\r
- boolean keepRunning = true;\r
- \r
- while(keepRunning) {\r
- try {\r
- Pair<String, String> content;\r
- idle = true;\r
- content = workQueue.take();\r
- if (!content.getFirst().equalsIgnoreCase("stop")) { \r
- idle = false;\r
- \r
- // This is a bit of a hack. It causes this thread to pause for 0.2 seconds.\r
- // This helps make sure that the main thread gets to the\r
- // database first when switching notes, othrewise it really \r
- // slows things down when fetching new notes.\r
- GregorianCalendar now = new GregorianCalendar();\r
- long prev = now.getTimeInMillis();\r
- prev = prev+200;\r
- while (prev>now.getTimeInMillis()) {\r
- now = new GregorianCalendar(); \r
- }\r
- \r
- updateNoteContent(content.getFirst(), content.getSecond());\r
- } else {\r
- return;\r
- }\r
- threadLock.unlock();\r
- } catch (InterruptedException e) { }\r
- }\r
- conn.dbShutdown();\r
- }\r
- \r
- \r
- public synchronized void addWork(String guid, String content) {\r
- while(workQueue.size() > 0) {}\r
- Pair<String, String> pair = new Pair<String, String>(guid, content);\r
- workQueue.offer(pair);\r
- }\r
- \r
- public synchronized void release(String guid, String content) {\r
- Pair<String, String> pair = new Pair<String, String>(guid, content);\r
- workQueue.add(pair);\r
- }\r
- \r
- public synchronized int getWorkQueueSize() {\r
- return workQueue.size();\r
- }\r
-\r
- \r
- //*********************************************\r
- //* Getter & Setter method to tell the thread *\r
- //* to keep running. *\r
- //*********************************************\r
- public void setKeepRunning(boolean b) {\r
- keepRunning = b;\r
- }\r
- public boolean keepRunning() {\r
- return keepRunning;\r
- }\r
- \r
- public boolean isIdle() {\r
- return idle;\r
- }\r
- \r
- \r
- //*********************************************\r
- //* Do the actual work *\r
- //*********************************************\r
- public void updateNoteContent(String guid, String content) {\r
- logger.log(logger.HIGH, "Entering ListManager.updateNoteContent");\r
- \r
- // Actually save the content\r
- EnmlConverter enml = new EnmlConverter(logger);\r
- String newContent = enml.convert(guid, content);\r
- String fixedContent = enml.fixEnXMLCrap(newContent);\r
- if (fixedContent != null) {\r
- conn.getNoteTable().updateNoteContent(guid, fixedContent);\r
- logger.log(logger.EXTREME, "Saving new note resources");\r
- List<Resource> oldResources = conn.getNoteTable().noteResourceTable.getNoteResources(guid, false);\r
- List<String> newResources = enml.getResources();\r
- removeObsoleteResources(oldResources, newResources);\r
- } else {\r
- noteSignals.noteSaveRunnerError.emit(guid, null);\r
- }\r
- logger.log(logger.HIGH, "Leaving ListManager.updateNoteContent");\r
- }\r
- \r
- // Remove resources that are no longer needed\r
- private void removeObsoleteResources(List<Resource> oldResources, List<String> newResources) {\r
- if (oldResources == null || oldResources.size() == 0)\r
- return;\r
- if (newResources == null || newResources.size() == 0) {\r
- for (int i=0; i<oldResources.size(); i++) {\r
- conn.getNoteTable().noteResourceTable.expungeNoteResource(oldResources.get(i).getGuid());\r
- }\r
- }\r
- for (int i=0; i<oldResources.size(); i++) {\r
- boolean matchFound = false;\r
- for (int j=0; j<newResources.size(); j++) {\r
- if (newResources.get(j).equalsIgnoreCase(oldResources.get(i).getGuid())) \r
- matchFound = true;\r
- if (Global.resourceMap.get(newResources.get(j))!= null) {\r
- if (Global.resourceMap.get(newResources.get(j)).equalsIgnoreCase(oldResources.get(i).getGuid())) \r
- matchFound = true;\r
- }\r
- if (matchFound)\r
- j = newResources.size();\r
- }\r
- if (!matchFound)\r
- conn.getNoteTable().noteResourceTable.expungeNoteResource(oldResources.get(i).getGuid());\r
- }\r
- }\r
-}\r
+/*
+ * This file is part of NixNote
+ * Copyright 2009 Randy Baumgarte
+ *
+ * This file may be licensed under the terms of of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+*/
+
+package cx.fbn.nevernote.threads;
+
+import java.util.GregorianCalendar;
+import java.util.List;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import com.evernote.edam.type.Resource;
+import com.trolltech.qt.core.QMutex;
+import com.trolltech.qt.core.QObject;
+
+import cx.fbn.nevernote.Global;
+import cx.fbn.nevernote.evernote.EnmlConverter;
+import cx.fbn.nevernote.signals.NoteSignal;
+import cx.fbn.nevernote.sql.DatabaseConnection;
+import cx.fbn.nevernote.utilities.ApplicationLogger;
+import cx.fbn.nevernote.utilities.Pair;
+
+public class SaveRunner extends QObject implements Runnable {
+
+ private final ApplicationLogger logger;
+ public volatile boolean keepRunning;
+ public QMutex threadLock;
+ private final DatabaseConnection conn;
+ private boolean idle;
+ public NoteSignal noteSignals;
+
+ private volatile LinkedBlockingQueue<Pair<String, String>> workQueue = new LinkedBlockingQueue<Pair<String, String>>();
+
+
+ //*********************************************
+ //* Constructor *
+ //*********************************************
+ // ICHANGED String bを追加
+ public SaveRunner(String logname, String u, String i, String r, String b, String uid, String pswd, String cpswd) {
+ logger = new ApplicationLogger(logname);
+ // ICHANGED bを追加
+ conn = new DatabaseConnection(logger, u, i, r, b, uid, pswd, cpswd, 0);
+ threadLock = new QMutex();
+ keepRunning = true;
+ noteSignals = new NoteSignal();
+ }
+
+ public SaveRunner(ApplicationLogger l, DatabaseConnection c) {
+ logger = l;
+ conn = c;
+ keepRunning = true;
+ noteSignals = new NoteSignal();
+ }
+
+
+
+ //*********************************************
+ //* Run unit *
+ //*********************************************
+ @Override
+ public void run() {
+ thread().setPriority(Thread.MIN_PRIORITY);
+ boolean keepRunning = true;
+
+ while(keepRunning) {
+ try {
+ Pair<String, String> content;
+ idle = true;
+ content = workQueue.take();
+ if (!content.getFirst().equalsIgnoreCase("stop")) {
+ idle = false;
+
+ // This is a bit of a hack. It causes this thread to pause for 0.2 seconds.
+ // This helps make sure that the main thread gets to the
+ // database first when switching notes, othrewise it really
+ // slows things down when fetching new notes.
+ GregorianCalendar now = new GregorianCalendar();
+ long prev = now.getTimeInMillis();
+ prev = prev+200;
+ while (prev>now.getTimeInMillis()) {
+ now = new GregorianCalendar();
+ }
+
+ updateNoteContent(content.getFirst(), content.getSecond());
+ } else {
+ return;
+ }
+ threadLock.unlock();
+ } catch (InterruptedException e) { }
+ }
+ conn.dbShutdown();
+ }
+
+
+ public synchronized void addWork(String guid, String content) {
+ while(workQueue.size() > 0) {}
+ Pair<String, String> pair = new Pair<String, String>(guid, content);
+ workQueue.offer(pair);
+ }
+
+ public synchronized void release(String guid, String content) {
+ Pair<String, String> pair = new Pair<String, String>(guid, content);
+ workQueue.add(pair);
+ }
+
+ public synchronized int getWorkQueueSize() {
+ return workQueue.size();
+ }
+
+
+ //*********************************************
+ //* Getter & Setter method to tell the thread *
+ //* to keep running. *
+ //*********************************************
+ public void setKeepRunning(boolean b) {
+ keepRunning = b;
+ }
+ public boolean keepRunning() {
+ return keepRunning;
+ }
+
+ public boolean isIdle() {
+ return idle;
+ }
+
+
+ //*********************************************
+ //* Do the actual work *
+ //*********************************************
+ public void updateNoteContent(String guid, String content) {
+ logger.log(logger.HIGH, "Entering ListManager.updateNoteContent");
+
+ // Actually save the content
+ EnmlConverter enml = new EnmlConverter(logger);
+ String newContent = enml.convert(guid, content);
+ String fixedContent = enml.fixEnXMLCrap(newContent);
+ if (fixedContent != null) {
+ conn.getNoteTable().updateNoteContent(guid, fixedContent);
+ logger.log(logger.EXTREME, "Saving new note resources");
+ List<Resource> oldResources = conn.getNoteTable().noteResourceTable.getNoteResources(guid, false);
+ List<String> newResources = enml.getResources();
+ removeObsoleteResources(oldResources, newResources);
+ } else {
+ noteSignals.noteSaveRunnerError.emit(guid, null);
+ }
+ logger.log(logger.HIGH, "Leaving ListManager.updateNoteContent");
+ }
+
+ // Remove resources that are no longer needed
+ private void removeObsoleteResources(List<Resource> oldResources, List<String> newResources) {
+ if (oldResources == null || oldResources.size() == 0)
+ return;
+ if (newResources == null || newResources.size() == 0) {
+ for (int i=0; i<oldResources.size(); i++) {
+ conn.getNoteTable().noteResourceTable.expungeNoteResource(oldResources.get(i).getGuid());
+ }
+ }
+ for (int i=0; i<oldResources.size(); i++) {
+ boolean matchFound = false;
+ for (int j=0; j<newResources.size(); j++) {
+ if (newResources.get(j).equalsIgnoreCase(oldResources.get(i).getGuid()))
+ matchFound = true;
+ if (Global.resourceMap.get(newResources.get(j))!= null) {
+ if (Global.resourceMap.get(newResources.get(j)).equalsIgnoreCase(oldResources.get(i).getGuid()))
+ matchFound = true;
+ }
+ if (matchFound)
+ j = newResources.size();
+ }
+ if (!matchFound)
+ conn.getNoteTable().noteResourceTable.expungeNoteResource(oldResources.get(i).getGuid());
+ }
+ }
+}
-/*\r
- * This file is part of NixNote \r
- * Copyright 2009 Randy Baumgarte\r
- * \r
- * This file may be licensed under the terms of of the\r
- * GNU General Public License Version 2 (the ``GPL'').\r
- *\r
- * Software distributed under the License is distributed\r
- * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either\r
- * express or implied. See the GPL for the specific language\r
- * governing rights and limitations.\r
- *\r
- * You should have received a copy of the GPL along with this\r
- * program. If not, go to http://www.gnu.org/licenses/gpl.html\r
- * or write to the Free Software Foundation, Inc.,\r
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
- *\r
-*/\r
-package cx.fbn.nevernote.threads;\r
-\r
-import java.io.BufferedOutputStream;\r
-import java.io.File;\r
-import java.io.FileOutputStream;\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
-import java.io.UnsupportedEncodingException;\r
-import java.net.UnknownHostException;\r
-import java.util.ArrayList;\r
-import java.util.Calendar;\r
-import java.util.Date;\r
-import java.util.GregorianCalendar;\r
-import java.util.HashMap;\r
-import java.util.List;\r
-import java.util.TreeSet;\r
-import java.util.concurrent.LinkedBlockingQueue;\r
-\r
-import org.apache.http.HttpEntity;\r
-import org.apache.http.HttpResponse;\r
-import org.apache.http.NameValuePair;\r
-import org.apache.http.client.ClientProtocolException;\r
-import org.apache.http.client.HttpClient;\r
-import org.apache.http.client.entity.UrlEncodedFormEntity;\r
-import org.apache.http.client.methods.HttpPost;\r
-import org.apache.http.impl.client.DefaultHttpClient;\r
-import org.apache.http.message.BasicNameValuePair;\r
-import org.apache.http.protocol.HTTP;\r
-import org.apache.thrift.TException;\r
-import org.apache.thrift.protocol.TBinaryProtocol;\r
-import org.apache.thrift.transport.THttpClient;\r
-import org.apache.thrift.transport.TTransportException;\r
-\r
-import com.evernote.edam.error.EDAMNotFoundException;\r
-import com.evernote.edam.error.EDAMSystemException;\r
-import com.evernote.edam.error.EDAMUserException;\r
-import com.evernote.edam.notestore.NoteStore;\r
-import com.evernote.edam.notestore.NoteStore.Client;\r
-import com.evernote.edam.notestore.SyncChunk;\r
-import com.evernote.edam.notestore.SyncState;\r
-import com.evernote.edam.type.Data;\r
-import com.evernote.edam.type.LinkedNotebook;\r
-import com.evernote.edam.type.Note;\r
-import com.evernote.edam.type.Notebook;\r
-import com.evernote.edam.type.Resource;\r
-import com.evernote.edam.type.SavedSearch;\r
-import com.evernote.edam.type.SharedNotebook;\r
-import com.evernote.edam.type.Tag;\r
-import com.evernote.edam.type.User;\r
-import com.evernote.edam.userstore.AuthenticationResult;\r
-import com.evernote.edam.userstore.UserStore;\r
-import com.trolltech.qt.core.QByteArray;\r
-import com.trolltech.qt.core.QFile;\r
-import com.trolltech.qt.core.QIODevice.OpenModeFlag;\r
-import com.trolltech.qt.core.QObject;\r
-import com.trolltech.qt.core.QTextCodec;\r
-import com.trolltech.qt.gui.QMessageBox;\r
-\r
-import cx.fbn.nevernote.signals.NoteIndexSignal;\r
-import cx.fbn.nevernote.signals.NoteResourceSignal;\r
-import cx.fbn.nevernote.signals.NoteSignal;\r
-import cx.fbn.nevernote.signals.NotebookSignal;\r
-import cx.fbn.nevernote.signals.SavedSearchSignal;\r
-import cx.fbn.nevernote.signals.StatusSignal;\r
-import cx.fbn.nevernote.signals.SyncSignal;\r
-import cx.fbn.nevernote.signals.TagSignal;\r
-import cx.fbn.nevernote.sql.DatabaseConnection;\r
-import cx.fbn.nevernote.sql.DeletedItemRecord;\r
-import cx.fbn.nevernote.utilities.ApplicationLogger;\r
-\r
-public class SyncRunner extends QObject implements Runnable {\r
- \r
- private final ApplicationLogger logger;\r
- private DatabaseConnection conn;\r
- private boolean idle;\r
- public boolean error;\r
- public volatile List<String> errorSharedNotebooks;\r
- public volatile HashMap<String,String> errorSharedNotebooksIgnored;\r
- public volatile boolean isConnected;\r
- public volatile boolean keepRunning;\r
- public volatile String authToken;\r
- private long evernoteUpdateCount;\r
- private final String userAgent = "NixNote/" + System.getProperty("os.name")\r
- +"/"+System.getProperty("java.vendor") + "/"\r
- + System.getProperty("java.version") +";";\r
- \r
- public volatile NoteStore.Client localNoteStore;\r
- private UserStore.Client userStore;\r
- \r
- public volatile StatusSignal status;\r
- public volatile TagSignal tagSignal;\r
- public volatile NotebookSignal notebookSignal;\r
- public volatile NoteIndexSignal noteIndexSignal;\r
- public volatile NoteSignal noteSignal;\r
- public volatile SavedSearchSignal searchSignal;\r
- public volatile NoteResourceSignal resourceSignal;\r
- public volatile SyncSignal syncSignal;\r
- public volatile boolean authRefreshNeeded;\r
- public volatile boolean syncNeeded;\r
- public volatile boolean disableUploads;\r
- public volatile boolean syncDeletedContent;\r
- private volatile List<String> dirtyNoteGuids;\r
- \r
- public volatile String username = ""; \r
- public volatile String password = ""; \r
- public volatile String userStoreUrl;\r
-// private final static String consumerKey = "baumgarte"; \r
-// private final static String consumerSecret = "eb8b5740e17cb55f";\r
- public String noteStoreUrlBase;\r
- private THttpClient userStoreTrans;\r
- private TBinaryProtocol userStoreProt;\r
- //private AuthenticationResult authResult;\r
- private AuthenticationResult linkedAuthResult;\r
- private User user; \r
-// private long authTimeRemaining;\r
- public long authRefreshTime;\r
- public long failedRefreshes = 0;\r
- public THttpClient noteStoreTrans;\r
- public TBinaryProtocol noteStoreProt;\r
- public String noteStoreUrl;\r
- public long sequenceDate;\r
- public int updateSequenceNumber;\r
- private boolean refreshNeeded;\r
- private volatile LinkedBlockingQueue<String> workQueue;\r
- private static int MAX_QUEUED_WAITING = 1000;\r
- String dbuid;\r
- String dburl;\r
- String indexUrl;\r
- String resourceUrl;\r
- String dbpswd;\r
- String dbcpswd;\r
- private final TreeSet<String> ignoreTags;\r
- private final TreeSet<String> ignoreNotebooks;\r
- private final TreeSet<String> ignoreLinkedNotebooks;\r
- private HashMap<String,String> badTagSync;\r
- \r
- \r
- \r
- public SyncRunner(String logname, String u, String i, String r, String uid, String pswd, String cpswd) {\r
- logger = new ApplicationLogger(logname);\r
- \r
- noteSignal = new NoteSignal();\r
- status = new StatusSignal();\r
- tagSignal = new TagSignal();\r
- notebookSignal = new NotebookSignal();\r
- noteIndexSignal = new NoteIndexSignal();\r
- noteSignal = new NoteSignal();\r
- searchSignal = new SavedSearchSignal();\r
- syncSignal = new SyncSignal();\r
- resourceSignal = new NoteResourceSignal();\r
- resourceUrl = r;\r
- indexUrl = i;\r
- dbuid = uid;\r
- dburl = u;\r
- dbpswd = pswd;\r
- dbcpswd = cpswd;\r
-// this.setAutoDelete(false);\r
- \r
- isConnected = false;\r
- syncNeeded = false;\r
- authRefreshNeeded = false;\r
- keepRunning = true;\r
- idle = true;\r
- disableUploads = false;\r
- ignoreTags = new TreeSet<String>();\r
- ignoreNotebooks = new TreeSet<String>();\r
- ignoreLinkedNotebooks = new TreeSet<String>();\r
- \r
-// setAutoDelete(false);\r
- workQueue=new LinkedBlockingQueue<String>(MAX_QUEUED_WAITING);\r
- }\r
- @Override\r
- public void run() {\r
- errorSharedNotebooks = new ArrayList<String>();\r
- errorSharedNotebooksIgnored = new HashMap<String,String>();\r
- try {\r
- logger.log(logger.EXTREME, "Starting thread");\r
- conn = new DatabaseConnection(logger, dburl, indexUrl, resourceUrl, dbuid, dbpswd, dbcpswd, 200);\r
- while(keepRunning) {\r
- logger.log(logger.EXTREME, "Blocking until work is found");\r
- String work = workQueue.take();\r
- logger.log(logger.LOW, "Dirty Notes Before Sync: " +new Integer(conn.getNoteTable().getDirtyCount()).toString());\r
- logger.log(logger.EXTREME, "Work found: " +work);\r
- if (work.equalsIgnoreCase("stop")) {\r
- idle=false;\r
- return;\r
- }\r
- conn.getNoteTable().dumpDirtyNotes(); // Debugging statement\r
- idle=false;\r
- error=false;\r
- if (syncNeeded) {\r
- logger.log(logger.EXTREME, "SyncNeeded is true");\r
- refreshNeeded=false;\r
- sequenceDate = conn.getSyncTable().getLastSequenceDate();\r
- updateSequenceNumber = conn.getSyncTable().getUpdateSequenceNumber();\r
- try {\r
- logger.log(logger.EXTREME, "Beginning sync");\r
- evernoteSync(localNoteStore);\r
- logger.log(logger.EXTREME, "Sync finished");\r
- } catch (UnknownHostException e) {\r
- status.message.emit(e.getMessage());\r
- }\r
- }\r
- idle=true;\r
- logger.log(logger.EXTREME, "Signaling refresh finished. refreshNeeded=" +refreshNeeded);\r
- syncSignal.finished.emit(refreshNeeded);\r
- if (error) {\r
- syncSignal.errorDisconnect.emit();\r
- status.message.emit(tr("Error synchronizing - see log for details."));\r
- }\r
- logger.log(logger.LOW, "Dirty Notes After Sync: " +new Integer(conn.getNoteTable().getDirtyCount()).toString());\r
- conn.getNoteTable().dumpDirtyNotes();\r
- logger.log(logger.LOW, "---");\r
- }\r
- } \r
- catch (InterruptedException e1) {\r
- e1.printStackTrace();\r
- }\r
- conn.dbShutdown();\r
- }\r
-\r
- \r
- public DatabaseConnection getConnection() {\r
- return conn;\r
- }\r
-\r
- public boolean isIdle() {\r
- return idle;\r
- }\r
-\r
-\r
- public void setConnected(boolean c) {\r
- isConnected = c;\r
- }\r
- public void setKeepRunning(boolean r) {\r
- logger.log(logger.EXTREME, "Setting keepRunning=" +r);\r
- keepRunning = r;\r
- }\r
- public void setNoteStore(NoteStore.Client c) {\r
- logger.log(logger.EXTREME, "Setting NoteStore in sync thread");\r
- localNoteStore = c;\r
- }\r
- public void setUserStore(UserStore.Client c) {\r
- logger.log(logger.EXTREME, "Setting UserStore in sync thread");\r
- userStore = c;\r
- }\r
-\r
- public void setEvernoteUpdateCount(long s) {\r
- logger.log(logger.EXTREME, "Setting Update Count in sync thread");\r
- evernoteUpdateCount = s;\r
- }\r
- \r
- //***************************************************************\r
- //***************************************************************\r
- //** These functions deal with Evernote communications\r
- //***************************************************************\r
- //***************************************************************\r
- // Synchronize changes with Evernote\r
- @SuppressWarnings("unused")\r
- private void evernoteSync(Client noteStore) throws java.net.UnknownHostException {\r
- logger.log(logger.HIGH, "Entering SyncRunner.evernoteSync");\r
- \r
- // Rebuild list of tags & notebooks to ignore\r
- ignoreNotebooks.clear();\r
- List<String> ignore = conn.getSyncTable().getIgnoreRecords("NOTEBOOK");\r
- for (int i=0; i<ignore.size(); i++) \r
- ignoreNotebooks.add(ignore.get(i));\r
- \r
- ignore.clear();\r
- ignore = conn.getSyncTable().getIgnoreRecords("LINKEDNOTEBOOK");\r
- for (int i=0; i<ignore.size(); i++) \r
- ignoreLinkedNotebooks.add(ignore.get(i));\r
- \r
- ignoreTags.clear();\r
- ignore = conn.getSyncTable().getIgnoreRecords("TAG");\r
- for (int i=0; i<ignore.size(); i++) \r
- ignoreTags.add(ignore.get(i));\r
-\r
- // Make sure we are connected & should keep running\r
- if (isConnected && keepRunning) {\r
- error = false;\r
- logger.log(logger.EXTREME, "Synchronizing with Evernote");\r
- status.message.emit(tr("Synchronizing with Evernote"));\r
- \r
- // Get user information\r
- try {\r
- logger.log(logger.EXTREME, "getting user from userstore");\r
- User user = userStore.getUser(authToken);\r
- logger.log(logger.EXTREME, "Saving user information");\r
- syncSignal.saveUserInformation.emit(user);\r
- } catch (EDAMUserException e1) {\r
- e1.printStackTrace();\r
- status.message.emit(tr("User exception getting user account information. Aborting sync and disconnecting"));\r
- syncSignal.errorDisconnect.emit();\r
- error = true;\r
- enDisconnect();\r
- return;\r
- } catch (EDAMSystemException e1) {\r
- e1.printStackTrace();\r
- status.message.emit(tr("System error user account information. Aborting sync and disconnecting!"));\r
- syncSignal.errorDisconnect.emit();\r
- error = true;\r
- enDisconnect();\r
- return;\r
- } catch (TException e1) {\r
- e1.printStackTrace();\r
- syncSignal.errorDisconnect.emit();\r
- error = true;\r
- status.message.emit(tr("Transaction error getting user account information. Aborting sync and disconnecting!"));\r
- enDisconnect();\r
- return;\r
- }\r
- \r
- // Get sync state\r
- SyncState syncState = null;\r
- try { \r
- logger.log(logger.EXTREME, "Getting sync state");\r
- syncState = noteStore.getSyncState(authToken); \r
- syncSignal.saveUploadAmount.emit(syncState.getUploaded());\r
- syncSignal.saveEvernoteUpdateCount.emit(syncState.getUpdateCount());\r
- evernoteUpdateCount = syncState.getUpdateCount();\r
- } catch (EDAMUserException e) {\r
- e.printStackTrace();\r
- status.message.emit(tr("Error getting sync state! Aborting sync and disconnecting!"));\r
- syncSignal.errorDisconnect.emit();\r
- enDisconnect();\r
- return;\r
- } catch (EDAMSystemException e) {\r
- e.printStackTrace();\r
- status.message.emit(tr("Error getting sync state! Aborting sync and disconnecting!"));\r
- syncSignal.errorDisconnect.emit();\r
- enDisconnect();\r
- return;\r
- } catch (TException e) {\r
- e.printStackTrace();\r
- status.message.emit(tr("Error getting sync state! Aborting sync and disconnecting!"));\r
- syncSignal.errorDisconnect.emit();\r
- enDisconnect();\r
- return;\r
- }\r
- \r
- if (syncState == null) {\r
- logger.log(logger.EXTREME, "Sync State is null");\r
- status.message.emit(tr("Syncronization Error!"));\r
- return;\r
- }\r
-\r
- // Determine what to do. \r
- // If we need to do a full sync.\r
- logger.log(logger.LOW, "Full Sequence Before: " +syncState.getFullSyncBefore());\r
- logger.log(logger.LOW, "Last Sequence Date: " +sequenceDate);\r
- logger.log(logger.LOW, "Var Last Sequence Number: " +updateSequenceNumber);\r
- logger.log(logger.LOW, "DB Last Sequence Number: " + conn.getSyncTable().getUpdateSequenceNumber());\r
- if (syncState.getFullSyncBefore() > sequenceDate) {\r
- logger.log(logger.EXTREME, "Full sequence date has expired");\r
- sequenceDate = 0;\r
- conn.getSyncTable().setLastSequenceDate(0);\r
- updateSequenceNumber = 0;\r
- conn.getSyncTable().setUpdateSequenceNumber(0);\r
- }\r
- // Check for "special" sync instructions\r
- String syncLinked = conn.getSyncTable().getRecord("FullLinkedNotebookSync");\r
- String syncShared = conn.getSyncTable().getRecord("FullSharedNotebookSync");\r
- String syncNotebooks = conn.getSyncTable().getRecord("FullNotebookSync");\r
- String syncInkNoteImages = conn.getSyncTable().getRecord("FullInkNoteImageSync");\r
- if (syncLinked != null) {\r
- downloadAllLinkedNotebooks(localNoteStore);\r
- }\r
- if (syncShared != null) {\r
- downloadAllSharedNotebooks(localNoteStore);\r
- }\r
- if (syncNotebooks != null) {\r
- downloadAllNotebooks(localNoteStore);\r
- }\r
- \r
- if (syncInkNoteImages != null) {\r
- List<String> guids = conn.getNoteTable().noteResourceTable.findInkNotes();\r
- for (int i=0; i<guids.size(); i++) {\r
- downloadInkNoteImage(guids.get(i), authToken);\r
- }\r
- conn.getSyncTable().deleteRecord("FullInkNoteImageSync");\r
- }\r
- \r
- // If there are remote changes\r
- logger.log(logger.LOW, "Update Count: " +syncState.getUpdateCount());\r
- logger.log(logger.LOW, "Last Update Count: " +updateSequenceNumber);\r
- \r
- if (syncState.getUpdateCount() > updateSequenceNumber) {\r
- logger.log(logger.EXTREME, "Refresh needed is true");\r
- refreshNeeded = true;\r
- logger.log(logger.EXTREME, "Downloading changes");\r
- syncRemoteToLocal(localNoteStore);\r
- }\r
- \r
- //*****************************************\r
- //* Sync linked/shared notebooks \r
- //*****************************************\r
- //syncLinkedNotebooks();\r
- //conn.getNoteTable().getDirty();\r
- //disableUploads = true; /// DELETE THIS LINE!!!!\r
- if (!disableUploads) {\r
- logger.log(logger.EXTREME, "Uploading changes");\r
- // Synchronize remote changes\r
- if (!error)\r
- syncExpunged(localNoteStore);\r
- if (!error)\r
- syncLocalTags(localNoteStore);\r
- if (!error)\r
- syncLocalNotebooks(localNoteStore);\r
- if (!error)\r
- syncLocalLinkedNotebooks(localNoteStore);\r
- if (!error) \r
- syncDeletedNotes(localNoteStore);\r
- if (!error)\r
- syncLocalNotes();\r
- if (!error)\r
- syncLocalSavedSearches(localNoteStore);\r
- }\r
- \r
- status.message.emit(tr("Cleaning up"));\r
- List<String> notes = conn.getNoteTable().expungeIgnoreSynchronizedNotes(conn.getSyncTable().getIgnoreRecords("NOTEBOOK"), \r
- conn.getSyncTable().getIgnoreRecords("TAG"), conn.getSyncTable().getIgnoreRecords("LINKEDNOTEBOOK"));\r
- if (notes.size() > 0)\r
- syncSignal.refreshLists.emit();\r
- \r
- //*****************************************\r
- //* End of synchronization\r
- //*****************************************\r
- if (refreshNeeded)\r
- syncSignal.refreshLists.emit();\r
- \r
- if (!error) {\r
- logger.log(logger.LOW, "Sync completed. Errors=" +error);\r
- if (!disableUploads) \r
- status.message.emit(tr("Synchronizing complete"));\r
- else\r
- status.message.emit(tr("Download syncronization complete. Uploads have been disabled."));\r
- \r
- logger.log(logger.EXTREME, "Saving sync time");\r
- if (syncState.getCurrentTime() > sequenceDate)\r
- sequenceDate = syncState.getCurrentTime();\r
- if (syncState.getUpdateCount() > updateSequenceNumber)\r
- updateSequenceNumber = syncState.getUpdateCount();\r
- conn.getSyncTable().setLastSequenceDate(sequenceDate);\r
- conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);\r
- }\r
- }\r
- logger.log(logger.HIGH, "Leaving SyncRunner.evernoteSync");\r
- }\r
- \r
- // Sync deleted items with Evernote\r
- private void syncExpunged(Client noteStore) {\r
- logger.log(logger.HIGH, "Entering SyncRunner.syncExpunged");\r
- \r
- List<DeletedItemRecord> expunged = conn.getDeletedTable().getAllDeleted();\r
- boolean error = false;\r
- for (int i=0; i<expunged.size() && keepRunning; i++) {\r
-\r
-// if (authRefreshNeeded)\r
-// if (!refreshConnection())\r
-// return;\r
-\r
- try {\r
- if (expunged.get(i).type.equalsIgnoreCase("TAG")) {\r
- logger.log(logger.EXTREME, "Tag expunged");\r
+/*
+ * This file is part of NixNote
+ * Copyright 2009 Randy Baumgarte
+ *
+ * This file may be licensed under the terms of of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+*/
+package cx.fbn.nevernote.threads;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.TreeSet;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.HTTP;
+import org.apache.thrift.TException;
+import org.apache.thrift.protocol.TBinaryProtocol;
+import org.apache.thrift.transport.THttpClient;
+import org.apache.thrift.transport.TTransportException;
+
+import com.evernote.edam.error.EDAMNotFoundException;
+import com.evernote.edam.error.EDAMSystemException;
+import com.evernote.edam.error.EDAMUserException;
+import com.evernote.edam.notestore.NoteStore;
+import com.evernote.edam.notestore.NoteStore.Client;
+import com.evernote.edam.notestore.SyncChunk;
+import com.evernote.edam.notestore.SyncState;
+import com.evernote.edam.type.Data;
+import com.evernote.edam.type.LinkedNotebook;
+import com.evernote.edam.type.Note;
+import com.evernote.edam.type.Notebook;
+import com.evernote.edam.type.Resource;
+import com.evernote.edam.type.SavedSearch;
+import com.evernote.edam.type.SharedNotebook;
+import com.evernote.edam.type.Tag;
+import com.evernote.edam.type.User;
+import com.evernote.edam.userstore.AuthenticationResult;
+import com.evernote.edam.userstore.UserStore;
+import com.trolltech.qt.core.QByteArray;
+import com.trolltech.qt.core.QFile;
+import com.trolltech.qt.core.QIODevice.OpenModeFlag;
+import com.trolltech.qt.core.QObject;
+import com.trolltech.qt.core.QTextCodec;
+import com.trolltech.qt.gui.QMessageBox;
+
+import cx.fbn.nevernote.signals.NoteIndexSignal;
+import cx.fbn.nevernote.signals.NoteResourceSignal;
+import cx.fbn.nevernote.signals.NoteSignal;
+import cx.fbn.nevernote.signals.NotebookSignal;
+import cx.fbn.nevernote.signals.SavedSearchSignal;
+import cx.fbn.nevernote.signals.StatusSignal;
+import cx.fbn.nevernote.signals.SyncSignal;
+import cx.fbn.nevernote.signals.TagSignal;
+import cx.fbn.nevernote.sql.DatabaseConnection;
+import cx.fbn.nevernote.sql.DeletedItemRecord;
+import cx.fbn.nevernote.utilities.ApplicationLogger;
+
+public class SyncRunner extends QObject implements Runnable {
+
+ private final ApplicationLogger logger;
+ private DatabaseConnection conn;
+ private boolean idle;
+ public boolean error;
+ public volatile List<String> errorSharedNotebooks;
+ public volatile HashMap<String,String> errorSharedNotebooksIgnored;
+ public volatile boolean isConnected;
+ public volatile boolean keepRunning;
+ public volatile String authToken;
+ private long evernoteUpdateCount;
+ private final String userAgent = "NeighborNote/" + System.getProperty("os.name")
+ +"/"+System.getProperty("java.vendor") + "/"
+ + System.getProperty("java.version") +";";
+
+ public volatile NoteStore.Client localNoteStore;
+ private UserStore.Client userStore;
+
+ public volatile StatusSignal status;
+ public volatile TagSignal tagSignal;
+ public volatile NotebookSignal notebookSignal;
+ public volatile NoteIndexSignal noteIndexSignal;
+ public volatile NoteSignal noteSignal;
+ public volatile SavedSearchSignal searchSignal;
+ public volatile NoteResourceSignal resourceSignal;
+ public volatile SyncSignal syncSignal;
+ public volatile boolean authRefreshNeeded;
+ public volatile boolean syncNeeded;
+ public volatile boolean disableUploads;
+ public volatile boolean syncDeletedContent;
+ private volatile List<String> dirtyNoteGuids;
+
+ public volatile String username = "";
+ public volatile String password = "";
+ public volatile String userStoreUrl;
+// private final static String consumerKey = "baumgarte";
+// private final static String consumerSecret = "eb8b5740e17cb55f";
+ public String noteStoreUrlBase;
+ private THttpClient userStoreTrans;
+ private TBinaryProtocol userStoreProt;
+ //private AuthenticationResult authResult;
+ private AuthenticationResult linkedAuthResult;
+ private User user;
+// private long authTimeRemaining;
+ public long authRefreshTime;
+ public long failedRefreshes = 0;
+ public THttpClient noteStoreTrans;
+ public TBinaryProtocol noteStoreProt;
+ public String noteStoreUrl;
+ public long sequenceDate;
+ public int updateSequenceNumber;
+ private boolean refreshNeeded;
+ private volatile LinkedBlockingQueue<String> workQueue;
+ private static int MAX_QUEUED_WAITING = 1000;
+ String dbuid;
+ String dburl;
+ String indexUrl;
+ String resourceUrl;
+ // ICHANGED
+ String behaviorUrl;
+
+ String dbpswd;
+ String dbcpswd;
+ private final TreeSet<String> ignoreTags;
+ private final TreeSet<String> ignoreNotebooks;
+ private final TreeSet<String> ignoreLinkedNotebooks;
+ private HashMap<String,String> badTagSync;
+
+
+ // ICHANGED String bを追加
+ public SyncRunner(String logname, String u, String i, String r, String b, String uid, String pswd, String cpswd) {
+ logger = new ApplicationLogger(logname);
+
+ noteSignal = new NoteSignal();
+ status = new StatusSignal();
+ tagSignal = new TagSignal();
+ notebookSignal = new NotebookSignal();
+ noteIndexSignal = new NoteIndexSignal();
+ noteSignal = new NoteSignal();
+ searchSignal = new SavedSearchSignal();
+ syncSignal = new SyncSignal();
+ resourceSignal = new NoteResourceSignal();
+ resourceUrl = r;
+ indexUrl = i;
+ // ICHANGED
+ behaviorUrl = b;
+
+ dbuid = uid;
+ dburl = u;
+ dbpswd = pswd;
+ dbcpswd = cpswd;
+// this.setAutoDelete(false);
+
+ isConnected = false;
+ syncNeeded = false;
+ authRefreshNeeded = false;
+ keepRunning = true;
+ idle = true;
+ disableUploads = false;
+ ignoreTags = new TreeSet<String>();
+ ignoreNotebooks = new TreeSet<String>();
+ ignoreLinkedNotebooks = new TreeSet<String>();
+
+// setAutoDelete(false);
+ workQueue=new LinkedBlockingQueue<String>(MAX_QUEUED_WAITING);
+ }
+ @Override
+ public void run() {
+ errorSharedNotebooks = new ArrayList<String>();
+ errorSharedNotebooksIgnored = new HashMap<String,String>();
+ try {
+ logger.log(logger.EXTREME, "Starting thread");
+ // ICHANGED behaviorUrlを追加
+ conn = new DatabaseConnection(logger, dburl, indexUrl, resourceUrl, behaviorUrl, dbuid, dbpswd, dbcpswd, 200);
+ while(keepRunning) {
+ logger.log(logger.EXTREME, "Blocking until work is found");
+ String work = workQueue.take();
+ logger.log(logger.LOW, "Dirty Notes Before Sync: " +new Integer(conn.getNoteTable().getDirtyCount()).toString());
+ logger.log(logger.EXTREME, "Work found: " +work);
+ if (work.equalsIgnoreCase("stop")) {
+ idle=false;
+ return;
+ }
+ conn.getNoteTable().dumpDirtyNotes(); // Debugging statement
+ idle=false;
+ error=false;
+ if (syncNeeded) {
+ logger.log(logger.EXTREME, "SyncNeeded is true");
+ refreshNeeded=false;
+ sequenceDate = conn.getSyncTable().getLastSequenceDate();
+ updateSequenceNumber = conn.getSyncTable().getUpdateSequenceNumber();
+ try {
+ logger.log(logger.EXTREME, "Beginning sync");
+ evernoteSync(localNoteStore);
+ logger.log(logger.EXTREME, "Sync finished");
+ } catch (UnknownHostException e) {
+ status.message.emit(e.getMessage());
+ }
+ }
+ idle=true;
+ logger.log(logger.EXTREME, "Signaling refresh finished. refreshNeeded=" +refreshNeeded);
+ syncSignal.finished.emit(refreshNeeded);
+ if (error) {
+ syncSignal.errorDisconnect.emit();
+ status.message.emit(tr("Error synchronizing - see log for details."));
+ }
+ logger.log(logger.LOW, "Dirty Notes After Sync: " +new Integer(conn.getNoteTable().getDirtyCount()).toString());
+ conn.getNoteTable().dumpDirtyNotes();
+ logger.log(logger.LOW, "---");
+ }
+ }
+ catch (InterruptedException e1) {
+ e1.printStackTrace();
+ }
+ conn.dbShutdown();
+ }
+
+
+ public DatabaseConnection getConnection() {
+ return conn;
+ }
+
+ public boolean isIdle() {
+ return idle;
+ }
+
+
+ public void setConnected(boolean c) {
+ isConnected = c;
+ }
+ public void setKeepRunning(boolean r) {
+ logger.log(logger.EXTREME, "Setting keepRunning=" +r);
+ keepRunning = r;
+ }
+ public void setNoteStore(NoteStore.Client c) {
+ logger.log(logger.EXTREME, "Setting NoteStore in sync thread");
+ localNoteStore = c;
+ }
+ public void setUserStore(UserStore.Client c) {
+ logger.log(logger.EXTREME, "Setting UserStore in sync thread");
+ userStore = c;
+ }
+
+ public void setEvernoteUpdateCount(long s) {
+ logger.log(logger.EXTREME, "Setting Update Count in sync thread");
+ evernoteUpdateCount = s;
+ }
+
+ //***************************************************************
+ //***************************************************************
+ //** These functions deal with Evernote communications
+ //***************************************************************
+ //***************************************************************
+ // Synchronize changes with Evernote
+ @SuppressWarnings("unused")
+ private void evernoteSync(Client noteStore) throws java.net.UnknownHostException {
+ logger.log(logger.HIGH, "Entering SyncRunner.evernoteSync");
+
+ // Rebuild list of tags & notebooks to ignore
+ ignoreNotebooks.clear();
+ List<String> ignore = conn.getSyncTable().getIgnoreRecords("NOTEBOOK");
+ for (int i=0; i<ignore.size(); i++)
+ ignoreNotebooks.add(ignore.get(i));
+
+ ignore.clear();
+ ignore = conn.getSyncTable().getIgnoreRecords("LINKEDNOTEBOOK");
+ for (int i=0; i<ignore.size(); i++)
+ ignoreLinkedNotebooks.add(ignore.get(i));
+
+ ignoreTags.clear();
+ ignore = conn.getSyncTable().getIgnoreRecords("TAG");
+ for (int i=0; i<ignore.size(); i++)
+ ignoreTags.add(ignore.get(i));
+
+ // Make sure we are connected & should keep running
+ if (isConnected && keepRunning) {
+ error = false;
+ logger.log(logger.EXTREME, "Synchronizing with Evernote");
+ status.message.emit(tr("Synchronizing with Evernote"));
+
+ // Get user information
+ try {
+ logger.log(logger.EXTREME, "getting user from userstore");
+ User user = userStore.getUser(authToken);
+ logger.log(logger.EXTREME, "Saving user information");
+ syncSignal.saveUserInformation.emit(user);
+ } catch (EDAMUserException e1) {
+ e1.printStackTrace();
+ status.message.emit(tr("User exception getting user account information. Aborting sync and disconnecting"));
+ syncSignal.errorDisconnect.emit();
+ error = true;
+ enDisconnect();
+ return;
+ } catch (EDAMSystemException e1) {
+ e1.printStackTrace();
+ status.message.emit(tr("System error user account information. Aborting sync and disconnecting!"));
+ syncSignal.errorDisconnect.emit();
+ error = true;
+ enDisconnect();
+ return;
+ } catch (TException e1) {
+ e1.printStackTrace();
+ syncSignal.errorDisconnect.emit();
+ error = true;
+ status.message.emit(tr("Transaction error getting user account information. Aborting sync and disconnecting!"));
+ enDisconnect();
+ return;
+ }
+
+ // Get sync state
+ SyncState syncState = null;
+ try {
+ logger.log(logger.EXTREME, "Getting sync state");
+ syncState = noteStore.getSyncState(authToken);
+ syncSignal.saveUploadAmount.emit(syncState.getUploaded());
+ syncSignal.saveEvernoteUpdateCount.emit(syncState.getUpdateCount());
+ evernoteUpdateCount = syncState.getUpdateCount();
+ } catch (EDAMUserException e) {
+ e.printStackTrace();
+ status.message.emit(tr("Error getting sync state! Aborting sync and disconnecting!"));
+ syncSignal.errorDisconnect.emit();
+ enDisconnect();
+ return;
+ } catch (EDAMSystemException e) {
+ e.printStackTrace();
+ status.message.emit(tr("Error getting sync state! Aborting sync and disconnecting!"));
+ syncSignal.errorDisconnect.emit();
+ enDisconnect();
+ return;
+ } catch (TException e) {
+ e.printStackTrace();
+ status.message.emit(tr("Error getting sync state! Aborting sync and disconnecting!"));
+ syncSignal.errorDisconnect.emit();
+ enDisconnect();
+ return;
+ }
+
+ if (syncState == null) {
+ logger.log(logger.EXTREME, "Sync State is null");
+ status.message.emit(tr("Syncronization Error!"));
+ return;
+ }
+
+ // Determine what to do.
+ // If we need to do a full sync.
+ logger.log(logger.LOW, "Full Sequence Before: " +syncState.getFullSyncBefore());
+ logger.log(logger.LOW, "Last Sequence Date: " +sequenceDate);
+ logger.log(logger.LOW, "Var Last Sequence Number: " +updateSequenceNumber);
+ logger.log(logger.LOW, "DB Last Sequence Number: " + conn.getSyncTable().getUpdateSequenceNumber());
+ if (syncState.getFullSyncBefore() > sequenceDate) {
+ logger.log(logger.EXTREME, "Full sequence date has expired");
+ sequenceDate = 0;
+ conn.getSyncTable().setLastSequenceDate(0);
+ updateSequenceNumber = 0;
+ conn.getSyncTable().setUpdateSequenceNumber(0);
+ }
+ // Check for "special" sync instructions
+ String syncLinked = conn.getSyncTable().getRecord("FullLinkedNotebookSync");
+ String syncShared = conn.getSyncTable().getRecord("FullSharedNotebookSync");
+ String syncNotebooks = conn.getSyncTable().getRecord("FullNotebookSync");
+ String syncInkNoteImages = conn.getSyncTable().getRecord("FullInkNoteImageSync");
+ if (syncLinked != null) {
+ downloadAllLinkedNotebooks(localNoteStore);
+ }
+ if (syncShared != null) {
+ downloadAllSharedNotebooks(localNoteStore);
+ }
+ if (syncNotebooks != null) {
+ downloadAllNotebooks(localNoteStore);
+ }
+
+ if (syncInkNoteImages != null) {
+ List<String> guids = conn.getNoteTable().noteResourceTable.findInkNotes();
+ for (int i=0; i<guids.size(); i++) {
+ downloadInkNoteImage(guids.get(i), authToken);
+ }
+ conn.getSyncTable().deleteRecord("FullInkNoteImageSync");
+ }
+
+ // If there are remote changes
+ logger.log(logger.LOW, "Update Count: " +syncState.getUpdateCount());
+ logger.log(logger.LOW, "Last Update Count: " +updateSequenceNumber);
+
+ if (syncState.getUpdateCount() > updateSequenceNumber) {
+ logger.log(logger.EXTREME, "Refresh needed is true");
+ refreshNeeded = true;
+ logger.log(logger.EXTREME, "Downloading changes");
+ syncRemoteToLocal(localNoteStore);
+ }
+
+ //*****************************************
+ //* Sync linked/shared notebooks
+ //*****************************************
+ //syncLinkedNotebooks();
+ //conn.getNoteTable().getDirty();
+ //disableUploads = true; /// DELETE THIS LINE!!!!
+ if (!disableUploads) {
+ logger.log(logger.EXTREME, "Uploading changes");
+ // Synchronize remote changes
+ if (!error)
+ syncExpunged(localNoteStore);
+ if (!error)
+ syncLocalTags(localNoteStore);
+ if (!error)
+ syncLocalNotebooks(localNoteStore);
+ if (!error)
+ syncLocalLinkedNotebooks(localNoteStore);
+ if (!error)
+ syncDeletedNotes(localNoteStore);
+ if (!error)
+ syncLocalNotes();
+ if (!error)
+ syncLocalSavedSearches(localNoteStore);
+ }
+
+ status.message.emit(tr("Cleaning up"));
+ List<String> notes = conn.getNoteTable().expungeIgnoreSynchronizedNotes(conn.getSyncTable().getIgnoreRecords("NOTEBOOK"),
+ conn.getSyncTable().getIgnoreRecords("TAG"), conn.getSyncTable().getIgnoreRecords("LINKEDNOTEBOOK"));
+ if (notes.size() > 0)
+ syncSignal.refreshLists.emit();
+
+ //*****************************************
+ //* End of synchronization
+ //*****************************************
+ if (refreshNeeded)
+ syncSignal.refreshLists.emit();
+
+ if (!error) {
+ logger.log(logger.LOW, "Sync completed. Errors=" +error);
+ if (!disableUploads)
+ status.message.emit(tr("Synchronizing complete"));
+ else
+ status.message.emit(tr("Download syncronization complete. Uploads have been disabled."));
+
+ logger.log(logger.EXTREME, "Saving sync time");
+ if (syncState.getCurrentTime() > sequenceDate)
+ sequenceDate = syncState.getCurrentTime();
+ if (syncState.getUpdateCount() > updateSequenceNumber)
+ updateSequenceNumber = syncState.getUpdateCount();
+ conn.getSyncTable().setLastSequenceDate(sequenceDate);
+ conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);
+ }
+ }
+ logger.log(logger.HIGH, "Leaving SyncRunner.evernoteSync");
+ }
+
+ // Sync deleted items with Evernote
+ private void syncExpunged(Client noteStore) {
+ logger.log(logger.HIGH, "Entering SyncRunner.syncExpunged");
+
+ List<DeletedItemRecord> expunged = conn.getDeletedTable().getAllDeleted();
+ boolean error = false;
+ for (int i=0; i<expunged.size() && keepRunning; i++) {
+
+// if (authRefreshNeeded)
+// if (!refreshConnection())
+// return;
+
+ try {
+ if (expunged.get(i).type.equalsIgnoreCase("TAG")) {
+ logger.log(logger.EXTREME, "Tag expunged");
conn.getDeletedTable().expungeDeletedItem(expunged.get(i).guid, "TAG"); \r
- updateSequenceNumber = noteStore.expungeTag(authToken, expunged.get(i).guid);\r
- conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);\r
- conn.getSyncTable().setLastSequenceDate(sequenceDate);\r
+ updateSequenceNumber = noteStore.expungeTag(authToken, expunged.get(i).guid);
+ conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);
+ conn.getSyncTable().setLastSequenceDate(sequenceDate);
conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber); \r
- }\r
- if (expunged.get(i).type.equalsIgnoreCase("NOTEBOOK")) {\r
- logger.log(logger.EXTREME, "Notebook expunged");\r
+ }
+ if (expunged.get(i).type.equalsIgnoreCase("NOTEBOOK")) {
+ logger.log(logger.EXTREME, "Notebook expunged");
conn.getDeletedTable().expungeDeletedItem(expunged.get(i).guid, "NOTEBOOK");\r
- updateSequenceNumber = noteStore.expungeNotebook(authToken, expunged.get(i).guid);\r
- conn.getSyncTable().setLastSequenceDate(sequenceDate);\r
- conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);\r
- }\r
- if (expunged.get(i).type.equalsIgnoreCase("NOTE")) {\r
- logger.log(logger.EXTREME, "Note expunged");\r
+ updateSequenceNumber = noteStore.expungeNotebook(authToken, expunged.get(i).guid);
+ conn.getSyncTable().setLastSequenceDate(sequenceDate);
+ conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);
+ }
+ if (expunged.get(i).type.equalsIgnoreCase("NOTE")) {
+ logger.log(logger.EXTREME, "Note expunged");
conn.getDeletedTable().expungeDeletedItem(expunged.get(i).guid, "NOTE");\r
- updateSequenceNumber = noteStore.deleteNote(authToken, expunged.get(i).guid);\r
- refreshNeeded = true;\r
- conn.getSyncTable().setLastSequenceDate(sequenceDate);\r
- conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);\r
- }\r
- if (expunged.get(i).type.equalsIgnoreCase("SAVEDSEARCH")) {\r
- logger.log(logger.EXTREME, "saved search expunged");\r
+ updateSequenceNumber = noteStore.deleteNote(authToken, expunged.get(i).guid);
+ refreshNeeded = true;
+ conn.getSyncTable().setLastSequenceDate(sequenceDate);
+ conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);
+ }
+ if (expunged.get(i).type.equalsIgnoreCase("SAVEDSEARCH")) {
+ logger.log(logger.EXTREME, "saved search expunged");
conn.getDeletedTable().expungeDeletedItem(expunged.get(i).guid, "SAVEDSEARCH");\r
- updateSequenceNumber = noteStore.expungeSearch(authToken, expunged.get(i).guid);\r
- conn.getSyncTable().setLastSequenceDate(sequenceDate);\r
- conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);\r
- }\r
- } catch (EDAMUserException e) {\r
- logger.log(logger.LOW, "EDAM User Excepton in syncExpunged: " +expunged.get(i).guid); // This can happen if we try to delete a deleted note\r
- } catch (EDAMSystemException e) {\r
- logger.log(logger.LOW, "EDAM System Excepton in syncExpunged: "+expunged.get(i).guid);\r
- logger.log(logger.LOW, e.getStackTrace());\r
- error=true;\r
- } catch (EDAMNotFoundException e) {\r
- logger.log(logger.LOW, "EDAM Not Found Excepton in syncExpunged: "+expunged.get(i).guid);\r
- } catch (TException e) {\r
- logger.log(logger.LOW, "EDAM TExcepton in syncExpunged: "+expunged.get(i).guid);\r
- logger.log(logger.LOW, e.getStackTrace());\r
- error=true;\r
- }\r
- }\r
- if (!error)\r
- conn.getDeletedTable().expungeAllDeletedRecords();\r
- \r
- logger.log(logger.HIGH, "Leaving SyncRunner.syncExpunged");\r
-\r
- }\r
- private void syncDeletedNotes(Client noteStore) {\r
- if (syncDeletedContent)\r
- return;\r
- logger.log(logger.HIGH, "Entering SyncRunner.syncDeletedNotes");\r
- status.message.emit(tr("Synchronizing deleted notes."));\r
-\r
- List<Note> notes = conn.getNoteTable().getDirty();\r
- // Sync the local notebooks with Evernote's\r
- for (int i=0; i<notes.size() && keepRunning; i++) {\r
- \r
-// if (authRefreshNeeded)\r
-// if (!refreshConnection())\r
-// return;\r
- \r
- Note enNote = notes.get(i);\r
- try {\r
- if (enNote.getUpdateSequenceNum() > 0 && (enNote.isActive() == false || enNote.getDeleted() > 0)) {\r
+ updateSequenceNumber = noteStore.expungeSearch(authToken, expunged.get(i).guid);
+ conn.getSyncTable().setLastSequenceDate(sequenceDate);
+ conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);
+ }
+ } catch (EDAMUserException e) {
+ logger.log(logger.LOW, "EDAM User Excepton in syncExpunged: " +expunged.get(i).guid); // This can happen if we try to delete a deleted note
+ } catch (EDAMSystemException e) {
+ logger.log(logger.LOW, "EDAM System Excepton in syncExpunged: "+expunged.get(i).guid);
+ logger.log(logger.LOW, e.getStackTrace());
+ error=true;
+ } catch (EDAMNotFoundException e) {
+ logger.log(logger.LOW, "EDAM Not Found Excepton in syncExpunged: "+expunged.get(i).guid);
+ } catch (TException e) {
+ logger.log(logger.LOW, "EDAM TExcepton in syncExpunged: "+expunged.get(i).guid);
+ logger.log(logger.LOW, e.getStackTrace());
+ error=true;
+ }
+ }
+ if (!error)
+ conn.getDeletedTable().expungeAllDeletedRecords();
+
+ logger.log(logger.HIGH, "Leaving SyncRunner.syncExpunged");
+
+ }
+ private void syncDeletedNotes(Client noteStore) {
+ if (syncDeletedContent)
+ return;
+ logger.log(logger.HIGH, "Entering SyncRunner.syncDeletedNotes");
+ status.message.emit(tr("Synchronizing deleted notes."));
+
+ List<Note> notes = conn.getNoteTable().getDirty();
+ // Sync the local notebooks with Evernote's
+ for (int i=0; i<notes.size() && keepRunning; i++) {
+
+// if (authRefreshNeeded)
+// if (!refreshConnection())
+// return;
+
+ Note enNote = notes.get(i);
+ try {
+ if (enNote.getUpdateSequenceNum() > 0 && (enNote.isActive() == false || enNote.getDeleted() > 0)) {
// Check that the note is valid. \r
if (enNote.isActive() == true || enNote.getDeleted() == 0) {\r
conn.getNoteTable().deleteNote(enNote.getGuid());\r
enNote = conn.getNoteTable().getNote(enNote.getGuid(), false, false, false, false, false);\r
}\r
- if (syncDeletedContent) {\r
- logger.log(logger.EXTREME, "Deleted note found & synch content selected");\r
- Note delNote = conn.getNoteTable().getNote(enNote.getGuid(), true, true, true, true, true);\r
- delNote = getNoteContent(delNote);\r
- delNote = noteStore.updateNote(authToken, delNote);\r
- enNote.setUpdateSequenceNum(delNote.getUpdateSequenceNum());\r
- conn.getNoteTable().updateNoteSequence(enNote.getGuid(), enNote.getUpdateSequenceNum());\r
- } else {\r
- logger.log(logger.EXTREME, "Deleted note found & sync content not selected");\r
- int usn = noteStore.deleteNote(authToken, enNote.getGuid());\r
- enNote.setUpdateSequenceNum(usn);\r
- conn.getNoteTable().updateNoteSequence(enNote.getGuid(), enNote.getUpdateSequenceNum()); \r
- }\r
- logger.log(logger.EXTREME, "Resetting deleted dirty flag");\r
- conn.getNoteTable().resetDirtyFlag(enNote.getGuid());\r
- updateSequenceNumber = enNote.getUpdateSequenceNum();\r
- logger.log(logger.EXTREME, "Saving sequence number");\r
- conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);\r
- } \r
- } catch (EDAMUserException e) {\r
+ if (syncDeletedContent) {
+ logger.log(logger.EXTREME, "Deleted note found & synch content selected");
+ Note delNote = conn.getNoteTable().getNote(enNote.getGuid(), true, true, true, true, true);
+ delNote = getNoteContent(delNote);
+ delNote = noteStore.updateNote(authToken, delNote);
+ enNote.setUpdateSequenceNum(delNote.getUpdateSequenceNum());
+ conn.getNoteTable().updateNoteSequence(enNote.getGuid(), enNote.getUpdateSequenceNum());
+ } else {
+ logger.log(logger.EXTREME, "Deleted note found & sync content not selected");
+ int usn = noteStore.deleteNote(authToken, enNote.getGuid());
+ enNote.setUpdateSequenceNum(usn);
+ conn.getNoteTable().updateNoteSequence(enNote.getGuid(), enNote.getUpdateSequenceNum());
+ }
+ logger.log(logger.EXTREME, "Resetting deleted dirty flag");
+ conn.getNoteTable().resetDirtyFlag(enNote.getGuid());
+ updateSequenceNumber = enNote.getUpdateSequenceNum();
+ logger.log(logger.EXTREME, "Saving sequence number");
+ conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);
+ }
+ } catch (EDAMUserException e) {
logger.log(logger.LOW, "*** EDAM User Excepton syncLocalNotes "+e);\r
- //status.message.emit("Error sending local note: " +e.getParameter());\r
- //logger.log(logger.LOW, e.toString()); \r
- //error = true;\r
- } catch (EDAMSystemException e) {\r
- logger.log(logger.LOW, "*** EDAM System Excepton syncLocalNotes "+e);\r
- status.message.emit(tr("Error: ") +e);\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- } catch (EDAMNotFoundException e) {\r
+ //status.message.emit("Error sending local note: " +e.getParameter());
+ //logger.log(logger.LOW, e.toString());
+ //error = true;
+ } catch (EDAMSystemException e) {
+ logger.log(logger.LOW, "*** EDAM System Excepton syncLocalNotes "+e);
+ status.message.emit(tr("Error: ") +e);
+ logger.log(logger.LOW, e.toString());
+ error = true;
+ } catch (EDAMNotFoundException e) {
logger.log(logger.LOW, "*** EDAM Not Found Excepton syncLocalNotes " +e);\r
- //status.message.emit("Error deleting local note: " +e +" - Continuing");\r
- //logger.log(logger.LOW, e.toString()); \r
- //error = true;\r
- } catch (TException e) {\r
- logger.log(logger.LOW, "*** EDAM TExcepton syncLocalNotes "+e);\r
- status.message.emit(tr("Error sending local note: ") +e);\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- } \r
- }\r
- }\r
- // Sync notes with Evernote\r
- private void syncLocalNotes() {\r
- logger.log(logger.HIGH, "Entering SyncRunner.syncNotes");\r
- logger.log(logger.LOW, "Dirty local notes found: " +new Integer(conn.getNoteTable().getDirtyCount()).toString());\r
- status.message.emit(tr("Sending local notes."));\r
-\r
- List<Note> notes = conn.getNoteTable().getDirty();\r
- // Sync the local notebooks with Evernote's\r
- for (int i=0; i<notes.size() && keepRunning; i++) {\r
- syncLocalNote(localNoteStore, notes.get(i), authToken);\r
- }\r
- logger.log(logger.HIGH, "Leaving SyncRunner.syncNotes");\r
-\r
- }\r
- // Sync notes with Evernote\r
- private void syncLocalNote(Client noteStore, Note enNote, String token) {\r
- logger.log(logger.HIGH, "Entering SyncRunner.syncNotes");\r
- status.message.emit(tr("Sending local notes."));\r
- \r
- if (enNote.isActive()) {\r
- try {\r
- if (enNote.getUpdateSequenceNum() > 0) {\r
- logger.log(logger.EXTREME, "Active dirty note found - non new - " +enNote.getGuid());\r
- logger.log(logger.EXTREME, "Fetching note content");\r
- enNote = getNoteContent(enNote);\r
- logger.log(logger.MEDIUM, "Updating note : "+ enNote.getGuid() +" <title>" +enNote.getTitle()+"</title>");\r
- enNote = noteStore.updateNote(token, enNote);\r
- } else { \r
- logger.log(logger.EXTREME, "Active dirty found - new note " +enNote.getGuid());\r
- String oldGuid = enNote.getGuid();\r
- logger.log(logger.MEDIUM, "Fetching note content");\r
- enNote = getNoteContent(enNote);\r
- logger.log(logger.MEDIUM, "Creating note : "+ enNote.getGuid() +" <title>" +enNote.getTitle()+"</title>");\r
- enNote = noteStore.createNote(token, enNote);\r
- logger.log(logger.MEDIUM, "New note Guid : "+ enNote.getGuid() +" <title>" +enNote.getTitle()+"</title>");\r
- noteSignal.guidChanged.emit(oldGuid, enNote.getGuid());\r
- conn.getNoteTable().updateNoteGuid(oldGuid, enNote.getGuid());\r
- }\r
- updateSequenceNumber = enNote.getUpdateSequenceNum();\r
- logger.log(logger.EXTREME, "Saving note");\r
- conn.getNoteTable().updateNoteSequence(enNote.getGuid(), enNote.getUpdateSequenceNum());\r
- List<Resource> rl = enNote.getResources();\r
- logger.log(logger.EXTREME, "Getting note resources");\r
- for (int j=0; j<enNote.getResourcesSize() && keepRunning; j++) {\r
- Resource newRes = rl.get(j);\r
- Data d = newRes.getData();\r
- if (d!=null) { \r
- logger.log(logger.EXTREME, "Calculating resource hash");\r
- String hash = byteArrayToHexString(d.getBodyHash());\r
- logger.log(logger.EXTREME, "updating resources by hash");\r
- String oldGuid = conn.getNoteTable().noteResourceTable.getNoteResourceGuidByHashHex(enNote.getGuid(), hash);\r
- conn.getNoteTable().updateNoteResourceGuidbyHash(enNote.getGuid(), newRes.getGuid(), hash);\r
- resourceSignal.resourceGuidChanged.emit(enNote.getGuid(), oldGuid, newRes.getGuid());\r
- }\r
- }\r
- logger.log(logger.EXTREME, "Resetting note dirty flag");\r
- conn.getNoteTable().resetDirtyFlag(enNote.getGuid());\r
- updateSequenceNumber = enNote.getUpdateSequenceNum();\r
- logger.log(logger.EXTREME, "Emitting note sequence number change");\r
- conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);\r
-\r
- } catch (EDAMUserException e) {\r
- logger.log(logger.LOW, "*** EDAM User Excepton syncLocalNotes "+e);\r
- status.message.emit(tr("Error sending local note: ") +e.getParameter());\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- } catch (EDAMSystemException e) {\r
- logger.log(logger.LOW, "*** EDAM System Excepton syncLocalNotes "+e);\r
- status.message.emit(tr("Error: ") +e);\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- } catch (EDAMNotFoundException e) {\r
- logger.log(logger.LOW, "*** EDAM Not Found Excepton syncLocalNotes " +e);\r
- status.message.emit(tr("Error sending local note: ") +e);\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- } catch (TException e) {\r
- logger.log(logger.LOW, "*** EDAM TExcepton syncLocalNotes "+e);\r
- status.message.emit(tr("Error sending local note: ") +e);\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- }\r
- }\r
- logger.log(logger.HIGH, "Leaving SyncRunner.syncLocalNote");\r
-\r
- }\r
-\r
- // Sync Notebooks with Evernote\r
- private void syncLocalNotebooks(Client noteStore) {\r
- logger.log(logger.HIGH, "Entering SyncRunner.syncLocalNotebooks");\r
- \r
- status.message.emit(tr("Sending local notebooks."));\r
- List<Notebook> remoteList = new ArrayList<Notebook>();\r
- try {\r
- logger.log(logger.EXTREME, "Getting remote notebooks to compare with local");\r
- remoteList = noteStore.listNotebooks(authToken);\r
- } catch (EDAMUserException e1) {\r
- logger.log(logger.LOW, "*** EDAM User Excepton syncLocalNotebooks getting remote Notebook List");\r
- status.message.emit(tr("Error: ") +e1);\r
- logger.log(logger.LOW, e1.toString()); \r
- error = true;\r
- } catch (EDAMSystemException e1) {\r
- logger.log(logger.LOW, "*** EDAM System Excepton syncLocalNotebooks getting remote Notebook List");\r
- status.message.emit(tr("Error: ") +e1);\r
- logger.log(logger.LOW, e1.toString()); \r
- error = true;\r
- } catch (TException e1) {\r
- logger.log(logger.LOW, "*** EDAM Transaction Excepton syncLocalNotebooks getting remote Notebook List");\r
- status.message.emit(tr("Error: ") +e1);\r
- logger.log(logger.LOW, e1.toString()); \r
- error = true;\r
- }\r
- logger.log(logger.EXTREME, "Getting local dirty notebooks");\r
- List<Notebook> notebooks = conn.getNotebookTable().getDirty();\r
- int sequence;\r
- // Sync the local notebooks with Evernote's\r
- for (int i=0; i<notebooks.size() && keepRunning; i++) {\r
- \r
-// if (authRefreshNeeded)\r
-// if (!refreshConnection())\r
-// return;\r
- \r
- Notebook enNotebook = notebooks.get(i);\r
- try {\r
- if (enNotebook.getUpdateSequenceNum() > 0) {\r
- logger.log(logger.EXTREME, "Existing notebook is dirty");\r
- sequence = noteStore.updateNotebook(authToken, enNotebook);\r
- } else {\r
- logger.log(logger.EXTREME, "New dirty notebook found");\r
- String oldGuid = enNotebook.getGuid();\r
- boolean found = false;\r
- \r
- // Look for a notebook with the same name. If one is found, we don't need \r
- // to create another one\r
- logger.log(logger.EXTREME, "Looking for matching notebook name");\r
- for (int k=0; k<remoteList.size() && !found && keepRunning; k++) {\r
- if (remoteList.get(k).getName().equalsIgnoreCase(enNotebook.getName())) {\r
- enNotebook = remoteList.get(k);\r
- logger.log(logger.EXTREME, "Matching notebook found");\r
- found = true;\r
- }\r
- }\r
- if (!found)\r
- enNotebook = noteStore.createNotebook(authToken, enNotebook);\r
- \r
- logger.log(logger.EXTREME, "Updating notebook in database");\r
- conn.getNotebookTable().updateNotebookGuid(oldGuid, enNotebook.getGuid());\r
- sequence = enNotebook.getUpdateSequenceNum();\r
- }\r
- logger.log(logger.EXTREME, "Updating notebook sequence in database");\r
- conn.getNotebookTable().updateNotebookSequence(enNotebook.getGuid(), sequence);\r
- logger.log(logger.EXTREME, "Resetting dirty flag in notebook");\r
- conn.getNotebookTable().resetDirtyFlag(enNotebook.getGuid());\r
- updateSequenceNumber = sequence;\r
- logger.log(logger.EXTREME, "Emitting sequence number to main thread");\r
- conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);\r
- } catch (EDAMUserException e) {\r
- logger.log(logger.LOW, "*** EDAM User Excepton syncLocalNotebooks");\r
- logger.log(logger.LOW, e.toString() + ": Stack : " +enNotebook.getStack()); \r
- error = true;\r
- } catch (EDAMSystemException e) {\r
- logger.log(logger.LOW, "*** EDAM System Excepton syncLocalNotebooks");\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- } catch (EDAMNotFoundException e) {\r
- logger.log(logger.LOW, "*** EDAM Not Found Excepton syncLocalNotebooks");\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- } catch (TException e) {\r
- logger.log(logger.LOW, "*** EDAM TExcepton syncLocalNotebooks");\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- } \r
- }\r
- logger.log(logger.HIGH, "Leaving SyncRunner.syncLocalNotebooks");\r
-\r
- }\r
- // Sync Tags with Evernote\r
- private void syncLocalTags(Client noteStore) {\r
- logger.log(logger.HIGH, "Entering SyncRunner.syncLocalTags");\r
- List<Tag> remoteList = new ArrayList<Tag>();\r
- status.message.emit(tr("Sending local tags."));\r
- \r
- try {\r
- logger.log(logger.EXTREME, "Getting remote tags to compare names with the local tags");\r
- remoteList = noteStore.listTags(authToken);\r
- } catch (EDAMUserException e1) {\r
- logger.log(logger.LOW, "*** EDAM User Excepton syncLocalTags getting remote Tag List");\r
- status.message.emit(tr("Error: ") +e1);\r
- logger.log(logger.LOW, e1.toString()); \r
- error = true;\r
- } catch (EDAMSystemException e1) {\r
- logger.log(logger.LOW, "*** EDAM System Excepton syncLocalTags getting remote Tag List");\r
- status.message.emit(tr("Error: ") +e1);\r
- logger.log(logger.LOW, e1.toString()); \r
- error = true;\r
- } catch (TException e1) {\r
- logger.log(logger.LOW, "*** EDAM Transaction Excepton syncLocalTags getting remote Tag List");\r
- status.message.emit(tr("Error: ") +e1);\r
- logger.log(logger.LOW, e1.toString()); \r
- error = true;\r
- } \r
- \r
- int sequence;\r
- \r
- if (badTagSync == null)\r
- badTagSync = new HashMap<String,String>();\r
- else\r
- badTagSync.clear();\r
- \r
- Tag enTag = findNextTag();\r
- \r
- // This is a hack. Sometimes this function goes flookey and goes into a \r
- // perpetual loop. This causes NeverNote to flood Evernote's servers.\r
- // This is a safety valve to prevent unlimited loops.\r
- int maxCount = conn.getTagTable().getDirty().size()+10;\r
- int loopCount = 0;\r
- \r
- while(enTag!=null && loopCount < maxCount) {\r
- loopCount++;\r
-// if (authRefreshNeeded)\r
-// if (!refreshConnection())\r
-// return;\r
-\r
- try {\r
- if (enTag.getUpdateSequenceNum() > 0) {\r
- logger.log(logger.EXTREME, "Updating tag");\r
- sequence = noteStore.updateTag(authToken, enTag);\r
- } else {\r
- \r
- // Look for a tag with the same name. If one is found, we don't need \r
- // to create another one\r
- logger.log(logger.EXTREME, "New tag. Comparing with remote names");\r
- boolean found = false;\r
- String oldGuid = enTag.getGuid();\r
- for (int k=0; k<remoteList.size() && !found && keepRunning; k++) {\r
- if (remoteList.get(k).getName().equalsIgnoreCase(enTag.getName())) {\r
- conn.getTagTable().updateTagGuid(enTag.getGuid(), remoteList.get(k).getGuid());\r
- enTag = remoteList.get(k);\r
- logger.log(logger.EXTREME, "Matching tag name found");\r
- found = true;\r
- }\r
- }\r
- if (!found)\r
- enTag = noteStore.createTag(authToken, enTag);\r
- else\r
- enTag.setUpdateSequenceNum(noteStore.updateTag(authToken,enTag));\r
- sequence = enTag.getUpdateSequenceNum();\r
- if (!oldGuid.equals(enTag.getGuid())) {\r
- logger.log(logger.EXTREME, "Updating tag guid");\r
- conn.getTagTable().updateTagGuid(oldGuid, enTag.getGuid());\r
- }\r
- }\r
- logger.log(logger.EXTREME, "Updating tag sequence number");\r
- conn.getTagTable().updateTagSequence(enTag.getGuid(), sequence);\r
- logger.log(logger.EXTREME, "Resetting tag dirty flag");\r
- conn.getTagTable().resetDirtyFlag(enTag.getGuid());\r
- logger.log(logger.EXTREME, "Emitting sequence number to the main thread.");\r
- updateSequenceNumber = sequence;\r
- conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);\r
- } catch (EDAMUserException e) {\r
- logger.log(logger.LOW, "*** EDAM User Excepton syncLocalTags: " +enTag.getName());\r
- logger.log(logger.LOW, e.toString());\r
- badTagSync.put(enTag.getGuid(),null);\r
- error = true;\r
- } catch (EDAMSystemException e) {\r
- logger.log(logger.LOW, "** EDAM System Excepton syncLocalTags: " +enTag.getName());\r
- logger.log(logger.LOW, e.toString()); \r
- badTagSync.put(enTag.getGuid(),null);\r
- error = true;\r
- } catch (EDAMNotFoundException e) {\r
- logger.log(logger.LOW, "*** EDAM Not Found Excepton syncLocalTags: " +enTag.getName());\r
- logger.log(logger.LOW, e.toString());\r
- badTagSync.put(enTag.getGuid(),null);\r
- error = true;\r
- } catch (TException e) {\r
- logger.log(logger.LOW, "*** EDAM TExcepton syncLocalTags: " +enTag.getName());\r
- logger.log(logger.LOW, e.toString());\r
- badTagSync.put(enTag.getGuid(),null);\r
- error = true;\r
- } \r
- \r
- // Find the next tag\r
- logger.log(logger.EXTREME, "Finding next tag");\r
- enTag = findNextTag();\r
- }\r
- logger.log(logger.HIGH, "Leaving SyncRunner.syncLocalTags");\r
- }\r
- private void syncLocalLinkedNotebooks(Client noteStore) {\r
- logger.log(logger.HIGH, "Entering SyncRunner.syncLocalLinkedNotebooks");\r
- \r
- List<String> list = conn.getLinkedNotebookTable().getDirtyGuids();\r
- for (int i=0; i<list.size(); i++) {\r
- LinkedNotebook book = conn.getLinkedNotebookTable().getNotebook(list.get(i));\r
- try {\r
- noteStore.updateLinkedNotebook(authToken, book);\r
- } catch (EDAMUserException e) {\r
- logger.log(logger.LOW, "*** EDAM User Excepton syncLocalLinkedNotebooks");\r
- status.message.emit(tr("Error: ") +e);\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- e.printStackTrace();\r
- } catch (EDAMNotFoundException e) {\r
- logger.log(logger.LOW, "*** EDAM Not Found Excepton syncLocalLinkedNotebooks");\r
- status.message.emit(tr("Error: ") +e);\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- e.printStackTrace();\r
- } catch (EDAMSystemException e) {\r
- logger.log(logger.LOW, "*** EDAM System Excepton syncLocalLinkedNotebooks");\r
- status.message.emit(tr("Error: ") +e);\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- e.printStackTrace();\r
- } catch (TException e) {\r
- logger.log(logger.LOW, "*** EDAM TExcepton syncLocalLinkedNotebooks");\r
- status.message.emit(tr("Error: ") +e);\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- e.printStackTrace();\r
- }\r
- }\r
- logger.log(logger.HIGH, "Leaving SyncRunner.syncLocalLinkedNotebooks");\r
- }\r
- // Sync Saved Searches with Evernote\r
- private void syncLocalSavedSearches(Client noteStore) {\r
- logger.log(logger.HIGH, "Entering SyncRunner.syncLocalSavedSearches");\r
- List<SavedSearch> remoteList = new ArrayList<SavedSearch>();\r
- status.message.emit(tr("Sending saved searches."));\r
- \r
- logger.log(logger.EXTREME, "Getting saved searches to compare with local");\r
- try {\r
- remoteList = noteStore.listSearches(authToken);\r
- } catch (EDAMUserException e1) {\r
- logger.log(logger.LOW, "*** EDAM User Excepton syncLocalTags getting remote saved search List");\r
- status.message.emit(tr("Error: ") +e1);\r
- logger.log(logger.LOW, e1.toString()); \r
- error = true;\r
- } catch (EDAMSystemException e1) {\r
- logger.log(logger.LOW, "*** EDAM System Excepton syncLocalTags getting remote saved search List");\r
- status.message.emit(tr("Error: ") +e1);\r
- logger.log(logger.LOW, e1.toString()); \r
- error = true;\r
- } catch (TException e1) {\r
- logger.log(logger.LOW, "*** EDAM Transaction Excepton syncLocalTags getting remote saved search List");\r
- status.message.emit(tr("Error: ") +e1);\r
- logger.log(logger.LOW, e1.toString()); \r
- error = true;\r
- } \r
- \r
- List<SavedSearch> searches = conn.getSavedSearchTable().getDirty();\r
- int sequence;\r
- // Sync the local notebooks with Evernote's\r
- logger.log(logger.EXTREME, "Beginning to send saved searches");\r
- for (int i=0; i<searches.size() && keepRunning; i++) {\r
- \r
-// if (authRefreshNeeded)\r
-// if (!refreshConnection())\r
-// return;\r
- \r
- SavedSearch enSearch = searches.get(i);\r
- try {\r
- if (enSearch.getUpdateSequenceNum() > 0) \r
- sequence = noteStore.updateSearch(authToken, enSearch);\r
- else {\r
- logger.log(logger.EXTREME, "New saved search found.");\r
- // Look for a tag with the same name. If one is found, we don't need \r
- // to create another one\r
- boolean found = false;\r
- logger.log(logger.EXTREME, "Matching remote saved search names with local");\r
- for (int k=0; k<remoteList.size() && !found && keepRunning; k++) {\r
- if (remoteList.get(k).getName().equalsIgnoreCase(enSearch.getName())) {\r
- enSearch = remoteList.get(k);\r
- found = true;\r
- logger.log(logger.EXTREME, "Matching saved search found");\r
- sequence = enSearch.getUpdateSequenceNum();\r
- }\r
- }\r
-\r
- String oldGuid = enSearch.getGuid();\r
- if (!found)\r
- enSearch = noteStore.createSearch(authToken, enSearch);\r
- sequence = enSearch.getUpdateSequenceNum();\r
- logger.log(logger.EXTREME, "Updating tag guid in local database");\r
- conn.getSavedSearchTable().updateSavedSearchGuid(oldGuid, enSearch.getGuid());\r
- }\r
- logger.log(logger.EXTREME, "Updating tag sequence in local database");\r
- conn.getSavedSearchTable().updateSavedSearchSequence(enSearch.getGuid(), sequence);\r
- logger.log(logger.EXTREME, "Resetting tag dirty flag");\r
- conn.getSavedSearchTable().resetDirtyFlag(enSearch.getGuid());\r
- logger.log(logger.EXTREME, "Emitting sequence number to the main thread.");\r
- updateSequenceNumber = sequence;\r
- conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);\r
- } catch (EDAMUserException e) {\r
- logger.log(logger.LOW, "*** EDAM User Excepton syncLocalTags");\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- } catch (EDAMSystemException e) {\r
- logger.log(logger.LOW, "** EDAM System Excepton syncLocalTags");\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- } catch (EDAMNotFoundException e) {\r
- logger.log(logger.LOW, "*** EDAM Not Found Excepton syncLocalTags");\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- } catch (TException e) {\r
- logger.log(logger.LOW, "*** EDAM TExcepton syncLocalTags");\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- } \r
- }\r
-\r
- logger.log(logger.HIGH, "Entering SyncRunner.syncLocalSavedSearches");\r
- } \r
-\r
- // Sync evernote changes with local database\r
- private void syncRemoteToLocal(Client noteStore) {\r
- logger.log(logger.HIGH, "Entering SyncRunner.syncRemoteToLocal");\r
-\r
- List<Note> dirtyNotes = conn.getNoteTable().getDirty();\r
+ //status.message.emit("Error deleting local note: " +e +" - Continuing");
+ //logger.log(logger.LOW, e.toString());
+ //error = true;
+ } catch (TException e) {
+ logger.log(logger.LOW, "*** EDAM TExcepton syncLocalNotes "+e);
+ status.message.emit(tr("Error sending local note: ") +e);
+ logger.log(logger.LOW, e.toString());
+ error = true;
+ }
+ }
+ }
+ // Sync notes with Evernote
+ private void syncLocalNotes() {
+ logger.log(logger.HIGH, "Entering SyncRunner.syncNotes");
+ logger.log(logger.LOW, "Dirty local notes found: " +new Integer(conn.getNoteTable().getDirtyCount()).toString());
+ status.message.emit(tr("Sending local notes."));
+
+ List<Note> notes = conn.getNoteTable().getDirty();
+ // Sync the local notebooks with Evernote's
+ for (int i=0; i<notes.size() && keepRunning; i++) {
+ syncLocalNote(localNoteStore, notes.get(i), authToken);
+ }
+ logger.log(logger.HIGH, "Leaving SyncRunner.syncNotes");
+
+ }
+ // Sync notes with Evernote
+ private void syncLocalNote(Client noteStore, Note enNote, String token) {
+ logger.log(logger.HIGH, "Entering SyncRunner.syncNotes");
+ status.message.emit(tr("Sending local notes."));
+
+ if (enNote.isActive()) {
+ try {
+ if (enNote.getUpdateSequenceNum() > 0) {
+ logger.log(logger.EXTREME, "Active dirty note found - non new - " +enNote.getGuid());
+ logger.log(logger.EXTREME, "Fetching note content");
+ enNote = getNoteContent(enNote);
+ logger.log(logger.MEDIUM, "Updating note : "+ enNote.getGuid() +" <title>" +enNote.getTitle()+"</title>");
+ enNote = noteStore.updateNote(token, enNote);
+ } else {
+ logger.log(logger.EXTREME, "Active dirty found - new note " +enNote.getGuid());
+ String oldGuid = enNote.getGuid();
+ logger.log(logger.MEDIUM, "Fetching note content");
+ enNote = getNoteContent(enNote);
+ logger.log(logger.MEDIUM, "Creating note : "+ enNote.getGuid() +" <title>" +enNote.getTitle()+"</title>");
+ enNote = noteStore.createNote(token, enNote);
+ logger.log(logger.MEDIUM, "New note Guid : "+ enNote.getGuid() +" <title>" +enNote.getTitle()+"</title>");
+ noteSignal.guidChanged.emit(oldGuid, enNote.getGuid());
+ conn.getNoteTable().updateNoteGuid(oldGuid, enNote.getGuid());
+ }
+ updateSequenceNumber = enNote.getUpdateSequenceNum();
+ logger.log(logger.EXTREME, "Saving note");
+ conn.getNoteTable().updateNoteSequence(enNote.getGuid(), enNote.getUpdateSequenceNum());
+ List<Resource> rl = enNote.getResources();
+ logger.log(logger.EXTREME, "Getting note resources");
+ for (int j=0; j<enNote.getResourcesSize() && keepRunning; j++) {
+ Resource newRes = rl.get(j);
+ Data d = newRes.getData();
+ if (d!=null) {
+ logger.log(logger.EXTREME, "Calculating resource hash");
+ String hash = byteArrayToHexString(d.getBodyHash());
+ logger.log(logger.EXTREME, "updating resources by hash");
+ String oldGuid = conn.getNoteTable().noteResourceTable.getNoteResourceGuidByHashHex(enNote.getGuid(), hash);
+ conn.getNoteTable().updateNoteResourceGuidbyHash(enNote.getGuid(), newRes.getGuid(), hash);
+ resourceSignal.resourceGuidChanged.emit(enNote.getGuid(), oldGuid, newRes.getGuid());
+ }
+ }
+ logger.log(logger.EXTREME, "Resetting note dirty flag");
+ conn.getNoteTable().resetDirtyFlag(enNote.getGuid());
+ updateSequenceNumber = enNote.getUpdateSequenceNum();
+ logger.log(logger.EXTREME, "Emitting note sequence number change");
+ conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);
+
+ } catch (EDAMUserException e) {
+ logger.log(logger.LOW, "*** EDAM User Excepton syncLocalNotes "+e);
+ status.message.emit(tr("Error sending local note: ") +e.getParameter());
+ logger.log(logger.LOW, e.toString());
+ error = true;
+ } catch (EDAMSystemException e) {
+ logger.log(logger.LOW, "*** EDAM System Excepton syncLocalNotes "+e);
+ status.message.emit(tr("Error: ") +e);
+ logger.log(logger.LOW, e.toString());
+ error = true;
+ } catch (EDAMNotFoundException e) {
+ logger.log(logger.LOW, "*** EDAM Not Found Excepton syncLocalNotes " +e);
+ status.message.emit(tr("Error sending local note: ") +e);
+ logger.log(logger.LOW, e.toString());
+ error = true;
+ } catch (TException e) {
+ logger.log(logger.LOW, "*** EDAM TExcepton syncLocalNotes "+e);
+ status.message.emit(tr("Error sending local note: ") +e);
+ logger.log(logger.LOW, e.toString());
+ error = true;
+ }
+ }
+ logger.log(logger.HIGH, "Leaving SyncRunner.syncLocalNote");
+
+ }
+
+ // Sync Notebooks with Evernote
+ private void syncLocalNotebooks(Client noteStore) {
+ logger.log(logger.HIGH, "Entering SyncRunner.syncLocalNotebooks");
+
+ status.message.emit(tr("Sending local notebooks."));
+ List<Notebook> remoteList = new ArrayList<Notebook>();
+ try {
+ logger.log(logger.EXTREME, "Getting remote notebooks to compare with local");
+ remoteList = noteStore.listNotebooks(authToken);
+ } catch (EDAMUserException e1) {
+ logger.log(logger.LOW, "*** EDAM User Excepton syncLocalNotebooks getting remote Notebook List");
+ status.message.emit(tr("Error: ") +e1);
+ logger.log(logger.LOW, e1.toString());
+ error = true;
+ } catch (EDAMSystemException e1) {
+ logger.log(logger.LOW, "*** EDAM System Excepton syncLocalNotebooks getting remote Notebook List");
+ status.message.emit(tr("Error: ") +e1);
+ logger.log(logger.LOW, e1.toString());
+ error = true;
+ } catch (TException e1) {
+ logger.log(logger.LOW, "*** EDAM Transaction Excepton syncLocalNotebooks getting remote Notebook List");
+ status.message.emit(tr("Error: ") +e1);
+ logger.log(logger.LOW, e1.toString());
+ error = true;
+ }
+ logger.log(logger.EXTREME, "Getting local dirty notebooks");
+ List<Notebook> notebooks = conn.getNotebookTable().getDirty();
+ int sequence;
+ // Sync the local notebooks with Evernote's
+ for (int i=0; i<notebooks.size() && keepRunning; i++) {
+
+// if (authRefreshNeeded)
+// if (!refreshConnection())
+// return;
+
+ Notebook enNotebook = notebooks.get(i);
+ try {
+ if (enNotebook.getUpdateSequenceNum() > 0) {
+ logger.log(logger.EXTREME, "Existing notebook is dirty");
+ sequence = noteStore.updateNotebook(authToken, enNotebook);
+ } else {
+ logger.log(logger.EXTREME, "New dirty notebook found");
+ String oldGuid = enNotebook.getGuid();
+ boolean found = false;
+
+ // Look for a notebook with the same name. If one is found, we don't need
+ // to create another one
+ logger.log(logger.EXTREME, "Looking for matching notebook name");
+ for (int k=0; k<remoteList.size() && !found && keepRunning; k++) {
+ if (remoteList.get(k).getName().equalsIgnoreCase(enNotebook.getName())) {
+ enNotebook = remoteList.get(k);
+ logger.log(logger.EXTREME, "Matching notebook found");
+ found = true;
+ }
+ }
+ if (!found)
+ enNotebook = noteStore.createNotebook(authToken, enNotebook);
+
+ logger.log(logger.EXTREME, "Updating notebook in database");
+ conn.getNotebookTable().updateNotebookGuid(oldGuid, enNotebook.getGuid());
+ sequence = enNotebook.getUpdateSequenceNum();
+ }
+ logger.log(logger.EXTREME, "Updating notebook sequence in database");
+ conn.getNotebookTable().updateNotebookSequence(enNotebook.getGuid(), sequence);
+ logger.log(logger.EXTREME, "Resetting dirty flag in notebook");
+ conn.getNotebookTable().resetDirtyFlag(enNotebook.getGuid());
+ updateSequenceNumber = sequence;
+ logger.log(logger.EXTREME, "Emitting sequence number to main thread");
+ conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);
+ } catch (EDAMUserException e) {
+ logger.log(logger.LOW, "*** EDAM User Excepton syncLocalNotebooks");
+ logger.log(logger.LOW, e.toString() + ": Stack : " +enNotebook.getStack());
+ error = true;
+ } catch (EDAMSystemException e) {
+ logger.log(logger.LOW, "*** EDAM System Excepton syncLocalNotebooks");
+ logger.log(logger.LOW, e.toString());
+ error = true;
+ } catch (EDAMNotFoundException e) {
+ logger.log(logger.LOW, "*** EDAM Not Found Excepton syncLocalNotebooks");
+ logger.log(logger.LOW, e.toString());
+ error = true;
+ } catch (TException e) {
+ logger.log(logger.LOW, "*** EDAM TExcepton syncLocalNotebooks");
+ logger.log(logger.LOW, e.toString());
+ error = true;
+ }
+ }
+ logger.log(logger.HIGH, "Leaving SyncRunner.syncLocalNotebooks");
+
+ }
+ // Sync Tags with Evernote
+ private void syncLocalTags(Client noteStore) {
+ logger.log(logger.HIGH, "Entering SyncRunner.syncLocalTags");
+ List<Tag> remoteList = new ArrayList<Tag>();
+ status.message.emit(tr("Sending local tags."));
+
+ try {
+ logger.log(logger.EXTREME, "Getting remote tags to compare names with the local tags");
+ remoteList = noteStore.listTags(authToken);
+ } catch (EDAMUserException e1) {
+ logger.log(logger.LOW, "*** EDAM User Excepton syncLocalTags getting remote Tag List");
+ status.message.emit(tr("Error: ") +e1);
+ logger.log(logger.LOW, e1.toString());
+ error = true;
+ } catch (EDAMSystemException e1) {
+ logger.log(logger.LOW, "*** EDAM System Excepton syncLocalTags getting remote Tag List");
+ status.message.emit(tr("Error: ") +e1);
+ logger.log(logger.LOW, e1.toString());
+ error = true;
+ } catch (TException e1) {
+ logger.log(logger.LOW, "*** EDAM Transaction Excepton syncLocalTags getting remote Tag List");
+ status.message.emit(tr("Error: ") +e1);
+ logger.log(logger.LOW, e1.toString());
+ error = true;
+ }
+
+ int sequence;
+
+ if (badTagSync == null)
+ badTagSync = new HashMap<String,String>();
+ else
+ badTagSync.clear();
+
+ Tag enTag = findNextTag();
+
+ // This is a hack. Sometimes this function goes flookey and goes into a
+ // perpetual loop. This causes NeverNote to flood Evernote's servers.
+ // This is a safety valve to prevent unlimited loops.
+ int maxCount = conn.getTagTable().getDirty().size()+10;
+ int loopCount = 0;
+
+ while(enTag!=null && loopCount < maxCount) {
+ loopCount++;
+// if (authRefreshNeeded)
+// if (!refreshConnection())
+// return;
+
+ try {
+ if (enTag.getUpdateSequenceNum() > 0) {
+ logger.log(logger.EXTREME, "Updating tag");
+ sequence = noteStore.updateTag(authToken, enTag);
+ } else {
+
+ // Look for a tag with the same name. If one is found, we don't need
+ // to create another one
+ logger.log(logger.EXTREME, "New tag. Comparing with remote names");
+ boolean found = false;
+ String oldGuid = enTag.getGuid();
+ for (int k=0; k<remoteList.size() && !found && keepRunning; k++) {
+ if (remoteList.get(k).getName().equalsIgnoreCase(enTag.getName())) {
+ conn.getTagTable().updateTagGuid(enTag.getGuid(), remoteList.get(k).getGuid());
+ enTag = remoteList.get(k);
+ logger.log(logger.EXTREME, "Matching tag name found");
+ found = true;
+ }
+ }
+ if (!found)
+ enTag = noteStore.createTag(authToken, enTag);
+ else
+ enTag.setUpdateSequenceNum(noteStore.updateTag(authToken,enTag));
+ sequence = enTag.getUpdateSequenceNum();
+ if (!oldGuid.equals(enTag.getGuid())) {
+ logger.log(logger.EXTREME, "Updating tag guid");
+ conn.getTagTable().updateTagGuid(oldGuid, enTag.getGuid());
+ }
+ }
+ logger.log(logger.EXTREME, "Updating tag sequence number");
+ conn.getTagTable().updateTagSequence(enTag.getGuid(), sequence);
+ logger.log(logger.EXTREME, "Resetting tag dirty flag");
+ conn.getTagTable().resetDirtyFlag(enTag.getGuid());
+ logger.log(logger.EXTREME, "Emitting sequence number to the main thread.");
+ updateSequenceNumber = sequence;
+ conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);
+ } catch (EDAMUserException e) {
+ logger.log(logger.LOW, "*** EDAM User Excepton syncLocalTags: " +enTag.getName());
+ logger.log(logger.LOW, e.toString());
+ badTagSync.put(enTag.getGuid(),null);
+ error = true;
+ } catch (EDAMSystemException e) {
+ logger.log(logger.LOW, "** EDAM System Excepton syncLocalTags: " +enTag.getName());
+ logger.log(logger.LOW, e.toString());
+ badTagSync.put(enTag.getGuid(),null);
+ error = true;
+ } catch (EDAMNotFoundException e) {
+ logger.log(logger.LOW, "*** EDAM Not Found Excepton syncLocalTags: " +enTag.getName());
+ logger.log(logger.LOW, e.toString());
+ badTagSync.put(enTag.getGuid(),null);
+ error = true;
+ } catch (TException e) {
+ logger.log(logger.LOW, "*** EDAM TExcepton syncLocalTags: " +enTag.getName());
+ logger.log(logger.LOW, e.toString());
+ badTagSync.put(enTag.getGuid(),null);
+ error = true;
+ }
+
+ // Find the next tag
+ logger.log(logger.EXTREME, "Finding next tag");
+ enTag = findNextTag();
+ }
+ logger.log(logger.HIGH, "Leaving SyncRunner.syncLocalTags");
+ }
+ private void syncLocalLinkedNotebooks(Client noteStore) {
+ logger.log(logger.HIGH, "Entering SyncRunner.syncLocalLinkedNotebooks");
+
+ List<String> list = conn.getLinkedNotebookTable().getDirtyGuids();
+ for (int i=0; i<list.size(); i++) {
+ LinkedNotebook book = conn.getLinkedNotebookTable().getNotebook(list.get(i));
+ try {
+ noteStore.updateLinkedNotebook(authToken, book);
+ } catch (EDAMUserException e) {
+ logger.log(logger.LOW, "*** EDAM User Excepton syncLocalLinkedNotebooks");
+ status.message.emit(tr("Error: ") +e);
+ logger.log(logger.LOW, e.toString());
+ error = true;
+ e.printStackTrace();
+ } catch (EDAMNotFoundException e) {
+ logger.log(logger.LOW, "*** EDAM Not Found Excepton syncLocalLinkedNotebooks");
+ status.message.emit(tr("Error: ") +e);
+ logger.log(logger.LOW, e.toString());
+ error = true;
+ e.printStackTrace();
+ } catch (EDAMSystemException e) {
+ logger.log(logger.LOW, "*** EDAM System Excepton syncLocalLinkedNotebooks");
+ status.message.emit(tr("Error: ") +e);
+ logger.log(logger.LOW, e.toString());
+ error = true;
+ e.printStackTrace();
+ } catch (TException e) {
+ logger.log(logger.LOW, "*** EDAM TExcepton syncLocalLinkedNotebooks");
+ status.message.emit(tr("Error: ") +e);
+ logger.log(logger.LOW, e.toString());
+ error = true;
+ e.printStackTrace();
+ }
+ }
+ logger.log(logger.HIGH, "Leaving SyncRunner.syncLocalLinkedNotebooks");
+ }
+ // Sync Saved Searches with Evernote
+ private void syncLocalSavedSearches(Client noteStore) {
+ logger.log(logger.HIGH, "Entering SyncRunner.syncLocalSavedSearches");
+ List<SavedSearch> remoteList = new ArrayList<SavedSearch>();
+ status.message.emit(tr("Sending saved searches."));
+
+ logger.log(logger.EXTREME, "Getting saved searches to compare with local");
+ try {
+ remoteList = noteStore.listSearches(authToken);
+ } catch (EDAMUserException e1) {
+ logger.log(logger.LOW, "*** EDAM User Excepton syncLocalTags getting remote saved search List");
+ status.message.emit(tr("Error: ") +e1);
+ logger.log(logger.LOW, e1.toString());
+ error = true;
+ } catch (EDAMSystemException e1) {
+ logger.log(logger.LOW, "*** EDAM System Excepton syncLocalTags getting remote saved search List");
+ status.message.emit(tr("Error: ") +e1);
+ logger.log(logger.LOW, e1.toString());
+ error = true;
+ } catch (TException e1) {
+ logger.log(logger.LOW, "*** EDAM Transaction Excepton syncLocalTags getting remote saved search List");
+ status.message.emit(tr("Error: ") +e1);
+ logger.log(logger.LOW, e1.toString());
+ error = true;
+ }
+
+ List<SavedSearch> searches = conn.getSavedSearchTable().getDirty();
+ int sequence;
+ // Sync the local notebooks with Evernote's
+ logger.log(logger.EXTREME, "Beginning to send saved searches");
+ for (int i=0; i<searches.size() && keepRunning; i++) {
+
+// if (authRefreshNeeded)
+// if (!refreshConnection())
+// return;
+
+ SavedSearch enSearch = searches.get(i);
+ try {
+ if (enSearch.getUpdateSequenceNum() > 0)
+ sequence = noteStore.updateSearch(authToken, enSearch);
+ else {
+ logger.log(logger.EXTREME, "New saved search found.");
+ // Look for a tag with the same name. If one is found, we don't need
+ // to create another one
+ boolean found = false;
+ logger.log(logger.EXTREME, "Matching remote saved search names with local");
+ for (int k=0; k<remoteList.size() && !found && keepRunning; k++) {
+ if (remoteList.get(k).getName().equalsIgnoreCase(enSearch.getName())) {
+ enSearch = remoteList.get(k);
+ found = true;
+ logger.log(logger.EXTREME, "Matching saved search found");
+ sequence = enSearch.getUpdateSequenceNum();
+ }
+ }
+
+ String oldGuid = enSearch.getGuid();
+ if (!found)
+ enSearch = noteStore.createSearch(authToken, enSearch);
+ sequence = enSearch.getUpdateSequenceNum();
+ logger.log(logger.EXTREME, "Updating tag guid in local database");
+ conn.getSavedSearchTable().updateSavedSearchGuid(oldGuid, enSearch.getGuid());
+ }
+ logger.log(logger.EXTREME, "Updating tag sequence in local database");
+ conn.getSavedSearchTable().updateSavedSearchSequence(enSearch.getGuid(), sequence);
+ logger.log(logger.EXTREME, "Resetting tag dirty flag");
+ conn.getSavedSearchTable().resetDirtyFlag(enSearch.getGuid());
+ logger.log(logger.EXTREME, "Emitting sequence number to the main thread.");
+ updateSequenceNumber = sequence;
+ conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);
+ } catch (EDAMUserException e) {
+ logger.log(logger.LOW, "*** EDAM User Excepton syncLocalTags");
+ logger.log(logger.LOW, e.toString());
+ error = true;
+ } catch (EDAMSystemException e) {
+ logger.log(logger.LOW, "** EDAM System Excepton syncLocalTags");
+ logger.log(logger.LOW, e.toString());
+ error = true;
+ } catch (EDAMNotFoundException e) {
+ logger.log(logger.LOW, "*** EDAM Not Found Excepton syncLocalTags");
+ logger.log(logger.LOW, e.toString());
+ error = true;
+ } catch (TException e) {
+ logger.log(logger.LOW, "*** EDAM TExcepton syncLocalTags");
+ logger.log(logger.LOW, e.toString());
+ error = true;
+ }
+ }
+
+ logger.log(logger.HIGH, "Entering SyncRunner.syncLocalSavedSearches");
+ }
+
+ // Sync evernote changes with local database
+ private void syncRemoteToLocal(Client noteStore) {
+ logger.log(logger.HIGH, "Entering SyncRunner.syncRemoteToLocal");
+
+ List<Note> dirtyNotes = conn.getNoteTable().getDirty();
dirtyNoteGuids = new ArrayList<String>();\r
- for (int i=0; i<dirtyNotes.size() && keepRunning; i++) {\r
- dirtyNoteGuids.add(dirtyNotes.get(i).getGuid());\r
- }\r
- \r
- int chunkSize = 10;\r
- SyncChunk chunk = null;\r
- boolean fullSync = false;\r
- boolean more = true;\r
- \r
- if (updateSequenceNumber == 0)\r
- fullSync = true;\r
- \r
- status.message.emit(tr("Downloading 0% complete."));\r
- \r
- while(more && keepRunning) {\r
- \r
-// if (authRefreshNeeded)\r
-// if (!refreshConnection())\r
-// return;\r
- \r
- int sequence = updateSequenceNumber;\r
- try {\r
-// conn.beginTransaction();\r
- logger.log(logger.EXTREME, "Getting chunk from Evernote");\r
- chunk = noteStore.getSyncChunk(authToken, sequence, chunkSize, fullSync);\r
- logger.log(logger.LOW, "Chunk High Sequence: " +chunk.getChunkHighUSN());\r
- } catch (EDAMUserException e) {\r
- error = true;\r
- e.printStackTrace();\r
- status.message.emit(e.getMessage());\r
- } catch (EDAMSystemException e) {\r
- error = true;\r
- e.printStackTrace();\r
- status.message.emit(e.getMessage());\r
- } catch (TException e) {\r
- error = true;\r
- e.printStackTrace();\r
- status.message.emit(e.getMessage());\r
- } \r
- if (error || chunk == null) \r
- return;\r
- \r
- \r
- \r
- syncRemoteTags(chunk.getTags());\r
- syncRemoteSavedSearches(chunk.getSearches());\r
- syncRemoteNotebooks(chunk.getNotebooks());\r
- syncRemoteNotes(noteStore, chunk.getNotes(), fullSync, authToken);\r
- syncRemoteResources(noteStore, chunk.getResources());\r
- syncRemoteLinkedNotebooks(chunk.getLinkedNotebooks());\r
- \r
- // Signal about any updated notes to invalidate the cache\r
- for (int i=0; i<chunk.getNotesSize(); i++) \r
- noteSignal.noteChanged.emit(chunk.getNotes().get(i).getGuid(), null); \r
- syncExpungedNotes(chunk);\r
- \r
- \r
- // Check for more notes\r
- if (chunk.getChunkHighUSN() <= updateSequenceNumber) \r
- more = false;\r
- if (error)\r
- more = false;\r
- logger.log(logger.EXTREME, "More notes? " +more);\r
-\r
- \r
- // Save the chunk sequence number\r
- if (!error && chunk.getChunkHighUSN() > 0 && keepRunning) {\r
- logger.log(logger.EXTREME, "emitting sequence number to main thread");\r
- updateSequenceNumber = chunk.getChunkHighUSN();\r
- conn.getSyncTable().setLastSequenceDate(chunk.getCurrentTime());\r
- conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);\r
-// conn.commitTransaction();\r
- }\r
- \r
- \r
- if (more) {\r
- long pct = chunk.getChunkHighUSN() * 100;\r
- conn.getSyncTable().setLastSequenceDate(chunk.getCurrentTime());\r
- pct = pct/evernoteUpdateCount;\r
- status.message.emit(tr("Downloading ") +new Long(pct).toString()+tr("% complete."));\r
- }\r
-// conn.commitTransaction();\r
- }\r
- logger.log(logger.HIGH, "Leaving SyncRunner.syncRemoteToLocal");\r
- }\r
- // Sync expunged notes\r
- private void syncExpungedNotes(SyncChunk chunk) {\r
- // Do the local deletes\r
- logger.log(logger.EXTREME, "Doing local deletes");\r
- List<String> guid = chunk.getExpungedNotes();\r
- if (guid != null) {\r
- for (int i=0; i<guid.size() && keepRunning; i++) {\r
- String notebookGuid = "";\r
- Note localNote = conn.getNoteTable().getNote(guid.get(i), false, false, false, false, false);\r
- if (localNote != null) {\r
- conn.getNoteTable().updateNoteSequence(guid.get(i), 0);\r
- notebookGuid = localNote.getNotebookGuid();\r
- }\r
+ for (int i=0; i<dirtyNotes.size() && keepRunning; i++) {
+ dirtyNoteGuids.add(dirtyNotes.get(i).getGuid());
+ }
+
+ int chunkSize = 10;
+ SyncChunk chunk = null;
+ boolean fullSync = false;
+ boolean more = true;
+
+ if (updateSequenceNumber == 0)
+ fullSync = true;
+
+ status.message.emit(tr("Downloading 0% complete."));
+
+ while(more && keepRunning) {
+
+// if (authRefreshNeeded)
+// if (!refreshConnection())
+// return;
+
+ int sequence = updateSequenceNumber;
+ try {
+// conn.beginTransaction();
+ logger.log(logger.EXTREME, "Getting chunk from Evernote");
+ chunk = noteStore.getSyncChunk(authToken, sequence, chunkSize, fullSync);
+ logger.log(logger.LOW, "Chunk High Sequence: " +chunk.getChunkHighUSN());
+ } catch (EDAMUserException e) {
+ error = true;
+ e.printStackTrace();
+ status.message.emit(e.getMessage());
+ } catch (EDAMSystemException e) {
+ error = true;
+ e.printStackTrace();
+ status.message.emit(e.getMessage());
+ } catch (TException e) {
+ error = true;
+ e.printStackTrace();
+ status.message.emit(e.getMessage());
+ }
+ if (error || chunk == null)
+ return;
+
+
+
+ syncRemoteTags(chunk.getTags());
+ syncRemoteSavedSearches(chunk.getSearches());
+ syncRemoteNotebooks(chunk.getNotebooks());
+ syncRemoteNotes(noteStore, chunk.getNotes(), fullSync, authToken);
+ syncRemoteResources(noteStore, chunk.getResources());
+ syncRemoteLinkedNotebooks(chunk.getLinkedNotebooks());
+
+ // Signal about any updated notes to invalidate the cache
+ for (int i=0; i<chunk.getNotesSize(); i++)
+ noteSignal.noteChanged.emit(chunk.getNotes().get(i).getGuid(), null);
+ syncExpungedNotes(chunk);
+
+
+ // Check for more notes
+ if (chunk.getChunkHighUSN() <= updateSequenceNumber)
+ more = false;
+ if (error)
+ more = false;
+ logger.log(logger.EXTREME, "More notes? " +more);
+
+
+ // Save the chunk sequence number
+ if (!error && chunk.getChunkHighUSN() > 0 && keepRunning) {
+ logger.log(logger.EXTREME, "emitting sequence number to main thread");
+ updateSequenceNumber = chunk.getChunkHighUSN();
+ conn.getSyncTable().setLastSequenceDate(chunk.getCurrentTime());
+ conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);
+// conn.commitTransaction();
+ }
+
+
+ if (more) {
+ long pct = chunk.getChunkHighUSN() * 100;
+ conn.getSyncTable().setLastSequenceDate(chunk.getCurrentTime());
+ pct = pct/evernoteUpdateCount;
+ status.message.emit(tr("Downloading ") +new Long(pct).toString()+tr("% complete."));
+ }
+// conn.commitTransaction();
+ }
+ logger.log(logger.HIGH, "Leaving SyncRunner.syncRemoteToLocal");
+ }
+ // Sync expunged notes
+ private void syncExpungedNotes(SyncChunk chunk) {
+ // Do the local deletes
+ logger.log(logger.EXTREME, "Doing local deletes");
+ List<String> guid = chunk.getExpungedNotes();
+ if (guid != null) {
+ for (int i=0; i<guid.size() && keepRunning; i++) {
+ String notebookGuid = "";
+ Note localNote = conn.getNoteTable().getNote(guid.get(i), false, false, false, false, false);
+ if (localNote != null) {
+ conn.getNoteTable().updateNoteSequence(guid.get(i), 0);
+ notebookGuid = localNote.getNotebookGuid();
+ }
// If the note is in a local notebook (which means we moved it) or if the \r
// note returned is null (which means it is already deleted or flagged expunged) \r
// we delete it.\r
if (!conn.getNotebookTable().isNotebookLocal(notebookGuid) || localNote == null) {\r
- logger.log(logger.EXTREME, "Expunging local note from database");\r
- conn.getNoteTable().expungeNote(guid.get(i), true, false);\r
- }\r
- }\r
- }\r
- guid = chunk.getExpungedNotebooks();\r
- if (guid != null)\r
- for (int i=0; i<guid.size() && keepRunning; i++) {\r
- logger.log(logger.EXTREME, "Expunging local notebook from database");\r
- conn.getNotebookTable().expungeNotebook(guid.get(i), false);\r
- }\r
- guid = chunk.getExpungedTags();\r
- if (guid != null)\r
- for (int i=0; i<guid.size() && keepRunning; i++) {\r
- logger.log(logger.EXTREME, "Expunging tags from local database");\r
- conn.getTagTable().expungeTag(guid.get(i), false);\r
- }\r
- guid = chunk.getExpungedSearches();\r
- if (guid != null) \r
- for (int i=0; i<guid.size() && keepRunning; i++) {\r
- logger.log(logger.EXTREME, "Expunging saved search from local database");\r
- conn.getSavedSearchTable().expungeSavedSearch(guid.get(i), false);\r
- }\r
- guid = chunk.getExpungedLinkedNotebooks();\r
- if (guid != null) \r
- for (int i=0; i<guid.size() && keepRunning; i++) {\r
- logger.log(logger.EXTREME, "Expunging linked notebook from local database");\r
- conn.getLinkedNotebookTable().expungeNotebook(guid.get(i), false);\r
- }\r
+ logger.log(logger.EXTREME, "Expunging local note from database");
+ conn.getNoteTable().expungeNote(guid.get(i), true, false);
+ }
+ }
+ }
+ guid = chunk.getExpungedNotebooks();
+ if (guid != null)
+ for (int i=0; i<guid.size() && keepRunning; i++) {
+ logger.log(logger.EXTREME, "Expunging local notebook from database");
+ conn.getNotebookTable().expungeNotebook(guid.get(i), false);
+ }
+ guid = chunk.getExpungedTags();
+ if (guid != null)
+ for (int i=0; i<guid.size() && keepRunning; i++) {
+ logger.log(logger.EXTREME, "Expunging tags from local database");
+ conn.getTagTable().expungeTag(guid.get(i), false);
+ }
+ guid = chunk.getExpungedSearches();
+ if (guid != null)
+ for (int i=0; i<guid.size() && keepRunning; i++) {
+ logger.log(logger.EXTREME, "Expunging saved search from local database");
+ conn.getSavedSearchTable().expungeSavedSearch(guid.get(i), false);
+ }
+ guid = chunk.getExpungedLinkedNotebooks();
+ if (guid != null)
+ for (int i=0; i<guid.size() && keepRunning; i++) {
+ logger.log(logger.EXTREME, "Expunging linked notebook from local database");
+ conn.getLinkedNotebookTable().expungeNotebook(guid.get(i), false);
+ }
+
+ }
+ // Sync remote tags
+ private void syncRemoteTags(List<Tag> tags) {
+ logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteTags");
+ if (tags != null) {
+ for (int i=0; i<tags.size() && keepRunning; i++) {
+ String oldGuid;
+ oldGuid = conn.getTagTable().findTagByName(tags.get(i).getName());
+ if (oldGuid != null && !tags.get(i).getGuid().equalsIgnoreCase(oldGuid))
+ conn.getTagTable().updateTagGuid(oldGuid, tags.get(i).getGuid());
+ conn.getTagTable().syncTag(tags.get(i), false);
+ }
+ }
+ logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteTags");
+ }
+ // Sync remote saved searches
+ private void syncRemoteSavedSearches(List<SavedSearch> searches) {
+ logger.log(logger.EXTREME, "Entering SyncRunner.syncSavedSearches");
+ if (searches != null) {
+ for (int i=0; i<searches.size() && keepRunning; i++) {
+ String oldGuid;
+ oldGuid = conn.getSavedSearchTable().findSavedSearchByName(searches.get(i).getName());
+ if (oldGuid != null && !searches.get(i).getGuid().equalsIgnoreCase(oldGuid))
+ conn.getSavedSearchTable().updateSavedSearchGuid(oldGuid, searches.get(i).getGuid());
+ conn.getSavedSearchTable().syncSavedSearch(searches.get(i), false);
+ }
+ }
+ logger.log(logger.EXTREME, "Leaving SyncRunner.syncSavedSearches");
+ }
+ // Sync remote linked notebooks
+ private void syncRemoteLinkedNotebooks(List<LinkedNotebook> books) {
+ logger.log(logger.EXTREME, "Entering SyncRunner.syncLinkedNotebooks");
+ if (books != null) {
+ for (int i=0; i<books.size() && keepRunning; i++) {
+ conn.getLinkedNotebookTable().updateNotebook(books.get(i), false);
+ }
+ }
+ logger.log(logger.EXTREME, "Leaving SyncRunner.syncLinkedNotebooks");
+ }
+ // Sync remote Notebooks 2
+ private void syncRemoteNotebooks(List<Notebook> notebooks) {
+ logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteNotebooks");
+ if (notebooks != null) {
+ for (int i=0; i<notebooks.size() && keepRunning; i++) {
+ String oldGuid;
+ oldGuid = conn.getNotebookTable().findNotebookByName(notebooks.get(i).getName());
+ if (oldGuid != null && !conn.getNotebookTable().isNotebookLocal(oldGuid) && !notebooks.get(i).getGuid().equalsIgnoreCase(oldGuid))
+ conn.getNotebookTable().updateNotebookGuid(oldGuid, notebooks.get(i).getGuid());
+ conn.getNotebookTable().syncNotebook(notebooks.get(i), false);
+
+ // Synchronize shared notebook information
+// if (notebooks.get(i).getSharedNotebookIdsSize() > 0) {
+// conn.getSharedNotebookTable().expungeNotebookByGuid(notebooks.get(i).getGuid(), false);
+// for (int j=0; j<notebooks.get(i).getSharedNotebookIdsSize(); j++) {
+// syncRemoteSharedNotebook(notebooks.get(i).getGuid(), notebooks.get(i).getSharedNotebookIds().get(j), authToken);
+// }
+// }
+ }
+ }
+ logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteNotebooks");
+ }
+ // Sync remote shared notebook
+// private void syncRemoteSharedNotebook(String guid, Long id, String token) {
+// List<SharedNotebook> books = noteStore.getSharedNotebookByAuth(authToken);
+// }
+ // Sync remote Resources
+ private void syncRemoteResources(Client noteStore, List<Resource> resource) {
+ logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteResources");
+ if (resource != null) {
+ for (int i=0; i<resource.size() && keepRunning; i++) {
+ syncRemoteResource(noteStore, resource.get(i), authToken);
+ }
+ }
+ logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteResources");
+ }
+ // Sync remote resource
+ private void syncRemoteResource(Client noteStore, Resource resource, String authToken) {
+ // This is how the logic for this works.
+ // 1.) If the resource is not in the local database, we add it.
+ // 2.) If a copy of the resource is in the local database and the note isn't dirty, we update the local copy
+ // 3.) If a copy of the resource is in the local databbase and it is dirty and the hash doesn't match, we ignore it because there
+ // is a conflict. The note conflict should get a copy of the resource at that time.
+
+ Note n = conn.getNoteTable().getNote(resource.getNoteGuid(), false, false, false, false, false);
+ if (n!=null) {
+ logger.log(logger.HIGH, "Resource for note " +n.getGuid() +" : " +n.getTitle());
+ }
+ boolean saveNeeded = false;
+ /* #1 */ Resource r = getEvernoteResource(noteStore, resource.getGuid(), true,true,true, authToken);
+ Resource l = conn.getNoteTable().noteResourceTable.getNoteResource(r.getGuid(), false);
+ if (l == null) {
+ logger.log(logger.HIGH, "Local resource not found");
+ saveNeeded = true;
+ } else {
+ /* #2 */ boolean isNoteDirty = conn.getNoteTable().isNoteDirty(r.getNoteGuid());
+ if (!isNoteDirty) {
+ logger.log(logger.HIGH, "Local resource found, but is not dirty");
+ saveNeeded = true;
+ } else {
+ /* #3 */ String remoteHash = "";
+ if (r != null && r.getData() != null && r.getData().getBodyHash() != null)
+ remoteHash = byteArrayToHexString(r.getData().getBodyHash());
+ String localHash = "";
+ if (l != null && l.getData() != null && l.getData().getBodyHash() != null)
+ remoteHash = byteArrayToHexString(l.getData().getBodyHash());
+
+ if (localHash.equalsIgnoreCase(remoteHash))
+ saveNeeded = true;
+ }
+ }
+
+ logger.log(logger.HIGH, "Resource save needed: " +saveNeeded);
+ if (saveNeeded)
+ conn.getNoteTable().noteResourceTable.updateNoteResource(r, false);
+ if (r.getMime().equalsIgnoreCase("application/vnd.evernote.ink"))
+ downloadInkNoteImage(r.getGuid(), authToken);
+
+
+ }
+ // Sync remote notes
+ private void syncRemoteNotes(Client noteStore, List<Note> note, boolean fullSync, String token) {
\r
- }\r
- // Sync remote tags\r
- private void syncRemoteTags(List<Tag> tags) {\r
- logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteTags");\r
- if (tags != null) {\r
- for (int i=0; i<tags.size() && keepRunning; i++) {\r
- String oldGuid;\r
- oldGuid = conn.getTagTable().findTagByName(tags.get(i).getName());\r
- if (oldGuid != null && !tags.get(i).getGuid().equalsIgnoreCase(oldGuid))\r
- conn.getTagTable().updateTagGuid(oldGuid, tags.get(i).getGuid());\r
- conn.getTagTable().syncTag(tags.get(i), false);\r
- }\r
- }\r
- logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteTags");\r
- }\r
- // Sync remote saved searches\r
- private void syncRemoteSavedSearches(List<SavedSearch> searches) {\r
- logger.log(logger.EXTREME, "Entering SyncRunner.syncSavedSearches");\r
- if (searches != null) {\r
- for (int i=0; i<searches.size() && keepRunning; i++) {\r
- String oldGuid;\r
- oldGuid = conn.getSavedSearchTable().findSavedSearchByName(searches.get(i).getName());\r
- if (oldGuid != null && !searches.get(i).getGuid().equalsIgnoreCase(oldGuid))\r
- conn.getSavedSearchTable().updateSavedSearchGuid(oldGuid, searches.get(i).getGuid());\r
- conn.getSavedSearchTable().syncSavedSearch(searches.get(i), false);\r
- }\r
- }\r
- logger.log(logger.EXTREME, "Leaving SyncRunner.syncSavedSearches");\r
- }\r
- // Sync remote linked notebooks\r
- private void syncRemoteLinkedNotebooks(List<LinkedNotebook> books) {\r
- logger.log(logger.EXTREME, "Entering SyncRunner.syncLinkedNotebooks");\r
- if (books != null) {\r
- for (int i=0; i<books.size() && keepRunning; i++) {\r
- conn.getLinkedNotebookTable().updateNotebook(books.get(i), false); \r
- }\r
- }\r
- logger.log(logger.EXTREME, "Leaving SyncRunner.syncLinkedNotebooks");\r
- }\r
- // Sync remote Notebooks 2\r
- private void syncRemoteNotebooks(List<Notebook> notebooks) {\r
- logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteNotebooks");\r
- if (notebooks != null) {\r
- for (int i=0; i<notebooks.size() && keepRunning; i++) {\r
- String oldGuid;\r
- oldGuid = conn.getNotebookTable().findNotebookByName(notebooks.get(i).getName());\r
- if (oldGuid != null && !conn.getNotebookTable().isNotebookLocal(oldGuid) && !notebooks.get(i).getGuid().equalsIgnoreCase(oldGuid))\r
- conn.getNotebookTable().updateNotebookGuid(oldGuid, notebooks.get(i).getGuid());\r
- conn.getNotebookTable().syncNotebook(notebooks.get(i), false); \r
- \r
- // Synchronize shared notebook information\r
-// if (notebooks.get(i).getSharedNotebookIdsSize() > 0) {\r
-// conn.getSharedNotebookTable().expungeNotebookByGuid(notebooks.get(i).getGuid(), false);\r
-// for (int j=0; j<notebooks.get(i).getSharedNotebookIdsSize(); j++) {\r
-// syncRemoteSharedNotebook(notebooks.get(i).getGuid(), notebooks.get(i).getSharedNotebookIds().get(j), authToken);\r
-// }\r
-// }\r
- }\r
- } \r
- logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteNotebooks");\r
- }\r
- // Sync remote shared notebook\r
-// private void syncRemoteSharedNotebook(String guid, Long id, String token) {\r
-// List<SharedNotebook> books = noteStore.getSharedNotebookByAuth(authToken);\r
-// }\r
- // Sync remote Resources\r
- private void syncRemoteResources(Client noteStore, List<Resource> resource) {\r
- logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteResources");\r
- if (resource != null) {\r
- for (int i=0; i<resource.size() && keepRunning; i++) {\r
- syncRemoteResource(noteStore, resource.get(i), authToken);\r
- }\r
- }\r
- logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteResources");\r
- }\r
- // Sync remote resource\r
- private void syncRemoteResource(Client noteStore, Resource resource, String authToken) {\r
- // This is how the logic for this works.\r
- // 1.) If the resource is not in the local database, we add it.\r
- // 2.) If a copy of the resource is in the local database and the note isn't dirty, we update the local copy\r
- // 3.) If a copy of the resource is in the local databbase and it is dirty and the hash doesn't match, we ignore it because there\r
- // is a conflict. The note conflict should get a copy of the resource at that time.\r
- \r
- Note n = conn.getNoteTable().getNote(resource.getNoteGuid(), false, false, false, false, false);\r
- if (n!=null) {\r
- logger.log(logger.HIGH, "Resource for note " +n.getGuid() +" : " +n.getTitle());\r
- }\r
- boolean saveNeeded = false;\r
- /* #1 */ Resource r = getEvernoteResource(noteStore, resource.getGuid(), true,true,true, authToken);\r
- Resource l = conn.getNoteTable().noteResourceTable.getNoteResource(r.getGuid(), false);\r
- if (l == null) {\r
- logger.log(logger.HIGH, "Local resource not found");\r
- saveNeeded = true;\r
- } else {\r
- /* #2 */ boolean isNoteDirty = conn.getNoteTable().isNoteDirty(r.getNoteGuid());\r
- if (!isNoteDirty) {\r
- logger.log(logger.HIGH, "Local resource found, but is not dirty");\r
- saveNeeded = true;\r
- } else {\r
- /* #3 */ String remoteHash = "";\r
- if (r != null && r.getData() != null && r.getData().getBodyHash() != null)\r
- remoteHash = byteArrayToHexString(r.getData().getBodyHash());\r
- String localHash = "";\r
- if (l != null && l.getData() != null && l.getData().getBodyHash() != null)\r
- remoteHash = byteArrayToHexString(l.getData().getBodyHash());\r
- \r
- if (localHash.equalsIgnoreCase(remoteHash))\r
- saveNeeded = true;\r
- }\r
- }\r
- \r
- logger.log(logger.HIGH, "Resource save needed: " +saveNeeded);\r
- if (saveNeeded) \r
- conn.getNoteTable().noteResourceTable.updateNoteResource(r, false);\r
- if (r.getMime().equalsIgnoreCase("application/vnd.evernote.ink"))\r
- downloadInkNoteImage(r.getGuid(), authToken);\r
- \r
-\r
- }\r
- // Sync remote notes\r
- private void syncRemoteNotes(Client noteStore, List<Note> note, boolean fullSync, String token) {\r
-\r
- if (note != null) {\r
+ if (note != null) {
\r
logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteNotes");\r
logger.log(logger.LOW, "Local Dirty Notes: ");\r
}\r
logger.log(logger.LOW, "---");\r
\r
- for (int i=0; i<note.size() && keepRunning; i++) {\r
- Note n = getEvernoteNote(noteStore, note.get(i).getGuid(), true, fullSync, true,true, token);\r
- syncRemoteNote(n, fullSync, token);\r
- }\r
- }\r
- logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteNotes");\r
- }\r
- private void syncRemoteNote(Note n, boolean fullSync, String token) {\r
- if (n!=null) {\r
- \r
- // Basically, this is how the sync logic for a note works.\r
- // If the remote note has changed and the local has not, we\r
- // accept the change.\r
- // If both the local & remote have changed but the sequence\r
- // numbers are the same, we don't accept the change. This\r
- // seems to happen when attachments are indexed by the server.\r
- // If both the local & remote have changed and the sequence numbers\r
- // are different we move the local copy to a local notebook (making sure\r
- // to copy all resources) and we accept the new one. \r
- boolean conflictingNote = true;\r
+ for (int i=0; i<note.size() && keepRunning; i++) {
+ Note n = getEvernoteNote(noteStore, note.get(i).getGuid(), true, fullSync, true,true, token);
+ syncRemoteNote(n, fullSync, token);
+ }
+ }
+ logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteNotes");
+ }
+ private void syncRemoteNote(Note n, boolean fullSync, String token) {
+ if (n!=null) {
+
+ // Basically, this is how the sync logic for a note works.
+ // If the remote note has changed and the local has not, we
+ // accept the change.
+ // If both the local & remote have changed but the sequence
+ // numbers are the same, we don't accept the change. This
+ // seems to happen when attachments are indexed by the server.
+ // If both the local & remote have changed and the sequence numbers
+ // are different we move the local copy to a local notebook (making sure
+ // to copy all resources) and we accept the new one.
+ boolean conflictingNote = true;
logger.log(logger.EXTREME, "Checking for duplicate note " +n.getGuid() +" : " +n.getTitle());\r
- if (dirtyNoteGuids != null && dirtyNoteGuids.contains(n.getGuid())) { \r
- logger.log(logger.EXTREME, "Conflict check beginning");\r
- conflictingNote = checkForConflict(n);\r
- logger.log(logger.EXTREME, "Conflict check results " +conflictingNote);\r
- if (conflictingNote)\r
- moveConflictingNote(n.getGuid());\r
- }\r
- boolean ignoreNote = false;\r
- if (ignoreNotebooks.contains(n.getNotebookGuid()))\r
- ignoreNote = true;\r
- for (int i=0; i<n.getTagGuidsSize(); i++) {\r
- if (ignoreTags.contains(n.getTagGuids().get(i))) {\r
- ignoreNote = true;\r
- i=n.getTagGuidsSize();\r
- }\r
- }\r
- \r
- if ((conflictingNote || fullSync) && !ignoreNote) {\r
- logger.log(logger.EXTREME, "Saving Note");\r
- conn.getNoteTable().syncNote(n);\r
- // The following was commented out because it caused a race condition on the database where resources \r
- // may be lost. We do the same thing elsewhere;.\r
-// noteSignal.noteChanged.emit(n.getGuid(), null); // Signal to ivalidate note cache \r
- noteSignal.noteDownloaded.emit(n, true); // Signal to add note to index\r
- logger.log(logger.EXTREME, "Note Saved");\r
- if (fullSync && n.getResources() != null) {\r
- for (int q=0; q<n.getResources().size() && keepRunning; q++) {\r
- logger.log(logger.EXTREME, "Getting note resources.");\r
- conn.getNoteTable().noteResourceTable.updateNoteResource(n.getResources().get(q), false);\r
- if (n.getResources().get(q).getMime().equalsIgnoreCase("application/vnd.evernote.ink"))\r
- downloadInkNoteImage(n.getResources().get(q).getGuid(), token);\r
- }\r
- }\r
- }\r
- }\r
- }\r
- private Note getEvernoteNote(Client noteStore, String guid, boolean withContent, boolean withResourceData, boolean withResourceRecognition, boolean withResourceAlternateData, String token) { \r
- Note n = null;\r
- try {\r
- logger.log(logger.EXTREME, "Retrieving note " +guid);\r
- n = noteStore.getNote(token, guid, withContent, withResourceData, withResourceRecognition, withResourceAlternateData);\r
- logger.log(logger.EXTREME, "Note " +guid +" has been retrieved.");\r
- } catch (EDAMUserException e) {\r
- logger.log(logger.LOW, "*** EDAM User Excepton getEvernoteNote");\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- e.printStackTrace();\r
- } catch (EDAMSystemException e) {\r
- logger.log(logger.LOW, "*** EDAM System Excepton getEvernoteNote");\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- e.printStackTrace();\r
- } catch (EDAMNotFoundException e) {\r
- logger.log(logger.LOW, "*** EDAM Not Found Excepton getEvernoteNote");\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- e.printStackTrace();\r
- } catch (TException e) {\r
- logger.log(logger.LOW, "*** EDAM TExcepton getEvernoteNote");\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- e.printStackTrace();\r
- }\r
- return n;\r
- }\r
- private Resource getEvernoteResource(Client noteStore, String guid, boolean withData, boolean withRecognition, boolean withAttributes, String token) { \r
- Resource n = null;\r
- try {\r
- logger.log(logger.EXTREME, "Retrieving resource " +guid);\r
- n = noteStore.getResource(token, guid, withData, withRecognition, withAttributes, withAttributes);\r
- logger.log(logger.EXTREME, "Resource " +guid +" has been retrieved.");\r
- } catch (EDAMUserException e) {\r
- logger.log(logger.LOW, "*** EDAM User Excepton getEvernoteNote");\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- e.printStackTrace();\r
- } catch (EDAMSystemException e) {\r
- logger.log(logger.LOW, "*** EDAM System Excepton getEvernoteNote");\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- e.printStackTrace();\r
- } catch (EDAMNotFoundException e) {\r
- logger.log(logger.LOW, "*** EDAM Not Found Excepton getEvernoteNote");\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- e.printStackTrace();\r
- } catch (TException e) {\r
- logger.log(logger.LOW, "*** EDAM TExcepton getEvernoteNote");\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- e.printStackTrace();\r
- }\r
- return n;\r
- }\r
-\r
- \r
- private boolean checkForConflict(Note n) {\r
- logger.log(logger.EXTREME, "Checking note sequence number " +n.getGuid());\r
- Note oldNote = conn.getNoteTable().getNote(n.getGuid(), false, false, false, false, false);\r
- logger.log(logger.EXTREME, "Local/Remote sequence numbers: " +oldNote.getUpdateSequenceNum()+"/"+n.getUpdateSequenceNum());\r
+ if (dirtyNoteGuids != null && dirtyNoteGuids.contains(n.getGuid())) {
+ logger.log(logger.EXTREME, "Conflict check beginning");
+ conflictingNote = checkForConflict(n);
+ logger.log(logger.EXTREME, "Conflict check results " +conflictingNote);
+ if (conflictingNote)
+ moveConflictingNote(n.getGuid());
+ }
+ boolean ignoreNote = false;
+ if (ignoreNotebooks.contains(n.getNotebookGuid()))
+ ignoreNote = true;
+ for (int i=0; i<n.getTagGuidsSize(); i++) {
+ if (ignoreTags.contains(n.getTagGuids().get(i))) {
+ ignoreNote = true;
+ i=n.getTagGuidsSize();
+ }
+ }
+
+ if ((conflictingNote || fullSync) && !ignoreNote) {
+ logger.log(logger.EXTREME, "Saving Note");
+ conn.getNoteTable().syncNote(n);
+ // The following was commented out because it caused a race condition on the database where resources
+ // may be lost. We do the same thing elsewhere;.
+// noteSignal.noteChanged.emit(n.getGuid(), null); // Signal to ivalidate note cache
+ noteSignal.noteDownloaded.emit(n, true); // Signal to add note to index
+ logger.log(logger.EXTREME, "Note Saved");
+ if (fullSync && n.getResources() != null) {
+ for (int q=0; q<n.getResources().size() && keepRunning; q++) {
+ logger.log(logger.EXTREME, "Getting note resources.");
+ conn.getNoteTable().noteResourceTable.updateNoteResource(n.getResources().get(q), false);
+ if (n.getResources().get(q).getMime().equalsIgnoreCase("application/vnd.evernote.ink"))
+ downloadInkNoteImage(n.getResources().get(q).getGuid(), token);
+ }
+ }
+ }
+ }
+ }
+ private Note getEvernoteNote(Client noteStore, String guid, boolean withContent, boolean withResourceData, boolean withResourceRecognition, boolean withResourceAlternateData, String token) {
+ Note n = null;
+ try {
+ logger.log(logger.EXTREME, "Retrieving note " +guid);
+ n = noteStore.getNote(token, guid, withContent, withResourceData, withResourceRecognition, withResourceAlternateData);
+ logger.log(logger.EXTREME, "Note " +guid +" has been retrieved.");
+ } catch (EDAMUserException e) {
+ logger.log(logger.LOW, "*** EDAM User Excepton getEvernoteNote");
+ logger.log(logger.LOW, e.toString());
+ error = true;
+ e.printStackTrace();
+ } catch (EDAMSystemException e) {
+ logger.log(logger.LOW, "*** EDAM System Excepton getEvernoteNote");
+ logger.log(logger.LOW, e.toString());
+ error = true;
+ e.printStackTrace();
+ } catch (EDAMNotFoundException e) {
+ logger.log(logger.LOW, "*** EDAM Not Found Excepton getEvernoteNote");
+ logger.log(logger.LOW, e.toString());
+ error = true;
+ e.printStackTrace();
+ } catch (TException e) {
+ logger.log(logger.LOW, "*** EDAM TExcepton getEvernoteNote");
+ logger.log(logger.LOW, e.toString());
+ error = true;
+ e.printStackTrace();
+ }
+ return n;
+ }
+ private Resource getEvernoteResource(Client noteStore, String guid, boolean withData, boolean withRecognition, boolean withAttributes, String token) {
+ Resource n = null;
+ try {
+ logger.log(logger.EXTREME, "Retrieving resource " +guid);
+ n = noteStore.getResource(token, guid, withData, withRecognition, withAttributes, withAttributes);
+ logger.log(logger.EXTREME, "Resource " +guid +" has been retrieved.");
+ } catch (EDAMUserException e) {
+ logger.log(logger.LOW, "*** EDAM User Excepton getEvernoteNote");
+ logger.log(logger.LOW, e.toString());
+ error = true;
+ e.printStackTrace();
+ } catch (EDAMSystemException e) {
+ logger.log(logger.LOW, "*** EDAM System Excepton getEvernoteNote");
+ logger.log(logger.LOW, e.toString());
+ error = true;
+ e.printStackTrace();
+ } catch (EDAMNotFoundException e) {
+ logger.log(logger.LOW, "*** EDAM Not Found Excepton getEvernoteNote");
+ logger.log(logger.LOW, e.toString());
+ error = true;
+ e.printStackTrace();
+ } catch (TException e) {
+ logger.log(logger.LOW, "*** EDAM TExcepton getEvernoteNote");
+ logger.log(logger.LOW, e.toString());
+ error = true;
+ e.printStackTrace();
+ }
+ return n;
+ }
+
+
+ private boolean checkForConflict(Note n) {
+ logger.log(logger.EXTREME, "Checking note sequence number " +n.getGuid());
+ Note oldNote = conn.getNoteTable().getNote(n.getGuid(), false, false, false, false, false);
+ logger.log(logger.EXTREME, "Local/Remote sequence numbers: " +oldNote.getUpdateSequenceNum()+"/"+n.getUpdateSequenceNum());
logger.log(logger.LOW, "Remote Note Title:" +n.getTitle());\r
logger.log(logger.LOW, "Local Note Title:" +oldNote.getTitle());\r
if (oldNote.getUpdateSequenceNum() == n.getUpdateSequenceNum()) {\r
} \r
boolean oldIsDirty = conn.getNoteTable().isNoteDirty(n.getGuid());\r
if (!oldIsDirty) \r
- return false;\r
- return true;\r
- }\r
- \r
- private void moveConflictingNote(String guid) {\r
- logger.log(logger.EXTREME, "Conflicting change found for note " +guid);\r
- List<Notebook> books = conn.getNotebookTable().getAllLocal();\r
- String notebookGuid = null;\r
- for (int i=0; i<books.size() && keepRunning; i++) {\r
- if (books.get(i).getName().equalsIgnoreCase("Conflicting Changes (local)") ||\r
- books.get(i).getName().equalsIgnoreCase("Conflicting Changes")) {\r
- notebookGuid = books.get(i).getGuid();\r
- i=books.size();\r
- }\r
- }\r
- \r
- if (notebookGuid == null) {\r
- logger.log(logger.EXTREME, "Building conflicting change notebook " +guid);\r
- Calendar currentTime = new GregorianCalendar();\r
- Long l = new Long(currentTime.getTimeInMillis());\r
- long prevTime = l;\r
- while (prevTime==l) {\r
- currentTime = new GregorianCalendar();\r
- l=currentTime.getTimeInMillis();\r
- }\r
- String randint = new String(Long.toString(l));\r
- \r
- Notebook newBook = new Notebook();\r
- newBook.setUpdateSequenceNum(0);\r
- newBook.setGuid(randint);\r
- newBook.setName("Conflicting Changes");\r
- newBook.setServiceCreated(new Date().getTime());\r
- newBook.setServiceUpdated(new Date().getTime());\r
- newBook.setDefaultNotebook(false);\r
- newBook.setPublished(false);\r
- \r
- conn.getNotebookTable().addNotebook(newBook, false, true);\r
- notebookSignal.listChanged.emit();\r
- notebookGuid = newBook.getGuid();\r
- refreshNeeded = true;\r
- }\r
- \r
- // Now that we have a good notebook guid, we need to move the conflicting note\r
- // to the local notebook\r
- logger.log(logger.EXTREME, "Moving conflicting note " +guid);\r
- Calendar currentTime = new GregorianCalendar();\r
- Long l = new Long(currentTime.getTimeInMillis());\r
- long prevTime = l;\r
- while (prevTime==l) {\r
- currentTime = new GregorianCalendar();\r
- l = currentTime.getTimeInMillis();\r
- }\r
- String newGuid = new String(Long.toString(l));\r
- \r
- Note oldNote = conn.getNoteTable().getNote(guid, true, true, false, false, false);\r
- for (int i=0; i<oldNote.getResources().size() && keepRunning; i++) {\r
- l = new Long(currentTime.getTimeInMillis());\r
- String newResG = new String(Long.toString(l));\r
- String oldResG = oldNote.getResources().get(i).getGuid();\r
- conn.getNoteTable().noteResourceTable.resetUpdateSequenceNumber(oldResG, true);\r
- conn.getNoteTable().noteResourceTable.updateNoteResourceGuid(oldResG, newResG, true);\r
- }\r
- \r
- conn.getNoteTable().resetNoteSequence(guid);\r
- conn.getNoteTable().updateNoteGuid(guid, newGuid);\r
- conn.getNoteTable().updateNoteNotebook(newGuid, notebookGuid, true);\r
- \r
- noteSignal.notebookChanged.emit(newGuid, notebookGuid);\r
- refreshNeeded = true;\r
- noteSignal.guidChanged.emit(guid,newGuid);\r
- }\r
- \r
-\r
-\r
- \r
- //******************************************************\r
- //******************************************************\r
- //** Utility Functions\r
- //******************************************************\r
- //******************************************************\r
- // Convert a byte array to a hex string\r
- private static String byteArrayToHexString(byte data[]) {\r
- StringBuffer buf = new StringBuffer();\r
- for (byte element : data) {\r
- int halfbyte = (element >>> 4) & 0x0F;\r
- int two_halfs = 0;\r
- do {\r
- if ((0 <= halfbyte) && (halfbyte <= 9))\r
- buf.append((char) ('0' + halfbyte));\r
- else\r
- buf.append((char) ('a' + (halfbyte - 10)));\r
- halfbyte = element & 0x0F;\r
- } while(two_halfs++ < 1);\r
- }\r
- return buf.toString(); \r
- }\r
-\r
- \r
- \r
- //*******************************************************\r
- //* Find dirty tags, which do not have newly created parents\r
- //*******************************************************\r
- private Tag findNextTag() {\r
- logger.log(logger.HIGH, "Entering SyncRunner.findNextTag");\r
- Tag nextTag = null;\r
- List<Tag> tags = conn.getTagTable().getDirty();\r
- \r
- // Find the parent. If the parent has a sequence > 0 then it is a good\r
- // parent.\r
- for (int i=0; i<tags.size() && keepRunning; i++) {\r
- if (!badTagSync.containsKey(tags.get(i).getGuid())) {\r
- if (tags.get(i).getParentGuid() == null) {\r
- logger.log(logger.HIGH, "Leaving SyncRunner.findNextTag - tag found without parent");\r
- return tags.get(i);\r
- }\r
- Tag parentTag = conn.getTagTable().getTag(tags.get(i).getParentGuid());\r
- if (parentTag.getUpdateSequenceNum() > 0) {\r
- logger.log(logger.HIGH, "Leaving SyncRunner.findNextTag - tag found");\r
- return tags.get(i);\r
- }\r
- }\r
- }\r
- \r
- logger.log(logger.HIGH, "Leaving SyncRunner.findNextTag - no tags returned");\r
- return nextTag;\r
- }\r
- \r
- \r
- // Connect to Evernote\r
- public boolean enConnect() {\r
- try {\r
- userStoreTrans = new THttpClient(userStoreUrl);\r
- userStoreTrans.setCustomHeader("User-Agent", userAgent);\r
- } catch (TTransportException e) {\r
- QMessageBox mb = new QMessageBox(QMessageBox.Icon.Critical, "Transport Excepton", e.getLocalizedMessage());\r
- mb.exec();\r
- e.printStackTrace();\r
- }\r
- userStoreProt = new TBinaryProtocol(userStoreTrans);\r
- userStore = new UserStore.Client(userStoreProt, userStoreProt);\r
- syncSignal.saveUserStore.emit(userStore);\r
- try {\r
- //authResult = userStore.authenticate(username, password, consumerKey, consumerSecret);\r
- user = userStore.getUser(authToken);\r
- } catch (EDAMUserException e) {\r
- QMessageBox mb = new QMessageBox(QMessageBox.Icon.Critical, "Error", "Invalid Authorization");\r
- mb.exec();\r
- isConnected = false;\r
- return false;\r
- } catch (EDAMSystemException e) {\r
- QMessageBox mb = new QMessageBox(QMessageBox.Icon.Critical, "EDAM System Excepton", e.getLocalizedMessage());\r
- mb.exec();\r
- e.printStackTrace();\r
- isConnected = false;\r
- } catch (TException e) {\r
- QMessageBox mb = new QMessageBox(QMessageBox.Icon.Critical, "Transport Excepton", e.getLocalizedMessage());\r
- mb.exec();\r
- e.printStackTrace();\r
- isConnected = false;\r
- }\r
- \r
- boolean versionOk = false;\r
- try {\r
- versionOk = userStore.checkVersion("NixNote", \r
- com.evernote.edam.userstore.Constants.EDAM_VERSION_MAJOR, \r
- com.evernote.edam.userstore.Constants.EDAM_VERSION_MINOR);\r
- } catch (TException e) {\r
- e.printStackTrace();\r
- isConnected = false;\r
- } \r
- if (!versionOk) { \r
- System.err.println("Incomatible EDAM client protocol version"); \r
- isConnected = false;\r
- }\r
- //if (authResult != null) {\r
- //user = authResult.getUser(); \r
- //authToken = authResult.getAuthenticationToken(); \r
+ return false;
+ return true;
+ }
+
+ private void moveConflictingNote(String guid) {
+ logger.log(logger.EXTREME, "Conflicting change found for note " +guid);
+ List<Notebook> books = conn.getNotebookTable().getAllLocal();
+ String notebookGuid = null;
+ for (int i=0; i<books.size() && keepRunning; i++) {
+ if (books.get(i).getName().equalsIgnoreCase("Conflicting Changes (local)") ||
+ books.get(i).getName().equalsIgnoreCase("Conflicting Changes")) {
+ notebookGuid = books.get(i).getGuid();
+ i=books.size();
+ }
+ }
+
+ if (notebookGuid == null) {
+ logger.log(logger.EXTREME, "Building conflicting change notebook " +guid);
+ Calendar currentTime = new GregorianCalendar();
+ Long l = new Long(currentTime.getTimeInMillis());
+ long prevTime = l;
+ while (prevTime==l) {
+ currentTime = new GregorianCalendar();
+ l=currentTime.getTimeInMillis();
+ }
+ String randint = new String(Long.toString(l));
+
+ Notebook newBook = new Notebook();
+ newBook.setUpdateSequenceNum(0);
+ newBook.setGuid(randint);
+ newBook.setName("Conflicting Changes");
+ newBook.setServiceCreated(new Date().getTime());
+ newBook.setServiceUpdated(new Date().getTime());
+ newBook.setDefaultNotebook(false);
+ newBook.setPublished(false);
+
+ conn.getNotebookTable().addNotebook(newBook, false, true);
+ notebookSignal.listChanged.emit();
+ notebookGuid = newBook.getGuid();
+ refreshNeeded = true;
+ }
+
+ // Now that we have a good notebook guid, we need to move the conflicting note
+ // to the local notebook
+ logger.log(logger.EXTREME, "Moving conflicting note " +guid);
+ Calendar currentTime = new GregorianCalendar();
+ Long l = new Long(currentTime.getTimeInMillis());
+ long prevTime = l;
+ while (prevTime==l) {
+ currentTime = new GregorianCalendar();
+ l = currentTime.getTimeInMillis();
+ }
+ String newGuid = new String(Long.toString(l));
+
+ Note oldNote = conn.getNoteTable().getNote(guid, true, true, false, false, false);
+ for (int i=0; i<oldNote.getResources().size() && keepRunning; i++) {
+ l = new Long(currentTime.getTimeInMillis());
+ String newResG = new String(Long.toString(l));
+ String oldResG = oldNote.getResources().get(i).getGuid();
+ conn.getNoteTable().noteResourceTable.resetUpdateSequenceNumber(oldResG, true);
+ conn.getNoteTable().noteResourceTable.updateNoteResourceGuid(oldResG, newResG, true);
+ }
+
+ conn.getNoteTable().resetNoteSequence(guid);
+ conn.getNoteTable().updateNoteGuid(guid, newGuid);
+ conn.getNoteTable().updateNoteNotebook(newGuid, notebookGuid, true);
+
+ noteSignal.notebookChanged.emit(newGuid, notebookGuid);
+ refreshNeeded = true;
+ noteSignal.guidChanged.emit(guid,newGuid);
+ }
+
+
+
+
+ //******************************************************
+ //******************************************************
+ //** Utility Functions
+ //******************************************************
+ //******************************************************
+ // Convert a byte array to a hex string
+ private static String byteArrayToHexString(byte data[]) {
+ StringBuffer buf = new StringBuffer();
+ for (byte element : data) {
+ int halfbyte = (element >>> 4) & 0x0F;
+ int two_halfs = 0;
+ do {
+ if ((0 <= halfbyte) && (halfbyte <= 9))
+ buf.append((char) ('0' + halfbyte));
+ else
+ buf.append((char) ('a' + (halfbyte - 10)));
+ halfbyte = element & 0x0F;
+ } while(two_halfs++ < 1);
+ }
+ return buf.toString();
+ }
+
+
+
+ //*******************************************************
+ //* Find dirty tags, which do not have newly created parents
+ //*******************************************************
+ private Tag findNextTag() {
+ logger.log(logger.HIGH, "Entering SyncRunner.findNextTag");
+ Tag nextTag = null;
+ List<Tag> tags = conn.getTagTable().getDirty();
+
+ // Find the parent. If the parent has a sequence > 0 then it is a good
+ // parent.
+ for (int i=0; i<tags.size() && keepRunning; i++) {
+ if (!badTagSync.containsKey(tags.get(i).getGuid())) {
+ if (tags.get(i).getParentGuid() == null) {
+ logger.log(logger.HIGH, "Leaving SyncRunner.findNextTag - tag found without parent");
+ return tags.get(i);
+ }
+ Tag parentTag = conn.getTagTable().getTag(tags.get(i).getParentGuid());
+ if (parentTag.getUpdateSequenceNum() > 0) {
+ logger.log(logger.HIGH, "Leaving SyncRunner.findNextTag - tag found");
+ return tags.get(i);
+ }
+ }
+ }
+
+ logger.log(logger.HIGH, "Leaving SyncRunner.findNextTag - no tags returned");
+ return nextTag;
+ }
+
+
+ // Connect to Evernote
+ public boolean enConnect() {
+ try {
+ userStoreTrans = new THttpClient(userStoreUrl);
+ userStoreTrans.setCustomHeader("User-Agent", userAgent);
+ } catch (TTransportException e) {
+ QMessageBox mb = new QMessageBox(QMessageBox.Icon.Critical, "Transport Excepton", e.getLocalizedMessage());
+ mb.exec();
+ e.printStackTrace();
+ }
+ userStoreProt = new TBinaryProtocol(userStoreTrans);
+ userStore = new UserStore.Client(userStoreProt, userStoreProt);
+ syncSignal.saveUserStore.emit(userStore);
+ try {
+ //authResult = userStore.authenticate(username, password, consumerKey, consumerSecret);
+ user = userStore.getUser(authToken);
+ } catch (EDAMUserException e) {
+ QMessageBox mb = new QMessageBox(QMessageBox.Icon.Critical, "Error", "Invalid Authorization");
+ mb.exec();
+ isConnected = false;
+ return false;
+ } catch (EDAMSystemException e) {
+ QMessageBox mb = new QMessageBox(QMessageBox.Icon.Critical, "EDAM System Excepton", e.getLocalizedMessage());
+ mb.exec();
+ e.printStackTrace();
+ isConnected = false;
+ } catch (TException e) {
+ QMessageBox mb = new QMessageBox(QMessageBox.Icon.Critical, "Transport Excepton", e.getLocalizedMessage());
+ mb.exec();
+ e.printStackTrace();
+ isConnected = false;
+ }
+
+ boolean versionOk = false;
+ try {
+ versionOk = userStore.checkVersion("NeighborNote",
+ com.evernote.edam.userstore.Constants.EDAM_VERSION_MAJOR,
+ com.evernote.edam.userstore.Constants.EDAM_VERSION_MINOR);
+ } catch (TException e) {
+ e.printStackTrace();
+ isConnected = false;
+ }
+ if (!versionOk) {
+ System.err.println("Incomatible EDAM client protocol version");
+ isConnected = false;
+ }
+ //if (authResult != null) {
+ //user = authResult.getUser();
+ //authToken = authResult.getAuthenticationToken();
if (user == null || noteStoreUrlBase == null) {\r
logger.log(logger.LOW, "Error retrieving user information. Aborting.");\r
System.err.println("Error retrieving user information.");\r
return false;\r
\r
}\r
- noteStoreUrl = noteStoreUrlBase + user.getShardId();\r
- syncSignal.saveAuthToken.emit(authToken);\r
- syncSignal.saveNoteStore.emit(localNoteStore);\r
- \r
- \r
- try {\r
- noteStoreTrans = new THttpClient(noteStoreUrl);\r
- noteStoreTrans.setCustomHeader("User-Agent", userAgent);\r
- } catch (TTransportException e) {\r
- QMessageBox mb = new QMessageBox(QMessageBox.Icon.Critical, "Transport Excepton", e.getLocalizedMessage());\r
- mb.exec();\r
- e.printStackTrace();\r
- isConnected = false;\r
- } \r
- noteStoreProt = new TBinaryProtocol(noteStoreTrans);\r
- localNoteStore = \r
- new NoteStore.Client(noteStoreProt, noteStoreProt); \r
- isConnected = true;\r
- //authTimeRemaining = authResult.getExpiration() - authResult.getCurrentTime();\r
- //authRefreshTime = authTimeRemaining / 2;\r
- //}\r
- \r
- // Get user information\r
- try {\r
- User user = userStore.getUser(authToken);\r
- syncSignal.saveUserInformation.emit(user);\r
- } catch (EDAMUserException e1) {\r
- e1.printStackTrace();\r
- } catch (EDAMSystemException e1) {\r
- e1.printStackTrace();\r
- } catch (TException e1) {\r
- e1.printStackTrace();\r
- }\r
- \r
- return isConnected;\r
- }\r
- // Disconnect from the database \r
- public void enDisconnect() {\r
- isConnected = false;\r
- }\r
- \r
- /*\r
- // Refresh the connection\r
- private synchronized boolean refreshConnection() {\r
- \r
- logger.log(logger.EXTREME, "Entering SyncRunner.refreshConnection()");\r
-// Calendar cal = Calendar.getInstance();\r
- \r
- // If we are not connected let's get out of here\r
- if (!isConnected)\r
- return false;\r
- \r
- // If we fail too many times, then let's give up.\r
- if (failedRefreshes >=5) {\r
- logger.log(logger.EXTREME, "Refresh attempts have failed. Disconnecting.");\r
- isConnected = false;\r
- status.message.emit(tr("Unable to synchronize - Authentication failed"));\r
- return false;\r
- }\r
- \r
- // If this is the first time through, then we need to set this\r
-// if (authRefreshTime == 0 || cal.getTimeInMillis() > authRefreshTime) \r
-// authRefreshTime = cal.getTimeInMillis();\r
- \r
- // // Default to checking again in 5 min. This in case we fail.\r
- // authRefreshTime = authRefreshTime +(5*60*1000); \r
-\r
- // Try to get a new token\r
- AuthenticationResult newAuth = null; \r
- logger.log(logger.EXTREME, "Beginning to try authentication refresh");\r
- try {\r
- if (userStore != null && authToken != null) \r
- newAuth = userStore.refreshAuthentication(authToken); \r
- else\r
- return false;\r
- logger.log(logger.EXTREME, "UserStore.refreshAuthentication has succeeded.");\r
- } catch (EDAMUserException e) {\r
- e.printStackTrace();\r
- syncSignal.authRefreshComplete.emit(false);\r
- failedRefreshes++;\r
- return false;\r
- } catch (EDAMSystemException e) {\r
- e.printStackTrace();\r
- syncSignal.authRefreshComplete.emit(false);\r
- failedRefreshes++;\r
- return false; \r
- } catch (TException e) { \r
- e.printStackTrace();\r
- syncSignal.authRefreshComplete.emit(false);\r
- failedRefreshes++;\r
- return false;\r
- }\r
- \r
- // If we didn't get a good auth, then we've failed\r
- if (newAuth == null) {\r
- failedRefreshes++;\r
- status.message.emit(tr("Unable to synchronize - Authentication failed"));\r
- logger.log(logger.EXTREME, "Authentication failure #" +failedRefreshes);\r
- status.message.emit(tr("Unable to synchronize - Authentication failed"));\r
- syncSignal.authRefreshComplete.emit(false);\r
- return false;\r
- }\r
- \r
- // We got a good token. Now we need to setup the time to renew it.\r
- logger.log(logger.EXTREME, "Saving authentication tokens");\r
- authResult = newAuth;\r
- authToken = new String(newAuth.getAuthenticationToken());\r
-// authTimeRemaining = authResult.getExpiration() - authResult.getCurrentTime();\r
-// authRefreshTime = cal.getTimeInMillis() + (authTimeRemaining/4); \r
- failedRefreshes=0;\r
- syncSignal.authRefreshComplete.emit(true);\r
- authRefreshNeeded = false;\r
- \r
- // This should never happen, but if it does we consider this a faild attempt.\r
-// if (authTimeRemaining <= 0) {\r
-// failedRefreshes++;\r
-// syncSignal.authRefreshComplete.emit(false);\r
-// }\r
- \r
- return true;\r
- }\r
- \r
- */\r
- \r
- public synchronized boolean addWork(String request) {\r
- if (workQueue.offer(request))\r
- return true;\r
- return false;\r
- }\r
- \r
- private Note getNoteContent(Note n) {\r
- QTextCodec codec = QTextCodec.codecForLocale();\r
- codec = QTextCodec.codecForName("UTF-8");\r
- n.setContent(codec.toUnicode(new QByteArray(n.getContent())));\r
- return n;\r
- }\r
-\r
-\r
-\r
- //*********************************************************\r
- //* Special download instructions. Used for DB upgrades\r
- //*********************************************************\r
- private void downloadAllSharedNotebooks(Client noteStore) {\r
- try {\r
- List<SharedNotebook> books = noteStore.listSharedNotebooks(authToken);\r
- logger.log(logger.LOW, "Shared notebooks found = " +books.size());\r
- for (int i=0; i<books.size(); i++) {\r
- conn.getSharedNotebookTable().updateNotebook(books.get(i), false);\r
- }\r
- conn.getSyncTable().deleteRecord("FullSharedNotebookSync");\r
- } catch (EDAMUserException e1) {\r
- e1.printStackTrace();\r
- status.message.emit(tr("User exception Listing shared notebooks."));\r
- logger.log(logger.LOW, e1.getMessage());\r
- return;\r
- } catch (EDAMSystemException e1) {\r
- e1.printStackTrace();\r
- status.message.emit(tr("System exception Listing shared notebooks."));\r
- logger.log(logger.LOW, e1.getMessage());\r
- return;\r
- } catch (TException e1) {\r
- e1.printStackTrace();\r
- status.message.emit(tr("Transaction exception Listing shared notebooks."));\r
- logger.log(logger.LOW, e1.getMessage());\r
- return;\r
- } catch (EDAMNotFoundException e1) {\r
- e1.printStackTrace();\r
- status.message.emit(tr("EDAM Not Found exception Listing shared notebooks."));\r
- logger.log(logger.LOW, e1.getMessage());\r
- }\r
- }\r
- private void downloadAllNotebooks(Client noteStore) {\r
- try {\r
- List<Notebook> books = noteStore.listNotebooks(authToken);\r
- logger.log(logger.LOW, "Shared notebooks found = " +books.size());\r
- for (int i=0; i<books.size(); i++) {\r
- conn.getNotebookTable().updateNotebook(books.get(i), false);\r
- }\r
- conn.getSyncTable().deleteRecord("FullNotebookSync");\r
- } catch (EDAMUserException e1) {\r
- e1.printStackTrace();\r
- status.message.emit(tr("User exception Listing notebooks."));\r
- logger.log(logger.LOW, e1.getMessage());\r
- return;\r
- } catch (EDAMSystemException e1) {\r
- e1.printStackTrace();\r
- status.message.emit(tr("System exception Listing notebooks."));\r
- logger.log(logger.LOW, e1.getMessage());\r
- return;\r
- } catch (TException e1) {\r
- e1.printStackTrace();\r
- status.message.emit(tr("Transaction exception Listing notebooks."));\r
- logger.log(logger.LOW, e1.getMessage());\r
- return;\r
- }\r
- }\r
- private void downloadAllLinkedNotebooks(Client noteStore) {\r
- try {\r
- List<LinkedNotebook> books = noteStore.listLinkedNotebooks(authToken);\r
- logger.log(logger.LOW, "Linked notebooks found = " +books.size());\r
- for (int i=0; i<books.size(); i++) {\r
- conn.getLinkedNotebookTable().updateNotebook(books.get(i), false);\r
- }\r
- conn.getSyncTable().deleteRecord("FullLinkedNotebookSync");\r
- } catch (EDAMUserException e1) {\r
- e1.printStackTrace();\r
- status.message.emit(tr("User exception Listing linked notebooks."));\r
- logger.log(logger.LOW, e1.getMessage());\r
- return;\r
- } catch (EDAMSystemException e1) {\r
- e1.printStackTrace();\r
- status.message.emit(tr("System exception Listing linked notebooks."));\r
- logger.log(logger.LOW, e1.getMessage());\r
- return;\r
- } catch (TException e1) {\r
- e1.printStackTrace();\r
- status.message.emit(tr("Transaction exception Listing lineked notebooks."));\r
- logger.log(logger.LOW, e1.getMessage());\r
- return;\r
- } catch (EDAMNotFoundException e1) {\r
- e1.printStackTrace();\r
- status.message.emit(tr("EDAM Not Found exception Listing linked notebooks."));\r
- logger.log(logger.LOW, e1.getMessage());\r
- }\r
- }\r
-\r
- \r
- private void downloadInkNoteImage(String guid, String authToken) {\r
- String urlBase = noteStoreUrl.replace("/edam/note/", "/shard/") + "/res/"+guid+".ink?slice=";\r
-// urlBase = "https://www.evernote.com/shard/s1/res/52b567a9-54ae-4a08-afc5-d5bae275b2a8.ink?slice=";\r
- Integer slice = 1;\r
- Resource r = conn.getNoteTable().noteResourceTable.getNoteResource(guid, false);\r
- conn.getInkImagesTable().expungeImage(r.getGuid());\r
- int sliceCount = 1+((r.getHeight()-1)/480);\r
- HttpClient http = new DefaultHttpClient();\r
- for (int i=0; i<sliceCount; i++) {\r
- String url = urlBase + slice.toString();\r
- HttpPost post = new HttpPost(url);\r
- post.getParams().setParameter("auth", authToken);\r
- List <NameValuePair> nvps = new ArrayList <NameValuePair>();\r
- nvps.add(new BasicNameValuePair("auth", authToken));\r
-\r
- try {\r
- post.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));\r
- } catch (UnsupportedEncodingException e1) {\r
- e1.printStackTrace();\r
- }\r
- try {\r
- HttpResponse response = http.execute(post);\r
- HttpEntity resEntity = response.getEntity();\r
- InputStream is = resEntity.getContent();\r
- QByteArray data = writeToFile(is);\r
- conn.getInkImagesTable().saveImage(guid, slice, data);\r
- } catch (ClientProtocolException e) {\r
- e.printStackTrace();\r
- } catch (IOException e) {\r
- e.printStackTrace();\r
- }\r
-\r
- slice++;\r
- }\r
- http.getConnectionManager().shutdown(); \r
- noteSignal.noteChanged.emit(r.getNoteGuid(), null); // Signal to ivalidate note cache\r
- }\r
- \r
- \r
- public QByteArray writeToFile(InputStream iStream) throws IOException {\r
-\r
- File temp = File.createTempFile("nn-inknote-temp", ".png");\r
-\r
- // Save InputStream to the file.\r
- BufferedOutputStream fOut = null;\r
- try {\r
- fOut = new BufferedOutputStream(new FileOutputStream(temp));\r
- byte[] buffer = new byte[32 * 1024];\r
- int bytesRead = 0;\r
- while ((bytesRead = iStream.read(buffer)) != -1) {\r
- fOut.write(buffer, 0, bytesRead);\r
- }\r
- }\r
- finally {\r
- iStream.close();\r
- fOut.close();\r
- }\r
- QFile tempFile = new QFile(temp.getAbsoluteFile().toString());\r
- tempFile.open(OpenModeFlag.ReadOnly);\r
- QByteArray data = tempFile.readAll();\r
- tempFile.close();\r
- tempFile.remove();\r
- return data;\r
- }\r
- \r
- \r
- //******************************************\r
- //* Begin syncing shared notebooks \r
- //******************************************\r
- private void syncLinkedNotebooks() {\r
- logger.log(logger.MEDIUM, "Authenticating linked Notebooks");\r
- status.message.emit(tr("Synchronizing shared notebooks."));\r
- List<LinkedNotebook> books = conn.getLinkedNotebookTable().getAll();\r
- \r
- errorSharedNotebooks.clear();\r
- \r
- for (int i=0; i<books.size(); i++) {\r
- if (errorSharedNotebooksIgnored.containsKey(books.get(i).getGuid()))\r
- break;\r
- try {\r
- logger.log(logger.EXTREME, "Checking notebook: " +books.get(i).getShareName());\r
- long lastSyncDate = conn.getLinkedNotebookTable().getLastSequenceDate(books.get(i).getGuid());\r
- int lastSequenceNumber = conn.getLinkedNotebookTable().getLastSequenceNumber(books.get(i).getGuid());\r
-\r
- logger.log(logger.EXTREME, "Last Sequence Number on file: " +lastSequenceNumber);\r
- \r
- // Authenticate to the owner's shard\r
- String linkedNoteStoreUrl = noteStoreUrlBase + books.get(i).getShardId();\r
- logger.log(logger.EXTREME, "linkedNoteStoreURL: " +linkedNoteStoreUrl);\r
- THttpClient linkedNoteStoreTrans = new THttpClient(linkedNoteStoreUrl);\r
- TBinaryProtocol linkedNoteStoreProt = new TBinaryProtocol(linkedNoteStoreTrans);\r
- Client linkedNoteStore = new NoteStore.Client(linkedNoteStoreProt, linkedNoteStoreProt); \r
-\r
- linkedAuthResult = null;\r
- if (books.get(i).getShareKey() != null) {\r
- logger.log(logger.EXTREME, "Share Key Not Null: " +books.get(i).getShareKey());\r
- linkedAuthResult = linkedNoteStore.authenticateToSharedNotebook(books.get(i).getShareKey(), authToken);\r
- logger.log(logger.EXTREME, "Authentication Token" +linkedAuthResult.getAuthenticationToken());\r
- } else {\r
- logger.log(logger.EXTREME, "Share key is null");\r
- linkedAuthResult = new AuthenticationResult();\r
- linkedAuthResult.setAuthenticationToken("");\r
- }\r
- SyncState linkedSyncState = \r
- linkedNoteStore.getLinkedNotebookSyncState(linkedAuthResult.getAuthenticationToken(), books.get(i));\r
- if (linkedSyncState.getUpdateCount() > lastSequenceNumber) {\r
- logger.log(logger.EXTREME, "Remote changes found");\r
- if (lastSyncDate < linkedSyncState.getFullSyncBefore()) {\r
- lastSequenceNumber = 0;\r
- } \r
- logger.log(logger.EXTREME, "Calling syncLinkedNotebook for " +books.get(i).getShareName());\r
- syncLinkedNotebook(linkedNoteStore, books.get(i), \r
- lastSequenceNumber, linkedSyncState.getUpdateCount(), authToken);\r
- }\r
- \r
- // Synchronize local changes\r
- syncLocalLinkedNoteChanges(linkedNoteStore, books.get(i));\r
- \r
- } catch (EDAMUserException e) {\r
- e.printStackTrace();\r
- } catch (EDAMNotFoundException e) {\r
- status.message.emit(tr("Error synchronizing \" " +\r
- books.get(i).getShareName()+"\". Please verify you still have access to that shared notebook."));\r
- errorSharedNotebooks.add(books.get(i).getGuid());\r
- errorSharedNotebooksIgnored.put(books.get(i).getGuid(), books.get(i).getGuid());\r
- logger.log(logger.LOW, "Error synchronizing shared notebook. EDAMNotFound: "+e.getMessage());\r
- logger.log(logger.LOW, e.getStackTrace());\r
- error = true;\r
- e.printStackTrace();\r
- } catch (EDAMSystemException e) {\r
- error = true;\r
- logger.log(logger.LOW, "System error authenticating against shared notebook. "+\r
- "Key: "+books.get(i).getShareKey() +" Error:" +e.getMessage());\r
- e.printStackTrace();\r
- } catch (TException e) {\r
- error = true;\r
- e.printStackTrace();\r
- }\r
- }\r
- \r
- // Cleanup tags\r
- conn.getTagTable().removeUnusedLinkedTags();\r
- conn.getTagTable().cleanupTags();\r
- tagSignal.listChanged.emit();\r
- return;\r
- }\r
-\r
- \r
- //**************************************************************\r
- //* Linked notebook contents (from someone else's account)\r
- //*************************************************************\r
- private void syncLinkedNotebook(Client linkedNoteStore, LinkedNotebook book, int usn, int highSequence, String token) {\r
- logger.log(logger.EXTREME, "Entering syncLinkedNotebook");\r
- if (ignoreLinkedNotebooks.contains(book.getGuid()))\r
- return;\r
- List<Note> dirtyNotes = conn.getNoteTable().getDirtyLinkedNotes();\r
- if (dirtyNoteGuids == null) \r
+ noteStoreUrl = noteStoreUrlBase + user.getShardId();
+ syncSignal.saveAuthToken.emit(authToken);
+ syncSignal.saveNoteStore.emit(localNoteStore);
+
+
+ try {
+ noteStoreTrans = new THttpClient(noteStoreUrl);
+ noteStoreTrans.setCustomHeader("User-Agent", userAgent);
+ } catch (TTransportException e) {
+ QMessageBox mb = new QMessageBox(QMessageBox.Icon.Critical, "Transport Excepton", e.getLocalizedMessage());
+ mb.exec();
+ e.printStackTrace();
+ isConnected = false;
+ }
+ noteStoreProt = new TBinaryProtocol(noteStoreTrans);
+ localNoteStore =
+ new NoteStore.Client(noteStoreProt, noteStoreProt);
+ isConnected = true;
+ //authTimeRemaining = authResult.getExpiration() - authResult.getCurrentTime();
+ //authRefreshTime = authTimeRemaining / 2;
+ //}
+
+ // Get user information
+ try {
+ User user = userStore.getUser(authToken);
+ syncSignal.saveUserInformation.emit(user);
+ } catch (EDAMUserException e1) {
+ e1.printStackTrace();
+ } catch (EDAMSystemException e1) {
+ e1.printStackTrace();
+ } catch (TException e1) {
+ e1.printStackTrace();
+ }
+
+ return isConnected;
+ }
+ // Disconnect from the database
+ public void enDisconnect() {
+ isConnected = false;
+ }
+
+ /*
+ // Refresh the connection
+ private synchronized boolean refreshConnection() {
+
+ logger.log(logger.EXTREME, "Entering SyncRunner.refreshConnection()");
+// Calendar cal = Calendar.getInstance();
+
+ // If we are not connected let's get out of here
+ if (!isConnected)
+ return false;
+
+ // If we fail too many times, then let's give up.
+ if (failedRefreshes >=5) {
+ logger.log(logger.EXTREME, "Refresh attempts have failed. Disconnecting.");
+ isConnected = false;
+ status.message.emit(tr("Unable to synchronize - Authentication failed"));
+ return false;
+ }
+
+ // If this is the first time through, then we need to set this
+// if (authRefreshTime == 0 || cal.getTimeInMillis() > authRefreshTime)
+// authRefreshTime = cal.getTimeInMillis();
+
+ // // Default to checking again in 5 min. This in case we fail.
+ // authRefreshTime = authRefreshTime +(5*60*1000);
+
+ // Try to get a new token
+ AuthenticationResult newAuth = null;
+ logger.log(logger.EXTREME, "Beginning to try authentication refresh");
+ try {
+ if (userStore != null && authToken != null)
+ newAuth = userStore.refreshAuthentication(authToken);
+ else
+ return false;
+ logger.log(logger.EXTREME, "UserStore.refreshAuthentication has succeeded.");
+ } catch (EDAMUserException e) {
+ e.printStackTrace();
+ syncSignal.authRefreshComplete.emit(false);
+ failedRefreshes++;
+ return false;
+ } catch (EDAMSystemException e) {
+ e.printStackTrace();
+ syncSignal.authRefreshComplete.emit(false);
+ failedRefreshes++;
+ return false;
+ } catch (TException e) {
+ e.printStackTrace();
+ syncSignal.authRefreshComplete.emit(false);
+ failedRefreshes++;
+ return false;
+ }
+
+ // If we didn't get a good auth, then we've failed
+ if (newAuth == null) {
+ failedRefreshes++;
+ status.message.emit(tr("Unable to synchronize - Authentication failed"));
+ logger.log(logger.EXTREME, "Authentication failure #" +failedRefreshes);
+ status.message.emit(tr("Unable to synchronize - Authentication failed"));
+ syncSignal.authRefreshComplete.emit(false);
+ return false;
+ }
+
+ // We got a good token. Now we need to setup the time to renew it.
+ logger.log(logger.EXTREME, "Saving authentication tokens");
+ authResult = newAuth;
+ authToken = new String(newAuth.getAuthenticationToken());
+// authTimeRemaining = authResult.getExpiration() - authResult.getCurrentTime();
+// authRefreshTime = cal.getTimeInMillis() + (authTimeRemaining/4);
+ failedRefreshes=0;
+ syncSignal.authRefreshComplete.emit(true);
+ authRefreshNeeded = false;
+
+ // This should never happen, but if it does we consider this a faild attempt.
+// if (authTimeRemaining <= 0) {
+// failedRefreshes++;
+// syncSignal.authRefreshComplete.emit(false);
+// }
+
+ return true;
+ }
+
+ */
+
+ public synchronized boolean addWork(String request) {
+ if (workQueue.offer(request))
+ return true;
+ return false;
+ }
+
+ private Note getNoteContent(Note n) {
+ QTextCodec codec = QTextCodec.codecForLocale();
+ codec = QTextCodec.codecForName("UTF-8");
+ n.setContent(codec.toUnicode(new QByteArray(n.getContent())));
+ return n;
+ }
+
+
+
+ //*********************************************************
+ //* Special download instructions. Used for DB upgrades
+ //*********************************************************
+ private void downloadAllSharedNotebooks(Client noteStore) {
+ try {
+ List<SharedNotebook> books = noteStore.listSharedNotebooks(authToken);
+ logger.log(logger.LOW, "Shared notebooks found = " +books.size());
+ for (int i=0; i<books.size(); i++) {
+ conn.getSharedNotebookTable().updateNotebook(books.get(i), false);
+ }
+ conn.getSyncTable().deleteRecord("FullSharedNotebookSync");
+ } catch (EDAMUserException e1) {
+ e1.printStackTrace();
+ status.message.emit(tr("User exception Listing shared notebooks."));
+ logger.log(logger.LOW, e1.getMessage());
+ return;
+ } catch (EDAMSystemException e1) {
+ e1.printStackTrace();
+ status.message.emit(tr("System exception Listing shared notebooks."));
+ logger.log(logger.LOW, e1.getMessage());
+ return;
+ } catch (TException e1) {
+ e1.printStackTrace();
+ status.message.emit(tr("Transaction exception Listing shared notebooks."));
+ logger.log(logger.LOW, e1.getMessage());
+ return;
+ } catch (EDAMNotFoundException e1) {
+ e1.printStackTrace();
+ status.message.emit(tr("EDAM Not Found exception Listing shared notebooks."));
+ logger.log(logger.LOW, e1.getMessage());
+ }
+ }
+ private void downloadAllNotebooks(Client noteStore) {
+ try {
+ List<Notebook> books = noteStore.listNotebooks(authToken);
+ logger.log(logger.LOW, "Shared notebooks found = " +books.size());
+ for (int i=0; i<books.size(); i++) {
+ conn.getNotebookTable().updateNotebook(books.get(i), false);
+ }
+ conn.getSyncTable().deleteRecord("FullNotebookSync");
+ } catch (EDAMUserException e1) {
+ e1.printStackTrace();
+ status.message.emit(tr("User exception Listing notebooks."));
+ logger.log(logger.LOW, e1.getMessage());
+ return;
+ } catch (EDAMSystemException e1) {
+ e1.printStackTrace();
+ status.message.emit(tr("System exception Listing notebooks."));
+ logger.log(logger.LOW, e1.getMessage());
+ return;
+ } catch (TException e1) {
+ e1.printStackTrace();
+ status.message.emit(tr("Transaction exception Listing notebooks."));
+ logger.log(logger.LOW, e1.getMessage());
+ return;
+ }
+ }
+ private void downloadAllLinkedNotebooks(Client noteStore) {
+ try {
+ List<LinkedNotebook> books = noteStore.listLinkedNotebooks(authToken);
+ logger.log(logger.LOW, "Linked notebooks found = " +books.size());
+ for (int i=0; i<books.size(); i++) {
+ conn.getLinkedNotebookTable().updateNotebook(books.get(i), false);
+ }
+ conn.getSyncTable().deleteRecord("FullLinkedNotebookSync");
+ } catch (EDAMUserException e1) {
+ e1.printStackTrace();
+ status.message.emit(tr("User exception Listing linked notebooks."));
+ logger.log(logger.LOW, e1.getMessage());
+ return;
+ } catch (EDAMSystemException e1) {
+ e1.printStackTrace();
+ status.message.emit(tr("System exception Listing linked notebooks."));
+ logger.log(logger.LOW, e1.getMessage());
+ return;
+ } catch (TException e1) {
+ e1.printStackTrace();
+ status.message.emit(tr("Transaction exception Listing lineked notebooks."));
+ logger.log(logger.LOW, e1.getMessage());
+ return;
+ } catch (EDAMNotFoundException e1) {
+ e1.printStackTrace();
+ status.message.emit(tr("EDAM Not Found exception Listing linked notebooks."));
+ logger.log(logger.LOW, e1.getMessage());
+ }
+ }
+
+
+ private void downloadInkNoteImage(String guid, String authToken) {
+ String urlBase = noteStoreUrl.replace("/edam/note/", "/shard/") + "/res/"+guid+".ink?slice=";
+// urlBase = "https://www.evernote.com/shard/s1/res/52b567a9-54ae-4a08-afc5-d5bae275b2a8.ink?slice=";
+ Integer slice = 1;
+ Resource r = conn.getNoteTable().noteResourceTable.getNoteResource(guid, false);
+ conn.getInkImagesTable().expungeImage(r.getGuid());
+ int sliceCount = 1+((r.getHeight()-1)/480);
+ HttpClient http = new DefaultHttpClient();
+ for (int i=0; i<sliceCount; i++) {
+ String url = urlBase + slice.toString();
+ HttpPost post = new HttpPost(url);
+ post.getParams().setParameter("auth", authToken);
+ List <NameValuePair> nvps = new ArrayList <NameValuePair>();
+ nvps.add(new BasicNameValuePair("auth", authToken));
+
+ try {
+ post.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
+ } catch (UnsupportedEncodingException e1) {
+ e1.printStackTrace();
+ }
+ try {
+ HttpResponse response = http.execute(post);
+ HttpEntity resEntity = response.getEntity();
+ InputStream is = resEntity.getContent();
+ QByteArray data = writeToFile(is);
+ conn.getInkImagesTable().saveImage(guid, slice, data);
+ } catch (ClientProtocolException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ slice++;
+ }
+ http.getConnectionManager().shutdown();
+ noteSignal.noteChanged.emit(r.getNoteGuid(), null); // Signal to ivalidate note cache
+ }
+
+
+ public QByteArray writeToFile(InputStream iStream) throws IOException {
+
+ File temp = File.createTempFile("nn-inknote-temp", ".png");
+
+ // Save InputStream to the file.
+ BufferedOutputStream fOut = null;
+ try {
+ fOut = new BufferedOutputStream(new FileOutputStream(temp));
+ byte[] buffer = new byte[32 * 1024];
+ int bytesRead = 0;
+ while ((bytesRead = iStream.read(buffer)) != -1) {
+ fOut.write(buffer, 0, bytesRead);
+ }
+ }
+ finally {
+ iStream.close();
+ fOut.close();
+ }
+ QFile tempFile = new QFile(temp.getAbsoluteFile().toString());
+ tempFile.open(OpenModeFlag.ReadOnly);
+ QByteArray data = tempFile.readAll();
+ tempFile.close();
+ tempFile.remove();
+ return data;
+ }
+
+
+ //******************************************
+ //* Begin syncing shared notebooks
+ //******************************************
+ private void syncLinkedNotebooks() {
+ logger.log(logger.MEDIUM, "Authenticating linked Notebooks");
+ status.message.emit(tr("Synchronizing shared notebooks."));
+ List<LinkedNotebook> books = conn.getLinkedNotebookTable().getAll();
+
+ errorSharedNotebooks.clear();
+
+ for (int i=0; i<books.size(); i++) {
+ if (errorSharedNotebooksIgnored.containsKey(books.get(i).getGuid()))
+ break;
+ try {
+ logger.log(logger.EXTREME, "Checking notebook: " +books.get(i).getShareName());
+ long lastSyncDate = conn.getLinkedNotebookTable().getLastSequenceDate(books.get(i).getGuid());
+ int lastSequenceNumber = conn.getLinkedNotebookTable().getLastSequenceNumber(books.get(i).getGuid());
+
+ logger.log(logger.EXTREME, "Last Sequence Number on file: " +lastSequenceNumber);
+
+ // Authenticate to the owner's shard
+ String linkedNoteStoreUrl = noteStoreUrlBase + books.get(i).getShardId();
+ logger.log(logger.EXTREME, "linkedNoteStoreURL: " +linkedNoteStoreUrl);
+ THttpClient linkedNoteStoreTrans = new THttpClient(linkedNoteStoreUrl);
+ TBinaryProtocol linkedNoteStoreProt = new TBinaryProtocol(linkedNoteStoreTrans);
+ Client linkedNoteStore = new NoteStore.Client(linkedNoteStoreProt, linkedNoteStoreProt);
+
+ linkedAuthResult = null;
+ if (books.get(i).getShareKey() != null) {
+ logger.log(logger.EXTREME, "Share Key Not Null: " +books.get(i).getShareKey());
+ linkedAuthResult = linkedNoteStore.authenticateToSharedNotebook(books.get(i).getShareKey(), authToken);
+ logger.log(logger.EXTREME, "Authentication Token" +linkedAuthResult.getAuthenticationToken());
+ } else {
+ logger.log(logger.EXTREME, "Share key is null");
+ linkedAuthResult = new AuthenticationResult();
+ linkedAuthResult.setAuthenticationToken("");
+ }
+ SyncState linkedSyncState =
+ linkedNoteStore.getLinkedNotebookSyncState(linkedAuthResult.getAuthenticationToken(), books.get(i));
+ if (linkedSyncState.getUpdateCount() > lastSequenceNumber) {
+ logger.log(logger.EXTREME, "Remote changes found");
+ if (lastSyncDate < linkedSyncState.getFullSyncBefore()) {
+ lastSequenceNumber = 0;
+ }
+ logger.log(logger.EXTREME, "Calling syncLinkedNotebook for " +books.get(i).getShareName());
+ syncLinkedNotebook(linkedNoteStore, books.get(i),
+ lastSequenceNumber, linkedSyncState.getUpdateCount(), authToken);
+ }
+
+ // Synchronize local changes
+ syncLocalLinkedNoteChanges(linkedNoteStore, books.get(i));
+
+ } catch (EDAMUserException e) {
+ e.printStackTrace();
+ } catch (EDAMNotFoundException e) {
+ status.message.emit(tr("Error synchronizing \" " +
+ books.get(i).getShareName()+"\". Please verify you still have access to that shared notebook."));
+ errorSharedNotebooks.add(books.get(i).getGuid());
+ errorSharedNotebooksIgnored.put(books.get(i).getGuid(), books.get(i).getGuid());
+ logger.log(logger.LOW, "Error synchronizing shared notebook. EDAMNotFound: "+e.getMessage());
+ logger.log(logger.LOW, e.getStackTrace());
+ error = true;
+ e.printStackTrace();
+ } catch (EDAMSystemException e) {
+ error = true;
+ logger.log(logger.LOW, "System error authenticating against shared notebook. "+
+ "Key: "+books.get(i).getShareKey() +" Error:" +e.getMessage());
+ e.printStackTrace();
+ } catch (TException e) {
+ error = true;
+ e.printStackTrace();
+ }
+ }
+
+ // Cleanup tags
+ conn.getTagTable().removeUnusedLinkedTags();
+ conn.getTagTable().cleanupTags();
+ tagSignal.listChanged.emit();
+ return;
+ }
+
+
+ //**************************************************************
+ //* Linked notebook contents (from someone else's account)
+ //*************************************************************
+ private void syncLinkedNotebook(Client linkedNoteStore, LinkedNotebook book, int usn, int highSequence, String token) {
+ logger.log(logger.EXTREME, "Entering syncLinkedNotebook");
+ if (ignoreLinkedNotebooks.contains(book.getGuid()))
+ return;
+ List<Note> dirtyNotes = conn.getNoteTable().getDirtyLinkedNotes();
+ if (dirtyNoteGuids == null)
dirtyNoteGuids = new ArrayList<String>();\r
-\r
- for (int i=0; i<dirtyNotes.size() && keepRunning; i++) {\r
- dirtyNoteGuids.add(dirtyNotes.get(i).getGuid());\r
- }\r
- boolean fullSync = false;\r
- if (usn == 0)\r
- fullSync = true;\r
- boolean syncError = false;\r
- while (usn < highSequence && !syncError) {\r
- refreshNeeded = true;\r
- try {\r
- SyncChunk chunk = \r
- linkedNoteStore.getLinkedNotebookSyncChunk(token, book, usn, 10, fullSync);\r
- \r
- // Expunge notes\r
- syncExpungedNotes(chunk);\r
-\r
- logger.log(logger.EXTREME, "Syncing remote notes: " +chunk.getNotesSize());\r
- syncRemoteNotes(linkedNoteStore, chunk.getNotes(), fullSync, linkedAuthResult.getAuthenticationToken());\r
- logger.log(logger.EXTREME, "Finding new linked tags");\r
- findNewLinkedTags(linkedNoteStore, chunk.getNotes(), linkedAuthResult.getAuthenticationToken());\r
- // Sync resources\r
- logger.log(logger.EXTREME, "Synchronizing tags: " +chunk.getTagsSize());\r
- for (int i=0; i<chunk.getResourcesSize(); i++) {\r
- syncRemoteResource(linkedNoteStore, chunk.getResources().get(i), linkedAuthResult.getAuthenticationToken());\r
- }\r
- logger.log(logger.EXTREME, "Synchronizing linked notebooks: " +chunk.getNotebooksSize());\r
- syncRemoteLinkedNotebooks(linkedNoteStore, chunk.getNotebooks(), false, book);\r
- syncLinkedTags(chunk.getTags(), book.getGuid());\r
- \r
- // Go through & signal any notes that have changed so we can refresh the user's view\r
- for (int i=0; i<chunk.getNotesSize(); i++) \r
- noteSignal.noteChanged.emit(chunk.getNotes().get(i).getGuid(), null);\r
-\r
- // Expunge Notebook records\r
- logger.log(logger.EXTREME, "Expunging linked notebooks: " +chunk.getExpungedLinkedNotebooksSize());\r
- for (int i=0; i<chunk.getExpungedLinkedNotebooksSize(); i++) {\r
- conn.getLinkedNotebookTable().expungeNotebook(chunk.getExpungedLinkedNotebooks().get(i), false);\r
- }\r
- usn = chunk.getChunkHighUSN();\r
- conn.getLinkedNotebookTable().setLastSequenceDate(book.getGuid(),chunk.getCurrentTime());\r
- conn.getLinkedNotebookTable().setLastSequenceNumber(book.getGuid(),chunk.getChunkHighUSN());\r
- } catch (EDAMUserException e) {\r
- syncError = true;\r
- status.message.emit(tr("EDAM UserException synchronizing linked notbook. See the log for datails."));\r
- e.printStackTrace();\r
- logger.log(logger.LOW, tr("EDAM UserException synchronizing linked notbook ")+ e.getMessage());\r
- } catch (EDAMSystemException e) {\r
- syncError = true;\r
- status.message.emit(tr("EDAM SystemException synchronizing linked notbook. See the log for datails."));\r
- e.printStackTrace();\r
- logger.log(logger.LOW, tr("EDAM SystemException synchronizing linked notbook. See the log for datails") +e.getMessage());\r
- } catch (EDAMNotFoundException e) {\r
- syncError = true;\r
- status.message.emit(tr("Notebook URL not found. Removing notobook ") +book.getShareName());\r
- conn.getNotebookTable().deleteLinkedTags(book.getGuid());\r
- conn.getLinkedNotebookTable().expungeNotebook(book.getGuid(), false);\r
- logger.log(logger.LOW, tr("Notebook URL not found. Removing notobook ") +e.getMessage());\r
- } catch (TException e) {\r
- syncError = true;\r
- status.message.emit(tr("EDAM TException synchronizing linked notbook. See the log for datails."));\r
- e.printStackTrace();\r
- logger.log(logger.LOW, tr("EDAM TException synchronizing linked notbook. See the log for datails." )+e.getMessage());\r
- }\r
- }\r
- logger.log(logger.EXTREME, "leaving syncLinkedNotebook");\r
- }\r
- // Sync remote tags\r
- private void syncLinkedTags(List<Tag> tags, String notebookGuid) {\r
- logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteTags");\r
- if (tags != null) {\r
- for (int i=0; i<tags.size() && keepRunning; i++) {\r
- conn.getTagTable().syncLinkedTag(tags.get(i), notebookGuid, false);\r
- }\r
- }\r
- logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteTags");\r
- }\r
- \r
- // Sync notebooks from a linked notebook\r
- private void syncRemoteLinkedNotebooks(Client noteStore, List<Notebook> notebooks, boolean readOnly, LinkedNotebook linked) {\r
- logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteNotebooks");\r
- if (notebooks != null) {\r
- for (int i=0; i<notebooks.size() && keepRunning; i++) {\r
- try {\r
- logger.log(logger.EXTREME, "auth token:" +linkedAuthResult.getAuthenticationToken());\r
- if (!linkedAuthResult.getAuthenticationToken().equals("")) {\r
- SharedNotebook s = noteStore.getSharedNotebookByAuth(linkedAuthResult.getAuthenticationToken());\r
- logger.log(logger.EXTREME, "share key:"+s.getShareKey() +" notebookGuid" +s.getNotebookGuid());\r
- conn.getLinkedNotebookTable().setNotebookGuid(s.getShareKey(), s.getNotebookGuid());\r
- readOnly = !s.isNotebookModifiable();\r
- } else {\r
- readOnly = true;\r
- }\r
- notebooks.get(i).setName(linked.getShareName());\r
- notebooks.get(i).setDefaultNotebook(false);\r
- conn.getNotebookTable().syncLinkedNotebook(notebooks.get(i), false, readOnly); \r
- } catch (EDAMUserException e) {\r
- readOnly = true;\r
- e.printStackTrace();\r
- } catch (EDAMNotFoundException e) {\r
- readOnly = true;\r
- e.printStackTrace();\r
- } catch (EDAMSystemException e) {\r
- readOnly = true;\r
- e.printStackTrace();\r
- } catch (TException e) {\r
- readOnly = true;\r
- e.printStackTrace();\r
- }\r
-\r
- }\r
- } \r
- logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteNotebooks");\r
- }\r
-\r
- private void findNewLinkedTags(Client noteStore, List<Note> newNotes, String token) {\r
- if (newNotes == null)\r
- return;\r
- for (int i=0; i<newNotes.size(); i++) {\r
- Note n = newNotes.get(i);\r
- for (int j=0; j<n.getTagGuidsSize(); j++) {\r
- String tag = n.getTagGuids().get(j);\r
- if (!conn.getTagTable().exists(tag)) {\r
- Tag newTag;\r
- try {\r
- newTag = noteStore.getTag(token, tag);\r
- conn.getTagTable().addTag(newTag, false);\r
- } catch (EDAMUserException e) {\r
- e.printStackTrace();\r
- } catch (EDAMSystemException e) {\r
- e.printStackTrace();\r
- } catch (EDAMNotFoundException e) {\r
- e.printStackTrace();\r
- } catch (TException e) {\r
- e.printStackTrace();\r
- }\r
- \r
- }\r
- }\r
- }\r
- }\r
-\r
- // Synchronize changes locally done to linked notes\r
- private void syncLocalLinkedNoteChanges(Client noteStore, LinkedNotebook book) {\r
- logger.log(logger.EXTREME, "Entering SyncRunner.synclocalLinkedNoteChanges");\r
- String notebookGuid = conn.getLinkedNotebookTable().getNotebookGuid(book.getGuid());\r
- logger.log(logger.EXTREME, "Finding changes for " +book.getShareName() +":" +book.getGuid() + ":" +notebookGuid);\r
- List<Note> notes = conn.getNoteTable().getDirtyLinked(notebookGuid);\r
- logger.log(logger.EXTREME, "Number of changes found: " +notes.size());\r
- for (int i=0; i<notes.size(); i++) {\r
- logger.log(logger.EXTREME, "Calling syncLocalNote with key " +linkedAuthResult.getAuthenticationToken());\r
- syncLocalNote(noteStore, notes.get(i), linkedAuthResult.getAuthenticationToken());\r
- }\r
- logger.log(logger.EXTREME, "Leaving SyncRunner.synclocalLinkedNoteChanges");\r
- }\r
-\r
-}\r
+
+ for (int i=0; i<dirtyNotes.size() && keepRunning; i++) {
+ dirtyNoteGuids.add(dirtyNotes.get(i).getGuid());
+ }
+ boolean fullSync = false;
+ if (usn == 0)
+ fullSync = true;
+ boolean syncError = false;
+ while (usn < highSequence && !syncError) {
+ refreshNeeded = true;
+ try {
+ SyncChunk chunk =
+ linkedNoteStore.getLinkedNotebookSyncChunk(token, book, usn, 10, fullSync);
+
+ // Expunge notes
+ syncExpungedNotes(chunk);
+
+ logger.log(logger.EXTREME, "Syncing remote notes: " +chunk.getNotesSize());
+ syncRemoteNotes(linkedNoteStore, chunk.getNotes(), fullSync, linkedAuthResult.getAuthenticationToken());
+ logger.log(logger.EXTREME, "Finding new linked tags");
+ findNewLinkedTags(linkedNoteStore, chunk.getNotes(), linkedAuthResult.getAuthenticationToken());
+ // Sync resources
+ logger.log(logger.EXTREME, "Synchronizing tags: " +chunk.getTagsSize());
+ for (int i=0; i<chunk.getResourcesSize(); i++) {
+ syncRemoteResource(linkedNoteStore, chunk.getResources().get(i), linkedAuthResult.getAuthenticationToken());
+ }
+ logger.log(logger.EXTREME, "Synchronizing linked notebooks: " +chunk.getNotebooksSize());
+ syncRemoteLinkedNotebooks(linkedNoteStore, chunk.getNotebooks(), false, book);
+ syncLinkedTags(chunk.getTags(), book.getGuid());
+
+ // Go through & signal any notes that have changed so we can refresh the user's view
+ for (int i=0; i<chunk.getNotesSize(); i++)
+ noteSignal.noteChanged.emit(chunk.getNotes().get(i).getGuid(), null);
+
+ // Expunge Notebook records
+ logger.log(logger.EXTREME, "Expunging linked notebooks: " +chunk.getExpungedLinkedNotebooksSize());
+ for (int i=0; i<chunk.getExpungedLinkedNotebooksSize(); i++) {
+ conn.getLinkedNotebookTable().expungeNotebook(chunk.getExpungedLinkedNotebooks().get(i), false);
+ }
+ usn = chunk.getChunkHighUSN();
+ conn.getLinkedNotebookTable().setLastSequenceDate(book.getGuid(),chunk.getCurrentTime());
+ conn.getLinkedNotebookTable().setLastSequenceNumber(book.getGuid(),chunk.getChunkHighUSN());
+ } catch (EDAMUserException e) {
+ syncError = true;
+ status.message.emit(tr("EDAM UserException synchronizing linked notbook. See the log for datails."));
+ e.printStackTrace();
+ logger.log(logger.LOW, tr("EDAM UserException synchronizing linked notbook ")+ e.getMessage());
+ } catch (EDAMSystemException e) {
+ syncError = true;
+ status.message.emit(tr("EDAM SystemException synchronizing linked notbook. See the log for datails."));
+ e.printStackTrace();
+ logger.log(logger.LOW, tr("EDAM SystemException synchronizing linked notbook. See the log for datails") +e.getMessage());
+ } catch (EDAMNotFoundException e) {
+ syncError = true;
+ status.message.emit(tr("Notebook URL not found. Removing notobook ") +book.getShareName());
+ conn.getNotebookTable().deleteLinkedTags(book.getGuid());
+ conn.getLinkedNotebookTable().expungeNotebook(book.getGuid(), false);
+ logger.log(logger.LOW, tr("Notebook URL not found. Removing notobook ") +e.getMessage());
+ } catch (TException e) {
+ syncError = true;
+ status.message.emit(tr("EDAM TException synchronizing linked notbook. See the log for datails."));
+ e.printStackTrace();
+ logger.log(logger.LOW, tr("EDAM TException synchronizing linked notbook. See the log for datails." )+e.getMessage());
+ }
+ }
+ logger.log(logger.EXTREME, "leaving syncLinkedNotebook");
+ }
+ // Sync remote tags
+ private void syncLinkedTags(List<Tag> tags, String notebookGuid) {
+ logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteTags");
+ if (tags != null) {
+ for (int i=0; i<tags.size() && keepRunning; i++) {
+ conn.getTagTable().syncLinkedTag(tags.get(i), notebookGuid, false);
+ }
+ }
+ logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteTags");
+ }
+
+ // Sync notebooks from a linked notebook
+ private void syncRemoteLinkedNotebooks(Client noteStore, List<Notebook> notebooks, boolean readOnly, LinkedNotebook linked) {
+ logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteNotebooks");
+ if (notebooks != null) {
+ for (int i=0; i<notebooks.size() && keepRunning; i++) {
+ try {
+ logger.log(logger.EXTREME, "auth token:" +linkedAuthResult.getAuthenticationToken());
+ if (!linkedAuthResult.getAuthenticationToken().equals("")) {
+ SharedNotebook s = noteStore.getSharedNotebookByAuth(linkedAuthResult.getAuthenticationToken());
+ logger.log(logger.EXTREME, "share key:"+s.getShareKey() +" notebookGuid" +s.getNotebookGuid());
+ conn.getLinkedNotebookTable().setNotebookGuid(s.getShareKey(), s.getNotebookGuid());
+ readOnly = !s.isNotebookModifiable();
+ } else {
+ readOnly = true;
+ }
+ notebooks.get(i).setName(linked.getShareName());
+ notebooks.get(i).setDefaultNotebook(false);
+ conn.getNotebookTable().syncLinkedNotebook(notebooks.get(i), false, readOnly);
+ } catch (EDAMUserException e) {
+ readOnly = true;
+ e.printStackTrace();
+ } catch (EDAMNotFoundException e) {
+ readOnly = true;
+ e.printStackTrace();
+ } catch (EDAMSystemException e) {
+ readOnly = true;
+ e.printStackTrace();
+ } catch (TException e) {
+ readOnly = true;
+ e.printStackTrace();
+ }
+
+ }
+ }
+ logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteNotebooks");
+ }
+
+ private void findNewLinkedTags(Client noteStore, List<Note> newNotes, String token) {
+ if (newNotes == null)
+ return;
+ for (int i=0; i<newNotes.size(); i++) {
+ Note n = newNotes.get(i);
+ for (int j=0; j<n.getTagGuidsSize(); j++) {
+ String tag = n.getTagGuids().get(j);
+ if (!conn.getTagTable().exists(tag)) {
+ Tag newTag;
+ try {
+ newTag = noteStore.getTag(token, tag);
+ conn.getTagTable().addTag(newTag, false);
+ } catch (EDAMUserException e) {
+ e.printStackTrace();
+ } catch (EDAMSystemException e) {
+ e.printStackTrace();
+ } catch (EDAMNotFoundException e) {
+ e.printStackTrace();
+ } catch (TException e) {
+ e.printStackTrace();
+ }
+
+ }
+ }
+ }
+ }
+
+ // Synchronize changes locally done to linked notes
+ private void syncLocalLinkedNoteChanges(Client noteStore, LinkedNotebook book) {
+ logger.log(logger.EXTREME, "Entering SyncRunner.synclocalLinkedNoteChanges");
+ String notebookGuid = conn.getLinkedNotebookTable().getNotebookGuid(book.getGuid());
+ logger.log(logger.EXTREME, "Finding changes for " +book.getShareName() +":" +book.getGuid() + ":" +notebookGuid);
+ List<Note> notes = conn.getNoteTable().getDirtyLinked(notebookGuid);
+ logger.log(logger.EXTREME, "Number of changes found: " +notes.size());
+ for (int i=0; i<notes.size(); i++) {
+ logger.log(logger.EXTREME, "Calling syncLocalNote with key " +linkedAuthResult.getAuthenticationToken());
+ syncLocalNote(noteStore, notes.get(i), linkedAuthResult.getAuthenticationToken());
+ }
+ logger.log(logger.EXTREME, "Leaving SyncRunner.synclocalLinkedNoteChanges");
+ }
+
+}
-/*\r
- * This file is part of NixNote \r
- * Copyright 2009 Randy Baumgarte\r
- * \r
- * This file may be licensed under the terms of of the\r
- * GNU General Public License Version 2 (the ``GPL'').\r
- *\r
- * Software distributed under the License is distributed\r
- * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either\r
- * express or implied. See the GPL for the specific language\r
- * governing rights and limitations.\r
- *\r
- * You should have received a copy of the GPL along with this\r
- * program. If not, go to http://www.gnu.org/licenses/gpl.html\r
- * or write to the Free Software Foundation, Inc.,\r
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
- *\r
-*/\r
-\r
-package cx.fbn.nevernote.threads;\r
-\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-import java.util.concurrent.LinkedBlockingQueue;\r
-\r
-import com.evernote.edam.type.Note;\r
-import com.trolltech.qt.core.QBuffer;\r
-import com.trolltech.qt.core.QByteArray;\r
-import com.trolltech.qt.core.QIODevice;\r
-import com.trolltech.qt.core.QMutex;\r
-import com.trolltech.qt.core.QObject;\r
-import com.trolltech.qt.core.QTemporaryFile;\r
-import com.trolltech.qt.gui.QPixmap;\r
-\r
-import cx.fbn.nevernote.Global;\r
-import cx.fbn.nevernote.signals.NoteSignal;\r
-import cx.fbn.nevernote.sql.DatabaseConnection;\r
-import cx.fbn.nevernote.utilities.ApplicationLogger;\r
-import cx.fbn.nevernote.xml.NoteFormatter;\r
-\r
-\r
-/*\r
- * \r
- * @author Randy Baumgarte\r
- * \r
- * Thumbnail Overview:\r
- * \r
- * How thumbnails are generated is a bit odd. The problem is that \r
- * process of creating the thumbnail involves actually creating an HTML\r
- * version of the note & all of its resources. That is very CPU intensive\r
- * so we try to do it in a separate thread. Unfortunately, the QWebPage class \r
- * which actually creates the thumbnail must be in the main GUI thread.\r
- * This is the odd way I've tried to get around the problem.\r
- * \r
- * First, the thumbail thread finds a note which needs a thumbnail. This\r
- * can be done by either scanning the database or specifically being told\r
- * a note needs a new thumbnail. \r
- * \r
- * When a note is found, this thread will read the database and write out\r
- * the resources and create an HTML version of the note. It then signals\r
- * the main GUI thread that a note is ready. \r
- * \r
- * Next, the main GUI thread will process the signal received from the \r
- * thumbnail thread. The GUI thread will create a QWebPage (via the\r
- * Thumbnailer class) and will render the image. The image is written to \r
- * the database to be used in the thumbnail view.\r
- * \r
- */\r
-public class ThumbnailRunner extends QObject implements Runnable {\r
- \r
- private final ApplicationLogger logger;\r
- private String guid;\r
- public NoteSignal noteSignal;\r
- private boolean keepRunning;\r
- public boolean interrupt;\r
- private final DatabaseConnection conn;\r
- private volatile LinkedBlockingQueue<String> workQueue;\r
- private static int MAX_QUEUED_WAITING = 1000;\r
- public QMutex mutex;\r
-\r
-\r
-\r
- public ThumbnailRunner(String logname, String u, String i, String r, String uid, String pswd, String cpswd) {\r
- logger = new ApplicationLogger(logname);\r
- conn = new DatabaseConnection(logger, u, i, r, uid, pswd, cpswd, 300);\r
- noteSignal = new NoteSignal();\r
- guid = null;\r
- keepRunning = true;\r
- mutex = new QMutex();\r
- workQueue=new LinkedBlockingQueue<String>(MAX_QUEUED_WAITING); \r
- }\r
- \r
- \r
- @Override\r
- public void run() {\r
- thread().setPriority(Thread.MIN_PRIORITY);\r
- \r
- logger.log(logger.MEDIUM, "Starting thumbnail thread ");\r
- while (keepRunning) {\r
- try {\r
- interrupt = false;\r
- String work = workQueue.take();\r
- if (work.startsWith("GENERATE")) {\r
- work = work.replace("GENERATE ", "");\r
- guid = work;\r
- generateThumbnail();\r
- }\r
- if (work.startsWith("SCAN")) {\r
- if (conn.getNoteTable().getThumbnailNeededCount() > 1)\r
- scanDatabase();\r
- }\r
- if (work.startsWith("IMAGE")) {\r
- work = work.replace("IMAGE ", "");\r
- guid = work;\r
- processImage();\r
- }\r
- if (work.startsWith("STOP")) {\r
- logger.log(logger.MEDIUM, "Stopping thumbail thread");\r
- keepRunning = false;\r
- }\r
- } catch (InterruptedException e) {\r
- // TODO Auto-generated catch block\r
- e.printStackTrace();\r
- }\r
- }\r
- conn.dbShutdown();\r
- }\r
- \r
- \r
- private void processImage() {\r
- boolean abort = true;\r
- if (abort)\r
- return;\r
- mutex.lock();\r
- logger.log(logger.EXTREME, "Image found "+guid);\r
- \r
- logger.log(logger.EXTREME, "Getting image");\r
- QPixmap image = new QPixmap();\r
- if (!image.load(Global.getFileManager().getResDirPath()+"thumbnail-"+guid+".png")) {\r
- logger.log(logger.EXTREME, "Failure to reload image. Aborting.");\r
- mutex.unlock();\r
- return;\r
- }\r
- \r
- \r
- logger.log(logger.EXTREME, "Opening buffer");\r
- QBuffer buffer = new QBuffer();\r
- if (!buffer.open(QIODevice.OpenModeFlag.WriteOnly)) {\r
- logger.log(logger.EXTREME, "Failure to open buffer. Aborting.");\r
- mutex.unlock();\r
- return;\r
- }\r
- \r
- logger.log(logger.EXTREME, "Filling buffer");\r
- if (!image.save(buffer, "PNG")) {\r
- logger.log(logger.EXTREME, "Failure to write to buffer. Aborting."); \r
- mutex.unlock();\r
- return;\r
- }\r
- buffer.close();\r
- \r
- logger.log(logger.EXTREME, "Updating database");\r
- QByteArray b = new QBuffer(buffer).buffer();\r
- conn.getNoteTable().setThumbnail(guid, b);\r
- conn.getNoteTable().setThumbnailNeeded(guid, false);\r
- mutex.unlock();\r
- }\r
- \r
- \r
- \r
- private void scanDatabase() {\r
- // If there is already work in the queue, that takes priority\r
- logger.log(logger.HIGH, "Scanning database for notes needing thumbnail");\r
- if (workQueue.size() > 0)\r
- return;\r
- \r
- // Find a few records that need thumbnails\r
- List<String> guids = conn.getNoteTable().findThumbnailsNeeded();\r
- logger.log(logger.HIGH, guids.size() +" records returned");\r
- for (int i=0; i<guids.size() && keepRunning && !interrupt; i++) {\r
- guid = guids.get(i);\r
- logger.log(logger.HIGH, "Working on:" +guids.get(i));\r
- generateThumbnail();\r
- }\r
- logger.log(logger.HIGH, "Scan completed");\r
- }\r
-\r
- \r
- public synchronized boolean addWork(String request) {\r
-\r
- if (workQueue.size() == 0) {\r
- workQueue.offer(request);\r
- return true;\r
- }\r
- return false;\r
- }\r
- \r
- public synchronized int getWorkQueueSize() {\r
- return workQueue.size();\r
- }\r
- \r
- private void generateThumbnail() {\r
- QByteArray js = new QByteArray();\r
- logger.log(logger.HIGH, "Starting thumbnail for " +guid);\r
- ArrayList<QTemporaryFile> tempFiles = new ArrayList<QTemporaryFile>();\r
- Note currentNote = conn.getNoteTable().getNote(guid,true,true,false,true,false);\r
- NoteFormatter formatter = new NoteFormatter(logger, conn, tempFiles);\r
- currentNote = conn.getNoteTable().getNote(guid, true, true, false, true, false);\r
- formatter.setNote(currentNote, true);\r
- formatter.setHighlight(null);\r
- js.append("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">"); \r
- js.append("<style type=\"text/css\">.en-crypt-temp { border-collapse:collapse; border-style:solid; border-color:blue; padding:0.0mm 0.0mm 0.0mm 0.0mm; }</style>");\r
- js.append("<style type=\"text/css\">en-hilight { background-color: rgb(255,255,0) }</style>");\r
- js.append("<style> img { max-width:100%; }</style>");\r
- js.append("<style type=\"text/css\">en-spell { text-decoration: none; border-bottom: dotted 1px #cc0000; }</style>");\r
- js.append("</head>");\r
- js.append(formatter.rebuildNoteHTML());\r
- js.append("</HTML>");\r
- js.replace("<!DOCTYPE en-note SYSTEM 'http://xml.evernote.com/pub/enml.dtd'>", "");\r
- js.replace("<!DOCTYPE en-note SYSTEM 'http://xml.evernote.com/pub/enml2.dtd'>", "");\r
- js.replace("<?xml version='1.0' encoding='UTF-8'?>", "");\r
- int zoom = 1;\r
- if (currentNote != null && currentNote.getContent() != null) {\r
- String content = currentNote.getContent();\r
- zoom = Global.calculateThumbnailZoom(content);\r
- }\r
- logger.log(logger.HIGH, "Thumbnail file ready");\r
- noteSignal.thumbnailPageReady.emit(guid, js, zoom);\r
- }\r
- \r
- \r
-\r
-\r
-}\r
+/*
+ * This file is part of NixNote
+ * Copyright 2009 Randy Baumgarte
+ *
+ * This file may be licensed under the terms of of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+*/
+
+package cx.fbn.nevernote.threads;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import com.evernote.edam.type.Note;
+import com.trolltech.qt.core.QBuffer;
+import com.trolltech.qt.core.QByteArray;
+import com.trolltech.qt.core.QIODevice;
+import com.trolltech.qt.core.QMutex;
+import com.trolltech.qt.core.QObject;
+import com.trolltech.qt.core.QTemporaryFile;
+import com.trolltech.qt.gui.QPixmap;
+
+import cx.fbn.nevernote.Global;
+import cx.fbn.nevernote.signals.NoteSignal;
+import cx.fbn.nevernote.sql.DatabaseConnection;
+import cx.fbn.nevernote.utilities.ApplicationLogger;
+import cx.fbn.nevernote.xml.NoteFormatter;
+
+
+/*
+ *
+ * @author Randy Baumgarte
+ *
+ * Thumbnail Overview:
+ *
+ * How thumbnails are generated is a bit odd. The problem is that
+ * process of creating the thumbnail involves actually creating an HTML
+ * version of the note & all of its resources. That is very CPU intensive
+ * so we try to do it in a separate thread. Unfortunately, the QWebPage class
+ * which actually creates the thumbnail must be in the main GUI thread.
+ * This is the odd way I've tried to get around the problem.
+ *
+ * First, the thumbail thread finds a note which needs a thumbnail. This
+ * can be done by either scanning the database or specifically being told
+ * a note needs a new thumbnail.
+ *
+ * When a note is found, this thread will read the database and write out
+ * the resources and create an HTML version of the note. It then signals
+ * the main GUI thread that a note is ready.
+ *
+ * Next, the main GUI thread will process the signal received from the
+ * thumbnail thread. The GUI thread will create a QWebPage (via the
+ * Thumbnailer class) and will render the image. The image is written to
+ * the database to be used in the thumbnail view.
+ *
+ */
+public class ThumbnailRunner extends QObject implements Runnable {
+
+ private final ApplicationLogger logger;
+ private String guid;
+ public NoteSignal noteSignal;
+ private boolean keepRunning;
+ public boolean interrupt;
+ private final DatabaseConnection conn;
+ private volatile LinkedBlockingQueue<String> workQueue;
+ private static int MAX_QUEUED_WAITING = 1000;
+ public QMutex mutex;
+
+
+ // ICHANGED String bを追加
+ public ThumbnailRunner(String logname, String u, String i, String r, String b, String uid, String pswd, String cpswd) {
+ logger = new ApplicationLogger(logname);
+ // ICHANGED bを追加
+ conn = new DatabaseConnection(logger, u, i, r, b, uid, pswd, cpswd, 300);
+ noteSignal = new NoteSignal();
+ guid = null;
+ keepRunning = true;
+ mutex = new QMutex();
+ workQueue=new LinkedBlockingQueue<String>(MAX_QUEUED_WAITING);
+ }
+
+
+ @Override
+ public void run() {
+ thread().setPriority(Thread.MIN_PRIORITY);
+
+ logger.log(logger.MEDIUM, "Starting thumbnail thread ");
+ while (keepRunning) {
+ try {
+ interrupt = false;
+ String work = workQueue.take();
+ if (work.startsWith("GENERATE")) {
+ work = work.replace("GENERATE ", "");
+ guid = work;
+ generateThumbnail();
+ }
+ if (work.startsWith("SCAN")) {
+ if (conn.getNoteTable().getThumbnailNeededCount() > 1)
+ scanDatabase();
+ }
+ if (work.startsWith("IMAGE")) {
+ work = work.replace("IMAGE ", "");
+ guid = work;
+ processImage();
+ }
+ if (work.startsWith("STOP")) {
+ logger.log(logger.MEDIUM, "Stopping thumbail thread");
+ keepRunning = false;
+ }
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ conn.dbShutdown();
+ }
+
+
+ private void processImage() {
+ boolean abort = true;
+ if (abort)
+ return;
+ mutex.lock();
+ logger.log(logger.EXTREME, "Image found "+guid);
+
+ logger.log(logger.EXTREME, "Getting image");
+ QPixmap image = new QPixmap();
+ if (!image.load(Global.getFileManager().getResDirPath()+"thumbnail-"+guid+".png")) {
+ logger.log(logger.EXTREME, "Failure to reload image. Aborting.");
+ mutex.unlock();
+ return;
+ }
+
+
+ logger.log(logger.EXTREME, "Opening buffer");
+ QBuffer buffer = new QBuffer();
+ if (!buffer.open(QIODevice.OpenModeFlag.WriteOnly)) {
+ logger.log(logger.EXTREME, "Failure to open buffer. Aborting.");
+ mutex.unlock();
+ return;
+ }
+
+ logger.log(logger.EXTREME, "Filling buffer");
+ if (!image.save(buffer, "PNG")) {
+ logger.log(logger.EXTREME, "Failure to write to buffer. Aborting.");
+ mutex.unlock();
+ return;
+ }
+ buffer.close();
+
+ logger.log(logger.EXTREME, "Updating database");
+ QByteArray b = new QBuffer(buffer).buffer();
+ conn.getNoteTable().setThumbnail(guid, b);
+ conn.getNoteTable().setThumbnailNeeded(guid, false);
+ mutex.unlock();
+ }
+
+
+
+ private void scanDatabase() {
+ // If there is already work in the queue, that takes priority
+ logger.log(logger.HIGH, "Scanning database for notes needing thumbnail");
+ if (workQueue.size() > 0)
+ return;
+
+ // Find a few records that need thumbnails
+ List<String> guids = conn.getNoteTable().findThumbnailsNeeded();
+ logger.log(logger.HIGH, guids.size() +" records returned");
+ for (int i=0; i<guids.size() && keepRunning && !interrupt; i++) {
+ guid = guids.get(i);
+ logger.log(logger.HIGH, "Working on:" +guids.get(i));
+ generateThumbnail();
+ }
+ logger.log(logger.HIGH, "Scan completed");
+ }
+
+
+ public synchronized boolean addWork(String request) {
+
+ if (workQueue.size() == 0) {
+ workQueue.offer(request);
+ return true;
+ }
+ return false;
+ }
+
+ public synchronized int getWorkQueueSize() {
+ return workQueue.size();
+ }
+
+ private void generateThumbnail() {
+ QByteArray js = new QByteArray();
+ logger.log(logger.HIGH, "Starting thumbnail for " +guid);
+ ArrayList<QTemporaryFile> tempFiles = new ArrayList<QTemporaryFile>();
+ Note currentNote = conn.getNoteTable().getNote(guid,true,true,false,true,false);
+ NoteFormatter formatter = new NoteFormatter(logger, conn, tempFiles);
+ currentNote = conn.getNoteTable().getNote(guid, true, true, false, true, false);
+ formatter.setNote(currentNote, true);
+ formatter.setHighlight(null);
+ js.append("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
+ js.append("<style type=\"text/css\">.en-crypt-temp { border-collapse:collapse; border-style:solid; border-color:blue; padding:0.0mm 0.0mm 0.0mm 0.0mm; }</style>");
+ js.append("<style type=\"text/css\">en-hilight { background-color: rgb(255,255,0) }</style>");
+ js.append("<style> img { max-width:100%; }</style>");
+ js.append("<style type=\"text/css\">en-spell { text-decoration: none; border-bottom: dotted 1px #cc0000; }</style>");
+ js.append("</head>");
+ js.append(formatter.rebuildNoteHTML());
+ js.append("</HTML>");
+ js.replace("<!DOCTYPE en-note SYSTEM 'http://xml.evernote.com/pub/enml.dtd'>", "");
+ js.replace("<!DOCTYPE en-note SYSTEM 'http://xml.evernote.com/pub/enml2.dtd'>", "");
+ js.replace("<?xml version='1.0' encoding='UTF-8'?>", "");
+ int zoom = 1;
+ if (currentNote != null && currentNote.getContent() != null) {
+ String content = currentNote.getContent();
+ zoom = Global.calculateThumbnailZoom(content);
+ }
+ logger.log(logger.HIGH, "Thumbnail file ready");
+ noteSignal.thumbnailPageReady.emit(guid, js, zoom);
+ }
+
+
+
+
+}
-/*\r
- * This file is part of NixNote \r
- * Copyright 2009 Randy Baumgarte\r
- * \r
- * This file may be licensed under the terms of of the\r
- * GNU General Public License Version 2 (the ``GPL'').\r
- *\r
- * Software distributed under the License is distributed\r
- * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either\r
- * express or implied. See the GPL for the specific language\r
- * governing rights and limitations.\r
- *\r
- * You should have received a copy of the GPL along with this\r
- * program. If not, go to http://www.gnu.org/licenses/gpl.html\r
- * or write to the Free Software Foundation, Inc.,\r
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
- *\r
-*/\r
-\r
-package cx.fbn.nevernote.utilities;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Calendar;\r
-import java.util.Collections;\r
-import java.util.Comparator;\r
-import java.util.GregorianCalendar;\r
-import java.util.HashMap;\r
-import java.util.List;\r
-import java.util.Vector;\r
-\r
-import com.evernote.edam.type.LinkedNotebook;\r
-import com.evernote.edam.type.Note;\r
-import com.evernote.edam.type.Notebook;\r
-import com.evernote.edam.type.SavedSearch;\r
-import com.evernote.edam.type.Tag;\r
-import com.trolltech.qt.QThread;\r
-import com.trolltech.qt.core.QDateTime;\r
-import com.trolltech.qt.gui.QImage;\r
-import com.trolltech.qt.gui.QPixmap;\r
-import com.trolltech.qt.sql.QSqlQuery;\r
-import com.trolltech.qt.xml.QDomAttr;\r
-import com.trolltech.qt.xml.QDomDocument;\r
-import com.trolltech.qt.xml.QDomElement;\r
-import com.trolltech.qt.xml.QDomNodeList;\r
-\r
-import cx.fbn.nevernote.Global;\r
-import cx.fbn.nevernote.evernote.NoteMetadata;\r
-import cx.fbn.nevernote.filters.EnSearch;\r
-import cx.fbn.nevernote.filters.NotebookCounter;\r
-import cx.fbn.nevernote.filters.TagCounter;\r
-import cx.fbn.nevernote.gui.NoteTableModel;\r
-import cx.fbn.nevernote.signals.NotebookSignal;\r
-import cx.fbn.nevernote.signals.StatusSignal;\r
-import cx.fbn.nevernote.signals.TagSignal;\r
-import cx.fbn.nevernote.signals.ThreadSignal;\r
-import cx.fbn.nevernote.signals.TrashSignal;\r
-import cx.fbn.nevernote.sql.DatabaseConnection;\r
-import cx.fbn.nevernote.threads.CounterRunner;\r
-import cx.fbn.nevernote.threads.SaveRunner;\r
-\r
-\r
-public class ListManager {\r
-\r
- \r
- private final ApplicationLogger logger; \r
- DatabaseConnection conn;\r
- QSqlQuery deleteWords;\r
- QSqlQuery insertWords;\r
- \r
- private List<Tag> tagIndex;\r
- private List<Notebook> notebookIndex;\r
- private List<Notebook> archiveNotebookIndex;\r
- private List<String> localNotebookIndex;\r
- private List<LinkedNotebook> linkedNotebookIndex;\r
-\r
- private List<SavedSearch> searchIndex;\r
-\r
- private List<String> selectedNotebooks;\r
- private final NoteTableModel noteModel;\r
- \r
- \r
- private List<String> selectedTags;\r
- private String selectedSearch;\r
- ThreadSignal signals;\r
- public StatusSignal status;\r
- private final CounterRunner notebookCounterRunner;\r
- private final QThread notebookThread;\r
- private final CounterRunner tagCounterRunner;\r
- private final QThread tagThread;\r
- \r
- private final CounterRunner trashCounterRunner;\r
- private final QThread trashThread;\r
- public TrashSignal trashSignal;\r
- \r
- private List<NotebookCounter> notebookCounter; // count of displayed notes in each notebook\r
- private List<TagCounter> tagCounter; // count of displayed notes for each tag\r
- \r
- private EnSearch enSearch;\r
- private boolean enSearchChanged;\r
- public HashMap<String, String> wordMap;\r
- public TagSignal tagSignal;\r
- public NotebookSignal notebookSignal;\r
- public boolean refreshCounters; // Used to control when to recount lists\r
- private int trashCount;\r
- public SaveRunner saveRunner; // Thread used to save content. Used because the xml conversion is slowwwww\r
- QThread saveThread;\r
- \r
-// private final HashMap<String, QImage> thumbnailList;\r
- \r
- // Constructor\r
- public ListManager(DatabaseConnection d, ApplicationLogger l) {\r
- conn = d;\r
- logger = l;\r
- \r
- conn.getTagTable().cleanupTags();\r
- status = new StatusSignal();\r
- signals = new ThreadSignal();\r
- \r
- // setup index locks\r
- enSearchChanged = false;\r
- \r
- // Setup arrays\r
- noteModel = new NoteTableModel(this);\r
- selectedTags = new ArrayList<String>();\r
-\r
- notebookCounter = new ArrayList<NotebookCounter>();\r
- tagCounter = new ArrayList<TagCounter>();\r
- selectedNotebooks = new ArrayList<String>();\r
- \r
- reloadIndexes();\r
- \r
- notebookSignal = new NotebookSignal();\r
- notebookCounterRunner = new CounterRunner("notebook_counter.log", CounterRunner.NOTEBOOK, \r
- Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(),\r
- Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);\r
- notebookCounterRunner.setNoteIndex(getNoteIndex());\r
- notebookCounterRunner.notebookSignal.countsChanged.connect(this, "setNotebookCounter(List)");\r
- notebookThread = new QThread(notebookCounterRunner, "Notebook Counter Thread");\r
- notebookThread.start();\r
- \r
- tagSignal = new TagSignal();\r
- tagCounterRunner = new CounterRunner("tag_counter.log", CounterRunner.TAG, \r
- Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(),\r
- Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);\r
- tagCounterRunner.setNoteIndex(getNoteIndex());\r
- tagCounterRunner.tagSignal.countsChanged.connect(this, "setTagCounter(List)");\r
- tagThread = new QThread(tagCounterRunner, "Tag Counter Thread");\r
- tagThread.start();\r
- \r
- trashSignal = new TrashSignal();\r
- trashCounterRunner = new CounterRunner("trash_counter.log", CounterRunner.TRASH, \r
- Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(),\r
- Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);\r
- trashCounterRunner.trashSignal.countChanged.connect(this, "trashSignalReceiver(Integer)");\r
- trashThread = new QThread(trashCounterRunner, "Trash Counter Thread");\r
- trashThread.start();\r
-// reloadTrashCount();\r
- \r
- wordMap = new HashMap<String, String>();\r
- tagSignal = new TagSignal();\r
- \r
- logger.log(logger.EXTREME, "Setting save thread");\r
- saveRunner = new SaveRunner("saveRunner.log", \r
- Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(),\r
- Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);\r
- saveThread = new QThread(saveRunner, "Save Runner Thread");\r
- saveThread.start();\r
- \r
-// thumbnailList = conn.getNoteTable().getThumbnails();\r
-// thumbnailList = new HashMap<String,QImage>();\r
- \r
- linkedNotebookIndex = conn.getLinkedNotebookTable().getAll();\r
- loadNoteTitleColors();\r
- refreshCounters = true;\r
- refreshCounters();\r
- \r
- }\r
- \r
- public void stop() {\r
- saveRunner.addWork("stop", "");\r
- tagCounterRunner.release(CounterRunner.EXIT);\r
- notebookCounterRunner.release(CounterRunner.EXIT);\r
- trashCounterRunner.release(CounterRunner.EXIT);\r
- \r
- logger.log(logger.MEDIUM, "Waiting for notebookCounterThread to stop"); \r
- try {\r
- notebookThread.join();\r
- } catch (InterruptedException e) {\r
- e.printStackTrace();\r
- }\r
- \r
- logger.log(logger.MEDIUM, "Waiting for tagCounterThread to stop"); \r
- try {\r
- tagThread.join();\r
- } catch (InterruptedException e) {\r
- e.printStackTrace();\r
- }\r
-\r
- logger.log(logger.MEDIUM, "Waiting for trashThread to stop"); \r
- try {\r
- trashThread.join();\r
- } catch (InterruptedException e) {\r
- e.printStackTrace();\r
- }\r
-\r
-\r
- logger.log(logger.MEDIUM, "Waiting for saveThread to stop"); \r
- try {\r
- saveThread.join(0);\r
- } catch (InterruptedException e) {\r
- e.printStackTrace();\r
- }\r
-\r
- }\r
-\r
- //***************************************************************\r
- //***************************************************************\r
- //* Refresh lists after a db sync\r
- //***************************************************************\r
- //***************************************************************\r
- public void refreshLists(Note n, boolean dirty, String content) {\r
- if (dirty) {\r
-// conn.getNoteTable().updateNoteContent(n.getGuid(), n.getContent());\r
- saveRunner.addWork(n.getGuid(), content);\r
- conn.getNoteTable().updateNoteTitle(n.getGuid(), n.getTitle());\r
- }\r
- \r
- setSavedSearchIndex(conn.getSavedSearchTable().getAll());\r
- setTagIndex(conn.getTagTable().getAll());\r
- setNotebookIndex(conn.getNotebookTable().getAll());\r
- \r
- List<Notebook> local = conn.getNotebookTable().getAllLocal();\r
- localNotebookIndex = new ArrayList<String>();\r
- for (int i=0; i<local.size(); i++)\r
- localNotebookIndex.add(local.get(i).getGuid());\r
- \r
- noteModel.setMasterNoteIndex(conn.getNoteTable().getAllNotes());\r
- // For performance reasons, we didn't get the tags for every note individually. We now need to \r
- // get them\r
- List<cx.fbn.nevernote.sql.NoteTagsRecord> noteTags = conn.getNoteTable().noteTagsTable.getAllNoteTags();\r
- for (int i=0; i<getMasterNoteIndex().size(); i++) {\r
- List<String> tags = new ArrayList<String>();\r
- List<String> names = new ArrayList<String>();\r
- for (int j=0; j<noteTags.size(); j++) {\r
- if (getMasterNoteIndex().get(i).getGuid().equals(noteTags.get(j).noteGuid)) {\r
- tags.add(noteTags.get(j).tagGuid);\r
- names.add(getTagNameByGuid(noteTags.get(j).tagGuid));\r
- }\r
- }\r
- \r
- getMasterNoteIndex().get(i).setTagGuids(tags);\r
- getMasterNoteIndex().get(i).setTagNames(names);\r
- }\r
- \r
- \r
- //setUnsynchronizedNotes(conn.getNoteTable().getUnsynchronizedGUIDs());\r
- \r
- linkedNotebookIndex = conn.getLinkedNotebookTable().getAll();\r
- \r
- enSearchChanged = true;\r
- }\r
-\r
- public void reloadTagIndex() {\r
- setTagIndex(conn.getTagTable().getAll()); \r
- }\r
- public void reloadIndexes() {\r
- //setUnsynchronizedNotes(conn.getNoteTable().getUnsynchronizedGUIDs());\r
-\r
- List<Notebook> local = conn.getNotebookTable().getAllLocal();\r
- localNotebookIndex = new ArrayList<String>();\r
- for (int i=0; i<local.size(); i++)\r
- localNotebookIndex.add(local.get(i).getGuid());\r
- \r
- reloadTagIndex();\r
- // Load notebooks\r
- setNotebookIndex(conn.getNotebookTable().getAll());\r
- // load archived notebooks (if note using the EN interface)\r
- setArchiveNotebookIndex(conn.getNotebookTable().getAllArchived());\r
- // load saved search index\r
- setSavedSearchIndex(conn.getSavedSearchTable().getAll());\r
- // Load search helper utility\r
- enSearch = new EnSearch(conn, logger, "", getTagIndex(), Global.getRecognitionWeight());\r
- logger.log(logger.HIGH, "Building note index");\r
-\r
-// if (getMasterNoteIndex() == null) { \r
- noteModel.setMasterNoteIndex(conn.getNoteTable().getAllNotes());\r
-// }\r
- // For performance reasons, we didn't get the tags for every note individually. We now need to \r
- // get them\r
- List<cx.fbn.nevernote.sql.NoteTagsRecord> noteTags = conn.getNoteTable().noteTagsTable.getAllNoteTags();\r
- for (int i=0; i<getMasterNoteIndex().size(); i++) {\r
- List<String> tags = new ArrayList<String>();\r
- List<String> names = new ArrayList<String>();\r
- for (int j=0; j<noteTags.size(); j++) {\r
- if (getMasterNoteIndex().get(i).getGuid().equals(noteTags.get(j).noteGuid)) {\r
- tags.add(noteTags.get(j).tagGuid);\r
- names.add(getTagNameByGuid(noteTags.get(j).tagGuid));\r
- }\r
- }\r
- \r
- getMasterNoteIndex().get(i).setTagGuids(tags);\r
- getMasterNoteIndex().get(i).setTagNames(names);\r
- }\r
- \r
- setNoteIndex(getMasterNoteIndex());\r
-\r
- }\r
- \r
- //***************************************************************\r
- //***************************************************************\r
- //* selected notebooks\r
- //***************************************************************\r
- //***************************************************************\r
- // Return the selected notebook(s)\r
- public List<String> getSelectedNotebooks() {\r
- return selectedNotebooks;\r
- }\r
- // Set the current selected notebook(s)\r
- public void setSelectedNotebooks(List <String> s) {\r
- if (s == null) \r
- s = new ArrayList<String>();\r
- selectedNotebooks = s;\r
- }\r
- \r
- \r
- //***************************************************************\r
- //***************************************************************\r
- //** These functions deal with setting & retrieving the master lists\r
- //***************************************************************\r
- //***************************************************************\r
- // Get the note table model\r
- public NoteTableModel getNoteTableModel() {\r
- return noteModel;\r
- }\r
- // save the saved search index\r
- private void setSavedSearchIndex(List<SavedSearch> t) {\r
- searchIndex = t;\r
- }\r
- // Retrieve the Tag index\r
- public List<SavedSearch> getSavedSearchIndex() {\r
- return searchIndex;\r
-\r
- }\r
- // save the tag index\r
- private void setTagIndex(List<Tag> t) {\r
- tagIndex = t;\r
- } \r
- // Retrieve the Tag index\r
- public List<Tag> getTagIndex() {\r
- return tagIndex;\r
- }\r
- private void setNotebookIndex(List<Notebook> t) {\r
- notebookIndex = t;\r
- }\r
- private void setArchiveNotebookIndex(List<Notebook> t) {\r
- archiveNotebookIndex = t;\r
- }\r
- // Retrieve the Notebook index\r
- public List<Notebook> getNotebookIndex() {\r
- return notebookIndex;\r
-\r
- }\r
- public List<LinkedNotebook> getLinkedNotebookIndex() {\r
- return linkedNotebookIndex;\r
- }\r
- public List<Notebook> getArchiveNotebookIndex() {\r
- return archiveNotebookIndex;\r
- }\r
- // Save the current note list\r
- private void setNoteIndex(List<Note> n) {\r
- noteModel.setNoteIndex(n);\r
- refreshNoteMetadata();\r
- }\r
- public void refreshNoteMetadata() {\r
- noteModel.setNoteMetadata(conn.getNoteTable().getNotesMetaInformation());\r
- }\r
- // Update a note's meta data\r
- public void updateNoteMetadata(NoteMetadata meta) {\r
- noteModel.metaData.remove(meta);\r
- noteModel.metaData.put(meta.getGuid(), meta);\r
- conn.getNoteTable().updateNoteMetadata(meta);\r
- }\r
- // Get the note index\r
- public synchronized List<Note> getNoteIndex() {\r
- return noteModel.getNoteIndex();\r
- }\r
- // Save the count of notes per notebook\r
- public void setNotebookCounter(List<NotebookCounter> n) {\r
- notebookCounter = n;\r
- notebookSignal.refreshNotebookTreeCounts.emit(getNotebookIndex(), notebookCounter);\r
- }\r
- public List<NotebookCounter> getNotebookCounter() {\r
- return notebookCounter;\r
- }\r
- // Save the count of notes for each tag\r
- public void setTagCounter(List<TagCounter> n) {\r
- tagCounter = n;\r
- tagSignal.refreshTagTreeCounts.emit(tagCounter);\r
- }\r
- public List<TagCounter> getTagCounter() {\r
- return tagCounter;\r
- }\r
- public List<String> getLocalNotebooks() {\r
- return localNotebookIndex;\r
- }\r
-\r
-// public void setUnsynchronizedNotes(List<String> l) {\r
-// noteModel.setUnsynchronizedNotes(l);\r
-// }\r
- // Return a count of items in the trash\r
- public int getTrashCount() {\r
- return trashCount;\r
- }\r
- // get the EnSearch variable\r
- public EnSearch getEnSearch() {\r
- return enSearch;\r
- }\r
- public List<Note> getMasterNoteIndex() {\r
- return noteModel.getMasterNoteIndex();\r
- }\r
- // Thumbnails\r
-// public HashMap<String, QImage> getThumbnails() {\r
-// return thumbnailList;\r
-// }\r
- public HashMap<String, NoteMetadata> getNoteMetadata() {\r
- return noteModel.metaData;\r
- }\r
- public QImage getThumbnail(String guid) {\r
-// if (getThumbnails().containsKey(guid))\r
-// return getThumbnails().get(guid);\r
- \r
- QImage img = new QImage();\r
- img = QImage.fromData(conn.getNoteTable().getThumbnail(guid));\r
- if (img == null || img.isNull()) \r
- return null;\r
- //getThumbnails().put(guid, img);\r
- return img;\r
- }\r
- public QPixmap getThumbnailPixmap(String guid) {\r
-// if (getThumbnails().containsKey(guid))\r
-// return getThumbnails().get(guid);\r
- \r
- QPixmap img = new QPixmap();\r
- img.loadFromData(conn.getNoteTable().getThumbnail(guid));\r
- if (img == null || img.isNull()) \r
- return null;\r
- //getThumbnails().put(guid, img);\r
- return img;\r
- }\r
- //***************************************************************\r
- //***************************************************************\r
- //** These functions deal with setting & retrieving filters\r
- //***************************************************************\r
- //***************************************************************\r
- public void setEnSearch(String t) {\r
- enSearch = new EnSearch(conn,logger, t, getTagIndex(), Global.getRecognitionWeight());\r
- enSearchChanged = true;\r
- }\r
- // Save search tags\r
- public void setSelectedTags(List<String> selectedTags) {\r
- this.selectedTags = selectedTags;\r
- }\r
- // Save seleceted search\r
- public void setSelectedSavedSearch(String s) {\r
- this.selectedSearch = s;\r
- }\r
- // Get search tags\r
- public List<String> getSelectedTags() {\r
- return selectedTags;\r
- }\r
- // Get saved search\r
- public String getSelectedSearch() {\r
- return selectedSearch;\r
- }\r
- \r
- \r
- \r
- \r
- //***************************************************************\r
- //***************************************************************\r
- //** Note functions\r
- //***************************************************************\r
- //***************************************************************\r
- // Save Note Tags\r
+/*
+ * This file is part of NixNote
+ * Copyright 2009 Randy Baumgarte
+ *
+ * This file may be licensed under the terms of of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+*/
+
+package cx.fbn.nevernote.utilities;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Vector;
+
+import com.evernote.edam.type.LinkedNotebook;
+import com.evernote.edam.type.Note;
+import com.evernote.edam.type.Notebook;
+import com.evernote.edam.type.SavedSearch;
+import com.evernote.edam.type.Tag;
+import com.trolltech.qt.QThread;
+import com.trolltech.qt.core.QDateTime;
+import com.trolltech.qt.gui.QImage;
+import com.trolltech.qt.gui.QPixmap;
+import com.trolltech.qt.sql.QSqlQuery;
+import com.trolltech.qt.xml.QDomAttr;
+import com.trolltech.qt.xml.QDomDocument;
+import com.trolltech.qt.xml.QDomElement;
+import com.trolltech.qt.xml.QDomNodeList;
+
+import cx.fbn.nevernote.Global;
+import cx.fbn.nevernote.evernote.NoteMetadata;
+import cx.fbn.nevernote.filters.EnSearch;
+import cx.fbn.nevernote.filters.NotebookCounter;
+import cx.fbn.nevernote.filters.TagCounter;
+import cx.fbn.nevernote.gui.NoteTableModel;
+import cx.fbn.nevernote.signals.NotebookSignal;
+import cx.fbn.nevernote.signals.StatusSignal;
+import cx.fbn.nevernote.signals.TagSignal;
+import cx.fbn.nevernote.signals.ThreadSignal;
+import cx.fbn.nevernote.signals.TrashSignal;
+import cx.fbn.nevernote.sql.DatabaseConnection;
+import cx.fbn.nevernote.threads.CounterRunner;
+import cx.fbn.nevernote.threads.SaveRunner;
+
+
+public class ListManager {
+
+
+ private final ApplicationLogger logger;
+ DatabaseConnection conn;
+ QSqlQuery deleteWords;
+ QSqlQuery insertWords;
+
+ private List<Tag> tagIndex;
+ private List<Notebook> notebookIndex;
+ private List<Notebook> archiveNotebookIndex;
+ private List<String> localNotebookIndex;
+ private List<LinkedNotebook> linkedNotebookIndex;
+
+ private List<SavedSearch> searchIndex;
+
+ private List<String> selectedNotebooks;
+ private final NoteTableModel noteModel;
+
+
+ private List<String> selectedTags;
+ private String selectedSearch;
+ ThreadSignal signals;
+ public StatusSignal status;
+ private final CounterRunner notebookCounterRunner;
+ private final QThread notebookThread;
+ private final CounterRunner tagCounterRunner;
+ private final QThread tagThread;
+
+ private final CounterRunner trashCounterRunner;
+ private final QThread trashThread;
+ public TrashSignal trashSignal;
+
+ private List<NotebookCounter> notebookCounter; // count of displayed notes in each notebook
+ private List<TagCounter> tagCounter; // count of displayed notes for each tag
+
+ private EnSearch enSearch;
+ private boolean enSearchChanged;
+ public HashMap<String, String> wordMap;
+ public TagSignal tagSignal;
+ public NotebookSignal notebookSignal;
+ public boolean refreshCounters; // Used to control when to recount lists
+ private int trashCount;
+ public SaveRunner saveRunner; // Thread used to save content. Used because the xml conversion is slowwwww
+ QThread saveThread;
+
+// private final HashMap<String, QImage> thumbnailList;
+
+ // Constructor
+ public ListManager(DatabaseConnection d, ApplicationLogger l) {
+ conn = d;
+ logger = l;
+
+ conn.getTagTable().cleanupTags();
+ status = new StatusSignal();
+ signals = new ThreadSignal();
+
+ // setup index locks
+ enSearchChanged = false;
+
+ // Setup arrays
+ noteModel = new NoteTableModel(this);
+ selectedTags = new ArrayList<String>();
+
+ notebookCounter = new ArrayList<NotebookCounter>();
+ tagCounter = new ArrayList<TagCounter>();
+ selectedNotebooks = new ArrayList<String>();
+
+ reloadIndexes();
+
+ notebookSignal = new NotebookSignal();
+ // ICHANGED Global.getBehaviorDatabaseUrl()を追加
+ notebookCounterRunner = new CounterRunner("notebook_counter.log", CounterRunner.NOTEBOOK,
+ Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(), Global.getBehaviorDatabaseUrl(),
+ Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);
+ notebookCounterRunner.setNoteIndex(getNoteIndex());
+ notebookCounterRunner.notebookSignal.countsChanged.connect(this, "setNotebookCounter(List)");
+ notebookThread = new QThread(notebookCounterRunner, "Notebook Counter Thread");
+ notebookThread.start();
+
+ tagSignal = new TagSignal();
+ // ICHANGED Global.getBehaviorDatabaseUrl()を追加
+ tagCounterRunner = new CounterRunner("tag_counter.log", CounterRunner.TAG,
+ Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(), Global.getBehaviorDatabaseUrl(),
+ Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);
+ tagCounterRunner.setNoteIndex(getNoteIndex());
+ tagCounterRunner.tagSignal.countsChanged.connect(this, "setTagCounter(List)");
+ tagThread = new QThread(tagCounterRunner, "Tag Counter Thread");
+ tagThread.start();
+
+ trashSignal = new TrashSignal();
+ // ICHANGED Global.getBehaviorDatabaseUrl()を追加
+ trashCounterRunner = new CounterRunner("trash_counter.log", CounterRunner.TRASH,
+ Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(), Global.getBehaviorDatabaseUrl(),
+ Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);
+ trashCounterRunner.trashSignal.countChanged.connect(this, "trashSignalReceiver(Integer)");
+ trashThread = new QThread(trashCounterRunner, "Trash Counter Thread");
+ trashThread.start();
+// reloadTrashCount();
+
+ wordMap = new HashMap<String, String>();
+ tagSignal = new TagSignal();
+
+ logger.log(logger.EXTREME, "Setting save thread");
+ // ICHANGED Global.getBehaviorDatabaseUrl()を追加
+ saveRunner = new SaveRunner("saveRunner.log",
+ Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(), Global.getBehaviorDatabaseUrl(),
+ Global.getDatabaseUserid(), Global.getDatabaseUserPassword(), Global.cipherPassword);
+ saveThread = new QThread(saveRunner, "Save Runner Thread");
+ saveThread.start();
+
+// thumbnailList = conn.getNoteTable().getThumbnails();
+// thumbnailList = new HashMap<String,QImage>();
+
+ linkedNotebookIndex = conn.getLinkedNotebookTable().getAll();
+ loadNoteTitleColors();
+ refreshCounters = true;
+ refreshCounters();
+
+ }
+
+ public void stop() {
+ saveRunner.addWork("stop", "");
+ tagCounterRunner.release(CounterRunner.EXIT);
+ notebookCounterRunner.release(CounterRunner.EXIT);
+ trashCounterRunner.release(CounterRunner.EXIT);
+
+ logger.log(logger.MEDIUM, "Waiting for notebookCounterThread to stop");
+ try {
+ notebookThread.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ logger.log(logger.MEDIUM, "Waiting for tagCounterThread to stop");
+ try {
+ tagThread.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ logger.log(logger.MEDIUM, "Waiting for trashThread to stop");
+ try {
+ trashThread.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+
+ logger.log(logger.MEDIUM, "Waiting for saveThread to stop");
+ try {
+ saveThread.join(0);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ //***************************************************************
+ //***************************************************************
+ //* Refresh lists after a db sync
+ //***************************************************************
+ //***************************************************************
+ public void refreshLists(Note n, boolean dirty, String content) {
+ if (dirty) {
+// conn.getNoteTable().updateNoteContent(n.getGuid(), n.getContent());
+ saveRunner.addWork(n.getGuid(), content);
+ conn.getNoteTable().updateNoteTitle(n.getGuid(), n.getTitle());
+ }
+
+ setSavedSearchIndex(conn.getSavedSearchTable().getAll());
+ setTagIndex(conn.getTagTable().getAll());
+ setNotebookIndex(conn.getNotebookTable().getAll());
+
+ List<Notebook> local = conn.getNotebookTable().getAllLocal();
+ localNotebookIndex = new ArrayList<String>();
+ for (int i=0; i<local.size(); i++)
+ localNotebookIndex.add(local.get(i).getGuid());
+
+ noteModel.setMasterNoteIndex(conn.getNoteTable().getAllNotes());
+ // For performance reasons, we didn't get the tags for every note individually. We now need to
+ // get them
+ List<cx.fbn.nevernote.sql.NoteTagsRecord> noteTags = conn.getNoteTable().noteTagsTable.getAllNoteTags();
+ for (int i=0; i<getMasterNoteIndex().size(); i++) {
+ List<String> tags = new ArrayList<String>();
+ List<String> names = new ArrayList<String>();
+ for (int j=0; j<noteTags.size(); j++) {
+ if (getMasterNoteIndex().get(i).getGuid().equals(noteTags.get(j).noteGuid)) {
+ tags.add(noteTags.get(j).tagGuid);
+ names.add(getTagNameByGuid(noteTags.get(j).tagGuid));
+ }
+ }
+
+ getMasterNoteIndex().get(i).setTagGuids(tags);
+ getMasterNoteIndex().get(i).setTagNames(names);
+ }
+
+
+ //setUnsynchronizedNotes(conn.getNoteTable().getUnsynchronizedGUIDs());
+
+ linkedNotebookIndex = conn.getLinkedNotebookTable().getAll();
+
+ enSearchChanged = true;
+ }
+
+ public void reloadTagIndex() {
+ setTagIndex(conn.getTagTable().getAll());
+ }
+ public void reloadIndexes() {
+ //setUnsynchronizedNotes(conn.getNoteTable().getUnsynchronizedGUIDs());
+
+ List<Notebook> local = conn.getNotebookTable().getAllLocal();
+ localNotebookIndex = new ArrayList<String>();
+ for (int i=0; i<local.size(); i++)
+ localNotebookIndex.add(local.get(i).getGuid());
+
+ reloadTagIndex();
+ // Load notebooks
+ setNotebookIndex(conn.getNotebookTable().getAll());
+ // load archived notebooks (if note using the EN interface)
+ setArchiveNotebookIndex(conn.getNotebookTable().getAllArchived());
+ // load saved search index
+ setSavedSearchIndex(conn.getSavedSearchTable().getAll());
+ // Load search helper utility
+ enSearch = new EnSearch(conn, logger, "", getTagIndex(), Global.getRecognitionWeight());
+ logger.log(logger.HIGH, "Building note index");
+
+// if (getMasterNoteIndex() == null) {
+ noteModel.setMasterNoteIndex(conn.getNoteTable().getAllNotes());
+// }
+ // For performance reasons, we didn't get the tags for every note individually. We now need to
+ // get them
+ List<cx.fbn.nevernote.sql.NoteTagsRecord> noteTags = conn.getNoteTable().noteTagsTable.getAllNoteTags();
+ for (int i=0; i<getMasterNoteIndex().size(); i++) {
+ List<String> tags = new ArrayList<String>();
+ List<String> names = new ArrayList<String>();
+ for (int j=0; j<noteTags.size(); j++) {
+ if (getMasterNoteIndex().get(i).getGuid().equals(noteTags.get(j).noteGuid)) {
+ tags.add(noteTags.get(j).tagGuid);
+ names.add(getTagNameByGuid(noteTags.get(j).tagGuid));
+ }
+ }
+
+ getMasterNoteIndex().get(i).setTagGuids(tags);
+ getMasterNoteIndex().get(i).setTagNames(names);
+ }
+
+ setNoteIndex(getMasterNoteIndex());
+
+ }
+
+ //***************************************************************
+ //***************************************************************
+ //* selected notebooks
+ //***************************************************************
+ //***************************************************************
+ // Return the selected notebook(s)
+ public List<String> getSelectedNotebooks() {
+ return selectedNotebooks;
+ }
+ // Set the current selected notebook(s)
+ public void setSelectedNotebooks(List <String> s) {
+ if (s == null)
+ s = new ArrayList<String>();
+ selectedNotebooks = s;
+ }
+
+
+ //***************************************************************
+ //***************************************************************
+ //** These functions deal with setting & retrieving the master lists
+ //***************************************************************
+ //***************************************************************
+ // Get the note table model
+ public NoteTableModel getNoteTableModel() {
+ return noteModel;
+ }
+ // save the saved search index
+ private void setSavedSearchIndex(List<SavedSearch> t) {
+ searchIndex = t;
+ }
+ // Retrieve the Tag index
+ public List<SavedSearch> getSavedSearchIndex() {
+ return searchIndex;
+
+ }
+ // save the tag index
+ private void setTagIndex(List<Tag> t) {
+ tagIndex = t;
+ }
+ // Retrieve the Tag index
+ public List<Tag> getTagIndex() {
+ return tagIndex;
+ }
+ private void setNotebookIndex(List<Notebook> t) {
+ notebookIndex = t;
+ }
+ private void setArchiveNotebookIndex(List<Notebook> t) {
+ archiveNotebookIndex = t;
+ }
+ // Retrieve the Notebook index
+ public List<Notebook> getNotebookIndex() {
+ return notebookIndex;
+
+ }
+ public List<LinkedNotebook> getLinkedNotebookIndex() {
+ return linkedNotebookIndex;
+ }
+ public List<Notebook> getArchiveNotebookIndex() {
+ return archiveNotebookIndex;
+ }
+ // Save the current note list
+ private void setNoteIndex(List<Note> n) {
+ noteModel.setNoteIndex(n);
+ refreshNoteMetadata();
+ }
+ public void refreshNoteMetadata() {
+ noteModel.setNoteMetadata(conn.getNoteTable().getNotesMetaInformation());
+ }
+ // Update a note's meta data
+ public void updateNoteMetadata(NoteMetadata meta) {
+ noteModel.metaData.remove(meta);
+ noteModel.metaData.put(meta.getGuid(), meta);
+ conn.getNoteTable().updateNoteMetadata(meta);
+ }
+ // Get the note index
+ public synchronized List<Note> getNoteIndex() {
+ return noteModel.getNoteIndex();
+ }
+ // Save the count of notes per notebook
+ public void setNotebookCounter(List<NotebookCounter> n) {
+ notebookCounter = n;
+ notebookSignal.refreshNotebookTreeCounts.emit(getNotebookIndex(), notebookCounter);
+ }
+ public List<NotebookCounter> getNotebookCounter() {
+ return notebookCounter;
+ }
+ // Save the count of notes for each tag
+ public void setTagCounter(List<TagCounter> n) {
+ tagCounter = n;
+ tagSignal.refreshTagTreeCounts.emit(tagCounter);
+ }
+ public List<TagCounter> getTagCounter() {
+ return tagCounter;
+ }
+ public List<String> getLocalNotebooks() {
+ return localNotebookIndex;
+ }
+
+// public void setUnsynchronizedNotes(List<String> l) {
+// noteModel.setUnsynchronizedNotes(l);
+// }
+ // Return a count of items in the trash
+ public int getTrashCount() {
+ return trashCount;
+ }
+ // get the EnSearch variable
+ public EnSearch getEnSearch() {
+ return enSearch;
+ }
+ public List<Note> getMasterNoteIndex() {
+ return noteModel.getMasterNoteIndex();
+ }
+ // Thumbnails
+// public HashMap<String, QImage> getThumbnails() {
+// return thumbnailList;
+// }
+ public HashMap<String, NoteMetadata> getNoteMetadata() {
+ return noteModel.metaData;
+ }
+ public QImage getThumbnail(String guid) {
+// if (getThumbnails().containsKey(guid))
+// return getThumbnails().get(guid);
+
+ QImage img = new QImage();
+ img = QImage.fromData(conn.getNoteTable().getThumbnail(guid));
+ if (img == null || img.isNull())
+ return null;
+ //getThumbnails().put(guid, img);
+ return img;
+ }
+ public QPixmap getThumbnailPixmap(String guid) {
+// if (getThumbnails().containsKey(guid))
+// return getThumbnails().get(guid);
+
+ QPixmap img = new QPixmap();
+ img.loadFromData(conn.getNoteTable().getThumbnail(guid));
+ if (img == null || img.isNull())
+ return null;
+ //getThumbnails().put(guid, img);
+ return img;
+ }
+ //***************************************************************
+ //***************************************************************
+ //** These functions deal with setting & retrieving filters
+ //***************************************************************
+ //***************************************************************
+ public void setEnSearch(String t) {
+ enSearch = new EnSearch(conn,logger, t, getTagIndex(), Global.getRecognitionWeight());
+ enSearchChanged = true;
+ }
+ // Save search tags
+ public void setSelectedTags(List<String> selectedTags) {
+ this.selectedTags = selectedTags;
+ }
+ // Save seleceted search
+ public void setSelectedSavedSearch(String s) {
+ this.selectedSearch = s;
+ }
+ // Get search tags
+ public List<String> getSelectedTags() {
+ return selectedTags;
+ }
+ // Get saved search
+ public String getSelectedSearch() {
+ return selectedSearch;
+ }
+
+
+
+
+ //***************************************************************
+ //***************************************************************
+ //** Note functions
+ //***************************************************************
+ //***************************************************************
+ // Save Note Tags
public void saveNoteTags(String noteGuid, List<String> tags, boolean isDirty) {\r
- logger.log(logger.HIGH, "Entering ListManager.saveNoteTags");\r
- String tagName;\r
- conn.getNoteTable().noteTagsTable.deleteNoteTag(noteGuid);\r
- List<String> tagGuids = new ArrayList<String>();\r
- boolean newTagCreated = false;\r
- \r
- for (int i=0; i<tags.size(); i++) {\r
- tagName = tags.get(i);\r
- boolean found = false;\r
- for (int j=0; j<tagIndex.size(); j++) {\r
- if (tagIndex.get(j).getName().equalsIgnoreCase(tagName)) {\r
+ logger.log(logger.HIGH, "Entering ListManager.saveNoteTags");
+ // ICHANGED 同じタグが付けられた履歴を記録(必ずdeleteNoteTagの前にやる)
+ for (int i = 0; i < tags.size(); i++) {
+ String tagName = tags.get(i);
+ for (int j = 0; j < tagIndex.size(); j++) {
+ if (tagIndex.get(j).getName().equalsIgnoreCase(tagName)) {
+ conn.getHistoryTable().addSameTagHistory(noteGuid, tagIndex.get(j).getGuid());
+ }
+ }
+ }
+
+ String tagName;
+ conn.getNoteTable().noteTagsTable.deleteNoteTag(noteGuid);
+ List<String> tagGuids = new ArrayList<String>();
+ boolean newTagCreated = false;
+
+ for (int i=0; i<tags.size(); i++) {
+ tagName = tags.get(i);
+ boolean found = false;
+ for (int j=0; j<tagIndex.size(); j++) {
+ if (tagIndex.get(j).getName().equalsIgnoreCase(tagName)) {
conn.getNoteTable().noteTagsTable.saveNoteTag(noteGuid, tagIndex.get(j).getGuid(), isDirty);\r
- tagGuids.add(tagIndex.get(j).getGuid());\r
- j=tagIndex.size()+1;\r
- found = true;\r
- }\r
- }\r
- if (!found) {\r
- Tag nTag = new Tag();\r
- nTag.setName(tagName);\r
- Calendar currentTime = new GregorianCalendar();\r
- Long l = new Long(currentTime.getTimeInMillis());\r
- long prevTime = l;\r
- while (l==prevTime) {\r
- currentTime = new GregorianCalendar();\r
- l=currentTime.getTimeInMillis();\r
- }\r
- String randint = new String(Long.toString(l));\r
- \r
- nTag.setUpdateSequenceNum(0);\r
- nTag.setGuid(randint);\r
- conn.getTagTable().addTag(nTag, true);\r
- getTagIndex().add(nTag);\r
+ tagGuids.add(tagIndex.get(j).getGuid());
+ j=tagIndex.size()+1;
+ found = true;
+ }
+ }
+ if (!found) {
+ Tag nTag = new Tag();
+ nTag.setName(tagName);
+ Calendar currentTime = new GregorianCalendar();
+ Long l = new Long(currentTime.getTimeInMillis());
+ long prevTime = l;
+ while (l==prevTime) {
+ currentTime = new GregorianCalendar();
+ l=currentTime.getTimeInMillis();
+ }
+ String randint = new String(Long.toString(l));
+
+ nTag.setUpdateSequenceNum(0);
+ nTag.setGuid(randint);
+ conn.getTagTable().addTag(nTag, true);
+ getTagIndex().add(nTag);
conn.getNoteTable().noteTagsTable.saveNoteTag(noteGuid, nTag.getGuid(), isDirty);\r
- tagGuids.add(nTag.getGuid());\r
- newTagCreated = true;\r
- }\r
- }\r
- \r
- for (int i=0; i<getNoteIndex().size(); i++) {\r
- if (getNoteIndex().get(i).getGuid().equals(noteGuid)) {\r
- getNoteIndex().get(i).setTagNames(tags);\r
- getNoteIndex().get(i).setTagGuids(tagGuids);\r
- i=getNoteIndex().size()+1;\r
- }\r
- }\r
- if (newTagCreated)\r
- tagSignal.listChanged.emit();\r
- logger.log(logger.HIGH, "Leaving ListManager.saveNoteTags");\r
- }\r
- // Delete a note\r
- public void deleteNote(String guid) {\r
- trashCounterRunner.abortCount = true;\r
- Calendar currentTime = new GregorianCalendar();\r
- Long l = new Long(currentTime.getTimeInMillis());\r
- long prevTime = l;\r
- while (l==prevTime) {\r
- currentTime = new GregorianCalendar();\r
- l=currentTime.getTimeInMillis();\r
- }\r
- \r
- for (int i=0; i<getMasterNoteIndex().size(); i++) {\r
- if (getMasterNoteIndex().get(i).getGuid().equals(guid)) {\r
- getMasterNoteIndex().get(i).setActive(false);\r
- getMasterNoteIndex().get(i).setDeleted(l);\r
- i=getMasterNoteIndex().size();\r
- }\r
- }\r
- for (int i=0; i<getNoteIndex().size(); i++) {\r
- if (getNoteIndex().get(i).getGuid().equals(guid)) {\r
- getNoteIndex().get(i).setActive(false);\r
- getNoteIndex().get(i).setDeleted(l);\r
- i=getNoteIndex().size();\r
- }\r
- }\r
- conn.getNoteTable().deleteNote(guid);\r
- reloadTrashCount();\r
- }\r
- // Delete a note\r
- public void restoreNote(String guid) {\r
- trashCounterRunner.abortCount = true;\r
- for (int i=0; i<getMasterNoteIndex().size(); i++) {\r
- if (getMasterNoteIndex().get(i).getGuid().equals(guid)) {\r
- getMasterNoteIndex().get(i).setActive(true);\r
- getMasterNoteIndex().get(i).setDeleted(0);\r
- i=getMasterNoteIndex().size();\r
- }\r
- }\r
- for (int i=0; i<getNoteIndex().size(); i++) {\r
- if (getNoteIndex().get(i).getGuid().equals(guid)) {\r
- getNoteIndex().get(i).setActive(true);\r
- getNoteIndex().get(i).setDeleted(0);\r
- i=getNoteIndex().size();\r
- }\r
- }\r
- conn.getNoteTable().restoreNote(guid);\r
- reloadTrashCount();\r
- }\r
- public void updateNote(Note n) {\r
- \r
- for (int i=0; i<getMasterNoteIndex().size(); i++) {\r
- if (getMasterNoteIndex().get(i).getGuid().equals(n.getGuid())) {\r
- getMasterNoteIndex().remove(i);\r
- getMasterNoteIndex().add(n);\r
- }\r
- }\r
- for (int i=0; i<getNoteIndex().size(); i++) {\r
- if (getNoteIndex().get(i).getGuid().equals(n.getGuid())) {\r
- getNoteIndex().get(i).setActive(true);\r
- getNoteIndex().get(i).setDeleted(0);\r
- i=getNoteIndex().size();\r
- }\r
- }\r
- conn.getNoteTable().updateNote(n);\r
- }\r
- // Add a note. \r
- public void addNote(Note n, NoteMetadata meta) {\r
- noteModel.addNote(n, meta);\r
- noteModel.metaData.put(n.getGuid(), meta);\r
- }\r
- // Expunge a note\r
- public void expungeNote(String guid) {\r
- trashCounterRunner.abortCount = true;\r
- for (int i=0; i<getMasterNoteIndex().size(); i++) {\r
- if (getMasterNoteIndex().get(i).getGuid().equals(guid)) {\r
- getMasterNoteIndex().remove(i);\r
- i=getMasterNoteIndex().size();\r
- }\r
- }\r
- for (int i=0; i<getNoteIndex().size(); i++) {\r
- if (getNoteIndex().get(i).getGuid().equals(guid)) {\r
- getNoteIndex().remove(i);\r
- i=getNoteIndex().size();\r
- }\r
- }\r
- conn.getNoteTable().expungeNote(guid, false, true);\r
- reloadTrashCount();\r
- }\r
- // Expunge a note\r
- public void emptyTrash() {\r
- trashCounterRunner.abortCount = true; \r
- for (int i=getMasterNoteIndex().size()-1; i>=0; i--) {\r
- if (!getMasterNoteIndex().get(i).isActive()) {\r
- getMasterNoteIndex().remove(i);\r
- }\r
- }\r
- \r
- for (int i=getNoteIndex().size()-1; i>=0; i--) {\r
- if (!getNoteIndex().get(i).isActive()) {\r
- getNoteIndex().remove(i);\r
- } \r
- }\r
-\r
- conn.getNoteTable().expungeAllDeletedNotes();\r
- reloadTrashCount();\r
- }\r
- // The trash counter thread has produced a result\r
- @SuppressWarnings("unused")\r
- private void trashSignalReceiver(Integer i) {\r
- trashCount = i;\r
- trashSignal.countChanged.emit(i);\r
- }\r
- // Update note contents\r
- public void updateNoteContent(String guid, String content) {\r
- logger.log(logger.HIGH, "Entering ListManager.updateNoteContent");\r
-// EnmlConverter enml = new EnmlConverter(logger);\r
-// String text = enml.convert(guid, content);\r
- \r
- // Update the list tables \r
-/* for (int i=0; i<masterNoteIndex.size(); i++) {\r
- if (masterNoteIndex.get(i).getGuid().equals(guid)) {\r
- masterNoteIndex.get(i).setContent(text);\r
- i = masterNoteIndex.size();\r
- }\r
- }\r
- // Update the list tables \r
- for (int i=0; i<getNoteIndex().size(); i++) {\r
- if (getNoteIndex().get(i).getGuid().equals(guid)) {\r
- getNoteIndex().get(i).setContent(text);\r
- i = getNoteIndex().size();\r
- }\r
- }\r
-*/ \r
- // Check if any new tags were encountered\r
-/* if (enml.saveInvalidXML) {\r
- List<String> elements = Global.invalidElements;\r
- for (int i=0; i<elements.size(); i++) {\r
- conn.getInvalidXMLTable().addInvalidElement(elements.get(i));\r
- }\r
- for (String key : Global.invalidAttributes.keySet()) {\r
- ArrayList<String> attributes = Global.invalidAttributes.get(key);\r
- for (int i=0; i<attributes.size(); i++) {\r
- conn.getInvalidXMLTable().addInvalidAttribute(key, attributes.get(i));\r
- }\r
- }\r
- }\r
-*/\r
- saveRunner.addWork(guid, content);\r
-// conn.getNoteTable().updateNoteContent(guid, content);\r
- logger.log(logger.HIGH, "Leaving ListManager.updateNoteContent");\r
- }\r
- // Update a note creation date\r
- public void updateNoteCreatedDate(String guid, QDateTime date) {\r
- noteModel.updateNoteCreatedDate(guid, date);\r
- conn.getNoteTable().updateNoteCreatedDate(guid, date);\r
- }\r
- // Subject date has been changed\r
- public void updateNoteSubjectDate(String guid, QDateTime date) {\r
- noteModel.updateNoteSubjectDate(guid, date);\r
- conn.getNoteTable().updateNoteSubjectDate(guid, date);\r
- }\r
- // Author has changed\r
- public void updateNoteAuthor(String guid, String author) {\r
- noteModel.updateNoteAuthor(guid, author);\r
- conn.getNoteTable().updateNoteAuthor(guid, author);\r
- }\r
- // Author has changed\r
- public void updateNoteGeoTag(String guid, Double lon, Double lat, Double alt) {\r
- for (int i=0; i<getMasterNoteIndex().size(); i++) {\r
- if (getMasterNoteIndex().get(i).getGuid().equals(guid)) {\r
- getMasterNoteIndex().get(i).getAttributes().setLongitude(lon);\r
- getMasterNoteIndex().get(i).getAttributes().setLongitudeIsSet(true);\r
- getMasterNoteIndex().get(i).getAttributes().setLatitude(lat);\r
- getMasterNoteIndex().get(i).getAttributes().setLatitudeIsSet(true);\r
- getMasterNoteIndex().get(i).getAttributes().setAltitude(alt);\r
- getMasterNoteIndex().get(i).getAttributes().setAltitudeIsSet(true);\r
- i = getMasterNoteIndex().size();\r
- } \r
- }\r
- // Update the list tables \r
- for (int i=0; i<getNoteIndex().size(); i++) {\r
- if (getNoteIndex().get(i).getGuid().equals(guid)) {\r
- getNoteIndex().get(i).getAttributes().setLongitude(lon);\r
- getNoteIndex().get(i).getAttributes().setLongitudeIsSet(true);\r
- getNoteIndex().get(i).getAttributes().setLatitude(lat);\r
- getNoteIndex().get(i).getAttributes().setLatitudeIsSet(true);\r
- getNoteIndex().get(i).getAttributes().setAltitude(alt);\r
- getNoteIndex().get(i).getAttributes().setAltitudeIsSet(true);\r
- i = getNoteIndex().size();\r
- }\r
- }\r
- conn.getNoteTable().updateNoteGeoTags(guid, lon, lat, alt);\r
- }\r
- // Source URL changed\r
- public void updateNoteSourceUrl(String guid, String url) {\r
- noteModel.updateNoteSourceUrl(guid, url);\r
- conn.getNoteTable().updateNoteSourceUrl(guid, url);\r
- }\r
- // Update a note last changed date\r
- public void updateNoteAlteredDate(String guid, QDateTime date) {\r
- noteModel.updateNoteChangedDate(guid, date);\r
- conn.getNoteTable().updateNoteAlteredDate(guid, date);\r
- }\r
- // Update a note title\r
- public void updateNoteTitle(String guid, String title) {\r
- logger.log(logger.HIGH, "Entering ListManager.updateNoteTitle");\r
- conn.getNoteTable().updateNoteTitle(guid, title);\r
- noteModel.updateNoteTitle(guid, title);\r
- logger.log(logger.HIGH, "Leaving ListManager.updateNoteTitle");\r
- }\r
- // Update a note's notebook\r
- public void updateNoteNotebook(String guid, String notebookGuid) {\r
- logger.log(logger.HIGH, "Entering ListManager.updateNoteNotebook");\r
- noteModel.updateNoteNotebook(guid, notebookGuid);\r
- conn.getNoteTable().updateNoteNotebook(guid, notebookGuid, true);\r
- logger.log(logger.HIGH, "Leaving ListManager.updateNoteNotebook");\r
- }\r
- // Update a note sequence number\r
- public void updateNoteSequence(String guid, int sequence) {\r
- logger.log(logger.HIGH, "Entering ListManager.updateNoteSequence");\r
-\r
- conn.getNoteTable().updateNoteSequence(guid, sequence);\r
- \r
- for (int i=0; i<noteModel.getMasterNoteIndex().size(); i++) {\r
- if (noteModel.getMasterNoteIndex().get(i).getGuid().equals(guid)) {\r
- noteModel.getMasterNoteIndex().get(i).setUpdateSequenceNum(sequence);\r
- i=noteModel.getMasterNoteIndex().size()+1;\r
- }\r
- }\r
- \r
- for (int i=0; i<getNoteIndex().size(); i++) {\r
- if (getNoteIndex().get(i).getGuid().equals(guid)) {\r
- getNoteIndex().get(i).setUpdateSequenceNum(sequence);\r
- i=getNoteIndex().size()+1;\r
- }\r
- }\r
- logger.log(logger.HIGH, "Leaving ListManager.updateNoteSequence");\r
- }\r
- public void updateNoteGuid(String oldGuid, String newGuid, boolean updateDatabase) {\r
- logger.log(logger.HIGH, "Entering ListManager.updateNoteGuid");\r
- if (updateDatabase) \r
- conn.getNoteTable().updateNoteGuid(oldGuid, newGuid);\r
- noteModel.updateNoteGuid(oldGuid, newGuid);\r
- logger.log(logger.HIGH, "Leaving ListManager.updateNoteGuid");\r
-\r
- }\r
-\r
- \r
- //************************************************************************************\r
- //************************************************************************************\r
- //** Tag functions\r
- //************************************************************************************\r
- //************************************************************************************ \r
- // Update a tag sequence number\r
- public void updateTagSequence(String guid, int sequence) {\r
- logger.log(logger.HIGH, "Entering ListManager.updateTagSequence");\r
-\r
- conn.getTagTable().updateTagSequence(guid, sequence); \r
- for (int i=0; i<tagIndex.size(); i++) {\r
- if (tagIndex.get(i).getGuid().equals(guid)) {\r
- getTagIndex().get(i).setUpdateSequenceNum(sequence);\r
- i=tagIndex.size()+1;\r
- }\r
- }\r
- logger.log(logger.HIGH, "Leaving ListManager.updateTagSequence");\r
- }\r
- // Update a tag guid number\r
- public void updateTagGuid(String oldGuid, String newGuid) {\r
- logger.log(logger.HIGH, "Entering ListManager.updateTagGuid");\r
-\r
- conn.getTagTable().updateTagGuid(oldGuid, newGuid); \r
- for (int i=0; i<tagIndex.size(); i++) {\r
- if (tagIndex.get(i).getGuid().equals(oldGuid)) {\r
- tagIndex.get(i).setGuid(newGuid);\r
- i=tagIndex.size()+1;\r
- }\r
- }\r
- logger.log(logger.HIGH, "Leaving ListManager.updateTagGuid");\r
-\r
- }\r
- // Find all children for a tag\r
- public List<Tag> findAllChildren(String guid) {\r
- List<Tag> tags = new ArrayList<Tag>();\r
- return findAllChildrenRecursive(guid, tags);\r
- }\r
- public List<Tag> findAllChildrenRecursive(String guid, List<Tag> tags) {\r
- \r
- // Start looping through the tags. If we find a tag which has a parent that\r
- // matches guid, then we add it to the list of tags & search for its children.\r
- for (int i=0; i<getTagIndex().size(); i++) {\r
- if (getTagIndex().get(i).getParentGuid() != null && getTagIndex().get(i).getParentGuid().equals(guid)) {\r
- tags.add(getTagIndex().get(i));\r
- tags = findAllChildrenRecursive(getTagIndex().get(i).getGuid(), tags);\r
- }\r
- }\r
- return tags;\r
- }\r
- // Give a list of tags, does any of them match a child tag?\r
- public boolean checkNoteForChildTags(String guid, List<String> noteTags) {\r
- boolean returnValue = false;\r
- List<Tag> children = findAllChildren(guid);\r
- for (int i=0; i<noteTags.size(); i++) {\r
- String noteTag = noteTags.get(i);\r
- for (int j=0; j<children.size(); j++) {\r
- if (noteTag.equals(children.get(j).getGuid()))\r
- return true;\r
- }\r
- }\r
- return returnValue;\r
- }\r
-\r
-\r
- //************************************************************************************\r
- //************************************************************************************\r
- //** Notebook functions\r
- //************************************************************************************\r
- //************************************************************************************ \r
- // Delete a notebook\r
- public void deleteNotebook(String guid) {\r
- for (int i=0; i<getNotebookIndex().size(); i++) {\r
- if (getNotebookIndex().get(i).getGuid().equals(guid)) {\r
- getNotebookIndex().remove(i);\r
- i=getMasterNoteIndex().size();\r
- }\r
- }\r
- conn.getNotebookTable().expungeNotebook(guid, true); \r
- }\r
- // Rename a stack\r
- public void renameStack(String oldName, String newName) {\r
- for (int i=0; i<getNotebookIndex().size(); i++) {\r
- if (getNotebookIndex().get(i).getStack() != null && \r
- getNotebookIndex().get(i).getStack().equalsIgnoreCase(oldName)) {\r
- getNotebookIndex().get(i).setStack(newName);\r
- }\r
- } \r
- }\r
- // Update a notebook sequence number\r
- public void updateNotebookSequence(String guid, int sequence) {\r
- logger.log(logger.HIGH, "Entering ListManager.updateNotebookSequence");\r
-\r
- conn.getNotebookTable().updateNotebookSequence(guid, sequence);\r
- \r
- for (int i=0; i<notebookIndex.size(); i++) {\r
- if (notebookIndex.get(i).getGuid().equals(guid)) {\r
- notebookIndex.get(i).setUpdateSequenceNum(sequence);\r
- i=notebookIndex.size()+1;\r
- }\r
- }\r
- logger.log(logger.HIGH, "Leaving ListManager.updateNotebookSequence");\r
-\r
- }\r
- // Update a notebook Guid number\r
- public void updateNotebookGuid(String oldGuid, String newGuid) {\r
- logger.log(logger.HIGH, "Entering ListManager.updateNotebookGuid");\r
-\r
- conn.getNotebookTable().updateNotebookGuid(oldGuid, newGuid);\r
- \r
- for (int i=0; i<notebookIndex.size(); i++) {\r
- if (notebookIndex.get(i).getGuid().equals(oldGuid)) {\r
- notebookIndex.get(i).setGuid(newGuid);\r
- i=notebookIndex.size()+1;\r
- }\r
- }\r
- logger.log(logger.HIGH, "Leaving ListManager.updateNotebookGuid");\r
-\r
- }\r
- // Update a notebook Guid number\r
- public void updateNotebookStack(String oldGuid, String stack) {\r
- logger.log(logger.HIGH, "Entering ListManager.updateNotebookGuid");\r
-\r
- conn.getNotebookTable().setStack(oldGuid, stack);\r
- \r
- for (int i=0; i<notebookIndex.size(); i++) {\r
- if (notebookIndex.get(i).getGuid().equals(oldGuid)) {\r
- notebookIndex.get(i).setStack(stack);\r
- i=notebookIndex.size()+1;\r
- }\r
- }\r
- logger.log(logger.HIGH, "Leaving ListManager.updateNotebookGuid");\r
-\r
- }\r
- \r
- \r
- //************************************************************************************\r
- //************************************************************************************\r
- //** Load and filter the note index\r
- //************************************************************************************\r
- //************************************************************************************\r
- \r
- public void noteDownloaded(Note n) {\r
- boolean found = false;\r
- for (int i=0; i<getMasterNoteIndex().size(); i++) {\r
- if (getMasterNoteIndex().get(i).getGuid().equals(n.getGuid())) {\r
- getMasterNoteIndex().set(i,n);\r
- found = true;\r
- i=getMasterNoteIndex().size();\r
- }\r
- }\r
- \r
- if (!found)\r
- getMasterNoteIndex().add(n);\r
- \r
- for (int i=0; i<getNoteIndex().size(); i++) {\r
- if (getNoteIndex().get(i).getGuid().equals(n.getGuid())) {\r
- if (filterRecord(getNoteIndex().get(i)))\r
- getNoteIndex().add(n);\r
- getNoteIndex().remove(i);\r
- i=getNoteIndex().size();\r
- }\r
- }\r
- \r
- if (filterRecord(n))\r
- getNoteIndex().add(n);\r
- \r
- }\r
- // Check if a note matches the currently selected notebooks, tags, or attribute searches.\r
- public boolean filterRecord(Note n) {\r
- \r
- boolean goodNotebook = false;\r
- boolean goodTag = false;\r
- boolean goodStatus = false;\r
- \r
- // Check note status\r
- if (!n.isActive() && Global.showDeleted)\r
- return true;\r
- else {\r
- if (n.isActive() && !Global.showDeleted)\r
- goodStatus = true;\r
- }\r
- \r
- // Begin filtering results\r
- if (goodStatus)\r
- goodNotebook = filterByNotebook(n.getNotebookGuid());\r
- if (goodNotebook) \r
- goodTag = filterByTag(n.getTagGuids());\r
- if (goodTag) {\r
- boolean goodCreatedBefore = false;\r
- boolean goodCreatedSince = false;\r
- boolean goodChangedBefore = false;\r
- boolean goodChangedSince = false;\r
- boolean goodContains = false;\r
- if (!Global.createdBeforeFilter.hasSelection())\r
- goodCreatedBefore = true;\r
- else\r
- goodCreatedBefore = Global.createdBeforeFilter.check(n);\r
- \r
- if (!Global.createdSinceFilter.hasSelection())\r
- goodCreatedSince = true;\r
- else\r
- goodCreatedSince = Global.createdSinceFilter.check(n);\r
- \r
- if (!Global.changedBeforeFilter.hasSelection())\r
- goodChangedBefore = true;\r
- else\r
- goodChangedBefore = Global.changedBeforeFilter.check(n);\r
- if (!Global.changedSinceFilter.hasSelection())\r
- goodChangedSince = true;\r
- else\r
- goodChangedSince = Global.changedSinceFilter.check(n);\r
- if (!Global.containsFilter.hasSelection())\r
- goodContains = true;\r
- else\r
- goodContains = Global.containsFilter.check(conn.getNoteTable(), n);\r
- \r
- if (goodCreatedSince && goodCreatedBefore && goodChangedSince && goodChangedBefore && goodContains)\r
- return true;\r
- } \r
- return false;\r
- }\r
- \r
- // Trigger a recount of counters\r
- public void refreshCounters() {\r
-// refreshCounters= false;\r
- if (!refreshCounters)\r
- return;\r
- refreshCounters = false;\r
- tagCounterRunner.abortCount = true;\r
- notebookCounterRunner.abortCount = true;\r
- trashCounterRunner.abortCount = true;\r
- countNotebookResults(getNoteIndex());\r
- countTagResults(getNoteIndex());\r
- reloadTrashCount();\r
-\r
- }\r
- // Load the note index based upon what the user wants.\r
- public void loadNotesIndex() {\r
- logger.log(logger.EXTREME, "Entering ListManager.loadNotesIndex()");\r
- \r
- List<Note> matches;\r
- if (enSearchChanged || getMasterNoteIndex() == null)\r
- matches = enSearch.matchWords();\r
- else\r
- matches = getMasterNoteIndex();\r
- \r
- if (matches == null)\r
- matches = getMasterNoteIndex();\r
- \r
- setNoteIndex(new ArrayList<Note>());\r
- for (int i=0; i<matches.size(); i++) {\r
- if (filterRecord(matches.get(i)))\r
- getNoteIndex().add(matches.get(i));\r
- }\r
- refreshCounters = true;\r
- enSearchChanged = false;\r
- logger.log(logger.EXTREME, "Leaving ListManager.loadNotesIndex()");\r
- }\r
- public void countNotebookResults(List<Note> index) {\r
- logger.log(logger.EXTREME, "Entering ListManager.countNotebookResults()");\r
- notebookCounterRunner.abortCount = true;\r
- if (!Global.mimicEvernoteInterface) \r
- notebookCounterRunner.setNoteIndex(index);\r
- else \r
- notebookCounterRunner.setNoteIndex(getMasterNoteIndex());\r
- notebookCounterRunner.release(CounterRunner.NOTEBOOK);\r
- logger.log(logger.EXTREME, "Leaving ListManager.countNotebookResults()");\r
- }\r
- public void countTagResults(List<Note> index) {\r
- logger.log(logger.EXTREME, "Entering ListManager.countTagResults");\r
- trashCounterRunner.abortCount = true;\r
- if (!Global.tagBehavior().equalsIgnoreCase("DoNothing")) \r
- tagCounterRunner.setNoteIndex(index);\r
- else\r
- tagCounterRunner.setNoteIndex(getMasterNoteIndex());\r
- tagCounterRunner.release(CounterRunner.TAG);\r
- logger.log(logger.EXTREME, "Leaving ListManager.countTagResults()");\r
- }\r
- // Update the count of items in the trash\r
- public void reloadTrashCount() {\r
- logger.log(logger.EXTREME, "Entering ListManager.reloadTrashCount");\r
- trashCounterRunner.abortCount = true;\r
- trashCounterRunner.setNoteIndex(getMasterNoteIndex());\r
- trashCounterRunner.release(CounterRunner.TRASH);\r
- logger.log(logger.EXTREME, "Leaving ListManager.reloadTrashCount");\r
- } \r
- \r
- private boolean filterByNotebook(String guid) {\r
- boolean good = false;\r
- if (selectedNotebooks.size() == 0)\r
- good = true;\r
- if (!good && selectedNotebooks.contains(guid)) \r
- good = true;\r
-\r
- for (int i=0; i<getArchiveNotebookIndex().size() && good; i++) {\r
- if (guid.equals(getArchiveNotebookIndex().get(i).getGuid())) {\r
- good = false;\r
- return good;\r
- }\r
- }\r
- return good;\r
- }\r
- private boolean filterByTag(List<String> noteTags) {\r
- // If either the note has no tags or there are\r
- // no selected tags, then any note is good.\r
- if (noteTags == null || selectedTags == null)\r
- return true;\r
- \r
- // If there are no tags selected, then any note is good\r
- if (selectedTags.size() == 0) \r
- return true;\r
- \r
- // If ALL tags must be matched, then check ALL note tags, \r
- // otherwise we match on any criteria.\r
- if (!Global.anyTagSelectionMatch()) {\r
- for (int i=0; i<selectedTags.size(); i++) {\r
- String selectedGuid = selectedTags.get(i);\r
- boolean childMatch = false;\r
- // If we should include children in the results\r
- if (Global.includeTagChildren()) {\r
- childMatch = checkNoteForChildTags(selectedGuid, noteTags);\r
- // Do we have a match with this tag or any children\r
- if (!noteTags.contains(selectedGuid)&& !childMatch)\r
- return false;\r
- } else {\r
- // Does this note have a matching tag\r
- if (!noteTags.contains(selectedGuid))\r
- return false;\r
- }\r
- }\r
- return true;\r
- } else {\r
- // Any match is displayed.\r
- for (int i=0; i<selectedTags.size(); i++) {\r
- String selectedGuid = selectedTags.get(i);\r
- // If we have a simple match, then we're good\r
- if (noteTags.contains(selectedGuid))\r
- return true;\r
- // If we have a match with one of the children tags && we should include child tags\r
- if (Global.includeTagChildren() && checkNoteForChildTags(selectedGuid, noteTags))\r
- return true;\r
- }\r
- return false;\r
- }\r
- }\r
-\r
- public void setNoteSynchronized(String guid, boolean value) {\r
- getNoteTableModel().updateNoteSyncStatus(guid, value);\r
- }\r
- \r
- public void updateNoteTitleColor(String guid, Integer color) {\r
- NoteMetadata meta = getNoteMetadata().get(guid);\r
- if (meta != null) {\r
- noteModel.updateNoteTitleColor(guid, color);\r
- meta.setColor(color);\r
- conn.getNoteTable().updateNoteMetadata(meta);\r
- }\r
- }\r
- public void loadNoteTitleColors() {\r
- noteModel.setMetaData(getNoteMetadata());\r
- }\r
- \r
- //********************************************************************************\r
- //********************************************************************************\r
- //* Support signals from the index thread\r
- //********************************************************************************\r
- //********************************************************************************\r
- // Reset a flag if an index is needed\r
- public void setIndexNeeded(String guid, String type, Boolean b) {\r
- if (Global.keepRunning && type.equalsIgnoreCase("content"))\r
- conn.getNoteTable().setIndexNeeded(guid, false);\r
- if (Global.keepRunning && type.equalsIgnoreCase("resource")) {\r
- conn.getNoteTable().noteResourceTable.setIndexNeeded(guid, b);\r
- }\r
- }\r
- \r
- public boolean threadCheck(int id) {\r
- if (id == Global.notebookCounterThreadId) \r
- return notebookThread.isAlive();\r
- if (id == Global.tagCounterThreadId) \r
- return tagThread.isAlive();\r
- if (id == Global.trashCounterThreadId) \r
- return trashThread.isAlive();\r
- if (id == Global.saveThreadId) \r
- return saveThread.isAlive();\r
- return false;\r
- }\r
- \r
- \r
- \r
- //********************************************************************************\r
- //********************************************************************************\r
- //* Utility Functions\r
- //********************************************************************************\r
- //********************************************************************************\r
- public void compactDatabase() {\r
- conn.compactDatabase();\r
-// IndexConnection idx = new IndexConnection(logger, "nevernote-compact");\r
-// idx.dbSetup();\r
-// idx.dbShutdown();\r
- }\r
-\r
- // Rebuild the note HTML to something usable\r
- public List<String> scanNoteForResources(Note n) {\r
- logger.log(logger.HIGH, "Entering ListManager.scanNoteForResources");\r
- logger.log(logger.EXTREME, "Note guid: " +n.getGuid());\r
- QDomDocument doc = new QDomDocument();\r
- QDomDocument.Result result = doc.setContent(n.getContent());\r
- if (!result.success) {\r
- logger.log(logger.MEDIUM, "Parse error when scanning note for resources.");\r
- logger.log(logger.MEDIUM, "Note guid: " +n.getGuid());\r
- return null;\r
- }\r
- \r
- List<String> returnArray = new ArrayList<String>();\r
- QDomNodeList anchors = doc.elementsByTagName("en-media");\r
- for (int i=0; i<anchors.length(); i++) {\r
- QDomElement enmedia = anchors.at(i).toElement();\r
- if (enmedia.hasAttribute("type")) {\r
- QDomAttr hash = enmedia.attributeNode("hash");\r
- returnArray.add(hash.value().toString());\r
- }\r
- }\r
- logger.log(logger.HIGH, "Leaving ListManager.scanNoteForResources");\r
- return returnArray;\r
- }\r
- // Given a list of tags, produce a string list of tag names\r
- public String getTagNamesForNote(Note n) {\r
- StringBuffer buffer = new StringBuffer(100);\r
- Vector<String> v = new Vector<String>();\r
- List<String> guids = n.getTagGuids();\r
- \r
- if (guids == null) \r
- return "";\r
- \r
- for (int i=0; i<guids.size(); i++) {\r
- v.add(getTagNameByGuid(guids.get(i)));\r
- }\r
- Comparator<String> comparator = Collections.reverseOrder();\r
- Collections.sort(v,comparator);\r
- Collections.reverse(v);\r
- \r
- for (int i = 0; i<v.size(); i++) {\r
- if (i>0) \r
- buffer.append(", ");\r
- buffer.append(v.get(i));\r
- }\r
- \r
- return buffer.toString();\r
- }\r
- // Get a tag name when given a tag guid\r
- public String getTagNameByGuid(String guid) {\r
- for (int i=0; i<getTagIndex().size(); i++) {\r
- String s = getTagIndex().get(i).getGuid();\r
- if (s.equals(guid)) { \r
- return getTagIndex().get(i).getName();\r
- }\r
- }\r
- return "";\r
- }\r
- // For a notebook guid, return the name\r
- public String getNotebookNameByGuid(String guid) {\r
- if (notebookIndex == null)\r
- return null;\r
- for (int i=0; i<notebookIndex.size(); i++) {\r
- String s = notebookIndex.get(i).getGuid();\r
- if (s.equals(guid)) { \r
- return notebookIndex.get(i).getName();\r
- }\r
- }\r
- return "";\r
- }\r
- \r
- \r
- // Reload the note's tag names. This is called when a tag's name changes by\r
- // the user. It updates all notes with that tag to the new tag name.\r
- public void reloadNoteTagNames(String tagGuid, String newName) {\r
- \r
- // Set the master index\r
- for (int i=0; i<getMasterNoteIndex().size(); i++) {\r
- for (int j=0; j<getMasterNoteIndex().get(i).getTagGuids().size(); j++) {\r
- if (getMasterNoteIndex().get(i).getTagGuids().get(j).equals(tagGuid)) {\r
- getMasterNoteIndex().get(i).getTagNames().set(j, newName);\r
- }\r
- }\r
- }\r
- \r
- // Set the current index\r
- for (int i=0; i<getNoteIndex().size(); i++) {\r
- for (int j=0; j<getNoteIndex().get(i).getTagGuids().size(); j++) {\r
- if (getNoteIndex().get(i).getTagGuids().get(j).equals(tagGuid)) {\r
- getNoteIndex().get(i).getTagNames().set(j, newName);\r
- }\r
- }\r
- }\r
- }\r
- \r
-}\r
+ tagGuids.add(nTag.getGuid());
+ newTagCreated = true;
+ }
+ }
+
+ for (int i=0; i<getNoteIndex().size(); i++) {
+ if (getNoteIndex().get(i).getGuid().equals(noteGuid)) {
+ getNoteIndex().get(i).setTagNames(tags);
+ getNoteIndex().get(i).setTagGuids(tagGuids);
+ i=getNoteIndex().size()+1;
+ }
+ }
+ if (newTagCreated)
+ tagSignal.listChanged.emit();
+ logger.log(logger.HIGH, "Leaving ListManager.saveNoteTags");
+ }
+ // Delete a note
+ public void deleteNote(String guid) {
+ trashCounterRunner.abortCount = true;
+ Calendar currentTime = new GregorianCalendar();
+ Long l = new Long(currentTime.getTimeInMillis());
+ long prevTime = l;
+ while (l==prevTime) {
+ currentTime = new GregorianCalendar();
+ l=currentTime.getTimeInMillis();
+ }
+
+ for (int i=0; i<getMasterNoteIndex().size(); i++) {
+ if (getMasterNoteIndex().get(i).getGuid().equals(guid)) {
+ getMasterNoteIndex().get(i).setActive(false);
+ getMasterNoteIndex().get(i).setDeleted(l);
+ i=getMasterNoteIndex().size();
+ }
+ }
+ for (int i=0; i<getNoteIndex().size(); i++) {
+ if (getNoteIndex().get(i).getGuid().equals(guid)) {
+ getNoteIndex().get(i).setActive(false);
+ getNoteIndex().get(i).setDeleted(l);
+ i=getNoteIndex().size();
+ }
+ }
+ conn.getNoteTable().deleteNote(guid);
+ reloadTrashCount();
+ }
+ // Delete a note
+ public void restoreNote(String guid) {
+ trashCounterRunner.abortCount = true;
+ for (int i=0; i<getMasterNoteIndex().size(); i++) {
+ if (getMasterNoteIndex().get(i).getGuid().equals(guid)) {
+ getMasterNoteIndex().get(i).setActive(true);
+ getMasterNoteIndex().get(i).setDeleted(0);
+ i=getMasterNoteIndex().size();
+ }
+ }
+ for (int i=0; i<getNoteIndex().size(); i++) {
+ if (getNoteIndex().get(i).getGuid().equals(guid)) {
+ getNoteIndex().get(i).setActive(true);
+ getNoteIndex().get(i).setDeleted(0);
+ i=getNoteIndex().size();
+ }
+ }
+ conn.getNoteTable().restoreNote(guid);
+ reloadTrashCount();
+ }
+ public void updateNote(Note n) {
+
+ for (int i=0; i<getMasterNoteIndex().size(); i++) {
+ if (getMasterNoteIndex().get(i).getGuid().equals(n.getGuid())) {
+ getMasterNoteIndex().remove(i);
+ getMasterNoteIndex().add(n);
+ }
+ }
+ for (int i=0; i<getNoteIndex().size(); i++) {
+ if (getNoteIndex().get(i).getGuid().equals(n.getGuid())) {
+ getNoteIndex().get(i).setActive(true);
+ getNoteIndex().get(i).setDeleted(0);
+ i=getNoteIndex().size();
+ }
+ }
+ conn.getNoteTable().updateNote(n);
+ }
+ // Add a note.
+ public void addNote(Note n, NoteMetadata meta) {
+ noteModel.addNote(n, meta);
+ noteModel.metaData.put(n.getGuid(), meta);
+ }
+ // Expunge a note
+ public void expungeNote(String guid) {
+ trashCounterRunner.abortCount = true;
+ for (int i=0; i<getMasterNoteIndex().size(); i++) {
+ if (getMasterNoteIndex().get(i).getGuid().equals(guid)) {
+ getMasterNoteIndex().remove(i);
+ i=getMasterNoteIndex().size();
+ }
+ }
+ for (int i=0; i<getNoteIndex().size(); i++) {
+ if (getNoteIndex().get(i).getGuid().equals(guid)) {
+ getNoteIndex().remove(i);
+ i=getNoteIndex().size();
+ }
+ }
+ conn.getNoteTable().expungeNote(guid, false, true);
+ reloadTrashCount();
+ }
+ // Expunge a note
+ public void emptyTrash() {
+ trashCounterRunner.abortCount = true;
+ for (int i=getMasterNoteIndex().size()-1; i>=0; i--) {
+ if (!getMasterNoteIndex().get(i).isActive()) {
+ getMasterNoteIndex().remove(i);
+ }
+ }
+
+ for (int i=getNoteIndex().size()-1; i>=0; i--) {
+ if (!getNoteIndex().get(i).isActive()) {
+ getNoteIndex().remove(i);
+ }
+ }
+
+ conn.getNoteTable().expungeAllDeletedNotes();
+ reloadTrashCount();
+ }
+ // The trash counter thread has produced a result
+ @SuppressWarnings("unused")
+ private void trashSignalReceiver(Integer i) {
+ trashCount = i;
+ trashSignal.countChanged.emit(i);
+ }
+ // Update note contents
+ public void updateNoteContent(String guid, String content) {
+ logger.log(logger.HIGH, "Entering ListManager.updateNoteContent");
+// EnmlConverter enml = new EnmlConverter(logger);
+// String text = enml.convert(guid, content);
+
+ // Update the list tables
+/* for (int i=0; i<masterNoteIndex.size(); i++) {
+ if (masterNoteIndex.get(i).getGuid().equals(guid)) {
+ masterNoteIndex.get(i).setContent(text);
+ i = masterNoteIndex.size();
+ }
+ }
+ // Update the list tables
+ for (int i=0; i<getNoteIndex().size(); i++) {
+ if (getNoteIndex().get(i).getGuid().equals(guid)) {
+ getNoteIndex().get(i).setContent(text);
+ i = getNoteIndex().size();
+ }
+ }
+*/
+ // Check if any new tags were encountered
+/* if (enml.saveInvalidXML) {
+ List<String> elements = Global.invalidElements;
+ for (int i=0; i<elements.size(); i++) {
+ conn.getInvalidXMLTable().addInvalidElement(elements.get(i));
+ }
+ for (String key : Global.invalidAttributes.keySet()) {
+ ArrayList<String> attributes = Global.invalidAttributes.get(key);
+ for (int i=0; i<attributes.size(); i++) {
+ conn.getInvalidXMLTable().addInvalidAttribute(key, attributes.get(i));
+ }
+ }
+ }
+*/
+ saveRunner.addWork(guid, content);
+// conn.getNoteTable().updateNoteContent(guid, content);
+ logger.log(logger.HIGH, "Leaving ListManager.updateNoteContent");
+ }
+ // Update a note creation date
+ public void updateNoteCreatedDate(String guid, QDateTime date) {
+ noteModel.updateNoteCreatedDate(guid, date);
+ conn.getNoteTable().updateNoteCreatedDate(guid, date);
+ }
+ // Subject date has been changed
+ public void updateNoteSubjectDate(String guid, QDateTime date) {
+ noteModel.updateNoteSubjectDate(guid, date);
+ conn.getNoteTable().updateNoteSubjectDate(guid, date);
+ }
+ // Author has changed
+ public void updateNoteAuthor(String guid, String author) {
+ noteModel.updateNoteAuthor(guid, author);
+ conn.getNoteTable().updateNoteAuthor(guid, author);
+ }
+ // Author has changed
+ public void updateNoteGeoTag(String guid, Double lon, Double lat, Double alt) {
+ for (int i=0; i<getMasterNoteIndex().size(); i++) {
+ if (getMasterNoteIndex().get(i).getGuid().equals(guid)) {
+ getMasterNoteIndex().get(i).getAttributes().setLongitude(lon);
+ getMasterNoteIndex().get(i).getAttributes().setLongitudeIsSet(true);
+ getMasterNoteIndex().get(i).getAttributes().setLatitude(lat);
+ getMasterNoteIndex().get(i).getAttributes().setLatitudeIsSet(true);
+ getMasterNoteIndex().get(i).getAttributes().setAltitude(alt);
+ getMasterNoteIndex().get(i).getAttributes().setAltitudeIsSet(true);
+ i = getMasterNoteIndex().size();
+ }
+ }
+ // Update the list tables
+ for (int i=0; i<getNoteIndex().size(); i++) {
+ if (getNoteIndex().get(i).getGuid().equals(guid)) {
+ getNoteIndex().get(i).getAttributes().setLongitude(lon);
+ getNoteIndex().get(i).getAttributes().setLongitudeIsSet(true);
+ getNoteIndex().get(i).getAttributes().setLatitude(lat);
+ getNoteIndex().get(i).getAttributes().setLatitudeIsSet(true);
+ getNoteIndex().get(i).getAttributes().setAltitude(alt);
+ getNoteIndex().get(i).getAttributes().setAltitudeIsSet(true);
+ i = getNoteIndex().size();
+ }
+ }
+ conn.getNoteTable().updateNoteGeoTags(guid, lon, lat, alt);
+ }
+ // Source URL changed
+ public void updateNoteSourceUrl(String guid, String url) {
+ noteModel.updateNoteSourceUrl(guid, url);
+ conn.getNoteTable().updateNoteSourceUrl(guid, url);
+ }
+ // Update a note last changed date
+ public void updateNoteAlteredDate(String guid, QDateTime date) {
+ noteModel.updateNoteChangedDate(guid, date);
+ conn.getNoteTable().updateNoteAlteredDate(guid, date);
+ }
+ // Update a note title
+ public void updateNoteTitle(String guid, String title) {
+ logger.log(logger.HIGH, "Entering ListManager.updateNoteTitle");
+ conn.getNoteTable().updateNoteTitle(guid, title);
+ noteModel.updateNoteTitle(guid, title);
+ logger.log(logger.HIGH, "Leaving ListManager.updateNoteTitle");
+ }
+ // Update a note's notebook
+ public void updateNoteNotebook(String guid, String notebookGuid) {
+ logger.log(logger.HIGH, "Entering ListManager.updateNoteNotebook");
+ noteModel.updateNoteNotebook(guid, notebookGuid);
+ conn.getNoteTable().updateNoteNotebook(guid, notebookGuid, true);
+ logger.log(logger.HIGH, "Leaving ListManager.updateNoteNotebook");
+ }
+ // Update a note sequence number
+ public void updateNoteSequence(String guid, int sequence) {
+ logger.log(logger.HIGH, "Entering ListManager.updateNoteSequence");
+
+ conn.getNoteTable().updateNoteSequence(guid, sequence);
+
+ for (int i=0; i<noteModel.getMasterNoteIndex().size(); i++) {
+ if (noteModel.getMasterNoteIndex().get(i).getGuid().equals(guid)) {
+ noteModel.getMasterNoteIndex().get(i).setUpdateSequenceNum(sequence);
+ i=noteModel.getMasterNoteIndex().size()+1;
+ }
+ }
+
+ for (int i=0; i<getNoteIndex().size(); i++) {
+ if (getNoteIndex().get(i).getGuid().equals(guid)) {
+ getNoteIndex().get(i).setUpdateSequenceNum(sequence);
+ i=getNoteIndex().size()+1;
+ }
+ }
+ logger.log(logger.HIGH, "Leaving ListManager.updateNoteSequence");
+ }
+ public void updateNoteGuid(String oldGuid, String newGuid, boolean updateDatabase) {
+ logger.log(logger.HIGH, "Entering ListManager.updateNoteGuid");
+ if (updateDatabase)
+ conn.getNoteTable().updateNoteGuid(oldGuid, newGuid);
+ noteModel.updateNoteGuid(oldGuid, newGuid);
+ logger.log(logger.HIGH, "Leaving ListManager.updateNoteGuid");
+
+ }
+
+
+ //************************************************************************************
+ //************************************************************************************
+ //** Tag functions
+ //************************************************************************************
+ //************************************************************************************
+ // Update a tag sequence number
+ public void updateTagSequence(String guid, int sequence) {
+ logger.log(logger.HIGH, "Entering ListManager.updateTagSequence");
+
+ conn.getTagTable().updateTagSequence(guid, sequence);
+ for (int i=0; i<tagIndex.size(); i++) {
+ if (tagIndex.get(i).getGuid().equals(guid)) {
+ getTagIndex().get(i).setUpdateSequenceNum(sequence);
+ i=tagIndex.size()+1;
+ }
+ }
+ logger.log(logger.HIGH, "Leaving ListManager.updateTagSequence");
+ }
+ // Update a tag guid number
+ public void updateTagGuid(String oldGuid, String newGuid) {
+ logger.log(logger.HIGH, "Entering ListManager.updateTagGuid");
+
+ conn.getTagTable().updateTagGuid(oldGuid, newGuid);
+ for (int i=0; i<tagIndex.size(); i++) {
+ if (tagIndex.get(i).getGuid().equals(oldGuid)) {
+ tagIndex.get(i).setGuid(newGuid);
+ i=tagIndex.size()+1;
+ }
+ }
+ logger.log(logger.HIGH, "Leaving ListManager.updateTagGuid");
+
+ }
+ // Find all children for a tag
+ public List<Tag> findAllChildren(String guid) {
+ List<Tag> tags = new ArrayList<Tag>();
+ return findAllChildrenRecursive(guid, tags);
+ }
+ public List<Tag> findAllChildrenRecursive(String guid, List<Tag> tags) {
+
+ // Start looping through the tags. If we find a tag which has a parent that
+ // matches guid, then we add it to the list of tags & search for its children.
+ for (int i=0; i<getTagIndex().size(); i++) {
+ if (getTagIndex().get(i).getParentGuid() != null && getTagIndex().get(i).getParentGuid().equals(guid)) {
+ tags.add(getTagIndex().get(i));
+ tags = findAllChildrenRecursive(getTagIndex().get(i).getGuid(), tags);
+ }
+ }
+ return tags;
+ }
+ // Give a list of tags, does any of them match a child tag?
+ public boolean checkNoteForChildTags(String guid, List<String> noteTags) {
+ boolean returnValue = false;
+ List<Tag> children = findAllChildren(guid);
+ for (int i=0; i<noteTags.size(); i++) {
+ String noteTag = noteTags.get(i);
+ for (int j=0; j<children.size(); j++) {
+ if (noteTag.equals(children.get(j).getGuid()))
+ return true;
+ }
+ }
+ return returnValue;
+ }
+
+
+ //************************************************************************************
+ //************************************************************************************
+ //** Notebook functions
+ //************************************************************************************
+ //************************************************************************************
+ // Delete a notebook
+ public void deleteNotebook(String guid) {
+ for (int i=0; i<getNotebookIndex().size(); i++) {
+ if (getNotebookIndex().get(i).getGuid().equals(guid)) {
+ getNotebookIndex().remove(i);
+ i=getMasterNoteIndex().size();
+ }
+ }
+ conn.getNotebookTable().expungeNotebook(guid, true);
+ }
+ // Rename a stack
+ public void renameStack(String oldName, String newName) {
+ for (int i=0; i<getNotebookIndex().size(); i++) {
+ if (getNotebookIndex().get(i).getStack() != null &&
+ getNotebookIndex().get(i).getStack().equalsIgnoreCase(oldName)) {
+ getNotebookIndex().get(i).setStack(newName);
+ }
+ }
+ }
+ // Update a notebook sequence number
+ public void updateNotebookSequence(String guid, int sequence) {
+ logger.log(logger.HIGH, "Entering ListManager.updateNotebookSequence");
+
+ conn.getNotebookTable().updateNotebookSequence(guid, sequence);
+
+ for (int i=0; i<notebookIndex.size(); i++) {
+ if (notebookIndex.get(i).getGuid().equals(guid)) {
+ notebookIndex.get(i).setUpdateSequenceNum(sequence);
+ i=notebookIndex.size()+1;
+ }
+ }
+ logger.log(logger.HIGH, "Leaving ListManager.updateNotebookSequence");
+
+ }
+ // Update a notebook Guid number
+ public void updateNotebookGuid(String oldGuid, String newGuid) {
+ logger.log(logger.HIGH, "Entering ListManager.updateNotebookGuid");
+
+ conn.getNotebookTable().updateNotebookGuid(oldGuid, newGuid);
+
+ for (int i=0; i<notebookIndex.size(); i++) {
+ if (notebookIndex.get(i).getGuid().equals(oldGuid)) {
+ notebookIndex.get(i).setGuid(newGuid);
+ i=notebookIndex.size()+1;
+ }
+ }
+ logger.log(logger.HIGH, "Leaving ListManager.updateNotebookGuid");
+
+ }
+ // Update a notebook Guid number
+ public void updateNotebookStack(String oldGuid, String stack) {
+ logger.log(logger.HIGH, "Entering ListManager.updateNotebookGuid");
+
+ conn.getNotebookTable().setStack(oldGuid, stack);
+
+ for (int i=0; i<notebookIndex.size(); i++) {
+ if (notebookIndex.get(i).getGuid().equals(oldGuid)) {
+ notebookIndex.get(i).setStack(stack);
+ i=notebookIndex.size()+1;
+ }
+ }
+ logger.log(logger.HIGH, "Leaving ListManager.updateNotebookGuid");
+
+ }
+
+
+ //************************************************************************************
+ //************************************************************************************
+ //** Load and filter the note index
+ //************************************************************************************
+ //************************************************************************************
+
+ public void noteDownloaded(Note n) {
+ boolean found = false;
+ for (int i=0; i<getMasterNoteIndex().size(); i++) {
+ if (getMasterNoteIndex().get(i).getGuid().equals(n.getGuid())) {
+ getMasterNoteIndex().set(i,n);
+ found = true;
+ i=getMasterNoteIndex().size();
+ }
+ }
+
+ if (!found)
+ getMasterNoteIndex().add(n);
+
+ for (int i=0; i<getNoteIndex().size(); i++) {
+ if (getNoteIndex().get(i).getGuid().equals(n.getGuid())) {
+ if (filterRecord(getNoteIndex().get(i)))
+ getNoteIndex().add(n);
+ getNoteIndex().remove(i);
+ i=getNoteIndex().size();
+ }
+ }
+
+ if (filterRecord(n))
+ getNoteIndex().add(n);
+
+ }
+ // Check if a note matches the currently selected notebooks, tags, or attribute searches.
+ public boolean filterRecord(Note n) {
+
+ boolean goodNotebook = false;
+ boolean goodTag = false;
+ boolean goodStatus = false;
+
+ // Check note status
+ if (!n.isActive() && Global.showDeleted)
+ return true;
+ else {
+ if (n.isActive() && !Global.showDeleted)
+ goodStatus = true;
+ }
+
+ // Begin filtering results
+ if (goodStatus)
+ goodNotebook = filterByNotebook(n.getNotebookGuid());
+ if (goodNotebook)
+ goodTag = filterByTag(n.getTagGuids());
+ if (goodTag) {
+ boolean goodCreatedBefore = false;
+ boolean goodCreatedSince = false;
+ boolean goodChangedBefore = false;
+ boolean goodChangedSince = false;
+ boolean goodContains = false;
+ if (!Global.createdBeforeFilter.hasSelection())
+ goodCreatedBefore = true;
+ else
+ goodCreatedBefore = Global.createdBeforeFilter.check(n);
+
+ if (!Global.createdSinceFilter.hasSelection())
+ goodCreatedSince = true;
+ else
+ goodCreatedSince = Global.createdSinceFilter.check(n);
+
+ if (!Global.changedBeforeFilter.hasSelection())
+ goodChangedBefore = true;
+ else
+ goodChangedBefore = Global.changedBeforeFilter.check(n);
+ if (!Global.changedSinceFilter.hasSelection())
+ goodChangedSince = true;
+ else
+ goodChangedSince = Global.changedSinceFilter.check(n);
+ if (!Global.containsFilter.hasSelection())
+ goodContains = true;
+ else
+ goodContains = Global.containsFilter.check(conn.getNoteTable(), n);
+
+ if (goodCreatedSince && goodCreatedBefore && goodChangedSince && goodChangedBefore && goodContains)
+ return true;
+ }
+ return false;
+ }
+
+ // Trigger a recount of counters
+ public void refreshCounters() {
+// refreshCounters= false;
+ if (!refreshCounters)
+ return;
+ refreshCounters = false;
+ tagCounterRunner.abortCount = true;
+ notebookCounterRunner.abortCount = true;
+ trashCounterRunner.abortCount = true;
+ countNotebookResults(getNoteIndex());
+ countTagResults(getNoteIndex());
+ reloadTrashCount();
+
+ }
+ // Load the note index based upon what the user wants.
+ public void loadNotesIndex() {
+ logger.log(logger.EXTREME, "Entering ListManager.loadNotesIndex()");
+
+ List<Note> matches;
+ if (enSearchChanged || getMasterNoteIndex() == null)
+ matches = enSearch.matchWords();
+ else
+ matches = getMasterNoteIndex();
+
+ if (matches == null)
+ matches = getMasterNoteIndex();
+
+ setNoteIndex(new ArrayList<Note>());
+ for (int i=0; i<matches.size(); i++) {
+ if (filterRecord(matches.get(i)))
+ getNoteIndex().add(matches.get(i));
+ }
+ refreshCounters = true;
+ enSearchChanged = false;
+ logger.log(logger.EXTREME, "Leaving ListManager.loadNotesIndex()");
+ }
+ public void countNotebookResults(List<Note> index) {
+ logger.log(logger.EXTREME, "Entering ListManager.countNotebookResults()");
+ notebookCounterRunner.abortCount = true;
+ if (!Global.mimicEvernoteInterface)
+ notebookCounterRunner.setNoteIndex(index);
+ else
+ notebookCounterRunner.setNoteIndex(getMasterNoteIndex());
+ notebookCounterRunner.release(CounterRunner.NOTEBOOK);
+ logger.log(logger.EXTREME, "Leaving ListManager.countNotebookResults()");
+ }
+ public void countTagResults(List<Note> index) {
+ logger.log(logger.EXTREME, "Entering ListManager.countTagResults");
+ trashCounterRunner.abortCount = true;
+ if (!Global.tagBehavior().equalsIgnoreCase("DoNothing"))
+ tagCounterRunner.setNoteIndex(index);
+ else
+ tagCounterRunner.setNoteIndex(getMasterNoteIndex());
+ tagCounterRunner.release(CounterRunner.TAG);
+ logger.log(logger.EXTREME, "Leaving ListManager.countTagResults()");
+ }
+ // Update the count of items in the trash
+ public void reloadTrashCount() {
+ logger.log(logger.EXTREME, "Entering ListManager.reloadTrashCount");
+ trashCounterRunner.abortCount = true;
+ trashCounterRunner.setNoteIndex(getMasterNoteIndex());
+ trashCounterRunner.release(CounterRunner.TRASH);
+ logger.log(logger.EXTREME, "Leaving ListManager.reloadTrashCount");
+ }
+
+ private boolean filterByNotebook(String guid) {
+ boolean good = false;
+ if (selectedNotebooks.size() == 0)
+ good = true;
+ if (!good && selectedNotebooks.contains(guid))
+ good = true;
+
+ for (int i=0; i<getArchiveNotebookIndex().size() && good; i++) {
+ if (guid.equals(getArchiveNotebookIndex().get(i).getGuid())) {
+ good = false;
+ return good;
+ }
+ }
+ return good;
+ }
+ private boolean filterByTag(List<String> noteTags) {
+ // If either the note has no tags or there are
+ // no selected tags, then any note is good.
+ if (noteTags == null || selectedTags == null)
+ return true;
+
+ // If there are no tags selected, then any note is good
+ if (selectedTags.size() == 0)
+ return true;
+
+ // If ALL tags must be matched, then check ALL note tags,
+ // otherwise we match on any criteria.
+ if (!Global.anyTagSelectionMatch()) {
+ for (int i=0; i<selectedTags.size(); i++) {
+ String selectedGuid = selectedTags.get(i);
+ boolean childMatch = false;
+ // If we should include children in the results
+ if (Global.includeTagChildren()) {
+ childMatch = checkNoteForChildTags(selectedGuid, noteTags);
+ // Do we have a match with this tag or any children
+ if (!noteTags.contains(selectedGuid)&& !childMatch)
+ return false;
+ } else {
+ // Does this note have a matching tag
+ if (!noteTags.contains(selectedGuid))
+ return false;
+ }
+ }
+ return true;
+ } else {
+ // Any match is displayed.
+ for (int i=0; i<selectedTags.size(); i++) {
+ String selectedGuid = selectedTags.get(i);
+ // If we have a simple match, then we're good
+ if (noteTags.contains(selectedGuid))
+ return true;
+ // If we have a match with one of the children tags && we should include child tags
+ if (Global.includeTagChildren() && checkNoteForChildTags(selectedGuid, noteTags))
+ return true;
+ }
+ return false;
+ }
+ }
+
+ public void setNoteSynchronized(String guid, boolean value) {
+ getNoteTableModel().updateNoteSyncStatus(guid, value);
+ }
+
+ public void updateNoteTitleColor(String guid, Integer color) {
+ NoteMetadata meta = getNoteMetadata().get(guid);
+ if (meta != null) {
+ noteModel.updateNoteTitleColor(guid, color);
+ meta.setColor(color);
+ conn.getNoteTable().updateNoteMetadata(meta);
+ }
+ }
+ public void loadNoteTitleColors() {
+ noteModel.setMetaData(getNoteMetadata());
+ }
+
+ //********************************************************************************
+ //********************************************************************************
+ //* Support signals from the index thread
+ //********************************************************************************
+ //********************************************************************************
+ // Reset a flag if an index is needed
+ public void setIndexNeeded(String guid, String type, Boolean b) {
+ if (Global.keepRunning && type.equalsIgnoreCase("content"))
+ conn.getNoteTable().setIndexNeeded(guid, false);
+ if (Global.keepRunning && type.equalsIgnoreCase("resource")) {
+ conn.getNoteTable().noteResourceTable.setIndexNeeded(guid, b);
+ }
+ }
+
+ public boolean threadCheck(int id) {
+ if (id == Global.notebookCounterThreadId)
+ return notebookThread.isAlive();
+ if (id == Global.tagCounterThreadId)
+ return tagThread.isAlive();
+ if (id == Global.trashCounterThreadId)
+ return trashThread.isAlive();
+ if (id == Global.saveThreadId)
+ return saveThread.isAlive();
+ return false;
+ }
+
+
+
+ //********************************************************************************
+ //********************************************************************************
+ //* Utility Functions
+ //********************************************************************************
+ //********************************************************************************
+ public void compactDatabase() {
+ conn.compactDatabase();
+// IndexConnection idx = new IndexConnection(logger, "nevernote-compact");
+// idx.dbSetup();
+// idx.dbShutdown();
+ }
+
+ // Rebuild the note HTML to something usable
+ public List<String> scanNoteForResources(Note n) {
+ logger.log(logger.HIGH, "Entering ListManager.scanNoteForResources");
+ logger.log(logger.EXTREME, "Note guid: " +n.getGuid());
+ QDomDocument doc = new QDomDocument();
+ QDomDocument.Result result = doc.setContent(n.getContent());
+ if (!result.success) {
+ logger.log(logger.MEDIUM, "Parse error when scanning note for resources.");
+ logger.log(logger.MEDIUM, "Note guid: " +n.getGuid());
+ return null;
+ }
+
+ List<String> returnArray = new ArrayList<String>();
+ QDomNodeList anchors = doc.elementsByTagName("en-media");
+ for (int i=0; i<anchors.length(); i++) {
+ QDomElement enmedia = anchors.at(i).toElement();
+ if (enmedia.hasAttribute("type")) {
+ QDomAttr hash = enmedia.attributeNode("hash");
+ returnArray.add(hash.value().toString());
+ }
+ }
+ logger.log(logger.HIGH, "Leaving ListManager.scanNoteForResources");
+ return returnArray;
+ }
+ // Given a list of tags, produce a string list of tag names
+ public String getTagNamesForNote(Note n) {
+ StringBuffer buffer = new StringBuffer(100);
+ Vector<String> v = new Vector<String>();
+ List<String> guids = n.getTagGuids();
+
+ if (guids == null)
+ return "";
+
+ for (int i=0; i<guids.size(); i++) {
+ v.add(getTagNameByGuid(guids.get(i)));
+ }
+ Comparator<String> comparator = Collections.reverseOrder();
+ Collections.sort(v,comparator);
+ Collections.reverse(v);
+
+ for (int i = 0; i<v.size(); i++) {
+ if (i>0)
+ buffer.append(", ");
+ buffer.append(v.get(i));
+ }
+
+ return buffer.toString();
+ }
+ // Get a tag name when given a tag guid
+ public String getTagNameByGuid(String guid) {
+ for (int i=0; i<getTagIndex().size(); i++) {
+ String s = getTagIndex().get(i).getGuid();
+ if (s.equals(guid)) {
+ return getTagIndex().get(i).getName();
+ }
+ }
+ return "";
+ }
+ // For a notebook guid, return the name
+ public String getNotebookNameByGuid(String guid) {
+ if (notebookIndex == null)
+ return null;
+ for (int i=0; i<notebookIndex.size(); i++) {
+ String s = notebookIndex.get(i).getGuid();
+ if (s.equals(guid)) {
+ return notebookIndex.get(i).getName();
+ }
+ }
+ return "";
+ }
+
+
+ // Reload the note's tag names. This is called when a tag's name changes by
+ // the user. It updates all notes with that tag to the new tag name.
+ public void reloadNoteTagNames(String tagGuid, String newName) {
+
+ // Set the master index
+ for (int i=0; i<getMasterNoteIndex().size(); i++) {
+ for (int j=0; j<getMasterNoteIndex().get(i).getTagGuids().size(); j++) {
+ if (getMasterNoteIndex().get(i).getTagGuids().get(j).equals(tagGuid)) {
+ getMasterNoteIndex().get(i).getTagNames().set(j, newName);
+ }
+ }
+ }
+
+ // Set the current index
+ for (int i=0; i<getNoteIndex().size(); i++) {
+ for (int j=0; j<getNoteIndex().get(i).getTagGuids().size(); j++) {
+ if (getNoteIndex().get(i).getTagGuids().get(j).equals(tagGuid)) {
+ getNoteIndex().get(i).getTagNames().set(j, newName);
+ }
+ }
+ }
+ }
+
+}
exit 1
fi
-rm /usr/share/applications/nixnote.desktop
-rm -rf /usr/share/nixnote
+rm /usr/share/applications/neighbornote.desktop
+rm -rf /usr/share/neighbornote
echo "Uninstall completed"