2 * This file is part of NeverNote
\r
3 * Copyright 2009 Randy Baumgarte
\r
5 * This file may be licensed under the terms of of the
\r
6 * GNU General Public License Version 2 (the ``GPL'').
\r
8 * Software distributed under the License is distributed
\r
9 * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
\r
10 * express or implied. See the GPL for the specific language
\r
11 * governing rights and limitations.
\r
13 * You should have received a copy of the GPL along with this
\r
14 * program. If not, go to http://www.gnu.org/licenses/gpl.html
\r
15 * or write to the Free Software Foundation, Inc.,
\r
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
\r
20 package cx.fbn.nevernote.threads;
\r
22 import java.util.ArrayList;
\r
23 import java.util.List;
\r
24 import java.util.Vector;
\r
25 import java.util.concurrent.LinkedBlockingQueue;
\r
27 import com.evernote.edam.type.Note;
\r
28 import com.evernote.edam.type.Notebook;
\r
29 import com.evernote.edam.type.Tag;
\r
30 import com.trolltech.qt.core.QMutex;
\r
31 import com.trolltech.qt.core.QObject;
\r
33 import cx.fbn.nevernote.Global;
\r
34 import cx.fbn.nevernote.filters.NotebookCounter;
\r
35 import cx.fbn.nevernote.filters.TagCounter;
\r
36 import cx.fbn.nevernote.signals.NotebookSignal;
\r
37 import cx.fbn.nevernote.signals.TagSignal;
\r
38 import cx.fbn.nevernote.signals.TrashSignal;
\r
39 import cx.fbn.nevernote.sql.DatabaseConnection;
\r
40 import cx.fbn.nevernote.sql.runners.NoteTagsRecord;
\r
41 import cx.fbn.nevernote.utilities.ApplicationLogger;
\r
42 import cx.fbn.nevernote.utilities.Pair;
\r
44 public class CounterRunner extends QObject implements Runnable {
\r
46 private final ApplicationLogger logger;
\r
47 private volatile boolean keepRunning;
\r
49 public volatile NotebookSignal notebookSignal;
\r
50 public volatile TrashSignal trashSignal;
\r
51 public volatile TagSignal tagSignal;
\r
52 private volatile Vector<String> notebookIndex;
\r
53 private volatile Vector<String> noteIndex;
\r
54 private volatile Vector<Boolean> activeIndex;
\r
56 public QMutex threadLock;
\r
58 public static int EXIT=0;
\r
59 public static int NOTEBOOK=1;
\r
60 public static int TAG=2;
\r
61 public static int TRASH=3;
\r
62 public static int TAG_ALL = 4;
\r
63 public static int NOTEBOOK_ALL = 5;
\r
65 public boolean ready = false;
\r
66 public boolean abortCount = false;
\r
67 private volatile LinkedBlockingQueue<Integer> readyQueue = new LinkedBlockingQueue<Integer>();
\r
70 //*********************************************
\r
72 //*********************************************
\r
73 public CounterRunner(String logname, int t) {
\r
75 threadLock = new QMutex();
\r
76 logger = new ApplicationLogger(logname);
\r
77 // setAutoDelete(false);
\r
79 notebookSignal = new NotebookSignal();
\r
80 tagSignal = new TagSignal();
\r
81 trashSignal = new TrashSignal();
\r
83 notebookIndex = new Vector<String>();
\r
84 activeIndex = new Vector<Boolean>();
\r
85 noteIndex = new Vector<String>();
\r
90 //*********************************************
\r
92 //*********************************************
\r
95 boolean keepRunning = true;
\r
97 thread().setPriority(Thread.MIN_PRIORITY);
\r
98 while(keepRunning) {
\r
102 type = readyQueue.take();
\r
105 keepRunning = false;
\r
106 if (type == NOTEBOOK)
\r
107 countNotebookResults();
\r
108 if (type == NOTEBOOK_ALL)
\r
109 countNotebookResults();
\r
112 if (type == TAG_ALL)
\r
115 countTrashResults();
\r
116 threadLock.unlock();
\r
117 } catch (InterruptedException e) {}
\r
123 public void setNoteIndex(List<Note> idx) {
\r
126 abortCount = false;
\r
127 notebookIndex.clear();
\r
128 activeIndex.clear();
\r
131 for (int i=0; i<idx.size(); i++) {
\r
132 if (Global.showDeleted && !idx.get(i).isActive()) {
\r
133 notebookIndex.add(new String(idx.get(i).getNotebookGuid()));
\r
134 noteIndex.add(new String(idx.get(i).getGuid()));
\r
135 activeIndex.add(new Boolean(idx.get(i).isActive()));
\r
137 if (!Global.showDeleted && idx.get(i).isActive()) {
\r
138 notebookIndex.add(new String(idx.get(i).getNotebookGuid()));
\r
139 noteIndex.add(new String(idx.get(i).getGuid()));
\r
140 activeIndex.add(new Boolean(idx.get(i).isActive()));
\r
144 threadLock.unlock();
\r
146 public void release(int type) {
\r
147 readyQueue.add(type);
\r
150 //*********************************************
\r
151 //* Getter & Setter method to tell the thread *
\r
152 //* to keep running. *
\r
153 //*********************************************
\r
154 public void setKeepRunning(boolean b) {
\r
157 public boolean keepRunning() {
\r
158 return keepRunning;
\r
162 //*********************************************
\r
163 //* Do the actual counting *
\r
164 //*********************************************
\r
165 private void countNotebookResults() {
\r
166 logger.log(logger.EXTREME, "Entering ListManager.countNotebookResults");
\r
169 DatabaseConnection conn = new DatabaseConnection(logger, Global.tagCounterThreadId);
\r
170 List<NotebookCounter> nCounter = new ArrayList<NotebookCounter>();
\r
173 List<Notebook> books = conn.getNotebookTable().getAll();
\r
178 if (type == NOTEBOOK_ALL) {
\r
179 for (int i=0; i<books.size(); i++) {
\r
183 nCounter.add(new NotebookCounter());
\r
184 nCounter.get(i).setCount(0);
\r
185 nCounter.get(i).setGuid(books.get(i).getGuid());
\r
189 List<Pair<String, Integer>> notebookCounts = conn.getNotebookTable().getNotebookCounts();
\r
192 for (int i=0; notebookCounts != null && i<notebookCounts.size(); i++) {
\r
195 for (int j=0; j<nCounter.size(); j++) {
\r
199 if (notebookCounts.get(i).getFirst().equals(nCounter.get(j).getGuid())) {
\r
200 nCounter.get(j).setCount(notebookCounts.get(i).getSecond());
\r
208 notebookSignal.countsChanged.emit(nCounter);
\r
214 for (int i=notebookIndex.size()-1; i>=0 && keepRunning; i--) {
\r
217 boolean notebookFound = false;
\r
218 for (int j=0; j<nCounter.size() && keepRunning; j++) {
\r
221 if (nCounter.get(j).getGuid().equals(notebookIndex.get(i))) {
\r
222 notebookFound = true;
\r
223 if (activeIndex.get(i)) {
\r
224 int c = nCounter.get(j).getCount()+1;
\r
225 nCounter.get(j).setCount(c);
\r
232 if (!notebookFound) {
\r
233 NotebookCounter newCounter = new NotebookCounter();
\r
234 newCounter.setGuid(notebookIndex.get(i));
\r
235 newCounter.setCount(1);
\r
236 nCounter.add(newCounter);
\r
241 notebookSignal.countsChanged.emit(nCounter);
\r
242 logger.log(logger.EXTREME, "Leaving ListManager.countNotebookResults()");
\r
246 private void countTagResults() {
\r
247 logger.log(logger.EXTREME, "Entering ListManager.countTagResults");
\r
248 DatabaseConnection conn = new DatabaseConnection(logger, Global.tagCounterThreadId);
\r
249 List<TagCounter> counter = new ArrayList<TagCounter>();
\r
250 List<Tag> allTags = conn.getTagTable().getAll();
\r
254 if (allTags == null)
\r
256 for (int k=0; k<allTags.size() && keepRunning; k++) {
\r
257 TagCounter newCounter = new TagCounter();
\r
258 newCounter.setGuid(allTags.get(k).getGuid());
\r
259 newCounter.setCount(0);
\r
260 counter.add(newCounter);
\r
263 if (type == TAG_ALL) {
\r
264 List<Pair<String, Integer>> tagCounts = conn.getNoteTable().noteTagsTable.getTagCounts();
\r
267 for (int i=0; tagCounts != null && i<tagCounts.size(); i++) {
\r
270 for (int j=0; j<counter.size(); j++) {
\r
273 if (tagCounts.get(i).getFirst().equals(counter.get(j).getGuid())) {
\r
276 counter.get(j).setCount(tagCounts.get(i).getSecond());
\r
283 tagSignal.countsChanged.emit(counter);
\r
290 List<NoteTagsRecord> tags = conn.getNoteTable().noteTagsTable.getAllNoteTags();
\r
291 for (int i=noteIndex.size()-1; i>=0; i--) {
\r
294 String note = noteIndex.get(i);
\r
295 for (int x=0; tags!= null && x<tags.size() && keepRunning; x++) {
\r
298 String tag = tags.get(x).tagGuid;
\r
299 for (int j=0; j<counter.size() && keepRunning; j++) {
\r
302 if (counter.get(j).getGuid().equals(tag) && note.equals(tags.get(x).noteGuid)) {
\r
303 int c = counter.get(j).getCount()+1;
\r
304 counter.get(j).setCount(c);
\r
311 tagSignal.countsChanged.emit(counter);
\r
312 logger.log(logger.EXTREME, "Leaving ListManager.countTagResults()");
\r
316 private void countTrashResults() {
\r
317 logger.log(logger.EXTREME, "Entering CounterRunner.countTrashResults()");
\r
318 DatabaseConnection conn = new DatabaseConnection(logger, Global.trashCounterThreadId);
\r
322 Integer tCounter = conn.getNoteTable().getDeletedCount();
\r
327 trashSignal.countChanged.emit(tCounter);
\r
328 logger.log(logger.EXTREME, "Leaving CounterRunner.countTrashResults()");
\r