OSDN Git Service

Fix logic that caused a note's title to be pulled from the text when it is not manual...
[neighbornote/NeighborNote.git] / src / cx / fbn / nevernote / gui / BrowserWindow.java
index 8a429d5..ac9bd98 100644 (file)
@@ -20,6 +20,8 @@
 package cx.fbn.nevernote.gui;\r
 \r
 import java.io.File;\r
+import java.io.FileNotFoundException;\r
+import java.io.IOException;\r
 import java.net.FileNameMap;\r
 import java.net.URI;\r
 import java.net.URLConnection;\r
@@ -28,10 +30,12 @@ import java.security.NoSuchAlgorithmException;
 import java.text.SimpleDateFormat;\r
 import java.util.ArrayList;\r
 import java.util.Calendar;\r
+import java.util.Collections;\r
 import java.util.Date;\r
 import java.util.GregorianCalendar;\r
 import java.util.HashMap;\r
 import java.util.List;\r
+import java.util.Locale;\r
 \r
 import com.evernote.edam.limits.Constants;\r
 import com.evernote.edam.type.Data;\r
@@ -40,6 +44,13 @@ 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.swabunga.spell.engine.SpellDictionary;\r
+import com.swabunga.spell.engine.SpellDictionaryHashMap;\r
+import com.swabunga.spell.engine.Word;\r
+import com.swabunga.spell.event.SpellCheckEvent;\r
+import com.swabunga.spell.event.SpellCheckListener;\r
+import com.swabunga.spell.event.SpellChecker;\r
+import com.swabunga.spell.event.StringWordTokenizer;\r
 import com.trolltech.qt.core.QByteArray;\r
 import com.trolltech.qt.core.QDataStream;\r
 import com.trolltech.qt.core.QDateTime;\r
@@ -49,6 +60,7 @@ import com.trolltech.qt.core.QFileSystemWatcher;
 import com.trolltech.qt.core.QIODevice;\r
 import com.trolltech.qt.core.QMimeData;\r
 import com.trolltech.qt.core.QUrl;\r
+import com.trolltech.qt.gui.QAction;\r
 import com.trolltech.qt.gui.QApplication;\r
 import com.trolltech.qt.gui.QCalendarWidget;\r
 import com.trolltech.qt.gui.QClipboard;\r
@@ -74,6 +86,8 @@ import com.trolltech.qt.gui.QMessageBox;
 import com.trolltech.qt.gui.QPushButton;\r
 import com.trolltech.qt.gui.QShortcut;\r
 import com.trolltech.qt.gui.QTimeEdit;\r
+import com.trolltech.qt.gui.QToolButton;\r
+import com.trolltech.qt.gui.QToolButton.ToolButtonPopupMode;\r
 import com.trolltech.qt.gui.QVBoxLayout;\r
 import com.trolltech.qt.gui.QWidget;\r
 import com.trolltech.qt.network.QNetworkRequest;\r
@@ -87,6 +101,7 @@ import cx.fbn.nevernote.dialog.EnCryptDialog;
 import cx.fbn.nevernote.dialog.EnDecryptDialog;\r
 import cx.fbn.nevernote.dialog.GeoDialog;\r
 import cx.fbn.nevernote.dialog.InsertLinkDialog;\r
+import cx.fbn.nevernote.dialog.SpellCheck;\r
 import cx.fbn.nevernote.dialog.TableDialog;\r
 import cx.fbn.nevernote.dialog.TagAssign;\r
 import cx.fbn.nevernote.evernote.EnCrypt;\r
@@ -105,7 +120,7 @@ public class BrowserWindow extends QWidget {
        private final QComboBox geoBox;\r
        public final TagLineEdit tagEdit;\r
        public final QLabel tagLabel;\r
-       private final QLabel urlLabel;\r
+       private final QPushButton urlLabel;\r
        private final QLabel alteredLabel;\r
        private final QDateEdit alteredDate;\r
        private final QTimeEdit alteredTime;\r
@@ -118,6 +133,7 @@ public class BrowserWindow extends QWidget {
        private final QLabel notebookLabel;\r
        private final QLabel createdLabel;\r
        public final QComboBox fontSize;\r
+       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
@@ -137,26 +153,43 @@ public class BrowserWindow extends QWidget {
        private final QCalendarWidget subjectCalendarWidget;\r
 \r
        public final QPushButton undoButton;\r
+       public final QAction    undoAction;\r
        public final QPushButton redoButton;\r
+       public final QAction    redoAction;\r
        public final QPushButton cutButton;\r
+       public final QAction    cutAction;\r
        public final QPushButton copyButton;\r
+       public final QAction    copyAction;\r
        public final QPushButton pasteButton;\r
+       public final QAction    pasteAction;\r
        public final QPushButton boldButton;\r
+       public final QAction    boldAction;\r
        public final QPushButton underlineButton;\r
+       public final QAction    underlineAction;\r
        public final QPushButton italicButton;\r
+       public final QAction    italicAction;\r
        public final Signal0 focusLost;\r
        public final NoteResourceSignal resourceSignal;\r
 \r
        public QPushButton rightAlignButton;\r
+       public final QAction    rightAlignAction;\r
        public QPushButton leftAlignButton;\r
+       public final QAction    leftAlignAction;\r
        public QPushButton centerAlignButton;\r
+       public final QAction    centerAlignAction;\r
 \r
        public final QPushButton strikethroughButton;\r
+       public final QAction    strikethroughAction;\r
        public final QPushButton hlineButton;\r
+       public final QAction    hlineAction;\r
        public final QPushButton indentButton;\r
+       public final QAction    indentAction;\r
        public final QPushButton outdentButton;\r
+       public final QAction    outdentAction;\r
        public final QPushButton bulletListButton;\r
+       public final QAction    bulletListAction;\r
        public final QPushButton numberListButton;\r
+       public final QAction    numberListAction;\r
 \r
        public final QShortcut focusTitleShortcut;\r
        public final QShortcut focusTagShortcut;\r
@@ -164,11 +197,14 @@ public class BrowserWindow extends QWidget {
        public final QShortcut focusUrlShortcut;\r
        public final QShortcut focusAuthorShortcut;\r
        \r
+       public EditorButtonBar buttonLayout;\r
        public final QComboBox fontList;\r
-       public final QPushButton fontColor;\r
+       public final QAction    fontListAction;\r
+       public final QToolButton fontColor;\r
+       public final QAction    fontColorAction;\r
        private final ColorMenu fontColorMenu;\r
-       public final QPushButton fontHilight;\r
-//     public final ColorComboBox fontHilight;\r
+       public final QToolButton fontHilight;\r
+       public final QAction    fontHilightAction;\r
        private final ColorMenu fontHilightColorMenu;\r
        public final QFileSystemWatcher fileWatcher;\r
        public int cursorPosition;\r
@@ -181,6 +217,44 @@ public class BrowserWindow extends QWidget {
        private final HashMap<String,Integer> previewPageList; \r
        \r
        \r
+       public static class SuggestionListener implements SpellCheckListener {\r
+               public boolean abortSpellCheck = false;\r
+               public boolean errorsFound = false;\r
+               \r
+               private final BrowserWindow parent;\r
+               public SuggestionListener(BrowserWindow parent) {\r
+                       this.parent = parent;\r
+               }\r
+               public void spellingError(SpellCheckEvent event) {\r
+                       errorsFound = true;\r
+                       SpellCheck dialog = new SpellCheck();\r
+                       dialog.setWord(event.getInvalidWord());\r
+\r
+                   List<Word> suggestions = event.getSuggestions();\r
+                   if (suggestions.isEmpty()) {\r
+                      dialog.setNoSuggestions(true);\r
+                   } else {\r
+                      dialog.setCurrentSuggestion(suggestions.get(0).getWord());\r
+                      for (int i=0; i<suggestions.size(); i++) {\r
+                         dialog.addSuggestion(suggestions.get(i).getWord());\r
+                      }\r
+                      dialog.setSelectedSuggestion(0);\r
+                   }\r
+                   dialog.exec();\r
+                   if (dialog.cancelPressed()) {\r
+                       abortSpellCheck = true;\r
+                       return;\r
+                   }\r
+                   if (dialog.replacePressed()) {\r
+                       QClipboard clipboard = QApplication.clipboard();\r
+                       clipboard.setText(dialog.getReplacementWord()); \r
+                       parent.pasteClicked();\r
+                   }\r
+                }\r
+       }\r
+\r
+       \r
+       \r
        public BrowserWindow(DatabaseConnection c) {\r
                logger = new ApplicationLogger("browser.log");\r
                logger.log(logger.HIGH, "Setting up browser");\r
@@ -193,7 +267,8 @@ public class BrowserWindow extends QWidget {
                urlText = new QLineEdit();\r
                authorText = new QLineEdit();\r
                geoBox = new QComboBox();\r
-               urlLabel = new QLabel();\r
+               urlLabel = new QPushButton();\r
+               urlLabel.clicked.connect(this, "sourceUrlClicked()");\r
                authorLabel = new QLabel();\r
                conn = c;\r
                \r
@@ -337,49 +412,68 @@ public class BrowserWindow extends QWidget {
                bulletListButton = newEditorButton("bulletList", tr("Bullet List"));\r
                numberListButton = newEditorButton("numberList", tr("Number List"));\r
 \r
-\r
-               QHBoxLayout buttonLayout;\r
-               buttonLayout = new QHBoxLayout();\r
-               buttonLayout.setSpacing(0);\r
-               v.addLayout(buttonLayout);\r
                \r
-               buttonLayout.addWidget(undoButton);\r
-               buttonLayout.addWidget(redoButton);\r
-\r
-               buttonLayout.addWidget(newSeparator(), 0);\r
-               buttonLayout.addWidget(cutButton);\r
-               buttonLayout.addWidget(copyButton);\r
-               buttonLayout.addWidget(pasteButton);\r
-\r
-               buttonLayout.addWidget(newSeparator(), 0);\r
-               buttonLayout.addWidget(boldButton);\r
-               buttonLayout.addWidget(italicButton);\r
-               buttonLayout.addWidget(underlineButton);\r
-               buttonLayout.addWidget(strikethroughButton);\r
+               buttonLayout = new EditorButtonBar();\r
+//             buttonLayout.setSpacing(0);\r
+               v.addWidget(buttonLayout);\r
                \r
-               buttonLayout.addWidget(newSeparator(), 0);\r
-               buttonLayout.addWidget(leftAlignButton);\r
-               buttonLayout.addWidget(centerAlignButton);\r
-               buttonLayout.addWidget(rightAlignButton);\r
-\r
-               buttonLayout.addWidget(newSeparator(), 0);\r
-               buttonLayout.addWidget(hlineButton);\r
+               undoAction = buttonLayout.addWidget(undoButton);\r
+               buttonLayout.toggleUndoVisible.triggered.connect(this, "toggleUndoVisible(Boolean)");\r
+               redoAction = buttonLayout.addWidget(redoButton);\r
+               buttonLayout.toggleRedoVisible.triggered.connect(this, "toggleRedoVisible(Boolean)");\r
+               \r
+               buttonLayout.addWidget(newSeparator());\r
+               cutAction = buttonLayout.addWidget(cutButton);\r
+               buttonLayout.toggleCutVisible.triggered.connect(this, "toggleCutVisible(Boolean)");\r
+               copyAction = buttonLayout.addWidget(copyButton);\r
+               buttonLayout.toggleCopyVisible.triggered.connect(this, "toggleCopyVisible(Boolean)");\r
+               pasteAction = buttonLayout.addWidget(pasteButton);\r
+               buttonLayout.togglePasteVisible.triggered.connect(this, "togglePasteVisible(Boolean)");\r
+\r
+               buttonLayout.addWidget(newSeparator());\r
+               boldAction = buttonLayout.addWidget(boldButton);\r
+               buttonLayout.toggleBoldVisible.triggered.connect(this, "toggleBoldVisible(Boolean)");\r
+               italicAction = buttonLayout.addWidget(italicButton);\r
+               buttonLayout.toggleItalicVisible.triggered.connect(this, "toggleItalicVisible(Boolean)");\r
+               underlineAction = buttonLayout.addWidget(underlineButton);\r
+               buttonLayout.toggleUnderlineVisible.triggered.connect(this, "toggleUnderlineVisible(Boolean)");\r
+               strikethroughAction = buttonLayout.addWidget(strikethroughButton);\r
+               buttonLayout.toggleStrikethroughVisible.triggered.connect(this, "toggleStrikethroughVisible(Boolean)");\r
 \r
-               buttonLayout.addWidget(indentButton);\r
-               buttonLayout.addWidget(outdentButton);\r
-               buttonLayout.addWidget(bulletListButton);\r
-               buttonLayout.addWidget(numberListButton);\r
+               \r
+               buttonLayout.addWidget(newSeparator());\r
+               leftAlignAction = buttonLayout.addWidget(leftAlignButton);\r
+               buttonLayout.toggleLeftAlignVisible.triggered.connect(this, "toggleLeftAlignVisible(Boolean)");\r
+               centerAlignAction = buttonLayout.addWidget(centerAlignButton);\r
+               buttonLayout.toggleCenterAlignVisible.triggered.connect(this, "toggleCenterAlignVisible(Boolean)");\r
+               rightAlignAction = buttonLayout.addWidget(rightAlignButton);\r
+               buttonLayout.toggleRightAlignVisible.triggered.connect(this, "toggleRightAlignVisible(Boolean)");\r
+\r
+               buttonLayout.addWidget(newSeparator());\r
+               hlineAction = buttonLayout.addWidget(hlineButton);\r
+               buttonLayout.toggleHLineVisible.triggered.connect(this, "toggleHLineVisible(Boolean)");\r
+\r
+               indentAction = buttonLayout.addWidget(indentButton);\r
+               buttonLayout.toggleIndentVisible.triggered.connect(this, "toggleIndentVisible(Boolean)");\r
+               outdentAction = buttonLayout.addWidget(outdentButton);\r
+               buttonLayout.toggleOutdentVisible.triggered.connect(this, "toggleOutdentVisible(Boolean)");\r
+               bulletListAction = buttonLayout.addWidget(bulletListButton);\r
+               buttonLayout.toggleBulletListVisible.triggered.connect(this, "toggleBulletListVisible(Boolean)");\r
+               numberListAction = buttonLayout.addWidget(numberListButton);\r
+               buttonLayout.toggleNumberListVisible.triggered.connect(this, "toggleNumberListVisible(Boolean)");\r
 \r
                // Setup the font & font size combo boxes\r
-               buttonLayout.addWidget(newSeparator(), 0);\r
+               buttonLayout.addWidget(newSeparator());\r
                fontList = new QComboBox();\r
                fontSize = new QComboBox();\r
                fontList.setToolTip("Font");\r
                fontSize.setToolTip("Font Size");\r
                fontList.activated.connect(this, "fontChanged(String)");\r
                fontSize.activated.connect(this, "fontSizeChanged(String)");\r
-               buttonLayout.addWidget(fontList, 0);\r
-               buttonLayout.addWidget(fontSize, 0);\r
+               fontListAction = buttonLayout.addWidget(fontList);\r
+               buttonLayout.toggleFontVisible.triggered.connect(this, "toggleFontListVisible(Boolean)");\r
+               fontSizeAction = buttonLayout.addWidget(fontSize);\r
+               buttonLayout.toggleFontSizeVisible.triggered.connect(this, "toggleFontSizeVisible(Boolean)");\r
                QFontDatabase fonts = new QFontDatabase();\r
                List<String> fontFamilies = fonts.families();\r
                for (int i = 0; i < fontFamilies.size(); i++) {\r
@@ -389,21 +483,28 @@ public class BrowserWindow extends QWidget {
                        }\r
                }\r
 \r
-               buttonLayout.addWidget(newSeparator(), 0);\r
-               fontColor = newEditorButton("fontColor", tr("Font Color"));\r
+//             buttonLayout.addWidget(newSeparator(), 0);\r
+               fontColor = newToolButton("fontColor", tr("Font Color"));\r
                fontColorMenu = new ColorMenu(this);\r
                fontColor.setMenu(fontColorMenu.getMenu());\r
+               fontColor.setPopupMode(ToolButtonPopupMode.MenuButtonPopup);\r
+               fontColor.setAutoRaise(false);\r
                fontColorMenu.getMenu().triggered.connect(this, "fontColorClicked()");\r
-               buttonLayout.addWidget(fontColor);\r
-               fontHilight = newEditorButton("fontHilight", tr("Font Hilight Color"));\r
+               fontColorAction = buttonLayout.addWidget(fontColor);\r
+               buttonLayout.toggleFontColorVisible.triggered.connect(this, "toggleFontColorVisible(Boolean)");\r
+               fontHilight = newToolButton("fontHilight", tr("Font Hilight Color"));\r
+               fontHilight.setPopupMode(ToolButtonPopupMode.MenuButtonPopup);\r
+               fontHilight.setAutoRaise(false);\r
                fontHilightColorMenu = new ColorMenu(this);\r
+               fontHilightColorMenu.setDefault(QColor.yellow);\r
                fontHilight.setMenu(fontHilightColorMenu.getMenu());\r
                fontHilightColorMenu.getMenu().triggered.connect(this, "fontHilightClicked()");\r
-               buttonLayout.addWidget(fontHilight);\r
+               fontHilightAction = buttonLayout.addWidget(fontHilight);\r
+               fontHilightColorMenu.setDefault(QColor.yellow);\r
+               buttonLayout.toggleFontHilight.triggered.connect(this, "toggleFontHilightVisible(Boolean)");\r
 \r
-               buttonLayout.addWidget(new QLabel(), 1);\r
+//             buttonLayout.addWidget(new QLabel(), 1);\r
                v.addWidget(browser, 1);\r
-//             v.addLayout(buttonLayout,0);\r
                setLayout(v);\r
 \r
                browser.downloadAttachmentRequested.connect(this,\r
@@ -432,13 +533,15 @@ public class BrowserWindow extends QWidget {
                browser.page().mainFrame().setTextSizeMultiplier(Global.getTextSizeMultiplier());\r
                browser.page().mainFrame().setZoomFactor(Global.getZoomFactor());\r
                \r
-                previewPageList = new HashMap<String,Integer>();\r
+               previewPageList = new HashMap<String,Integer>();\r
                \r
                browser.page().microFocusChanged.connect(this, "microFocusChanged()");\r
+               \r
                logger.log(logger.HIGH, "Browser setup complete");\r
        }\r
 \r
        \r
+       \r
        private void setupShortcut(QShortcut action, String text) {\r
                if (!Global.shortcutKeys.containsAction(text))\r
                        return;\r
@@ -538,6 +641,15 @@ public class BrowserWindow extends QWidget {
                button.clicked.connect(this, name + "Clicked()");\r
                return button;\r
        }\r
+       // New Editor Button\r
+       private QToolButton newToolButton(String name, String toolTip) {\r
+               QToolButton button = new QToolButton();\r
+               QIcon icon = new QIcon(iconPath + name + ".gif");\r
+               button.setIcon(icon);\r
+               button.setToolTip(toolTip);\r
+               button.clicked.connect(this, name + "Clicked()");\r
+               return button;\r
+       }\r
 \r
        // New Separator\r
        private QLabel newSeparator() {\r
@@ -569,6 +681,21 @@ public class BrowserWindow extends QWidget {
                urlText.setText(t);\r
        }\r
 \r
+       // The user want's to launch a web browser on the source of the URL\r
+       public void sourceUrlClicked() {\r
+               // Make sure we have a valid URL\r
+               if (urlText.text().trim().equals(""))\r
+                       return;\r
+               \r
+               String url = urlText.text();\r
+               if (!url.toLowerCase().startsWith(tr("http://")))\r
+                       url = tr("http://") +url;\r
+               \r
+        if (!QDesktopServices.openUrl(new QUrl(url))) {\r
+               logger.log(logger.LOW, "Error opening file :" +url);\r
+        }\r
+       }\r
+       \r
        public void setAuthor(String t) {\r
                authorLabel.setText(tr("Author:\t"));\r
                authorText.setText(t);\r
@@ -631,33 +758,8 @@ public class BrowserWindow extends QWidget {
 \r
        public void hideButtons() {\r
 \r
+               undoButton.parentWidget().setVisible(false);\r
                buttonsVisible = false;\r
-               \r
-               undoButton.setVisible(false);\r
-               redoButton.setVisible(false);\r
-               cutButton.setVisible(false);\r
-               copyButton.setVisible(false);\r
-               pasteButton.setVisible(false);\r
-               boldButton.setVisible(false);\r
-               underlineButton.setVisible(false);\r
-               italicButton.setVisible(false);\r
-\r
-               rightAlignButton.setVisible(false);\r
-               leftAlignButton.setVisible(false);\r
-               centerAlignButton.setVisible(false);\r
-\r
-               strikethroughButton.setVisible(false);\r
-               hlineButton.setVisible(false);\r
-               indentButton.setVisible(false);\r
-               outdentButton.setVisible(false);\r
-               bulletListButton.setVisible(false);\r
-               numberListButton.setVisible(false);\r
-\r
-               fontList.setVisible(false);\r
-               fontSize.setVisible(false);\r
-               fontColor.setVisible(false);\r
-               fontHilight.setVisible(false);\r
-\r
        }\r
 \r
 \r
@@ -840,7 +942,7 @@ public class BrowserWindow extends QWidget {
        }\r
 \r
        // Listener when PASTE is clicked\r
-       void pasteClicked() {\r
+       public void pasteClicked() {\r
                logger.log(logger.EXTREME, "Paste Clicked");\r
                if (forceTextPaste) {\r
                        pasteWithoutFormattingClicked();\r
@@ -1133,7 +1235,9 @@ public class BrowserWindow extends QWidget {
                        String selectedText = browser.selectedText();\r
                        logger.log(logger.EXTREME, "Inserting link on text "+selectedText);\r
                        logger.log(logger.EXTREME, "URL Link " +dialog.getUrl().trim());\r
-                       String url = "<a href=\"" +dialog.getUrl().trim()+"\" >"+selectedText +"</a>";\r
+                       String url = "<a href=\"" +dialog.getUrl().trim()\r
+                                       +"\" title=" +dialog.getUrl().trim() \r
+                                       +" >"+selectedText +"</a>";\r
                        String script = "document.execCommand('insertHtml', false, '"+url+"');";\r
                        browser.page().mainFrame().evaluateJavaScript(script);\r
                        return;\r
@@ -1295,19 +1399,34 @@ public class BrowserWindow extends QWidget {
        // Tag line has been modified by typing text\r
        @SuppressWarnings("unused")\r
        private void modifyTagsTyping() {\r
+               String completionText = "";\r
                if (tagEdit.currentCompleterSelection != null && !tagEdit.currentCompleterSelection.equals("")) {\r
-                       tagEdit.completeText(tagEdit.currentCompleterSelection);\r
+                       completionText = tagEdit.currentCompleterSelection;\r
+                       tagEdit.currentCompleterSelection = "";\r
                }\r
                \r
-               \r
-               String newTags = tagEdit.text();\r
-               List<String> test = tagEdit.tagCompleter.getTagList();\r
-               if (newTags.equalsIgnoreCase(saveTagList))\r
+               if (tagEdit.text().equalsIgnoreCase(saveTagList))\r
                        return;\r
 \r
                // We know something has changed...\r
                String oldTagArray[] = saveTagList.split(Global.tagDelimeter);\r
-               String newTagArray[] = newTags.split(Global.tagDelimeter);\r
+               String newTagArray[] = tagEdit.text().split(Global.tagDelimeter);\r
+               \r
+               if (!completionText.equals("") && newTagArray.length > 0) {\r
+                       newTagArray[newTagArray.length-1] = completionText;\r
+               }\r
+               // Remove any potential duplicates from the new list\r
+               for (int i=0; i<newTagArray.length; i++) {\r
+                       boolean foundOnce = false;\r
+                       for (int j=0; j<newTagArray.length; j++) {\r
+                               if (newTagArray[j].equalsIgnoreCase(newTagArray[i])) {\r
+                                       if (!foundOnce) {\r
+                                               foundOnce = true;\r
+                                       } else\r
+                                               newTagArray[j] = "";\r
+                               }\r
+                       }\r
+               }\r
 \r
                List<String> newTagList = new ArrayList<String>();\r
                List<String> oldTagList = new ArrayList<String>();\r
@@ -1319,6 +1438,18 @@ public class BrowserWindow extends QWidget {
                        if (!newTagArray[i].trim().equals(""))\r
                                newTagList.add(newTagArray[i]);\r
 \r
+               // Let's cleanup the appearance of the tag list\r
+               Collections.sort(newTagList);\r
+               String newDisplay = "";\r
+               for (int i=0; i<newTagList.size(); i++) {\r
+                       newDisplay = newDisplay+newTagList.get(i);\r
+                       if (i<newTagList.size()-1)\r
+                               newDisplay = newDisplay+", ";\r
+               }\r
+               tagEdit.blockSignals(true);\r
+               tagEdit.setText(newDisplay);\r
+               tagEdit.blockSignals(false);\r
+               \r
                // We now have lists of the new & old. Remove duplicates. If all\r
                // are removed from both then nothing has really changed\r
                for (int i = newTagList.size() - 1; i >= 0; i--) {\r
@@ -1335,13 +1466,14 @@ public class BrowserWindow extends QWidget {
 \r
                if (oldTagList.size() != 0 || newTagList.size() != 0) {\r
                        currentTags.clear();\r
+                       newTagArray = tagEdit.text().split(Global.tagDelimeter);\r
                        for (int i = 0; i < newTagArray.length; i++)\r
                                if (!newTagArray[i].trim().equals(""))\r
                                        currentTags.add(newTagArray[i].trim());\r
 \r
                        noteSignal.tagsChanged.emit(currentNote.getGuid(), currentTags);\r
                }\r
-\r
+               \r
        }\r
 \r
        // Tab button was pressed\r
@@ -1451,7 +1583,7 @@ public class BrowserWindow extends QWidget {
        // Check the note title\r
        private void checkNoteTitle() {\r
                String text = browser.page().currentFrame().toPlainText();\r
-               if (saveNoteTitle.trim().equals("")) {\r
+               if (saveNoteTitle.trim().equals("") || saveNoteTitle.trim().equals("Untitled Note")) {\r
                        int newLine = text.indexOf("\n");\r
                        if (newLine > 0) {\r
                                text = text.substring(0, newLine);\r
@@ -1459,13 +1591,15 @@ public class BrowserWindow extends QWidget {
                                        text = tr("Untitled Note");\r
                                titleLabel.setText(text);\r
                        } else {\r
-                               if (text.length() > 20)\r
-                                       titleLabel.setText(text.substring(0, 20));\r
+                               if (text.length() > Constants.EDAM_NOTE_TITLE_LEN_MAX)\r
+                                       titleLabel.setText(text.substring(0, Constants.EDAM_NOTE_TITLE_LEN_MAX));\r
                                else {\r
+                                       titleLabel.blockSignals(true);\r
                                        if (text.trim().equals(""))\r
                                                titleLabel.setText(tr("Untitled Note"));\r
                                        else\r
                                                titleLabel.setText(text);\r
+                                       titleLabel.blockSignals(false);\r
                                }\r
                        }\r
                        noteSignal.titleChanged.emit(currentNote.getGuid(), titleLabel\r
@@ -1522,8 +1656,10 @@ public class BrowserWindow extends QWidget {
                buffer.append("\" en-tag=en-media type=\"image/jpeg\""\r
                                +" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\""\r
                                +" guid=\"" +newRes.getGuid() +"\""\r
-                               +" onContextMenu=\"window.jambi.imageContextMenu('" +tfile.fileName() +"');\""\r
+//                             +" onContextMenu=\"window.jambi.imageContextMenu('" +tfile.fileName() +"');\""\r
+                               +" onContextMenu=\"window.jambi.imageContextMenu(&amp." +tfile.fileName() +"&amp.);\""\r
                                + " />");\r
+               \r
                browser.page().mainFrame().evaluateJavaScript(\r
                                script_start + buffer + script_end);\r
 \r
@@ -1623,18 +1759,18 @@ public class BrowserWindow extends QWidget {
                String script_end = new String("');");\r
                StringBuffer buffer;\r
 \r
-               for (int i = 0; i < urlList.size(); i++) {\r
-                       buffer = new StringBuffer(100);\r
-                       String url = urlList.get(i).toString();\r
-\r
-                       // Start building the HTML\r
                        String[] type = mimeType.split("/");\r
                        String icon = findIcon(type[1]);\r
                        if (icon.equals("attachment.png"))\r
                                icon = findIcon(type[0]);\r
+                       buffer = new StringBuffer(100);\r
+\r
+               for (int i = 0; i < urlList.size(); i++) {\r
+                       String url = urlList.get(i).toString();\r
+\r
+                       // Start building the HTML\r
                        if (icon.equals("attachment.png"))\r
                                icon = findIcon(url.substring(url.lastIndexOf(".")+1));\r
-                       StringBuffer imageBuffer = new StringBuffer();\r
                        String imageURL = FileUtils.toFileURLString(Global.getFileManager().getImageDirFile(icon));\r
 \r
                        logger.log(logger.EXTREME, "Creating resource ");\r
@@ -1674,6 +1810,7 @@ public class BrowserWindow extends QWidget {
                        }\r
                                                \r
                        logger.log(logger.EXTREME, "Generating link tags");\r
+                       buffer.delete(0, buffer.length());\r
                        buffer.append("<a en-tag=\"en-media\" guid=\"" +newRes.getGuid()+"\" ");\r
                        buffer.append(" onContextMenu=\"window.jambi.imageContextMenu(&apos;")\r
                      .append(Global.getFileManager().getResDirPath(fileName))\r
@@ -1686,10 +1823,13 @@ public class BrowserWindow extends QWidget {
                }\r
                return;\r
        }\r
+\r
        private Resource createResource(String url, int sequence, String mime, boolean attachment) {\r
                logger.log(logger.EXTREME, "Inside create resource");\r
                QFile resourceFile;\r
-               url = new QUrl(url).toLocalFile();\r
+               String urlTest = new QUrl(url).toLocalFile();\r
+               if (!urlTest.equals(""))\r
+                       url = urlTest;\r
                url = url.replace("/", File.separator);\r
        resourceFile = new QFile(url); \r
        resourceFile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly));\r
@@ -1853,6 +1993,7 @@ public class BrowserWindow extends QWidget {
                noteSignal.authorChanged.emit(currentNote.getGuid(), authorText.text());\r
        }\r
        \r
+       @SuppressWarnings("unused")\r
        private void geoBoxChanged() {\r
                int index = geoBox.currentIndex();\r
                geoBox.setCurrentIndex(0);\r
@@ -2254,6 +2395,14 @@ public class BrowserWindow extends QWidget {
                                int guidEndPos = segment.indexOf("\"", guidStartPos+7);\r
                                String guid = segment.substring(guidStartPos+6,guidEndPos);\r
                                \r
+                               int mimeStartPos = segment.indexOf("type");\r
+                               int mimeEndPos = segment.indexOf("\"", mimeStartPos+7);\r
+                               String mime = segment.substring(mimeStartPos+6,mimeEndPos);\r
+\r
+                               int srcStartPos = segment.indexOf("src");\r
+                               int srcEndPos = segment.indexOf("\"", srcStartPos+6);\r
+                               String src = segment.substring(srcStartPos+5,srcEndPos);\r
+                               \r
                                Calendar currentTime = new GregorianCalendar();\r
                                Long l = new Long(currentTime.getTimeInMillis());\r
                                long prevTime = l;\r
@@ -2263,8 +2412,13 @@ public class BrowserWindow extends QWidget {
                                }\r
                                \r
                                Resource r = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);\r
-                               if (r==null)\r
-                                       return "";\r
+                               // if r==null, then the image doesn't exist (it was probably cut out of another note, so \r
+                               // we need to recereate it\r
+                               if (r==null) {\r
+                                       r = createResource(src, 1, mime, false);\r
+                                       if (r==null)\r
+                                               return "";\r
+                               }\r
                        String randint = new String(Long.toString(l));\r
                        String extension = null;\r
                        if (r.getMime()!= null) {\r
@@ -2388,4 +2542,154 @@ public class BrowserWindow extends QWidget {
 //             browser.previousPageAction.setVisible(false);\r
        }\r
 */\r
+       \r
+       private void toggleUndoVisible(Boolean toggle) {\r
+               undoAction.setVisible(toggle);\r
+               Global.saveEditorButtonsVisible("undo", toggle);\r
+       }\r
+       private void toggleRedoVisible(Boolean toggle) {\r
+               redoAction.setVisible(toggle);\r
+               Global.saveEditorButtonsVisible("redo", toggle);\r
+       }\r
+       private void toggleCutVisible(Boolean toggle) {\r
+               cutAction.setVisible(toggle);\r
+               Global.saveEditorButtonsVisible("cut", toggle);\r
+       }\r
+       private void toggleCopyVisible(Boolean toggle) {\r
+               copyAction.setVisible(toggle);\r
+               Global.saveEditorButtonsVisible("copy", toggle);\r
+       }\r
+       private void togglePasteVisible(Boolean toggle) {\r
+               pasteAction.setVisible(toggle);\r
+               Global.saveEditorButtonsVisible("paste", toggle);\r
+       }\r
+       private void toggleBoldVisible(Boolean toggle) {\r
+               boldAction.setVisible(toggle);\r
+               Global.saveEditorButtonsVisible("bold", toggle);\r
+       }\r
+       private void toggleItalicVisible(Boolean toggle) {\r
+               italicAction.setVisible(toggle);\r
+               Global.saveEditorButtonsVisible("italic", toggle);\r
+       }\r
+       private void toggleUnderlineVisible(Boolean toggle) {\r
+               underlineAction.setVisible(toggle);\r
+               Global.saveEditorButtonsVisible("underline", toggle);\r
+       }\r
+       private void toggleStrikethroughVisible(Boolean toggle) {\r
+               strikethroughAction.setVisible(toggle);\r
+               Global.saveEditorButtonsVisible("strikethrough", toggle);\r
+       }\r
+       private void toggleLeftAlignVisible(Boolean toggle) {\r
+               leftAlignAction.setVisible(toggle);\r
+               Global.saveEditorButtonsVisible("alignLeft", toggle);\r
+       }\r
+       private void toggleRightAlignVisible(Boolean toggle) {\r
+               rightAlignAction.setVisible(toggle);\r
+               Global.saveEditorButtonsVisible("alignRight", toggle);\r
+       }       \r
+       private void toggleCenterAlignVisible(Boolean toggle) {\r
+               centerAlignAction.setVisible(toggle);\r
+               Global.saveEditorButtonsVisible("alignCenter", toggle);\r
+       }\r
+       private void toggleHLineVisible(Boolean toggle) {\r
+               hlineAction.setVisible(toggle);\r
+               Global.saveEditorButtonsVisible("hline", toggle);\r
+       }\r
+       private void toggleIndentVisible(Boolean toggle) {\r
+               indentAction.setVisible(toggle);\r
+               Global.saveEditorButtonsVisible("indent", toggle);\r
+       }\r
+       private void toggleOutdentVisible(Boolean toggle) {\r
+               outdentAction.setVisible(toggle);\r
+               Global.saveEditorButtonsVisible("outdent", toggle);\r
+       }\r
+       private void toggleBulletListVisible(Boolean toggle) {\r
+               bulletListAction.setVisible(toggle);\r
+               Global.saveEditorButtonsVisible("bulletList", toggle);\r
+       }\r
+       private void toggleNumberListVisible(Boolean toggle) {\r
+               numberListAction.setVisible(toggle);\r
+               Global.saveEditorButtonsVisible("numberList", toggle);\r
+       }\r
+       private void toggleFontListVisible(Boolean toggle) {\r
+               fontListAction.setVisible(toggle);\r
+               Global.saveEditorButtonsVisible("font", toggle);\r
+       }\r
+       private void toggleFontColorVisible(Boolean toggle) {\r
+               fontColorAction.setVisible(toggle);\r
+               Global.saveEditorButtonsVisible("fontColor", toggle);\r
+       }\r
+       private void toggleFontSizeVisible(Boolean toggle) {\r
+               fontSizeAction.setVisible(toggle);\r
+               Global.saveEditorButtonsVisible("fontSize", toggle);\r
+       }\r
+       private void toggleFontHilightVisible(Boolean toggle) {\r
+               fontHilightAction.setVisible(toggle);\r
+               Global.saveEditorButtonsVisible("fontHilight", toggle);\r
+       }\r
+\r
+\r
+       // Invoke spell checker dialog\r
+       private void doSpellCheck() {\r
+\r
+               File wordList = new File(Global.getFileManager().getSpellDirPath()+Locale.getDefault()+".dic");\r
+           SpellDictionary dictionary;\r
+               try {\r
+                       dictionary = new SpellDictionaryHashMap(wordList);\r
+                       SpellChecker spellChecker = new SpellChecker(dictionary);\r
+                       SuggestionListener spellListener = new SuggestionListener(this);\r
+                       spellChecker.addSpellCheckListener(spellListener);\r
+\r
+                       String content = getBrowser().page().mainFrame().toPlainText();\r
+                       StringWordTokenizer tokenizer = new StringWordTokenizer(content);\r
+                       if (!tokenizer.hasMoreWords())\r
+                               return;\r
+                       String word = tokenizer.nextWord();\r
+                       getBrowser().page().action(WebAction.MoveToStartOfDocument);\r
+                       QWebPage.FindFlags flags = new QWebPage.FindFlags();\r
+                       flags.set(QWebPage.FindFlag.FindBackward);\r
+\r
+                       getBrowser().setFocus();\r
+                       boolean found = getBrowser().page().findText(word);\r
+                       if (!found) {\r
+                               QMessageBox.critical(this, tr("Spell Check Error"), \r
+                                               tr("An error has occurred while launching the spell check.  The most probable" +\r
+                                                               " cause is that the cursor was not at the beginning of the document.\n\n" +\r
+                                                               "Please place the cursor at the beginning & try again"));\r
+                               return;\r
+                       }\r
+                       while (found) {\r
+                               found = getBrowser().page().findText(word);\r
+                       }\r
+               \r
+                       spellChecker.checkSpelling(new StringWordTokenizer(word));\r
+                       getBrowser().setFocus();\r
+                       \r
+                       flags = new QWebPage.FindFlags();\r
+                       tokenizer = new StringWordTokenizer(content);\r
+                       \r
+                       while(tokenizer.hasMoreWords()) {\r
+                               word = tokenizer.nextWord();\r
+                               found = getBrowser().page().findText(word);\r
+                               if (found && !spellListener.abortSpellCheck) {\r
+                                       spellChecker.checkSpelling(new StringWordTokenizer(word));\r
+                                       getBrowser().setFocus();\r
+                               }\r
+                       }\r
+                       spellChecker.removeSpellCheckListener(spellListener);\r
+                       if (!spellListener.errorsFound)\r
+                               QMessageBox.information(this, tr("Spell Check Complete"), \r
+                                               tr("No spelling errors found"));\r
+               } catch (FileNotFoundException e) {\r
+                       QMessageBox.critical(this, tr("Spell Check Error"), \r
+                                       tr("Dictionary "+ Global.getFileManager().getSpellDirPath()+Locale.getDefault()+\r
+                                               ".dic was not found."));\r
+               } catch (IOException e) {\r
+                       QMessageBox.critical(this, tr("Spell Check Error"), \r
+                                       tr("Dictionary "+ Global.getFileManager().getSpellDirPath()+Locale.getDefault()+\r
+                                               ".dic is invalid."));\r
+               }\r
+\r
+    }\r
+\r
 }\r