Package cx.fbn.nevernote.utilities

Source Code of cx.fbn.nevernote.utilities.ListManager

/*
* 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();
     notebookCounterRunner = new CounterRunner("notebook_counter.log", CounterRunner.NOTEBOOK,
             Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(),
             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();
     tagCounterRunner = new CounterRunner("tag_counter.log", CounterRunner.TAG,
         Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(),
         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();
     trashCounterRunner = new CounterRunner("trash_counter.log", CounterRunner.TRASH,
         Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(),
         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");
    saveRunner = new SaveRunner("saveRunner.log",
        Global.getDatabaseUrl(), Global.getIndexDatabaseUrl(), Global.getResourceDatabaseUrl(),
        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) {
    logger.log(logger.HIGH, "Entering ListManager.saveNoteTags");
    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);
          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);
        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);
        }
      }
    }
  }
 
}
TOP

Related Classes of cx.fbn.nevernote.utilities.ListManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.