OSDN Git Service

Add QuickLink function.
authorRandy Baumgarte <randy@fbn.cx>
Mon, 29 Aug 2011 01:16:37 +0000 (21:16 -0400)
committerRandy Baumgarte <randy@fbn.cx>
Mon, 29 Aug 2011 01:16:37 +0000 (21:16 -0400)
src/cx/fbn/nevernote/NeverNote.java
src/cx/fbn/nevernote/dialog/NoteQuickLinkDialog.java [new file with mode: 0644]
src/cx/fbn/nevernote/gui/BrowserWindow.java
src/cx/fbn/nevernote/gui/ContentView.java
src/cx/fbn/nevernote/sql/NoteTable.java

index 708ff36..18b3796 100644 (file)
@@ -4273,7 +4273,6 @@ public class NeverNote extends QMainWindow{
     //** These functions deal with Note specific things
     //***************************************************************
     //***************************************************************    
-    @SuppressWarnings("unused")
        private void setNoteDirty() {
                logger.log(logger.EXTREME, "Entering NeverNote.setNoteDirty()");
                
diff --git a/src/cx/fbn/nevernote/dialog/NoteQuickLinkDialog.java b/src/cx/fbn/nevernote/dialog/NoteQuickLinkDialog.java
new file mode 100644 (file)
index 0000000..f8c85ea
--- /dev/null
@@ -0,0 +1,181 @@
+/*\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
index 8882212..f689286 100644 (file)
@@ -48,6 +48,7 @@ import com.evernote.edam.type.Notebook;
 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
@@ -126,6 +127,7 @@ import cx.fbn.nevernote.dialog.EnDecryptDialog;
 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
@@ -1398,7 +1400,39 @@ public class BrowserWindow extends QWidget {
                                script_start + buffer.toString() + script_end);\r
        }\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
@@ -1667,6 +1701,7 @@ public class BrowserWindow extends QWidget {
        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
@@ -1696,6 +1731,7 @@ public class BrowserWindow extends QWidget {
                \r
                browser.encryptAction.setEnabled(enabled);\r
                browser.insertLinkAction.setEnabled(enabled);\r
+               browser.insertQuickLinkAction.setEnabled(enabled);\r
 //             selectedText = text;\r
        }\r
 \r
@@ -2786,6 +2822,7 @@ public class BrowserWindow extends QWidget {
                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
index b270e01..e3cac5b 100644 (file)
@@ -75,6 +75,8 @@ public class ContentView extends QWebView {
        QAction deleteTableColumnAction;\r
        QShortcut deleteTableColumnShortcut;\r
        QAction openAction;\r
+       QAction insertQuickLinkAction;\r
+       QShortcut insertQuickLinkShortcut;\r
        \r
        QAction redBackgroundColor;\r
        \r
@@ -172,6 +174,15 @@ public class ContentView extends QWebView {
                insertLinkShortcut = new QShortcut(this);\r
                setupShortcut(insertLinkShortcut, "Edit_Insert_Hyperlink");\r
                insertLinkShortcut.activated.connect(parent, "insertLink()");\r
+               \r
+               insertQuickLinkAction = new QAction(tr("Quick Link"), this);\r
+               insertQuickLinkAction.triggered.connect(parent, "insertQuickLink()");\r
+               setupShortcut(insertQuickLinkAction, "Edit_Insert_QuickLink");\r
+               contextMenu.addAction(insertQuickLinkAction);\r
+               insertQuickLinkAction.setEnabled(false);\r
+               insertQuickLinkShortcut = new QShortcut(this);\r
+               setupShortcut(insertQuickLinkShortcut, "Edit_Insert_Quicklink");\r
+               insertQuickLinkShortcut.activated.connect(parent, "insertQuickLink()");\r
 \r
                insertLatexAction = new QAction(tr("Insert LaTeX Formula"), this);\r
                insertLatexAction.triggered.connect(parent, "insertLatex()");\r
index ac0aeb1..0901a8b 100644 (file)
@@ -43,6 +43,7 @@ import cx.fbn.nevernote.evernote.EnmlConverter;
 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
@@ -1139,6 +1140,28 @@ public class NoteTable {
                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