OSDN Git Service

Added logic to reveal source HTML for a note & correct possible null pointer when...
authorRandy Baumgarte <randy@fbn.cx>
Sat, 9 Jul 2011 00:50:41 +0000 (20:50 -0400)
committerRandy Baumgarte <randy@Centauri.(none)>
Tue, 12 Jul 2011 22:37:59 +0000 (18:37 -0400)
shortcuts_sample.txt
src/cx/fbn/nevernote/NeverNote.java
src/cx/fbn/nevernote/gui/BrowserWindow.java
src/cx/fbn/nevernote/gui/Highlighter.java [new file with mode: 0644]
src/cx/fbn/nevernote/gui/MainMenuBar.java
src/cx/fbn/nevernote/sql/DatabaseConnection.java
src/cx/fbn/nevernote/sql/NotebookTable.java

index 114f994..d9317cb 100644 (file)
@@ -50,6 +50,7 @@ Edit_Insert_Latex                             // Insert a LaTeX formula.
 View_List_Narrow                               // View with the list on the side
 View_List_Wide                                 // View with the list on the top
 View_Thumbnail                                 // Fullscreen preview
+View_Source                                    // Reveal the HTML source of a note
 View_Extended_Information      F8      // View details on the current note
 View_Show_Note_List            F10             // Show current notes
 View_Show_Notebooks                            // Show notebooks
index 251620e..07342b6 100644 (file)
@@ -3131,7 +3131,7 @@ public class NeverNote extends QMainWindow{
        
     }
     // Synchronize with Evernote
-       @SuppressWarnings("unused")
+
        private void evernoteSync() {
        logger.log(logger.HIGH, "Entering NeverNote.evernoteSync");
        if (!Global.isConnected)
@@ -4193,7 +4193,7 @@ public class NeverNote extends QMainWindow{
        private void externalWindowClosing(String guid) {
                externalWindows.remove(guid);
     }
-    
+
     
     
     //***************************************************************
@@ -4210,7 +4210,7 @@ public class NeverNote extends QMainWindow{
                        QTextCodec codec = QTextCodec.codecForName("UTF-8");
                QByteArray unicode =  codec.fromUnicode(browserWindow.getContent());
                        ExternalBrowse window = externalWindows.get(currentNoteGuid);
-               window.getBrowserWindow().getBrowser().setContent(unicode);
+               window.getBrowserWindow().setContent(unicode);
                }
                
                // If the note is dirty, then it is unsynchronized by default.
@@ -4249,7 +4249,7 @@ public class NeverNote extends QMainWindow{
                noteCache.put(guid, unicode.toString());
        if (guid.equals(currentNoteGuid)) {
                noteDirty = true;
-               browserWindow.getBrowser().setContent(unicode);
+               browserWindow.setContent(unicode);
        } 
        if (save) {
                thumbnailRunner.addWork("GENERATE "+ guid);
@@ -4343,7 +4343,7 @@ public class NeverNote extends QMainWindow{
 //             if (Global.enableHTMLEntitiesFix) {
 //                     browser.getBrowser().setContent(new QByteArray(StringEscapeUtils.unescapeHtml(js.toString())));
 //             } else
-                       browser.getBrowser().setContent(js);
+                       browser.setContent(js);
                        noteCache.put(guid, js.toString());
 
                        if (formatter.resourceError)
@@ -4365,7 +4365,7 @@ public class NeverNote extends QMainWindow{
                        logger.log(logger.HIGH, "Note content is being pulled from the cache");
                        String cachedContent = formatter.modifyCachedTodoTags(noteCache.get(guid));
                        js = new QByteArray(cachedContent);
-                       browser.getBrowser().setContent(js);
+                       browser.setContent(js);
                        if (readOnlyCache.containsKey(guid))
                                        readOnly = true;
                        if (inkNoteCache.containsKey(guid))
@@ -5580,7 +5580,7 @@ public class NeverNote extends QMainWindow{
                if (!alive) {
                        tagDeadCount++;
                        if (tagDeadCount > MAX && !disableTagThreadCheck) {
-                               QMessageBox.information(this, tr("A thread his died."), tr("It appears as the tag counter thread has died.  I recommend "+
+                               QMessageBox.information(this, tr("A thread has died."), tr("It appears as the tag counter thread has died.  I recommend "+
                                "checking stopping NeverNote, saving the logs for later viewing, and restarting.  Sorry."));
                                disableTagThreadCheck = true;
                        }
@@ -5591,7 +5591,7 @@ public class NeverNote extends QMainWindow{
                if (!alive) {
                        notebookThreadDeadCount++;
                        if (notebookThreadDeadCount > MAX && !disableNotebookThreadCheck) {
-                               QMessageBox.information(this, tr("A thread his died."), tr("It appears as the notebook counter thread has died.  I recommend "+
+                               QMessageBox.information(this, tr("A thread has died."), tr("It appears as the notebook counter thread has died.  I recommend "+
                                        "checking stopping NeverNote, saving the logs for later viewing, and restarting.  Sorry."));
                                disableNotebookThreadCheck=true;
                        }
@@ -5602,7 +5602,7 @@ public class NeverNote extends QMainWindow{
                if (!alive) {
                        trashDeadCount++;
                        if (trashDeadCount > MAX && !disableTrashThreadCheck) {
-                               QMessageBox.information(this, tr("A thread his died."), ("It appears as the trash counter thread has died.  I recommend "+
+                               QMessageBox.information(this, tr("A thread has died."), ("It appears as the trash counter thread has died.  I recommend "+
                                        "checking stopping NeverNote, saving the logs for later viewing, and restarting.  Sorry."));
                                disableTrashThreadCheck = true;
                        }
@@ -5613,7 +5613,7 @@ public class NeverNote extends QMainWindow{
                if (!alive) {
                        saveThreadDeadCount++;
                        if (saveThreadDeadCount > MAX && !disableSaveThreadCheck) {
-                               QMessageBox.information(this, tr("A thread his died."), tr("It appears as the note saver thread has died.  I recommend "+
+                               QMessageBox.information(this, tr("A thread has died."), tr("It appears as the note saver thread has died.  I recommend "+
                                        "checking stopping NeverNote, saving the logs for later viewing, and restarting.  Sorry."));
                                disableSaveThreadCheck = true;
                        }
@@ -5623,7 +5623,7 @@ public class NeverNote extends QMainWindow{
                if (!syncThread.isAlive()) {
                        syncThreadDeadCount++;
                        if (syncThreadDeadCount > MAX && !disableSyncThreadCheck) {
-                               QMessageBox.information(this, tr("A thread his died."), tr("It appears as the synchronization thread has died.  I recommend "+
+                               QMessageBox.information(this, tr("A thread has died."), tr("It appears as the synchronization thread has died.  I recommend "+
                                        "checking stopping NeverNote, saving the logs for later viewing, and restarting.  Sorry."));
                                disableSyncThreadCheck = true;
                        }
@@ -5633,7 +5633,7 @@ public class NeverNote extends QMainWindow{
                if (!indexThread.isAlive()) {
                        indexThreadDeadCount++;
                        if (indexThreadDeadCount > MAX && !disableIndexThreadCheck) {
-                               QMessageBox.information(this, tr("A thread his died."), tr("It appears as the index thread has died.  I recommend "+
+                               QMessageBox.information(this, tr("A thread has died."), tr("It appears as the index thread has died.  I recommend "+
                                        "checking stopping NeverNote, saving the logs for later viewing, and restarting.  Sorry."));
                                disableIndexThreadCheck = true;
                        }
@@ -6199,7 +6199,7 @@ public class NeverNote extends QMainWindow{
                                String content = browser.getContent().substring(0,position) +
                                                 newSegment +
                                                 browser.getContent().substring(endPos);
-                               browser.getBrowser().setContent(new QByteArray(content));;
+                               browser.setContent(new QByteArray(content));;
                        }
                        
                        position = browser.getContent().indexOf("en-tag=\"en-media\" guid=\""+guid+"\" type=", position+1);
@@ -6256,7 +6256,12 @@ public class NeverNote extends QMainWindow{
                        return true;
        }
 
-       
+       //*************************************************
+       //* View / Hide source HTML for a note
+       //*************************************************
+       public void viewSource() {
+               browserWindow.showSource(menuBar.viewSource.isChecked());
+       }
        //*************************************************
        // Block the program.  This is used for things  
        // like async web calls.
index fa1b7e2..0fb75aa 100644 (file)
@@ -83,6 +83,7 @@ import com.trolltech.qt.gui.QDesktopServices;
 import com.trolltech.qt.gui.QFileDialog;\r
 import com.trolltech.qt.gui.QFileDialog.AcceptMode;\r
 import com.trolltech.qt.gui.QFileDialog.FileMode;\r
+import com.trolltech.qt.gui.QFont;\r
 import com.trolltech.qt.gui.QFontDatabase;\r
 import com.trolltech.qt.gui.QFormLayout;\r
 import com.trolltech.qt.gui.QGridLayout;\r
@@ -100,6 +101,9 @@ import com.trolltech.qt.gui.QPalette;
 import com.trolltech.qt.gui.QPalette.ColorRole;\r
 import com.trolltech.qt.gui.QPushButton;\r
 import com.trolltech.qt.gui.QShortcut;\r
+import com.trolltech.qt.gui.QSplitter;\r
+import com.trolltech.qt.gui.QTextEdit;\r
+import com.trolltech.qt.gui.QTextEdit.LineWrapMode;\r
 import com.trolltech.qt.gui.QTimeEdit;\r
 import com.trolltech.qt.gui.QToolButton;\r
 import com.trolltech.qt.gui.QToolButton.ToolButtonPopupMode;\r
@@ -158,8 +162,11 @@ public class BrowserWindow extends QWidget {
        public final QAction    fontSizeAction;\r
        private boolean extendedOn;\r
        public boolean buttonsVisible;\r
-       private final String iconPath = new String("classpath:cx/fbn/nevernote/icons/");\r
+       private final String iconPath;\r
        private final ContentView browser;\r
+       private final QTextEdit sourceEdit;\r
+       private String sourceEditHeader;\r
+       Highlighter syntaxHighlighter;\r
        private List<Tag> allTags;\r
        private List<String> currentTags;\r
        public NoteSignal noteSignal;\r
@@ -234,7 +241,7 @@ public class BrowserWindow extends QWidget {
        private final ColorMenu fontHilightColorMenu;\r
        public final QFileSystemWatcher fileWatcher;\r
        public int cursorPosition;\r
-       private boolean forceTextPaste = false;\r
+       private boolean forceTextPaste;\r
        private String selectedFile;\r
        private String currentHyperlink;\r
        public boolean keepPDFNavigationHidden;\r
@@ -244,9 +251,9 @@ public class BrowserWindow extends QWidget {
     SpellChecker spellChecker;\r
     SuggestionListener spellListener;\r
        private final HashMap<String,Integer> previewPageList;  \r
-       boolean insertHyperlink = true;\r
-       boolean insideTable = false;\r
-       boolean insideEncryption = false;\r
+       boolean insertHyperlink;\r
+       boolean insideTable;\r
+       boolean insideEncryption;\r
        public Signal1<BrowserWindow> blockApplication;\r
        public Signal0 unblockApplication;\r
        public boolean awaitingHttpResponse;\r
@@ -299,6 +306,11 @@ public class BrowserWindow extends QWidget {
        public BrowserWindow(DatabaseConnection c) {\r
                logger = new ApplicationLogger("browser.log");\r
                logger.log(logger.HIGH, "Setting up browser");\r
+               iconPath = new String("classpath:cx/fbn/nevernote/icons/");\r
+               forceTextPaste = false;\r
+               insertHyperlink = true;\r
+               insideTable = false;\r
+               insideEncryption = false;\r
                \r
                fileWatcher = new QFileSystemWatcher();\r
 //             fileWatcher.fileChanged.connect(this, "fileChanged(String)");\r
@@ -384,11 +396,25 @@ public class BrowserWindow extends QWidget {
                setAcceptDrops(true);\r
 \r
                browser = new ContentView(this);\r
+                               \r
                browser.page().setLinkDelegationPolicy(\r
                                QWebPage.LinkDelegationPolicy.DelegateAllLinks);\r
                browser.linkClicked.connect(this, "linkClicked(QUrl)");\r
                currentHyperlink = "";\r
                \r
+               //Setup the source editor\r
+               sourceEdit = new QTextEdit(this);\r
+               sourceEdit.setVisible(false);\r
+               sourceEdit.setTabChangesFocus(true);\r
+               sourceEdit.setLineWrapMode(LineWrapMode.NoWrap);\r
+               QFont font = new QFont();\r
+               font.setFamily("Courier");\r
+               font.setFixedPitch(true);\r
+               font.setPointSize(10);\r
+               sourceEdit.setFont(font);\r
+               syntaxHighlighter = new Highlighter(sourceEdit.document());\r
+               sourceEdit.textChanged.connect(this, "sourceEdited()");\r
+\r
                QVBoxLayout v = new QVBoxLayout();\r
                QFormLayout notebookLayout = new QFormLayout();\r
                QGridLayout dateLayout = new QGridLayout();\r
@@ -554,9 +580,19 @@ public class BrowserWindow extends QWidget {
                buttonLayout.toggleNumberListVisible.triggered.connect(this, "todoClicked()");\r
                buttonLayout.toggleTodo.triggered.connect(this, "toggleTodoVisible(Boolean)");\r
 \r
+               // Setup the source browser);\r
 \r
 //             buttonLayout.addWidget(new QLabel(), 1);\r
-               v.addWidget(browser, 1);\r
+               QSplitter editSplitter = new QSplitter(this);\r
+               editSplitter.addWidget(browser);\r
+               editSplitter.setOrientation(Qt.Orientation.Vertical);\r
+               editSplitter.addWidget(sourceEdit);\r
+\r
+               \r
+\r
+//             v.addWidget(browser, 1);\r
+//             v.addWidget(sourceEdit);\r
+               v.addWidget(editSplitter);\r
                setLayout(v);\r
 \r
                browser.downloadAttachmentRequested.connect(this,\r
@@ -689,7 +725,7 @@ public class BrowserWindow extends QWidget {
        public void clear() {\r
                logger.log(logger.EXTREME, "Entering BrowserWindow.clear()");\r
                setNote(null);\r
-               browser.setContent(new QByteArray());\r
+               setContent(new QByteArray());\r
                tagEdit.setText("");\r
                tagEdit.tagCompleter.reset();\r
                urlLabel.setText(tr("Source URL:"));\r
@@ -697,6 +733,11 @@ public class BrowserWindow extends QWidget {
                logger.log(logger.EXTREME, "Exiting BrowserWindow.clear()");\r
        }\r
 \r
+       public void setContent(QByteArray data) {\r
+               sourceEdit.blockSignals(true);\r
+               browser.setContent(data);\r
+               setSource(getBrowser().page().mainFrame().toHtml());\r
+       }\r
        // get/set current note\r
        public void setNote(Note n) {\r
                currentNote = n;\r
@@ -1564,7 +1605,7 @@ public class BrowserWindow extends QWidget {
                        HtmlTagModifier modifier = new HtmlTagModifier(getContent());\r
                        modifier.modifyLatexTagHash(newRes);\r
                        String newContent = modifier.getHtml();\r
-                       browser.setContent(new QByteArray(newContent));\r
+                       setContent(new QByteArray(newContent));\r
                }\r
 \r
                logger.log(logger.EXTREME, "New HTML set\n" +browser.page().currentFrame().toHtml());\r
@@ -2012,6 +2053,8 @@ public class BrowserWindow extends QWidget {
        // The note contents have changed\r
        public void contentChanged() {\r
                String content = getContent();\r
+               setSource(content);\r
+               \r
                checkNoteTitle();\r
                noteSignal.noteChanged.emit(currentNote.getGuid(), content); \r
        }\r
@@ -2657,7 +2700,7 @@ public class BrowserWindow extends QWidget {
                                        text = text.substring(0,imagePos) +plainText+text.substring(endPos+1);  \r
                                        QTextCodec codec = QTextCodec.codecForName("UTF-8");\r
                                QByteArray unicode =  codec.fromUnicode(text);\r
-                                       browser.setContent(unicode);\r
+                                       setContent(unicode);\r
                                        if (permanent)\r
                                                contentChanged();\r
                        }\r
@@ -3337,5 +3380,36 @@ public class BrowserWindow extends QWidget {
                                        tr("No Errors Found"));\r
 \r
     }\r
+       \r
+       // Source edited\r
+       @SuppressWarnings("unused")\r
+       private void sourceEdited() {\r
+               QByteArray data = new QByteArray(sourceEditHeader+sourceEdit.toPlainText()+"</body></html>");\r
+               getBrowser().setContent(data);\r
+\r
+               checkNoteTitle();\r
+               noteSignal.noteChanged.emit(currentNote.getGuid(), sourceEdit.toPlainText()); \r
+       }\r
+       \r
+       private void setSource(String text) {\r
+               sourceEdit.blockSignals(true);\r
+               int body = text.indexOf("<body");\r
+               if (body > 0) {\r
+                       body = text.indexOf(">",body);\r
+                       if (body > 0) {\r
+                               sourceEditHeader =text.substring(0, body+1);\r
+                               text = text.substring(body+1);\r
+                       }\r
+               }\r
+               text = text.replace("</body></html>", "");\r
+               sourceEdit.setPlainText(text);\r
+               sourceEdit.setReadOnly(!getBrowser().page().isContentEditable());\r
+               syntaxHighlighter.rehighlight();\r
+               sourceEdit.blockSignals(false);\r
+       }\r
 \r
+       // show/hide view source window\r
+       public void showSource(boolean value) {\r
+               sourceEdit.setVisible(value);\r
+       }\r
 }\r
diff --git a/src/cx/fbn/nevernote/gui/Highlighter.java b/src/cx/fbn/nevernote/gui/Highlighter.java
new file mode 100644 (file)
index 0000000..b5ed928
--- /dev/null
@@ -0,0 +1,64 @@
+/*\r
+ * This file is part of NeverNote \r
+ * Copyright 2009 Randy Baumgarte\r
+ * \r
+ * This file may be licensed under the terms of of the\r
+ * GNU General Public License Version 2 (the ``GPL'').\r
+ *\r
+ * Software distributed under the License is distributed\r
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either\r
+ * express or implied. See the GPL for the specific language\r
+ * governing rights and limitations.\r
+ *\r
+ * You should have received a copy of the GPL along with this\r
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html\r
+ * or write to the Free Software Foundation, Inc.,\r
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
+ *\r
+ */\r
+\r
+package cx.fbn.nevernote.gui;\r
+\r
+import com.trolltech.qt.core.QRegExp;\r
+import com.trolltech.qt.core.Qt;\r
+import com.trolltech.qt.gui.QBrush;\r
+import com.trolltech.qt.gui.QColor;\r
+import com.trolltech.qt.gui.QFont;\r
+import com.trolltech.qt.gui.QSyntaxHighlighter;\r
+import com.trolltech.qt.gui.QTextCharFormat;\r
+import com.trolltech.qt.gui.QTextDocument;\r
+\r
+public class Highlighter extends QSyntaxHighlighter {\r
+       \r
+       public class HighlightingRule {\r
+               public QRegExp pattern;\r
+               public QTextCharFormat format;\r
+               \r
+               public HighlightingRule(QRegExp pattern, QTextCharFormat format) {\r
+                       this.pattern = pattern;\r
+                       this.format = format;\r
+               }\r
+       }\r
+\r
+       public Highlighter(QTextDocument parent)  {\r
+               super(parent);\r
+       }\r
+\r
+       @Override\r
+       protected void highlightBlock(String text) {\r
+               QTextCharFormat format = new QTextCharFormat();\r
+               QBrush brush = new QBrush(QColor.blue, Qt.BrushStyle.SolidPattern);\r
+               format.setForeground(brush);\r
+               format.setFontWeight(QFont.Weight.Bold.value());\r
+               \r
+               int index = text.indexOf("<");\r
+               while (index >= 0) {\r
+                       int length = text.indexOf(">", index)-index+1;\r
+                       setFormat(index, length, format);\r
+                       index = text.indexOf("<", index+1);\r
+               }\r
+               setCurrentBlockState(0);\r
+       }\r
+\r
+\r
+}\r
index 5eca7f0..2bb8edd 100644 (file)
@@ -78,6 +78,7 @@ public class MainMenuBar extends QMenuBar {
        public QAction                  hideNoteList;                           // show/hide the list of notes\r
        public QAction                  showEditorBar;                          // show/hide the editor button bar\r
        public QAction                  hideLeftSide;                           // Hide the entire left side\r
+       public QAction                  viewSource;                                     // View the source HTML of a note\r
        \r
        public QAction                  formatBold;                                     // Bold selected text\r
        public QAction                  formatItalic;                           // Italics selected text\r
@@ -387,6 +388,14 @@ public class MainMenuBar extends QMenuBar {
                hideLeftSide.setChecked(false);\r
                setupShortcut(hideLeftSide, "View_Show_Left_Side");\r
                //hideLeftSide.setShortcut("F11");\r
+               \r
+               viewSource = new QAction(tr("View Source"), this);\r
+               viewSource.setToolTip(tr("View the source HTML for a note"));\r
+               viewSource.triggered.connect(parent, "viewSource()");\r
+               viewSource.setCheckable(true);\r
+               viewSource.setChecked(false);\r
+               setupShortcut(viewSource, "View_Source");\r
+               //hideLeftSide.setShortcut("F11");\r
 \r
                alignLeftAction = new QAction(tr("Left"), this);\r
                alignLeftAction.setToolTip(tr("Left Align"));\r
@@ -681,6 +690,7 @@ public class MainMenuBar extends QMenuBar {
                \r
                viewMenu = addMenu(tr("&View"));\r
                viewMenu.addAction(noteAttributes);\r
+               viewMenu.addAction(viewSource);\r
                viewMenu.addSeparator();\r
                viewMenu.addAction(wideListView);\r
                viewMenu.addAction(narrowListView);\r
index d89ac43..7486246 100644 (file)
@@ -47,7 +47,7 @@ public class DatabaseConnection {
        private Connection                                      conn;
        private Connection                                      indexConn;
        private Connection                                      resourceConn;
-       int throttle=0;
+       int throttle;
        int id;
 
        
index 1c585fb..21602e0 100644 (file)
@@ -510,7 +510,7 @@ public class NotebookTable {
                                p.setAscending(query.valueBoolean(9, false));\r
                                p.setPublicDescription(query.valueString(10));\r
                                p.setOrder(NoteSortOrder.findByValue(query.valueInteger(11)));\r
-                               if (p.getPublicDescription().trim().equalsIgnoreCase(""))\r
+                               if (p.getPublicDescription() != null && p.getPublicDescription().trim().equalsIgnoreCase(""))\r
                                        p.setPublicDescription(null);\r
                                tempNotebook.setPublishing(p);\r
                        }\r