OSDN Git Service

GitHub最初のコミット(SourceForge.jp 128fa38 2013-02-28 15:28:57 と同じ内容)
[neighbornote/NeighborNote.git] / src / cx / fbn / nevernote / threads / ThumbnailRunner.java
index 61fbfd2..1bb4e0b 100644 (file)
-/*\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);
+       }
+               
+       
+
+
+}