-/*\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 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
-import java.security.MessageDigest;\r
-import java.security.NoSuchAlgorithmException;\r
-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 org.apache.commons.lang.StringUtils;\r
-\r
-import com.evernote.edam.limits.Constants;\r
-import com.evernote.edam.type.Data;\r
-import com.evernote.edam.type.Note;\r
-import com.evernote.edam.type.Notebook;\r
-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.Configuration;\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
-import com.trolltech.qt.core.QEvent;\r
-import com.trolltech.qt.core.QEvent.Type;\r
-import com.trolltech.qt.core.QFile;\r
-import com.trolltech.qt.core.QFileSystemWatcher;\r
-import com.trolltech.qt.core.QIODevice;\r
-import com.trolltech.qt.core.QMimeData;\r
-import com.trolltech.qt.core.QTextCodec;\r
-import com.trolltech.qt.core.QUrl;\r
-import com.trolltech.qt.core.Qt.Key;\r
-import com.trolltech.qt.core.Qt.KeyboardModifier;\r
-import com.trolltech.qt.core.Qt.KeyboardModifiers;\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
-import com.trolltech.qt.gui.QColor;\r
-import com.trolltech.qt.gui.QComboBox;\r
-import com.trolltech.qt.gui.QDateEdit;\r
-import com.trolltech.qt.gui.QDesktopServices;\r
-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.QFontDatabase;\r
-import com.trolltech.qt.gui.QFormLayout;\r
-import com.trolltech.qt.gui.QGridLayout;\r
-import com.trolltech.qt.gui.QHBoxLayout;\r
-import com.trolltech.qt.gui.QIcon;\r
-import com.trolltech.qt.gui.QImage;\r
-import com.trolltech.qt.gui.QKeyEvent;\r
-import com.trolltech.qt.gui.QKeySequence;\r
-import com.trolltech.qt.gui.QLabel;\r
-import com.trolltech.qt.gui.QLineEdit;\r
-import com.trolltech.qt.gui.QListWidgetItem;\r
-import com.trolltech.qt.gui.QMatrix;\r
-import com.trolltech.qt.gui.QMessageBox;\r
-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
-import com.trolltech.qt.webkit.QWebPage;\r
-import com.trolltech.qt.webkit.QWebPage.WebAction;\r
-import com.trolltech.qt.webkit.QWebSettings;\r
-import com.trolltech.qt.webkit.QWebView;\r
-\r
-import cx.fbn.nevernote.Global;\r
-import cx.fbn.nevernote.dialog.EnCryptDialog;\r
-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
-import cx.fbn.nevernote.signals.NoteResourceSignal;\r
-import cx.fbn.nevernote.signals.NoteSignal;\r
-import cx.fbn.nevernote.sql.DatabaseConnection;\r
-import cx.fbn.nevernote.utilities.ApplicationLogger;\r
-import cx.fbn.nevernote.utilities.FileUtils;\r
-import cx.fbn.nevernote.utilities.Pair;\r
-\r
-public class BrowserWindow extends QWidget {\r
-\r
- public final QLineEdit titleLabel;\r
- private final QLineEdit urlText;\r
- private final QLabel authorLabel;\r
- private final QLineEdit authorText;\r
- private final QComboBox geoBox;\r
- public final TagLineEdit tagEdit;\r
- public final QLabel tagLabel;\r
- private final QPushButton urlLabel;\r
- private final QLabel alteredLabel;\r
- private final QDateEdit alteredDate;\r
- private final QTimeEdit alteredTime;\r
- private final QDateEdit createdDate;\r
- private final QTimeEdit createdTime;\r
- private final QLabel subjectLabel;\r
- private final QDateEdit subjectDate;\r
- private final QTimeEdit subjectTime;\r
- public final QComboBox notebookBox;\r
- 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
- private final ContentView browser;\r
- private List<Tag> allTags;\r
- private List<String> currentTags;\r
- public NoteSignal noteSignal;\r
- private List<Notebook> notebookList;\r
- private Note currentNote;\r
- private String saveNoteTitle;\r
- private String saveTagList;\r
- private boolean insideList;\r
-// private String selectedText;\r
- private final DatabaseConnection conn;\r
- private final QCalendarWidget createdCalendarWidget;\r
- private final QCalendarWidget alteredCalendarWidget;\r
- 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
- public final QPushButton spellCheckButton;\r
- public final QAction spellCheckAction;\r
- public final QPushButton todoButton;\r
- public final QAction todoAction;\r
-\r
- public final QShortcut focusTitleShortcut;\r
- public final QShortcut focusTagShortcut;\r
- public final QShortcut focusNoteShortcut;\r
- public final QShortcut focusUrlShortcut;\r
- public final QShortcut focusAuthorShortcut;\r
- \r
- public EditorButtonBar buttonLayout;\r
- public final QComboBox fontList;\r
- public final QAction fontListAction;\r
- public final QToolButton fontColor;\r
- public final QAction fontColorAction;\r
- private final ColorMenu fontColorMenu;\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
- private boolean forceTextPaste = false;\r
- private String selectedFile;\r
- private String currentHyperlink;\r
- public boolean keepPDFNavigationHidden;\r
- private final ApplicationLogger logger;\r
- SpellDictionary dictionary;\r
- SpellDictionary userDictionary;\r
- SpellChecker spellChecker;\r
- SuggestionListener spellListener;\r
- 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
- private final SpellCheck spellCheckDialog;\r
- \r
- \r
- private final BrowserWindow parent;\r
- public SuggestionListener(BrowserWindow parent, SpellChecker checker) {\r
- this.parent = parent;\r
- spellCheckDialog = new SpellCheck(checker);\r
- }\r
- public void spellingError(SpellCheckEvent event) {\r
- errorsFound = true;\r
- spellCheckDialog.setWord(event.getInvalidWord());\r
-\r
- List<Word> suggestions = event.getSuggestions();\r
- spellCheckDialog.clearSuggestions();\r
- if (!suggestions.isEmpty()) {\r
-// spellCheckDialog.setCurrentSuggestion(suggestions.get(0).getWord());\r
- for (int i=0; i<suggestions.size(); i++) {\r
- spellCheckDialog.addSuggestion(suggestions.get(i).getWord());\r
- }\r
- spellCheckDialog.setSelectedSuggestion(0);\r
- }\r
- spellCheckDialog.exec();\r
- if (spellCheckDialog.cancelPressed()) {\r
- abortSpellCheck = true;\r
- event.cancel();\r
- return;\r
- }\r
- if (spellCheckDialog.replacePressed()) {\r
- QClipboard clipboard = QApplication.clipboard();\r
- clipboard.setText(spellCheckDialog.getReplacementWord()); \r
- parent.pasteClicked();\r
- }\r
- event.cancel();\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
- \r
- fileWatcher = new QFileSystemWatcher();\r
-// fileWatcher.fileChanged.connect(this, "fileChanged(String)");\r
- noteSignal = new NoteSignal();\r
- titleLabel = new QLineEdit();\r
- titleLabel.setMaxLength(Constants.EDAM_NOTE_TITLE_LEN_MAX);\r
- urlText = new QLineEdit();\r
- authorText = new QLineEdit();\r
- geoBox = new QComboBox();\r
- urlLabel = new QPushButton();\r
- urlLabel.clicked.connect(this, "sourceUrlClicked()");\r
- authorLabel = new QLabel();\r
- conn = c;\r
- \r
- focusLost = new Signal0();\r
-\r
- tagEdit = new TagLineEdit(allTags);\r
- tagLabel = new QLabel("Tags:");\r
- tagEdit.focusLost.connect(this, "modifyTagsTyping()");\r
-\r
- createdCalendarWidget = new QCalendarWidget();\r
- createdDate = new QDateEdit();\r
- createdDate.setDisplayFormat(Global.getDateFormat());\r
- createdDate.setCalendarPopup(true);\r
- createdDate.setCalendarWidget(createdCalendarWidget);\r
- createdTime = new QTimeEdit();\r
- createdDate.dateChanged.connect(this, "createdChanged()");\r
- createdTime.timeChanged.connect(this, "createdChanged()");\r
-\r
- alteredCalendarWidget = new QCalendarWidget();\r
- alteredDate = new QDateEdit();\r
- alteredDate.setDisplayFormat(Global.getDateFormat());\r
- alteredDate.setCalendarPopup(true);\r
- alteredDate.setCalendarWidget(alteredCalendarWidget);\r
- alteredTime = new QTimeEdit();\r
- alteredLabel = new QLabel("Altered:");\r
- alteredDate.dateChanged.connect(this, "alteredChanged()");\r
- alteredTime.timeChanged.connect(this, "alteredChanged()");\r
-\r
- subjectCalendarWidget = new QCalendarWidget();\r
- subjectDate = new QDateEdit();\r
- subjectDate.setDisplayFormat(Global.getDateFormat());\r
- subjectDate.setCalendarPopup(true);\r
- subjectDate.setCalendarWidget(subjectCalendarWidget);\r
- subjectTime = new QTimeEdit();\r
- subjectLabel = new QLabel(tr("Subject Date:"));\r
- subjectDate.dateChanged.connect(this, "subjectDateTimeChanged()");\r
- subjectTime.timeChanged.connect(this, "subjectDateTimeChanged()");\r
- authorText.textChanged.connect(this, "authorChanged()");\r
- urlText.textChanged.connect(this, "sourceUrlChanged()");\r
-\r
- notebookBox = new QComboBox();\r
- notebookLabel = new QLabel(tr("Notebook"));\r
- createdLabel = new QLabel(tr("Created:"));\r
- // selectedText = new String();\r
-\r
- urlLabel.setVisible(false);\r
- urlText.setVisible(false);\r
- authorLabel.setVisible(false);\r
- \r
- geoBox.setVisible(false);\r
- geoBox.addItem(new QIcon(iconPath+"globe.png"), "");\r
- geoBox.addItem(new String(tr("Set")));\r
- geoBox.addItem(new String(tr("Clear")));\r
- geoBox.addItem(new String(tr("View On Map")));\r
- geoBox.activated.connect(this, "geoBoxChanged()");\r
- \r
- authorText.setVisible(false);\r
- createdDate.setVisible(false);\r
- alteredLabel.setVisible(false);\r
- //notebookBox.setVisible(false);\r
- notebookLabel.setVisible(false);\r
- createdLabel.setVisible(false);\r
- createdTime.setVisible(false);\r
- alteredDate.setVisible(false);\r
- alteredTime.setVisible(false);\r
- subjectLabel.setVisible(false);\r
- subjectDate.setVisible(false);\r
- subjectTime.setVisible(false);\r
- extendedOn = false;\r
- buttonsVisible = true;\r
- setAcceptDrops(true);\r
-\r
- browser = new ContentView(this);\r
- browser.page().setLinkDelegationPolicy(\r
- QWebPage.LinkDelegationPolicy.DelegateAllLinks);\r
- browser.linkClicked.connect(this, "linkClicked(QUrl)");\r
- currentHyperlink = "";\r
- \r
- QVBoxLayout v = new QVBoxLayout();\r
- QFormLayout notebookLayout = new QFormLayout();\r
- QGridLayout dateLayout = new QGridLayout();\r
- titleLabel.setReadOnly(false);\r
- titleLabel.editingFinished.connect(this, "titleEdited()");\r
- browser.page().contentsChanged.connect(this, "contentChanged()");\r
- browser.page().selectionChanged.connect(this, "selectionChanged()");\r
- browser.page().mainFrame().javaScriptWindowObjectCleared.connect(this,\r
- "exposeToJavascript()");\r
-\r
- notebookBox.activated.connect(this, "notebookChanged()");\r
- resourceSignal = new NoteResourceSignal();\r
- \r
- QHBoxLayout tagLayout = new QHBoxLayout();\r
- v.addWidget(titleLabel, 0);\r
- notebookLayout.addRow(notebookLabel, notebookBox);\r
- tagLayout.addLayout(notebookLayout, 0);\r
- tagLayout.stretch(4);\r
- tagLayout.addWidget(tagLabel, 0);\r
- tagLayout.addWidget(tagEdit, 1);\r
- v.addLayout(tagLayout);\r
-\r
- QHBoxLayout urlLayout = new QHBoxLayout();\r
- urlLayout.addWidget(urlLabel, 0);\r
- urlLayout.addWidget(urlText, 0);\r
- v.addLayout(urlLayout);\r
-\r
- QHBoxLayout authorLayout = new QHBoxLayout();\r
- authorLayout.addWidget(authorLabel, 0);\r
- authorLayout.addWidget(authorText, 0);\r
- authorLayout.addWidget(geoBox);\r
- v.addLayout(authorLayout);\r
-\r
- dateLayout.addWidget(createdLabel, 0, 0);\r
- dateLayout.addWidget(createdDate, 0, 1);\r
- dateLayout.addWidget(createdTime, 0, 2);\r
- dateLayout.setColumnStretch(9, 100);\r
- dateLayout.addWidget(alteredLabel, 0, 3);\r
- dateLayout.addWidget(alteredDate, 0, 4);\r
- dateLayout.addWidget(alteredTime, 0, 5);\r
- dateLayout.addWidget(subjectLabel, 0, 6);\r
- dateLayout.addWidget(subjectDate, 0, 7);\r
- dateLayout.addWidget(subjectTime, 0, 8);\r
- v.addLayout(dateLayout, 0);\r
-\r
- undoButton = newEditorButton("undo", tr("Undo Change"));\r
- redoButton = newEditorButton("redo", tr("Redo Change"));\r
- cutButton = newEditorButton("cut", tr("Cut"));\r
- copyButton = newEditorButton("copy", tr("Copy"));\r
- pasteButton = newEditorButton("paste", tr("Paste"));\r
- boldButton = newEditorButton("bold", tr("Bold"));\r
- underlineButton = newEditorButton("underline", tr("Underline"));\r
- italicButton = newEditorButton("italic", tr("Italic"));\r
-\r
- rightAlignButton = newEditorButton("justifyRight", tr("Right Align"));\r
- leftAlignButton = newEditorButton("justifyLeft", tr("Left Align"));\r
- centerAlignButton = newEditorButton("justifyCenter", tr("Center Align"));\r
-\r
- strikethroughButton = newEditorButton("strikethrough", tr("Strikethrough"));\r
- hlineButton = newEditorButton("hline", tr("Insert Horizontal Line"));\r
- indentButton = newEditorButton("indent", tr("Shift Right"));\r
- outdentButton = newEditorButton("outdent", tr("Shift Left"));\r
- bulletListButton = newEditorButton("bulletList", tr("Bullet List"));\r
- numberListButton = newEditorButton("numberList", tr("Number List"));\r
- spellCheckButton = newEditorButton("spellCheck", tr("Spell Check"));\r
- todoButton = newEditorButton("todo", tr("To-do"));\r
-\r
- \r
- buttonLayout = new EditorButtonBar();\r
- v.addWidget(buttonLayout);\r
- \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
- \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());\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
- 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
- fontList.addItem(fontFamilies.get(i));\r
- if (i == 0) {\r
- loadFontSize(fontFamilies.get(i));\r
- }\r
- }\r
-\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
- 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
- fontHilightAction = buttonLayout.addWidget(fontHilight);\r
- fontHilightColorMenu.setDefault(QColor.yellow);\r
- buttonLayout.toggleFontHilight.triggered.connect(this, "toggleFontHilightVisible(Boolean)");\r
- \r
- spellCheckAction = buttonLayout.addWidget(spellCheckButton);\r
- buttonLayout.toggleNumberListVisible.triggered.connect(this, "spellCheckClicked()");\r
- buttonLayout.toggleSpellCheck.triggered.connect(this, "toggleSpellCheckVisible(Boolean)");\r
- \r
- todoAction = buttonLayout.addWidget(todoButton);\r
- buttonLayout.toggleNumberListVisible.triggered.connect(this, "todoClicked()");\r
- buttonLayout.toggleTodo.triggered.connect(this, "toggleTodoVisible(Boolean)");\r
-\r
-\r
-// buttonLayout.addWidget(new QLabel(), 1);\r
- v.addWidget(browser, 1);\r
- setLayout(v);\r
-\r
- browser.downloadAttachmentRequested.connect(this,\r
- "downloadAttachment(QNetworkRequest)");\r
- browser.downloadImageRequested.connect(this,\r
- "downloadImage(QNetworkRequest)");\r
- setTabOrder(notebookBox, tagEdit);\r
- setTabOrder(tagEdit, browser);\r
- \r
- focusNoteShortcut = new QShortcut(this);\r
- setupShortcut(focusNoteShortcut, "Focus_Note");\r
- focusNoteShortcut.activated.connect(this, "focusNote()");\r
- focusTitleShortcut = new QShortcut(this);\r
- setupShortcut(focusTitleShortcut, "Focus_Title");\r
- focusTitleShortcut.activated.connect(this, "focusTitle()");\r
- focusTagShortcut = new QShortcut(this);\r
- setupShortcut(focusTagShortcut, "Focus_Tag");\r
- focusTagShortcut.activated.connect(this, "focusTag()");\r
- focusAuthorShortcut = new QShortcut(this);\r
- setupShortcut(focusAuthorShortcut, "Focus_Author");\r
- focusAuthorShortcut.activated.connect(this, "focusAuthor()");\r
- focusUrlShortcut = new QShortcut(this);\r
- setupShortcut(focusUrlShortcut, "Focus_Url");\r
- focusUrlShortcut.activated.connect(this, "focusUrl()");\r
- \r
- browser.page().mainFrame().setTextSizeMultiplier(Global.getTextSizeMultiplier());\r
- browser.page().mainFrame().setZoomFactor(Global.getZoomFactor());\r
- \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
- action.setKey(new QKeySequence(Global.shortcutKeys.getShortcut(text)));\r
- }\r
- \r
- \r
-\r
- \r
- // Getter for the QWebView\r
- public QWebView getBrowser() {\r
- return browser;\r
- }\r
-\r
- // Block signals while loading data or things are flagged as dirty by\r
- // mistake\r
- public void loadingData(boolean val) {\r
- logger.log(logger.EXTREME, "Entering BrowserWindow.loadingData() " +val);\r
- notebookBox.blockSignals(val);\r
- browser.page().blockSignals(val);\r
- browser.page().mainFrame().blockSignals(val);\r
- titleLabel.blockSignals(val);\r
- alteredDate.blockSignals(val);\r
- alteredTime.blockSignals(val);\r
- createdTime.blockSignals(val);\r
- createdDate.blockSignals(val);\r
- subjectDate.blockSignals(val);\r
- subjectTime.blockSignals(val);\r
- urlText.blockSignals(val);\r
- authorText.blockSignals(val);\r
- if (!val)\r
- exposeToJavascript();\r
- logger.log(logger.EXTREME, "Exiting BrowserWindow.loadingData() " +val);\r
- }\r
-\r
- // Enable/disable\r
- public void setReadOnly(boolean v) {\r
- setEnabled(true);\r
- titleLabel.setEnabled(!v);\r
- notebookBox.setEnabled(!v);\r
- tagEdit.setEnabled(!v);\r
- authorLabel.setEnabled(!v);\r
- geoBox.setEnabled(!v);\r
- urlText.setEnabled(!v);\r
- createdDate.setEnabled(!v);\r
- subjectDate.setEnabled(!v);\r
- alteredDate.setEnabled(!v);\r
- getBrowser().setEnabled(true);\r
- }\r
- \r
- // expose this class to Javascript on the web page\r
- private void exposeToJavascript() {\r
- browser.page().mainFrame().addToJavaScriptWindowObject("jambi", this);\r
- }\r
-\r
- // Custom event queue\r
- @Override\r
- public boolean event(QEvent e) {\r
- if (e.type().equals(QEvent.Type.FocusOut)) {\r
- logger.log(logger.EXTREME, "Focus lost");\r
- focusLost.emit();\r
- }\r
- return super.event(e);\r
- }\r
-\r
- // clear out browser\r
- public void clear() {\r
- logger.log(logger.EXTREME, "Entering BrowserWindow.clear()");\r
- setNote(null);\r
- browser.setContent(new QByteArray());\r
- tagEdit.setText("");\r
- tagEdit.tagCompleter.reset();\r
- urlLabel.setText(tr("Source URL:"));\r
- titleLabel.setText("");\r
- logger.log(logger.EXTREME, "Exiting BrowserWindow.clear()");\r
- }\r
-\r
- // get/set current note\r
- public void setNote(Note n) {\r
- currentNote = n;\r
- if (n == null)\r
- n = new Note();\r
- saveNoteTitle = n.getTitle();\r
-\r
- }\r
-\r
- public Note getNote() {\r
- return currentNote;\r
- }\r
-\r
- // New Editor Button\r
- private QPushButton newEditorButton(String name, String toolTip) {\r
- QPushButton button = new QPushButton();\r
-// QIcon icon = new QIcon(iconPath + name + ".gif");\r
- QIcon icon = new QIcon(iconPath + name + ".png");\r
- button.setIcon(icon);\r
- button.setToolTip(toolTip);\r
- 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
- QIcon icon = new QIcon(iconPath + name + ".png");\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
- return new QLabel(" ");\r
- }\r
-\r
- // Set the title in the window\r
- public void setTitle(String t) {\r
- titleLabel.setText(t);\r
- saveNoteTitle = t;\r
- checkNoteTitle();\r
- }\r
-\r
- // Return the current text title\r
- public String getTitle() {\r
- return titleLabel.text();\r
- }\r
-\r
- // Set the tag name string\r
- public void setTag(String t) {\r
- saveTagList = t;\r
- tagEdit.setText(t);\r
- tagEdit.tagCompleter.reset();\r
- }\r
-\r
- // Set the source URL\r
- public void setUrl(String t) {\r
- urlLabel.setText(tr("Source URL:\t"));\r
- 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
- }\r
-\r
- // Set the creation date\r
- public void setCreation(long date) {\r
- QDateTime dt = new QDateTime();\r
- dt.setTime_t((int) (date / 1000));\r
- createdDate.setDateTime(dt);\r
- createdTime.setDateTime(dt);\r
- createdDate.setDisplayFormat(Global.getDateFormat());\r
- createdTime.setDisplayFormat(Global.getTimeFormat());\r
- }\r
-\r
- // Set the creation date\r
- public void setAltered(long date) {\r
- QDateTime dt = new QDateTime();\r
- dt.setTime_t((int) (date / 1000));\r
- alteredDate.setDateTime(dt);\r
- alteredTime.setDateTime(dt);\r
- alteredDate.setDisplayFormat(Global.getDateFormat());\r
- alteredTime.setDisplayFormat(Global.getTimeFormat());\r
- }\r
-\r
- // Set the subject date\r
- public void setSubjectDate(long date) {\r
- QDateTime dt = new QDateTime();\r
- dt.setTime_t((int) (date / 1000));\r
- subjectDate.setDateTime(dt);\r
- subjectTime.setDateTime(dt);\r
- subjectDate.setDisplayFormat(Global.getDateFormat());\r
- subjectTime.setDisplayFormat(Global.getTimeFormat());\r
- }\r
-\r
- // Toggle the extended attribute information\r
- public void toggleInformation() {\r
- if (extendedOn) {\r
- extendedOn = false;\r
- } else {\r
- extendedOn = true;\r
- }\r
- urlLabel.setVisible(extendedOn);\r
- urlText.setVisible(extendedOn);\r
- authorText.setVisible(extendedOn);\r
- geoBox.setVisible(extendedOn);\r
- authorLabel.setVisible(extendedOn);\r
- createdDate.setVisible(extendedOn);\r
- createdTime.setVisible(extendedOn);\r
- createdLabel.setVisible(extendedOn);\r
- alteredLabel.setVisible(extendedOn);\r
- alteredDate.setVisible(extendedOn);\r
- alteredTime.setVisible(extendedOn);\r
- //notebookBox.setVisible(extendedOn);\r
- notebookLabel.setVisible(extendedOn);\r
- subjectLabel.setVisible(extendedOn);\r
- subjectDate.setVisible(extendedOn);\r
- subjectTime.setVisible(extendedOn);\r
- }\r
-\r
- public void hideButtons() {\r
-\r
- undoButton.parentWidget().setVisible(false);\r
- buttonsVisible = false;\r
- }\r
-\r
-\r
- // Is the extended view on?\r
- public boolean isExtended() {\r
- return extendedOn;\r
- }\r
-\r
- // Listener for when a link is clicked\r
- @SuppressWarnings("unused")\r
- private void openFile() {\r
- logger.log(logger.EXTREME, "Starting openFile()");\r
- File fileHandle = new File(selectedFile);\r
- URI fileURL = fileHandle.toURI();\r
- String localURL = fileURL.toString();\r
- QUrl url = new QUrl(localURL);\r
- QFile file = new QFile(selectedFile);\r
- \r
- logger.log(logger.EXTREME, "Adding to fileWatcher:"+file.fileName());\r
- fileWatcher.addPath(file.fileName());\r
- \r
- if (!QDesktopServices.openUrl(url)) {\r
- logger.log(logger.LOW, "Error opening file :" +url);\r
- }\r
- }\r
- \r
- \r
- // Listener for when a link is clicked\r
- @SuppressWarnings("unused")\r
- private void linkClicked(QUrl url) {\r
- logger.log(logger.EXTREME, "URL Clicked: " +url.toString());\r
- if (url.toString().substring(0,8).equals("nnres://")) {\r
- logger.log(logger.EXTREME, "URL is NN resource");\r
- if (url.toString().endsWith("/vnd.evernote.ink")) {\r
- logger.log(logger.EXTREME, "Unable to open ink note");\r
- QMessageBox.information(this, tr("Unable Open"), tr("This is an ink note.\n"+\r
- "Ink notes are not supported since Evernote has not\n published any specifications on them\n" +\r
- "and I'm too lazy to figure them out by myself."));\r
- return;\r
- }\r
- String fullName = url.toString().substring(8);\r
- int index = fullName.indexOf(".");\r
- String guid = "";\r
- String type = "";\r
- if (index >-1) {\r
- type = fullName.substring(index+1);\r
- guid = fullName.substring(0,index);\r
- }\r
- index = guid.indexOf(Global.attachmentNameDelimeter);\r
- if (index > -1) {\r
- guid = guid.substring(0,index);\r
- }\r
- List<Resource> resList = currentNote.getResources();\r
- Resource res = null;\r
- for (int i=0; i<resList.size(); i++) {\r
- if (resList.get(i).getGuid().equals(guid)) {\r
- res = resList.get(i);\r
- i=resList.size();\r
- }\r
- }\r
- if (res == null) {\r
- String resGuid = Global.resourceMap.get(guid);\r
- if (resGuid != null) \r
- res = conn.getNoteTable().noteResourceTable.getNoteResource(resGuid, true);\r
- }\r
- if (res != null) {\r
- String fileName;\r
- if (res.getAttributes() != null && \r
- res.getAttributes().getFileName() != null && \r
- !res.getAttributes().getFileName().trim().equals(""))\r
- fileName = res.getGuid()+Global.attachmentNameDelimeter+res.getAttributes().getFileName();\r
- else\r
- fileName = res.getGuid()+"."+type;\r
- QFile file = new QFile(Global.getFileManager().getResDirPath(fileName));\r
- QFile.OpenMode mode = new QFile.OpenMode();\r
- mode.set(QFile.OpenModeFlag.WriteOnly);\r
- boolean openResult = file.open(mode);\r
- logger.log(logger.EXTREME, "File opened:" +openResult);\r
- QDataStream out = new QDataStream(file);\r
- Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(res.getGuid(), true);\r
- QByteArray binData = new QByteArray(resBinary.getData().getBody());\r
- resBinary = null;\r
- logger.log(logger.EXTREME, "Writing resource");\r
- out.writeBytes(binData.toByteArray());\r
- file.close();\r
- \r
- String whichOS = System.getProperty("os.name");\r
- if (whichOS.contains("Windows")) \r
- url.setUrl("file:///"+file.fileName());\r
- else\r
- url.setUrl("file://"+file.fileName());\r
- // fileWatcher.removePath(file.fileName());\r
- logger.log(logger.EXTREME, "Adding file watcher " +file.fileName());\r
- fileWatcher.addPath(file.fileName());\r
- \r
- // If we can't open it, then prompt the user to save it.\r
- if (!QDesktopServices.openUrl(url)) {\r
- logger.log(logger.EXTREME, "We can't handle this. Where do we put it?");\r
- QFileDialog dialog = new QFileDialog();\r
- dialog.show();\r
- if (dialog.exec()!=0) {\r
- List<String> fileNames = dialog.selectedFiles(); //gets all selected filenames\r
- if (fileNames.size() == 0) \r
- return;\r
- String sf = fileNames.get(0);\r
- QFile saveFile = new QFile(sf);\r
- mode.set(QFile.OpenModeFlag.WriteOnly);\r
- saveFile.open(mode);\r
- QDataStream saveOut = new QDataStream(saveFile);\r
- saveOut.writeBytes(binData.toByteArray());\r
- saveFile.close();\r
- return;\r
- }\r
- }\r
- }\r
- return;\r
- }\r
- logger.log(logger.EXTREME, "Launching URL");\r
- QDesktopServices.openUrl(url);\r
- }\r
-\r
- // Listener for when BOLD is clicked\r
- @SuppressWarnings("unused")\r
- private void undoClicked() {\r
- browser.page().triggerAction(WebAction.Undo);\r
- browser.setFocus();\r
- }\r
-\r
- // Listener for when BOLD is clicked\r
- @SuppressWarnings("unused")\r
- private void redoClicked() {\r
- browser.page().triggerAction(WebAction.Redo);\r
- browser.setFocus();\r
- }\r
-\r
- // Listener for when BOLD is clicked\r
- @SuppressWarnings("unused")\r
- private void boldClicked() {\r
- browser.page().triggerAction(WebAction.ToggleBold);\r
- microFocusChanged();\r
- browser.setFocus();\r
- }\r
-\r
- // Listener for when Italics is clicked\r
- @SuppressWarnings("unused")\r
- private void italicClicked() {\r
- browser.page().triggerAction(WebAction.ToggleItalic);\r
- microFocusChanged();\r
- browser.setFocus();\r
- }\r
-\r
- // Listener for when UNDERLINE is clicked\r
- @SuppressWarnings("unused")\r
- private void underlineClicked() {\r
- browser.page().triggerAction(WebAction.ToggleUnderline);\r
- microFocusChanged();\r
- browser.setFocus();\r
- }\r
-\r
- // Listener for when Strikethrough is clicked\r
- @SuppressWarnings("unused")\r
- private void strikethroughClicked() {\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('strikeThrough', false, '');");\r
- browser.setFocus();\r
- }\r
-\r
- // Listener for when cut is clicked\r
- @SuppressWarnings("unused")\r
- private void cutClicked() {\r
- browser.page().triggerAction(WebAction.Cut);\r
- browser.setFocus();\r
- }\r
-\r
- // Listener when COPY is clicked\r
- @SuppressWarnings("unused")\r
- private void copyClicked() {\r
- browser.page().triggerAction(WebAction.Copy);\r
- browser.setFocus();\r
- }\r
-\r
- // Listener when PASTE is clicked\r
- public void pasteClicked() {\r
- logger.log(logger.EXTREME, "Paste Clicked");\r
- if (forceTextPaste) {\r
- pasteWithoutFormattingClicked();\r
- return;\r
- }\r
- QClipboard clipboard = QApplication.clipboard();\r
- QMimeData mime = clipboard.mimeData();\r
- \r
-// String x = mime.html();\r
-\r
- if (mime.hasImage()) {\r
- logger.log(logger.EXTREME, "Image paste found");\r
- browser.setFocus();\r
- insertImage(mime);\r
- browser.setFocus();\r
- return;\r
- }\r
-\r
- if (mime.hasUrls()) {\r
- logger.log(logger.EXTREME, "URL paste found");\r
- handleUrls(mime);\r
- browser.setFocus();\r
- return;\r
- }\r
- \r
- String text = mime.html();\r
- if (text.contains("en-tag") && mime.hasHtml()) {\r
- logger.log(logger.EXTREME, "Intra-note paste found");\r
- text = fixInternotePaste(text);\r
- mime.setHtml(text);\r
- clipboard.setMimeData(mime);\r
- }\r
-\r
- logger.log(logger.EXTREME, "Final paste choice encountered");\r
- browser.page().triggerAction(WebAction.Paste);\r
- browser.setFocus();\r
-\r
- }\r
-\r
- // Paste text without formatting\r
- private void pasteWithoutFormattingClicked() {\r
- logger.log(logger.EXTREME, "Paste without format clipped");\r
- QClipboard clipboard = QApplication.clipboard();\r
- QMimeData mime = clipboard.mimeData();\r
- if (!mime.hasText())\r
- return;\r
- String text = mime.text();\r
- clipboard.setText(text);\r
- browser.page().triggerAction(WebAction.Paste);\r
- QApplication.clipboard().setMimeData(mime);\r
- browser.setFocus();\r
-\r
- }\r
- \r
- // insert date/time\r
- @SuppressWarnings("unused")\r
- private void insertDateTime() {\r
- String fmt = Global.getDateFormat() + " " + Global.getTimeFormat();\r
- String dateTimeFormat = new String(fmt);\r
- SimpleDateFormat simple = new SimpleDateFormat(dateTimeFormat);\r
- Calendar cal = Calendar.getInstance();\r
- \r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('insertHtml', false, '"+simple.format(cal.getTime())+"');");\r
- \r
- browser.setFocus();\r
-\r
- }\r
-\r
- // Listener when Left is clicked\r
- @SuppressWarnings("unused")\r
- private void justifyLeftClicked() {\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('JustifyLeft', false, '');");\r
- browser.setFocus();\r
- }\r
-\r
- // Listener when Center is clicked\r
- @SuppressWarnings("unused")\r
- private void justifyCenterClicked() {\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('JustifyCenter', false, '');");\r
- browser.setFocus();\r
- }\r
-\r
- // Listener when Left is clicked\r
- @SuppressWarnings("unused")\r
- private void justifyRightClicked() {\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('JustifyRight', false, '');");\r
- browser.setFocus();\r
- }\r
-\r
- // Listener when HLINE is clicked\r
- @SuppressWarnings("unused")\r
- private void hlineClicked() {\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('insertHorizontalRule', false, '');");\r
- browser.setFocus();\r
- }\r
-\r
- // Listener when outdent is clicked\r
- private void outdentClicked() {\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('outdent', false, '');");\r
- browser.setFocus();\r
- }\r
-\r
- // Listener when a bullet list is clicked\r
- @SuppressWarnings("unused")\r
- private void bulletListClicked() {\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('InsertUnorderedList', false, '');");\r
- browser.setFocus();\r
- }\r
-\r
- // Listener when a bullet list is clicked\r
- @SuppressWarnings("unused")\r
- private void numberListClicked() {\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('InsertOrderedList', false, '');");\r
- browser.setFocus();\r
- }\r
-\r
- // Listener when indent is clicked\r
- private void indentClicked() {\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('indent', false, '');");\r
- browser.setFocus();\r
- }\r
-\r
- // Listener when the font name is changed\r
- @SuppressWarnings("unused")\r
- private void fontChanged(String font) {\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('fontName',false,'" + font + "');");\r
- browser.setFocus();\r
- }\r
-\r
- // Listener when a font size is changed\r
- @SuppressWarnings("unused")\r
- private void fontSizeChanged(String font) {\r
- String text = browser.selectedText();\r
- if (text.trim().equalsIgnoreCase(""))\r
- return;\r
-\r
- String selectedText = browser.selectedText();\r
- String url = "<span style=\"font-size:" +font +"pt; \">"+selectedText +"</a>";\r
- String script = "document.execCommand('insertHtml', false, '"+url+"');";\r
- browser.page().mainFrame().evaluateJavaScript(script);\r
-/* browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('fontSize',false,'"\r
- + font + "');");\r
-*/\r
- browser.setFocus();\r
- }\r
-\r
- // Load the font combo box based upon the font selected\r
- private void loadFontSize(String name) { \r
- QFontDatabase db = new QFontDatabase(); \r
- fontSize.clear();\r
- List<Integer> points = db.pointSizes(name); \r
- for (int i=0; i<points.size(); i++) { \r
- fontSize.addItem(points.get(i).toString()); \r
- }\r
- /*\r
- fontSize.addItem("x-small");\r
- fontSize.addItem("small");\r
- fontSize.addItem("medium");\r
- fontSize.addItem("large");\r
- fontSize.addItem("x-large");\r
- fontSize.addItem("xx-large");\r
- fontSize.addItem("xxx-large");\r
- */\r
- }\r
-\r
- // Listener when a font size is changed\r
- @SuppressWarnings("unused")\r
- private void fontColorClicked() {\r
-// QColorDialog dialog = new QColorDialog();\r
-// QColor color = QColorDialog.getColor();\r
- QColor color = fontColorMenu.getColor();\r
- if (color.isValid())\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('foreColor',false,'" + color.name()\r
- + "');");\r
- browser.setFocus();\r
- }\r
-\r
- // Listener for when a background color change is requested\r
- @SuppressWarnings("unused")\r
- private void fontHilightClicked() {\r
-// QColorDialog dialog = new QColorDialog();\r
-// QColor color = QColorDialog.getColor();\r
- QColor color = fontHilightColorMenu.getColor();\r
- if (color.isValid())\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('backColor',false,'" + color.name()\r
- + "');");\r
- browser.setFocus();\r
- }\r
- \r
- // Listener for when a background color change is requested\r
- @SuppressWarnings("unused")\r
- private void superscriptClicked() {\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('superscript');");\r
- browser.setFocus();\r
- }\r
- \r
- // Listener for when a background color change is requested\r
- @SuppressWarnings("unused")\r
- private void subscriptClicked() {\r
- browser.page().mainFrame().evaluateJavaScript(\r
- "document.execCommand('subscript');");\r
- browser.setFocus();\r
- }\r
- // Insert a to-do checkbox\r
- @SuppressWarnings("unused")\r
- private void todoClicked() {\r
- FileNameMap fileNameMap = URLConnection.getFileNameMap();\r
- String script_start = new String(\r
- "document.execCommand('insertHtml', false, '");\r
- String script_end = new String("');");\r
- String todo = new String(\r
- "<input TYPE=\"CHECKBOX\" value=\"false\" onClick=\"value=checked; window.jambi.contentChanged(); \" />");\r
- browser.page().mainFrame().evaluateJavaScript(\r
- script_start + todo + script_end);\r
- browser.setFocus();\r
- }\r
-\r
- // Encrypt the selected text\r
- @SuppressWarnings("unused")\r
- private void encryptText() {\r
- String text = browser.selectedText();\r
- if (text.trim().equalsIgnoreCase(""))\r
- return;\r
- text = new String(text.replaceAll("\n", "<br/>"));\r
-\r
- EnCryptDialog dialog = new EnCryptDialog();\r
- dialog.exec();\r
- if (!dialog.okPressed()) {\r
- return;\r
- }\r
-\r
- EnCrypt crypt = new EnCrypt();\r
- String encrypted = crypt.encrypt(text, dialog.getPassword().trim(), 64);\r
- String decrypted = crypt.decrypt(encrypted, dialog.getPassword().trim(), 64);\r
-\r
- if (encrypted.trim().equals("")) {\r
- QMessageBox.information(this, tr("Error"), tr("Error Encrypting String"));\r
- return;\r
- }\r
- StringBuffer buffer = new StringBuffer(encrypted.length() + 100);\r
- buffer.append("<img en-tag=\"en-crypt\" cipher=\"RC2\" hint=\""\r
- + dialog.getHint().replace("'","\\'") + "\" length=\"64\" ");\r
- buffer.append("contentEditable=\"false\" alt=\"");\r
- buffer.append(encrypted);\r
- buffer.append("\" src=\"").append(FileUtils.toForwardSlashedPath(Global.getFileManager().getImageDirPath("encrypt.png") +"\""));\r
- Global.cryptCounter++;\r
- buffer.append(" id=\"crypt"+Global.cryptCounter.toString() +"\"");\r
- buffer.append(" onMouseOver=\"style.cursor=\\'hand\\'\"");\r
- buffer.append(" onClick=\"window.jambi.decryptText(\\'crypt"+Global.cryptCounter.toString() \r
- +"\\', \\'"+encrypted+"\\', \\'"+dialog.getHint().replace("'", "\\&apos;")+"\\');\"");\r
- buffer.append("style=\"display:block\" />");\r
-\r
- String script_start = new String(\r
- "document.execCommand('insertHtml', false, '");\r
- String script_end = new String("');");\r
- browser.page().mainFrame().evaluateJavaScript(\r
- script_start + buffer.toString() + script_end);\r
- }\r
-\r
- \r
- // Insert a hyperlink\r
- public void insertLink() {\r
- logger.log(logger.EXTREME, "Inserting link");\r
- String text = browser.selectedText();\r
- if (text.trim().equalsIgnoreCase(""))\r
- return;\r
-\r
- InsertLinkDialog dialog = new InsertLinkDialog();\r
- if (currentHyperlink != null && currentHyperlink != "") {\r
- dialog.setUrl(currentHyperlink);\r
- }\r
- dialog.exec();\r
- if (!dialog.okPressed()) {\r
- logger.log(logger.EXTREME, "Insert link canceled");\r
- return;\r
- }\r
- if (browser.insertLinkAction.text().equalsIgnoreCase("Insert Hyperlink")) {\r
- 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 dUrl = StringUtils.replace(dialog.getUrl().trim(), "'", "\\'");\r
- String url = "<a href=\"" +dUrl\r
- +"\" title=" +dUrl \r
- +" >"+selectedText +"</a>";\r
- String script = "document.execCommand('insertHtml', false, '"+url+"');";\r
- browser.page().mainFrame().evaluateJavaScript(script);\r
- return;\r
- } else {\r
- String js = new String( "function getCursorPos() {"\r
- +"var cursorPos;"\r
- +"if (window.getSelection) {"\r
- +" var selObj = window.getSelection();"\r
- +" var selRange = selObj.getRangeAt(0);"\r
- +" var workingNode = window.getSelection().anchorNode.parentNode;"\r
- +" while(workingNode != null) { " \r
- +" if (workingNode.nodeName.toLowerCase()=='a') workingNode.setAttribute('href','" +dialog.getUrl() +"');"\r
- +" workingNode = workingNode.parentNode;"\r
- +" }"\r
- +"}"\r
- +"} getCursorPos();");\r
- browser.page().mainFrame().evaluateJavaScript(js);\r
- contentChanged();\r
- }\r
- \r
- }\r
- \r
- // Insert a table\r
- public void insertTable() {\r
- TableDialog dialog = new TableDialog();\r
- dialog.exec();\r
- if (!dialog.okPressed()) {\r
- return;\r
- }\r
- \r
- int cols = dialog.getCols();\r
- int rows = dialog.getRows();\r
- int width = dialog.getWidth();\r
- boolean percent = dialog.isPercent();\r
- \r
- String newHTML = "<table border=\"1\" width=\"" +new Integer(width).toString();\r
- if (percent)\r
- newHTML = newHTML +"%";\r
- newHTML = newHTML + "\"><tbody>";\r
-\r
- for (int i=0; i<rows; i++) {\r
- newHTML = newHTML +"<tr>";\r
- for (int j=0; j<cols; j++) {\r
- newHTML = newHTML +"<td> </td>";\r
- }\r
- newHTML = newHTML +"</tr>";\r
- }\r
- newHTML = newHTML+"</tbody></table>"; \r
- \r
- String script = "document.execCommand('insertHtml', false, '"+newHTML+"');";\r
- browser.page().mainFrame().evaluateJavaScript(script);\r
- }\r
- \r
- \r
- // Text content changed\r
- @SuppressWarnings("unused")\r
- private void selectionChanged() {\r
- browser.encryptAction.setEnabled(true);\r
- browser.insertLinkAction.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
- + "if (parent_html == undefined) {window.jambi.saveSelectedText(selection_text); return;}"\r
- + "var first_text = range.startContainer.nodeValue.substr(range.startOffset);"\r
- + "var last_text = (range.endContainer.nodeValue).substring(0,range.endOffset);"\r
- + "var start = parent_html.indexOf(first_text);"\r
- + "var end = parent_html.indexOf(last_text,start+1)+last_text.length;"\r
- + "var value = parent_html.substring(start,end);"\r
- + "window.jambi.saveSelectedText(value);" ;\r
- browser.page().mainFrame().evaluateJavaScript(scriptStart);\r
-\r
- }\r
-\r
- public void saveSelectedText(String text) {\r
- boolean enabled = true;\r
- if (text.trim().length() == 0)\r
- enabled=false;\r
- if (text.indexOf("en-tag=\"en-crypt\"") >= 0)\r
- enabled=false;\r
- if (text.indexOf("<img en-tag=\"en-media\"") >= 0)\r
- enabled=false;\r
- if (text.indexOf("<a en-tag=\"en-media\"") >= 0)\r
- enabled=false;\r
- if (text.indexOf("<input ") >= 0)\r
- enabled=false;\r
- \r
- browser.encryptAction.setEnabled(enabled);\r
- browser.insertLinkAction.setEnabled(enabled);\r
-// selectedText = text;\r
- }\r
-\r
- // Decrypt clicked text\r
- public void decryptText(String id, String text, String hint) {\r
- EnCrypt crypt = new EnCrypt();\r
- String plainText = null;\r
- Calendar currentTime = new GregorianCalendar();\r
- Long l = new Long(currentTime.getTimeInMillis());\r
- String slot = new String(Long.toString(l));\r
- \r
- // First, try to decrypt with any keys we already have\r
- for (int i=0; i<Global.passwordRemember.size(); i++) {\r
- plainText = crypt.decrypt(text, Global.passwordRemember.get(i).getFirst(), 64);\r
- if (plainText != null) {\r
- slot = new String(Long.toString(l));\r
- Pair<String,String> passwordPair = new Pair<String,String>();\r
- Global.passwordSafe.put(slot, Global.passwordRemember.get(i));\r
- removeEncryption(id, plainText, false, slot); \r
- return;\r
- }\r
- }\r
- \r
- \r
- EnDecryptDialog dialog = new EnDecryptDialog();\r
- dialog.setHint(hint);\r
- while (plainText == null || !dialog.okPressed()) {\r
- dialog.exec();\r
- if (!dialog.okPressed()) {\r
- return;\r
- }\r
- plainText = crypt.decrypt(text, dialog.getPassword().trim(), 64);\r
- if (plainText == null) {\r
- QMessageBox.warning(this, "Incorrect Password", "The password entered is not correct");\r
- }\r
- }\r
- Pair<String,String> passwordPair = new Pair<String,String>();\r
- passwordPair.setFirst(dialog.getPassword());\r
- passwordPair.setSecond(dialog.getHint());\r
- Global.passwordSafe.put(slot, passwordPair);\r
-// removeEncryption(id, plainText.replaceAll("\n", "<br/>"), dialog.permanentlyDecrypt(), slot);\r
- removeEncryption(id, plainText, dialog.permanentlyDecrypt(), slot);\r
- if (dialog.rememberPassword()) {\r
- Pair<String, String> pair = new Pair<String,String>();\r
- pair.setFirst(dialog.getPassword());\r
- pair.setSecond(dialog.getHint());\r
- Global.passwordRemember.add(pair);\r
- }\r
-\r
- }\r
-\r
- // Get the editor tag line\r
- public TagLineEdit getTagLine() {\r
- return tagEdit;\r
- }\r
-\r
- // Modify a note's tags\r
- @SuppressWarnings("unused")\r
- private void modifyTags() {\r
- TagAssign tagWindow = new TagAssign(allTags, currentTags);\r
- tagWindow.exec();\r
- if (tagWindow.okClicked()) {\r
- currentTags.clear();\r
- StringBuffer tagDisplay = new StringBuffer();\r
-\r
- List<QListWidgetItem> newTags = tagWindow.getTagList()\r
- .selectedItems();\r
- for (int i = 0; i < newTags.size(); i++) {\r
- currentTags.add(newTags.get(i).text());\r
- tagDisplay.append(newTags.get(i).text());\r
- if (i < newTags.size() - 1) {\r
- tagDisplay.append(Global.tagDelimeter + " ");\r
- }\r
- }\r
- tagEdit.setText(tagDisplay.toString());\r
- noteSignal.tagsChanged.emit(currentNote.getGuid(), currentTags);\r
- }\r
- }\r
-\r
- // 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
- completionText = tagEdit.currentCompleterSelection;\r
- tagEdit.currentCompleterSelection = "";\r
- }\r
- \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[];\r
- if (!completionText.equals("")) {\r
- String before = tagEdit.text().substring(0,tagEdit.cursorPosition());\r
- int lastDelimiter = before.lastIndexOf(Global.tagDelimeter);\r
- if (lastDelimiter > 0)\r
- before = before.substring(0,before.lastIndexOf(Global.tagDelimeter));\r
- else \r
- before = "";\r
- String after = tagEdit.text().substring(tagEdit.cursorPosition());\r
- newTagArray = (before+Global.tagDelimeter+completionText+Global.tagDelimeter+after).split(Global.tagDelimeter);\r
- }\r
- else {\r
- newTagArray = tagEdit.text().split(Global.tagDelimeter);\r
- }\r
- \r
- // Remove any traling or leading blanks\r
- for (int i=0; i<newTagArray.length; i++)\r
- newTagArray[i] = newTagArray[i].trim().replaceAll("^\\s+", "");;\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
-\r
- for (int i = 0; i < oldTagArray.length; i++)\r
- if (!oldTagArray[i].trim().equals(""))\r
- oldTagList.add(oldTagArray[i]);\r
- for (int i = 0; i < newTagArray.length; i++)\r
- 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+Global.tagDelimeter +" ";\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
- String nTag = newTagList.get(i);\r
- for (int j = oldTagList.size() - 1; j >= 0; j--) {\r
- String oTag = oldTagList.get(j);\r
- if (oTag.equalsIgnoreCase(nTag)) {\r
- oldTagList.remove(j);\r
- newTagList.remove(i);\r
- j = -1;\r
- }\r
- }\r
- }\r
-\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
- // Tab button was pressed\r
- public void tabPressed() {\r
- if (!insideList) {\r
- String script_start = new String(\r
- "document.execCommand('insertHtml', false, ' ');");\r
- browser.page().mainFrame().evaluateJavaScript(script_start);\r
- } else \r
- indentClicked();\r
- }\r
- \r
- public void backtabPressed() {\r
- if (insideList)\r
- outdentClicked();\r
- }\r
- \r
- public void setInsideList() {\r
- insideList = true;\r
- }\r
- \r
- // The title has been edited\r
- @SuppressWarnings("unused")\r
- private void titleEdited() {\r
- // If we don't have a good note, or if the current title\r
- // matches the old title then we don't need to do anything\r
- if (currentNote == null)\r
- return;\r
- if (currentNote.getTitle().trim().equals(titleLabel.text().trim()))\r
- return;\r
- \r
- // If we have a real change, we need to save it.\r
- noteSignal.titleChanged.emit(currentNote.getGuid(), titleLabel.text());\r
- currentNote.setTitle(titleLabel.text());\r
- saveNoteTitle = titleLabel.text();\r
- checkNoteTitle();\r
- }\r
-\r
- // Set the list of note tags\r
- public void setAllTags(List<Tag> l) {\r
- allTags = l;\r
- tagEdit.setTagList(l);\r
- }\r
-\r
- // Setter for the current tags\r
- public void setCurrentTags(List<String> s) {\r
- currentTags = s;\r
- }\r
-\r
- // Save the list of notebooks\r
- public void setNotebookList(List<Notebook> n) {\r
- notebookList = n;\r
- loadNotebookList();\r
- }\r
-\r
- // Load the notebook list and select the current notebook\r
- private void loadNotebookList() {\r
- if (notebookBox.count() != 0)\r
- notebookBox.clear();\r
- if (notebookList == null)\r
- return;\r
-\r
- for (int i = 0; i < notebookList.size(); i++) {\r
- notebookBox.addItem(notebookList.get(i).getName());\r
- if (currentNote != null) {\r
- if (currentNote.getNotebookGuid().equals(\r
- notebookList.get(i).getGuid())) {\r
- notebookBox.setCurrentIndex(i);\r
- }\r
- }\r
- }\r
- }\r
- \r
- \r
- // Set the notebook for a note\r
- public void setNotebook(String notebook) {\r
- currentNote.setNotebookGuid(notebook);\r
- loadNotebookList();\r
- }\r
-\r
- // Get the contents of the editor\r
- public String getContent() {\r
- return browser.page().currentFrame().toHtml();\r
- }\r
-\r
- // The note contents have changed\r
- public void contentChanged() {\r
- String content = getContent();\r
- checkNoteTitle();\r
- noteSignal.noteChanged.emit(currentNote.getGuid(), content); \r
- }\r
-\r
- // The notebook selection has changed\r
- @SuppressWarnings("unused")\r
- private void notebookChanged() {\r
- boolean changed = false;\r
- String n = notebookBox.currentText();\r
- for (int i = 0; i < notebookList.size(); i++) {\r
- if (n.equals(notebookList.get(i).getName())) {\r
- if (!notebookList.get(i).getGuid().equals(currentNote.getNotebookGuid())) {\r
- currentNote.setNotebookGuid(notebookList.get(i).getGuid());\r
- changed = true;\r
- }\r
- i = notebookList.size();\r
- }\r
- }\r
- \r
- // If the notebook changed, signal the update\r
- if (changed)\r
- noteSignal.notebookChanged.emit(currentNote.getGuid(), currentNote\r
- .getNotebookGuid());\r
- }\r
-\r
- // Check the note title\r
- private void checkNoteTitle() {\r
- String text = browser.page().currentFrame().toPlainText();\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
- if (text.trim().equals(""))\r
- text = tr("Untitled Note");\r
- titleLabel.setText(text);\r
- } else {\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
- .text());\r
- }\r
- }\r
-\r
- // Return the note contents so we can email them\r
- public String getContentsToEmail() {\r
- return browser.page().currentFrame().toPlainText().trim();\r
- /*\r
- * int body = browser.page().currentFrame().toHtml().indexOf("<body>");\r
- * String temp = browser.page().currentFrame().toHtml(); if (body == -1)\r
- * temp = "<html><body><b>Test</b></body></html>"; else temp =\r
- * "<html>"+temp.substring(body); return temp; // return\r
- * urlEncode(browser.page().currentFrame().toHtml());\r
- */\r
- }\r
-\r
- // Insert an image into the editor\r
- private void insertImage(QMimeData mime) {\r
- logger.log(logger.EXTREME, "Entering insertImage");\r
- QImage img = (QImage) mime.imageData();\r
- String script_start = new String(\r
- "document.execCommand('insertHTML', false, '");\r
- String script_end = new String("');");\r
-\r
- long now = new Date().getTime();\r
- String path = Global.getFileManager().getResDirPath(\r
- (new Long(now).toString()) + ".jpg");\r
-\r
- // This block is just a hack to make sure we wait at least 1ms so we\r
- // don't\r
- // have collisions on image names\r
- long i = new Date().getTime();\r
- while (now == i)\r
- i = new Date().getTime();\r
-\r
- // Open the file & write the data\r
- QFile tfile = new QFile(path);\r
- tfile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.WriteOnly));\r
- if (!img.save(tfile)) {\r
- tfile.close();\r
- return;\r
- }\r
- tfile.close();\r
- \r
- Resource newRes = createResource(QUrl.fromLocalFile(path).toString(), 0, "image/jpeg", false);\r
- if (newRes == null)\r
- return;\r
- currentNote.getResources().add(newRes);\r
-\r
- // do the actual insert into the note\r
- StringBuffer buffer = new StringBuffer(100);\r
- buffer.append("<img src=\"");\r
- buffer.append(tfile.fileName());\r
- 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
- + " />");\r
- \r
- browser.page().mainFrame().evaluateJavaScript(\r
- script_start + buffer + script_end);\r
-\r
- return;\r
- }\r
-\r
- // Handle URLs that are trying to be pasted\r
- public void handleUrls(QMimeData mime) {\r
- logger.log(logger.EXTREME, "Starting handleUrls");\r
- FileNameMap fileNameMap = URLConnection.getFileNameMap();\r
-\r
- List<QUrl> urlList = mime.urls();\r
- String url = new String();\r
- String script_start = new String(\r
- "document.execCommand('createLink', false, '");\r
- String script_end = new String("');");\r
-\r
- for (int i = 0; i < urlList.size(); i++) {\r
- url = urlList.get(i).toString();\r
- // Find out what type of file we have\r
- String mimeType = fileNameMap.getContentTypeFor(url);\r
-\r
- // If null returned, we need to guess at the file type\r
- if (mimeType == null)\r
- mimeType = "application/"\r
- + url.substring(url.lastIndexOf(".") + 1);\r
-\r
- // Check if we have an image or some other type of file\r
- if (url.substring(0, 5).equalsIgnoreCase("file:")\r
- && mimeType.substring(0, 5).equalsIgnoreCase("image")) {\r
- handleLocalImageURLPaste(mime, mimeType);\r
- return;\r
- }\r
- String[] type = mimeType.split("/");\r
- boolean valid = validAttachment(type[1]);\r
- boolean smallEnough = checkFileAttachmentSize(url);\r
- if (smallEnough && valid\r
- && url.substring(0, 5).equalsIgnoreCase("file:")\r
- && !mimeType.substring(0, 5).equalsIgnoreCase("image")) {\r
- handleLocalAttachment(mime, mimeType);\r
- return;\r
- }\r
- browser.page().mainFrame().evaluateJavaScript(\r
- script_start + url + script_end);\r
- }\r
- return;\r
- }\r
-\r
- // If a URL being pasted is an image URL, then attach the image\r
- private void handleLocalImageURLPaste(QMimeData mime, String mimeType) {\r
- List<QUrl> urlList = mime.urls();\r
- String url = new String();\r
- String script_start_image = new String(\r
- "document.execCommand('insertHtml', false, '");\r
- String script_end = new String("');");\r
- StringBuffer buffer;\r
-\r
- // Copy the image over into the resource directory and create a new resource \r
- // record for each url pasted\r
- for (int i = 0; i < urlList.size(); i++) {\r
- url = urlList.get(i).toString();\r
-\r
- Resource newRes = createResource(url, i, mimeType, false);\r
- if (newRes == null)\r
- return;\r
- currentNote.getResources().add(newRes);\r
- buffer = new StringBuffer(100);\r
- \r
- // Open the file & write the data\r
- String fileName = Global.getFileManager().getResDirPath(newRes.getGuid());\r
- QFile tfile = new QFile(fileName);\r
- tfile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.WriteOnly));\r
- tfile.write(newRes.getData().getBody());\r
- tfile.close();\r
- buffer.append(script_start_image);\r
- buffer.append("<img src=\"" + FileUtils.toForwardSlashedPath(fileName));\r
-// if (mimeType.equalsIgnoreCase("image/jpg"))\r
-// mimeType = "image/jpeg";\r
- buffer.append("\" en-tag=\"en-media\" type=\"" + mimeType +"\""\r
- +" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\""\r
- +" guid=\"" +newRes.getGuid() +"\""\r
- +" onContextMenu=\"window.jambi.imageContextMenu('" +tfile.fileName() +"');\""\r
- + " />");\r
- buffer.append(script_end);\r
- browser.page().mainFrame().evaluateJavaScript(buffer.toString());\r
- }\r
- return;\r
- }\r
- \r
-\r
- // If a URL being pasted is a local file URL, then attach the file\r
- private void handleLocalAttachment(QMimeData mime, String mimeType) {\r
- logger.log(logger.EXTREME, "Attaching local file");\r
- List<QUrl> urlList = mime.urls();\r
- String script_start = new String(\r
- "document.execCommand('insertHtml', false, '");\r
- String script_end = new String("');");\r
- StringBuffer buffer;\r
-\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
- String imageURL = FileUtils.toFileURLString(Global.getFileManager().getImageDirFile(icon));\r
-\r
- logger.log(logger.EXTREME, "Creating resource ");\r
- Resource newRes = createResource(url, i, mimeType, true);\r
- if (newRes == null)\r
- return;\r
- logger.log(logger.EXTREME, "New resource size: " +newRes.getData().getSize());\r
- currentNote.getResources().add(newRes);\r
- \r
- String fileName = newRes.getGuid() + Global.attachmentNameDelimeter+newRes.getAttributes().getFileName();\r
- // If we have a PDF, we need to setup the preview.\r
- if (icon.equalsIgnoreCase("pdf.png") && Global.pdfPreview()) {\r
- logger.log(logger.EXTREME, "Setting up PDF preview");\r
- if (newRes.getAttributes() != null && \r
- newRes.getAttributes().getFileName() != null && \r
- !newRes.getAttributes().getFileName().trim().equals(""))\r
- fileName = newRes.getGuid()+Global.attachmentNameDelimeter+\r
- newRes.getAttributes().getFileName();\r
- else\r
- fileName = newRes.getGuid()+".pdf";\r
- QFile file = new QFile(Global.getFileManager().getResDirPath(fileName));\r
- QFile.OpenMode mode = new QFile.OpenMode();\r
- mode.set(QFile.OpenModeFlag.WriteOnly);\r
- file.open(mode);\r
- QDataStream out = new QDataStream(file);\r
-// Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(newRes.getGuid(), true);\r
- QByteArray binData = new QByteArray(newRes.getData().getBody());\r
-// resBinary = null;\r
- out.writeBytes(binData.toByteArray());\r
- file.close();\r
-\r
- PDFPreview pdfPreview = new PDFPreview();\r
- if (pdfPreview.setupPreview(Global.getFileManager().getResDirPath(fileName), "pdf",0)) {\r
- imageURL = file.fileName() + ".png";\r
- }\r
- }\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('")\r
- .append(Global.getFileManager().getResDirPath(fileName))\r
- .append("');\" "); buffer.append("type=\"" + mimeType + "\" href=\"nnres://" + fileName +"\" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\" >");\r
- buffer.append("<img src=\"" + imageURL + "\" title=\"" +newRes.getAttributes().getFileName());\r
- buffer.append("\"></img>");\r
- buffer.append("</a>");\r
- browser.page().mainFrame().evaluateJavaScript(\r
- script_start + buffer.toString() + script_end);\r
- }\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
- 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
- byte[] fileData = resourceFile.readAll().toByteArray();\r
- resourceFile.close();\r
- if (fileData.length == 0)\r
- return null;\r
- MessageDigest md;\r
- try {\r
- md = MessageDigest.getInstance("MD5");\r
- md.update(fileData);\r
- byte[] hash = md.digest();\r
- \r
- Resource r = new Resource();\r
- Calendar time = new GregorianCalendar();\r
- long prevTime = time.getTimeInMillis();\r
- while (prevTime == time.getTimeInMillis()) {\r
- time = new GregorianCalendar();\r
- }\r
- r.setGuid(time.getTimeInMillis()+new Integer(sequence).toString());\r
- r.setNoteGuid(currentNote.getGuid());\r
- r.setMime(mime);\r
- r.setActive(true);\r
- r.setUpdateSequenceNum(0);\r
- r.setWidth((short) 0);\r
- r.setHeight((short) 0);\r
- r.setDuration((short) 0);\r
- \r
- Data d = new Data();\r
- d.setBody(fileData);\r
- d.setBodyIsSet(true);\r
- d.setBodyHash(hash);\r
- d.setBodyHashIsSet(true);\r
- r.setData(d);\r
- d.setSize(fileData.length);\r
- \r
- int fileNamePos = url.lastIndexOf(File.separator);\r
- if (fileNamePos == -1)\r
- fileNamePos = url.lastIndexOf("/");\r
- String fileName = url.substring(fileNamePos+1);\r
- ResourceAttributes a = new ResourceAttributes();\r
- a.setAltitude(0);\r
- a.setAltitudeIsSet(false);\r
- a.setLongitude(0);\r
- a.setLongitudeIsSet(false);\r
- a.setLatitude(0);\r
- a.setLatitudeIsSet(false);\r
- a.setCameraMake("");\r
- a.setCameraMakeIsSet(false);\r
- a.setCameraModel("");\r
- a.setCameraModelIsSet(false);\r
- a.setAttachment(attachment);\r
- a.setAttachmentIsSet(true);\r
- a.setClientWillIndex(false);\r
- a.setClientWillIndexIsSet(true);\r
- a.setRecoType("");\r
- a.setRecoTypeIsSet(false);\r
- a.setSourceURL(url);\r
- a.setSourceURLIsSet(true);\r
- a.setTimestamp(0);\r
- a.setTimestampIsSet(false);\r
- a.setFileName(fileName);\r
- a.setFileNameIsSet(true);\r
- r.setAttributes(a);\r
- \r
- conn.getNoteTable().noteResourceTable.saveNoteResource(r, true);\r
- return r;\r
- } catch (NoSuchAlgorithmException e1) {\r
- e1.printStackTrace();\r
- }\r
- return null;\r
- }\r
- \r
-\r
- // find the appropriate icon for an attachment\r
- private String findIcon(String appl) {\r
- appl = appl.toLowerCase();\r
- File f = Global.getFileManager().getImageDirFile(appl + ".png");\r
- if (f.exists())\r
- return appl+".png";\r
- return "attachment.png";\r
- }\r
-\r
- // Check if the account supports this type of attachment\r
- private boolean validAttachment(String type) {\r
- if (Global.isPremium())\r
- return true;\r
- if (type.equalsIgnoreCase("JPG"))\r
- return true;\r
- if (type.equalsIgnoreCase("PNG"))\r
- return true;\r
- if (type.equalsIgnoreCase("GIF"))\r
- return true;\r
- if (type.equalsIgnoreCase("MP3"))\r
- return true;\r
- if (type.equalsIgnoreCase("WAV"))\r
- return true;\r
- if (type.equalsIgnoreCase("AMR"))\r
- return true;\r
- if (type.equalsIgnoreCase("PDF"))\r
- return true;\r
- String error = tr("Non-premium accounts can only attach JPG, PNG, GIF, MP3, WAV, AMR, or PDF files.");\r
- QMessageBox.information(this, tr("Non-Premium Account"), error);\r
-\r
- return false;\r
- }\r
-\r
- // Check the file attachment to be sure it isn't over 25 mb\r
- private boolean checkFileAttachmentSize(String url) {\r
- String fileName = url.substring(8);\r
- QFile resourceFile = new QFile(fileName);\r
- resourceFile.open(new QIODevice.OpenMode(\r
- QIODevice.OpenModeFlag.ReadOnly));\r
- long size = resourceFile.size();\r
- resourceFile.close();\r
- size = size / 1024 / 1024;\r
- if (size < 50 && Global.isPremium())\r
- return true;\r
- if (size < 25)\r
- return true;\r
-\r
- String error = tr("A file attachment may not exceed 25MB.");\r
- QMessageBox.information(this, tr("Attachment Size"), error);\r
- return false;\r
- }\r
-\r
-\r
- @SuppressWarnings("unused")\r
- private void createdChanged() {\r
- QDateTime dt = new QDateTime();\r
- dt.setDate(createdDate.date());\r
- dt.setTime(createdTime.time());\r
- noteSignal.createdDateChanged.emit(currentNote.getGuid(), dt);\r
-\r
- }\r
-\r
- @SuppressWarnings("unused")\r
- private void alteredChanged() {\r
- QDateTime dt = new QDateTime();\r
- dt.setDate(alteredDate.date());\r
- dt.setTime(alteredTime.time());\r
- noteSignal.alteredDateChanged.emit(currentNote.getGuid(), dt);\r
- }\r
-\r
- @SuppressWarnings("unused")\r
- private void subjectDateTimeChanged() {\r
- QDateTime dt = new QDateTime();\r
- dt.setDate(subjectDate.date());\r
- dt.setTime(subjectTime.time());\r
- noteSignal.subjectDateChanged.emit(currentNote.getGuid(), dt);\r
-\r
- }\r
-\r
- @SuppressWarnings("unused")\r
- private void sourceUrlChanged() {\r
- noteSignal.sourceUrlChanged.emit(currentNote.getGuid(), urlText.text());\r
- }\r
-\r
- @SuppressWarnings("unused")\r
- private void authorChanged() {\r
- 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
- if (index == 1) {\r
- GeoDialog box = new GeoDialog();\r
- box.setLongitude(currentNote.getAttributes().getLongitude());\r
- box.setLatitude(currentNote.getAttributes().getLatitude());\r
- box.setAltitude(currentNote.getAttributes().getAltitude());\r
- box.exec();\r
- if (!box.okPressed())\r
- return;\r
- double alt = box.getAltitude();\r
- double lat = box.getLatitude();\r
- double lon = box.getLongitude();\r
- if (alt != currentNote.getAttributes().getAltitude() ||\r
- lon != currentNote.getAttributes().getLongitude() ||\r
- lat != currentNote.getAttributes().getLatitude()) {\r
- noteSignal.geoChanged.emit(currentNote.getGuid(), lon, lat, alt);\r
- currentNote.getAttributes().setAltitude(alt);\r
- currentNote.getAttributes().setLongitude(lon);\r
- currentNote.getAttributes().setLatitude(lat);\r
- }\r
- }\r
- \r
- if (index == 2) {\r
- noteSignal.geoChanged.emit(currentNote.getGuid(), 0.0, 0.0, 0.0);\r
- currentNote.getAttributes().setAltitude(0.0);\r
- currentNote.getAttributes().setLongitude(0.0);\r
- currentNote.getAttributes().setLatitude(0.0);\r
- }\r
- \r
- if (index == 3 || index == 0) {\r
- QDesktopServices.openUrl(new QUrl("http://maps.google.com/maps?z=6&q="+currentNote.getAttributes().getLatitude() +"," +currentNote.getAttributes().getLongitude()));\r
- }\r
- }\r
-\r
- // ************************************************************\r
- // * User chose to save an attachment. Pares out the request *\r
- // * into a guid & file. Save the result. *\r
- // ************************************************************\r
- public void downloadAttachment(QNetworkRequest request) {\r
- String guid;\r
- QFileDialog fd = new QFileDialog(this);\r
- fd.setFileMode(FileMode.AnyFile);\r
- fd.setConfirmOverwrite(true);\r
- fd.setWindowTitle(tr("Save File"));\r
- fd.setAcceptMode(AcceptMode.AcceptSave);\r
- fd.setDirectory(System.getProperty("user.home"));\r
- String name = request.url().toString();\r
-\r
- int pos = name.lastIndexOf(Global.attachmentNameDelimeter);\r
- if (pos > -1) {\r
- guid = name.substring(0, pos).replace("nnres://", "");\r
- name = name.substring(pos +Global.attachmentNameDelimeter.length());\r
- fd.selectFile(name);\r
- pos = name.lastIndexOf('.');\r
- if (pos > -1) {\r
- String mimeType = "(*." + name.substring(pos + 1)\r
- + ");; All Files (*)";\r
- fd.setFilter(tr(mimeType));\r
- }\r
- } else {\r
- guid = name;\r
- }\r
-\r
- // Strip URL prefix and base dir\r
- guid = guid.replace("nnres://", "")\r
- .replace(FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath()), "");\r
-\r
- pos = guid.lastIndexOf('.');\r
- if (pos > 0)\r
- guid = guid.substring(0,pos);\r
- if (fd.exec() != 0 && fd.selectedFiles().size() > 0) {\r
- name = name.replace('\\', '/');\r
- Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);\r
- QFile saveFile = new QFile(fd.selectedFiles().get(0));\r
- QFile.OpenMode mode = new QFile.OpenMode();\r
- mode.set(QFile.OpenModeFlag.WriteOnly);\r
- saveFile.open(mode);\r
- QDataStream saveOut = new QDataStream(saveFile);\r
- QByteArray binData = new QByteArray(resBinary.getData().getBody());\r
- saveOut.writeBytes(binData.toByteArray());\r
- saveFile.close();\r
-\r
- }\r
- }\r
-\r
- \r
- // ************************************************************\r
- // * User chose to save an attachment. Pares out the request *\r
- // * into a guid & file. Save the result. --- DONE FROM downloadAttachment now!!!!! \r
- // ************************************************************\r
- public void downloadImage(QNetworkRequest request) {\r
- QFileDialog fd = new QFileDialog(this);\r
- fd.setFileMode(FileMode.AnyFile);\r
- fd.setConfirmOverwrite(true);\r
- fd.setWindowTitle(tr("Save File"));\r
- fd.setAcceptMode(AcceptMode.AcceptSave);\r
- fd.setDirectory(System.getProperty("user.home"));\r
- String name = request.url().toString();\r
- name = name.replace("nnres://", "");\r
- String dPath = FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath());\r
- name = name.replace(dPath, "");\r
- int pos = name.lastIndexOf('.');\r
- String guid = name;\r
- if (pos > -1) {\r
- String mimeType = "(*." + name.substring(pos + 1)\r
- + ");; All Files (*)";\r
- fd.setFilter(tr(mimeType));\r
- guid = guid.substring(0,pos);\r
- }\r
- pos = name.lastIndexOf(Global.attachmentNameDelimeter);\r
- if (pos > -1) {\r
- guid = name.substring(0, pos);\r
- fd.selectFile(name.substring(pos+Global.attachmentNameDelimeter.length())); \r
- }\r
- if (fd.exec() != 0 && fd.selectedFiles().size() > 0) {\r
- Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);\r
- String fileName = fd.selectedFiles().get(0);\r
- QFile saveFile = new QFile(fileName);\r
- QFile.OpenMode mode = new QFile.OpenMode();\r
- mode.set(QFile.OpenModeFlag.WriteOnly);\r
- saveFile.open(mode);\r
- QDataStream saveOut = new QDataStream(saveFile);\r
- QByteArray binData = new QByteArray(resBinary.getData().getBody());\r
- saveOut.writeBytes(binData.toByteArray());\r
- saveFile.close();\r
- }\r
- }\r
-\r
- \r
- // *************************************************************\r
- // * decrypt any hidden text. We could do an XML parse, but \r
- // * it is quicker here just to scan for an <img tag & do the fix\r
- // * the manual way\r
- // *************************************************************\r
- private void removeEncryption(String id, String plainText, boolean permanent, String slot) {\r
- if (!permanent) {\r
- plainText = " <table class=\"en-crypt-temp\" slot=\""\r
- +slot \r
- +"\""\r
- +"border=1 width=100%><tbody><tr><td>"\r
- +plainText+"</td></tr></tbody></table>";\r
- }\r
- \r
- String html = browser.page().mainFrame().toHtml();\r
- String text = html;\r
- int imagePos = html.indexOf("<img");\r
- int endPos;\r
- for ( ;imagePos>0; ) {\r
- // Find the end tag\r
- endPos = text.indexOf(">", imagePos);\r
- String tag = text.substring(imagePos-1,endPos);\r
- if (tag.indexOf("id=\""+id+"\"") > -1) {\r
- 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
- if (permanent)\r
- contentChanged();\r
- }\r
- imagePos = text.indexOf("<img", imagePos+1);\r
- }\r
- }\r
- \r
- \r
- //****************************************************************\r
- //* Focus shortcuts\r
- //****************************************************************\r
- @SuppressWarnings("unused")\r
- private void focusTitle() {\r
- titleLabel.setFocus();\r
- }\r
- @SuppressWarnings("unused")\r
- private void focusTag() {\r
- tagEdit.setFocus();\r
- }\r
- @SuppressWarnings("unused")\r
- private void focusNote() {\r
- browser.setFocus();\r
- }\r
- @SuppressWarnings("unused")\r
- private void focusAuthor() {\r
- authorLabel.setFocus();\r
- }\r
- @SuppressWarnings("unused")\r
- private void focusUrl() {\r
- urlLabel.setFocus();\r
- }\r
- \r
-\r
- //*****************************************************************\r
- //* Set the document background color\r
- //*****************************************************************\r
- public void setBackgroundColor(String color) {\r
- String js = "function changeBackground(color) {"\r
- +"document.body.style.background = color;"\r
- +"}" \r
- +"changeBackground('" +color+"');";\r
- browser.page().mainFrame().evaluateJavaScript(js);\r
- contentChanged();\r
- }\r
- \r
- \r
- //****************************************************************\r
- //* MicroFocus changed\r
- //****************************************************************\r
- private void microFocusChanged() {\r
- boldButton.setDown(false);\r
- italicButton.setDown(false);\r
- underlineButton.setDown(false);\r
- browser.openAction.setEnabled(false);\r
- browser.downloadAttachment.setEnabled(false);\r
- browser.downloadImage.setEnabled(false);\r
- browser.rotateImageLeft.setEnabled(false);\r
- browser.rotateImageRight.setEnabled(false);\r
- browser.insertTableAction.setEnabled(true);\r
- browser.insertTableRowAction.setEnabled(false);\r
- browser.deleteTableRowAction.setEnabled(false);\r
- browser.insertLinkAction.setText(tr("Insert Hyperlink"));\r
- currentHyperlink ="";\r
- insideList = false;\r
- forceTextPaste = false;\r
- \r
- String js = new String( "function getCursorPos() {"\r
- +"var cursorPos;"\r
- +"if (window.getSelection) {"\r
- +" var selObj = window.getSelection();"\r
- +" var selRange = selObj.getRangeAt(0);"\r
- +" var workingNode = window.getSelection().anchorNode.parentNode;"\r
- +" while(workingNode != null) { " \r
-// +" window.jambi.printNode(workingNode.nodeName);"\r
- +" if (workingNode.nodeName=='TABLE') { if (workingNode.getAttribute('class').toLowerCase() == 'en-crypt-temp') window.jambi.forceTextPaste(); }"\r
- +" if (workingNode.nodeName=='B') window.jambi.boldActive();"\r
- +" if (workingNode.nodeName=='I') window.jambi.italicActive();"\r
- +" if (workingNode.nodeName=='U') window.jambi.underlineActive();"\r
- +" if (workingNode.nodeName=='UL') window.jambi.setInsideList();"\r
- +" if (workingNode.nodeName=='OL') window.jambi.setInsideList();"\r
- +" if (workingNode.nodeName=='LI') window.jambi.setInsideList();"\r
- +" if (workingNode.nodeName=='TBODY') window.jambi.setInsideTable();"\r
- +" if (workingNode.nodeName=='A') {for(var x = 0; x < workingNode.attributes.length; x++ ) {if (workingNode.attributes[x].nodeName.toLowerCase() == 'href') window.jambi.setInsideLink(workingNode.attributes[x].nodeValue);}}"\r
- +" if (workingNode.nodeName=='SPAN') {"\r
- +" if (workingNode.getAttribute('style') == 'text-decoration: underline;') window.jambi.underlineActive();"\r
- +" }"\r
- +" workingNode = workingNode.parentNode;"\r
- +" }"\r
- +"}"\r
- +"} getCursorPos();");\r
- browser.page().mainFrame().evaluateJavaScript(js);\r
- }\r
- \r
- public void printNode(String n) {\r
- System.out.println("Node Vaule: " +n);\r
- }\r
- \r
- \r
- //****************************************************************\r
- //* Insert a table row\r
- //****************************************************************\r
- public void insertTableRow() {\r
- \r
- String js = new String( "function insertTableRow() {"\r
- +" var selObj = window.getSelection();"\r
- +" var selRange = selObj.getRangeAt(0);"\r
- +" var workingNode = window.getSelection().anchorNode.parentNode;"\r
- +" var cellCount = 0;"\r
- +" while(workingNode != null) { " \r
- +" if (workingNode.nodeName.toLowerCase()=='tr') {"\r
- +" row = document.createElement('TR');"\r
- +" var nodes = workingNode.getElementsByTagName('td');"\r
- +" for (j=0; j<nodes.length; j=j+1) {"\r
- +" cell = document.createElement('TD');"\r
- +" cell.innerHTML=' ';"\r
- +" row.appendChild(cell);"\r
- +" }" \r
- +" workingNode.parentNode.insertBefore(row,workingNode.nextSibling);"\r
- +" return;"\r
- +" }"\r
- +" workingNode = workingNode.parentNode;"\r
- +" }"\r
- +"} insertTableRow();");\r
- browser.page().mainFrame().evaluateJavaScript(js);\r
- contentChanged();\r
- }\r
- //****************************************************************\r
- //* Insert a table row\r
- //****************************************************************\r
- public void deleteTableRow() {\r
- \r
- String js = new String( "function deleteTableRow() {"\r
- +" var selObj = window.getSelection();"\r
- +" var selRange = selObj.getRangeAt(0);"\r
- +" var workingNode = window.getSelection().anchorNode.parentNode;"\r
- +" var cellCount = 0;"\r
- +" while(workingNode != null) { " \r
- +" if (workingNode.nodeName.toLowerCase()=='tr') {"\r
- +" workingNode.parentNode.removeChild(workingNode);"\r
- +" return;"\r
- +" }"\r
- +" workingNode = workingNode.parentNode;"\r
- +" }"\r
- +"} deleteTableRow();");\r
- browser.page().mainFrame().evaluateJavaScript(js);\r
- contentChanged();\r
- }\r
- public void setInsideTable() {\r
- browser.insertTableRowAction.setEnabled(true);\r
- browser.deleteTableRowAction.setEnabled(true);\r
- browser.insertTableAction.setEnabled(false);\r
- browser.encryptAction.setEnabled(false);\r
- }\r
- \r
- public void setInsideLink(String link) {\r
- browser.insertLinkAction.setText(tr("Edit Hyperlink"));\r
- currentHyperlink = link;\r
- }\r
- \r
- public void italicActive() {\r
- italicButton.setDown(true);\r
- }\r
- public void boldActive() {\r
- boldButton.setDown(true);\r
- }\r
- public void underlineActive() {\r
- underlineButton.setDown(true);\r
- }\r
- public void forceTextPaste() {\r
- forceTextPaste = true;\r
- }\r
- public void imageContextMenu(String f) {\r
- browser.downloadImage.setEnabled(true);\r
- browser.rotateImageRight.setEnabled(true);\r
- browser.rotateImageLeft.setEnabled(true);\r
- browser.openAction.setEnabled(true);\r
- selectedFile = f;\r
- }\r
- public void rotateImageRight() {\r
- QWebSettings.setMaximumPagesInCache(0);\r
- QWebSettings.setObjectCacheCapacities(0, 0, 0);\r
- QImage image = new QImage(selectedFile);\r
- QMatrix matrix = new QMatrix();\r
- matrix.rotate( 90.0 );\r
- image = image.transformed(matrix);\r
- image.save(selectedFile);\r
- QWebSettings.setMaximumPagesInCache(0);\r
- QWebSettings.setObjectCacheCapacities(0, 0, 0);\r
- browser.setHtml(browser.page().mainFrame().toHtml());\r
- browser.reload();\r
- contentChanged();\r
-// resourceSignal.contentChanged.emit(selectedFile);\r
-\r
- }\r
- public void rotateImageLeft() {\r
- QImage image = new QImage(selectedFile);\r
- QMatrix matrix = new QMatrix();\r
- matrix.rotate( -90.0 );\r
- image = image.transformed(matrix);\r
- image.save(selectedFile);\r
- browser.setHtml(browser.page().mainFrame().toHtml());\r
- browser.reload();\r
- contentChanged();\r
-// resourceSignal.contentChanged.emit(selectedFile);\r
- }\r
- public void resourceContextMenu(String f) {\r
- browser.downloadAttachment.setEnabled(true);\r
- browser.openAction.setEnabled(true);\r
- selectedFile = f;\r
- }\r
- \r
- \r
- //****************************************************************\r
- //* Apply CSS style to specified word\r
- //****************************************************************\r
-/* public void applyStyleToWords(String word, String style) {\r
- QFile script = new QFile("D:\\NeverNote\\js\\hilight1.js");\r
- script.open(OpenModeFlag.ReadOnly);\r
- String s = script.readAll().toString();\r
- String js = new String(s +" findit('"+word+"', '"+style+"');");\r
- browser.page().mainFrame().evaluateJavaScript(js);\r
- System.out.println(getContent());\r
- }\r
-*/ \r
- //****************************************************************\r
- //* Someone tried to paste a resource between notes, so we need *\r
- //* to do some special handling. *\r
- //****************************************************************\r
- private String fixInternotePaste(String text) {\r
- logger.log(logger.EXTREME, "Fixing internote paste");\r
- String returnValue = fixInternotePasteSearch(text, "<img", "src=\"");\r
- return fixInternotePasteSearch(returnValue, "<a", "href=\"nnres://");\r
- }\r
- private String fixInternotePasteSearch(String text, String type, String locTag) {\r
- \r
- // First, let's fix the images.\r
- int startPos = text.indexOf(type);\r
- int endPos;\r
- for (; startPos>=0;) {\r
- endPos = text.indexOf(">", startPos+1);\r
- String segment = text.substring(startPos, endPos);\r
- if (segment.indexOf("en-tag") > -1) {\r
- String newSegment = segment;\r
- \r
- int guidStartPos = segment.indexOf("guid=\"");\r
- 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
- while (l==prevTime) {\r
- currentTime = new GregorianCalendar();\r
- l= new Long(currentTime.getTimeInMillis());\r
- }\r
- \r
- Resource r = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);\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
- extension = r.getMime().toLowerCase();\r
- if (extension.indexOf("/")>-1)\r
- extension = extension.substring(extension.indexOf("/")+1);\r
- }\r
- String newFile = randint;\r
- if (r.getAttributes().getFileName() != null && r.getAttributes().getFileName() != "")\r
- if (!locTag.startsWith("src"))\r
- newFile = newFile+Global.attachmentNameDelimeter+r.getAttributes().getFileName();\r
- r.setNoteGuid(currentNote.getGuid());\r
- \r
- r.setGuid(randint);\r
- conn.getNoteTable().noteResourceTable.saveNoteResource(r, true);\r
- QFile f = new QFile(Global.getFileManager().getResDirPath(newFile));\r
- QByteArray bin = new QByteArray(r.getData().getBody());\r
- f.open(QFile.OpenModeFlag.WriteOnly);\r
- f.write(bin);\r
- f.close();\r
- newSegment = newSegment.replace("guid=\""+guid, "guid=\""+randint);\r
- currentNote.getResources().add(r);\r
- \r
- int startSrcPos = newSegment.indexOf(locTag);\r
- int endSrcPos = newSegment.indexOf("\"",startSrcPos+locTag.length()+1);\r
- String source; \r
- if (locTag.startsWith("src")) {\r
- source = newSegment.substring(startSrcPos+locTag.length(),endSrcPos);\r
- newSegment = newSegment.replace(source,\r
- FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath(newFile)));\r
- } else {\r
- source = newSegment.substring(startSrcPos+locTag.length(),endSrcPos);\r
- newSegment = newSegment.replace(source, newFile);\r
- }\r
- \r
- text = text.substring(0,startPos) + newSegment + text.substring(endPos);\r
- }\r
- startPos = text.indexOf(type, startPos+1);\r
- }\r
- return text;\r
- }\r
-\r
-\r
- public void nextPage(String file) {\r
- logger.log(logger.EXTREME, "Starting nextPage()");\r
- \r
- Integer pageNumber;\r
- if (previewPageList.containsKey(file))\r
- pageNumber = previewPageList.get(file)+1;\r
- else\r
- pageNumber = 2;\r
- previewPageList.remove(file);\r
- previewPageList.put(file, pageNumber);\r
- PDFPreview pdfPreview = new PDFPreview();\r
- boolean goodPreview = pdfPreview.setupPreview(file, "pdf", pageNumber);\r
- if (goodPreview) {\r
-\r
-// String html = getContent();\r
- QWebSettings.setMaximumPagesInCache(0);\r
- QWebSettings.setObjectCacheCapacities(0, 0, 0);\r
-// browser.setContent(new QByteArray());\r
- browser.setHtml(browser.page().mainFrame().toHtml());\r
- browser.reload();\r
-// browser.setContent(new QByteArray(html));\r
-// browser.triggerPageAction(WebAction.Reload);\r
-// pdfMouseOver(selectedFile);\r
- }\r
- }\r
-\r
- public void previousPage(String file) {\r
- logger.log(logger.EXTREME, "Starting previousPage()");\r
- \r
- Integer pageNumber;\r
- if (previewPageList.containsKey(file))\r
- pageNumber = previewPageList.get(file)-1;\r
- else\r
- pageNumber = 1;\r
- previewPageList.remove(file);\r
- previewPageList.put(file, pageNumber);\r
- PDFPreview pdfPreview = new PDFPreview();\r
- boolean goodPreview = pdfPreview.setupPreview(file, "pdf", pageNumber);\r
- if (goodPreview) {\r
-\r
-// String html = getContent();\r
- QWebSettings.setMaximumPagesInCache(0);\r
- QWebSettings.setObjectCacheCapacities(0, 0, 0);\r
- browser.setHtml(browser.page().mainFrame().toHtml());\r
- browser.reload();\r
-// browser.setContent(new QByteArray(html));\r
-// browser.triggerPageAction(WebAction.Reload);\r
- }\r
- }\r
- \r
-/* public void pdfMouseOver(String name) { \r
- int pageNumber;\r
- if (previewPageList.containsKey(selectedFile))\r
- pageNumber = previewPageList.get(selectedFile)+1;\r
- else\r
- pageNumber = 1;\r
- \r
- if (pageNumber <= 1)\r
- browser.previousPageAction.setEnabled(false);\r
- else\r
- browser.previousPageAction.setEnabled(true);\r
- \r
- PDFPreview pdf = new PDFPreview();\r
- int totalPages = pdf.getPageCount(name);\r
- if (previewPageList.containsKey(selectedFile))\r
- pageNumber = previewPageList.get(selectedFile)+1;\r
- else\r
- pageNumber = 1;\r
- if (totalPages > pageNumber)\r
- browser.nextPageAction.setEnabled(true);\r
- else\r
- browser.nextPageAction.setEnabled(false);\r
- }\r
- \r
-\r
- public void pdfMouseOut() { \r
-// browser.nextPageAction.setVisible(false);\r
-// 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 toggleTodoVisible(Boolean toggle) {\r
- todoAction.setVisible(toggle);\r
- Global.saveEditorButtonsVisible("todo", 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
- private void toggleSpellCheckVisible(Boolean toggle) {\r
- spellCheckAction.setVisible(toggle);\r
- Global.saveEditorButtonsVisible("spellCheck", toggle);\r
- }\r
-\r
-\r
- private void setupDictionary() {\r
- File wordList = new File(Global.getFileManager().getSpellDirPath()+Locale.getDefault()+".dic");\r
- try {\r
- dictionary = new SpellDictionaryHashMap(wordList);\r
- spellChecker = new SpellChecker(dictionary);\r
- \r
- File userWordList;\r
- userWordList = new File(Global.getFileManager().getSpellDirPathUser()+"user.dic");\r
- \r
- // Get the local user spell dictionary\r
- try {\r
- userDictionary = new SpellDictionaryHashMap(userWordList);\r
- } catch (FileNotFoundException e) {\r
- userWordList.createNewFile();\r
- userDictionary = new SpellDictionaryHashMap(userWordList);\r
- } catch (IOException e) {\r
- userWordList.createNewFile();\r
- userDictionary = new SpellDictionaryHashMap(userWordList);\r
- }\r
- \r
- spellListener = new SuggestionListener(this, spellChecker);\r
- \r
- // Add the user dictionary\r
- spellChecker.addSpellCheckListener(spellListener);\r
- spellChecker.setUserDictionary(userDictionary);\r
-\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
- // Invoke spell checker dialog\r
- private void spellCheckClicked() {\r
-\r
- if (spellChecker == null) {\r
- setupDictionary(); \r
- }\r
- \r
- // Read user settings\r
- spellChecker.getConfiguration().setBoolean(Configuration.SPELL_IGNOREDIGITWORDS, \r
- Global.getSpellSetting(Configuration.SPELL_IGNOREDIGITWORDS));\r
- spellChecker.getConfiguration().setBoolean(Configuration.SPELL_IGNOREINTERNETADDRESSES, \r
- Global.getSpellSetting(Configuration.SPELL_IGNOREINTERNETADDRESSES));\r
- spellChecker.getConfiguration().setBoolean(Configuration.SPELL_IGNOREMIXEDCASE, \r
- Global.getSpellSetting(Configuration.SPELL_IGNOREMIXEDCASE));\r
- spellChecker.getConfiguration().setBoolean(Configuration.SPELL_IGNOREUPPERCASE, \r
- Global.getSpellSetting(Configuration.SPELL_IGNOREUPPERCASE));\r
- spellChecker.getConfiguration().setBoolean(Configuration.SPELL_IGNORESENTENCECAPITALIZATION, \r
- Global.getSpellSetting(Configuration.SPELL_IGNORESENTENCECAPITALIZATION));\r
-\r
- spellListener.abortSpellCheck = false;\r
- spellListener.errorsFound = false;\r
- String content = getBrowser().page().mainFrame().toPlainText();\r
- StringWordTokenizer tokenizer = new StringWordTokenizer(content);\r
- if (!tokenizer.hasMoreWords())\r
- return;\r
- getBrowser().page().action(WebAction.MoveToStartOfDocument);\r
-\r
- getBrowser().setFocus();\r
- boolean found;\r
- \r
- // Move to the start of page\r
- KeyboardModifiers ctrl = new KeyboardModifiers(KeyboardModifier.ControlModifier.value());\r
- QKeyEvent home = new QKeyEvent(Type.KeyPress, Key.Key_Home.value(), ctrl); \r
- browser.keyPressEvent(home);\r
- getBrowser().setFocus();\r
- \r
- tokenizer = new StringWordTokenizer(content);\r
- String word;\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
-\r
- // Go to the end of the document & finish up.\r
- home = new QKeyEvent(Type.KeyPress, Key.Key_End.value(), ctrl); \r
- browser.keyPressEvent(home);\r
- if (!spellListener.errorsFound)\r
- QMessageBox.information(this, tr("Spell Check Complete"), \r
- tr("No Errors Found"));\r
-\r
- }\r
-\r
-}\r
+/*
+ * This file is part of NixNote/NeighborNote
+ * Copyright 2009 Randy Baumgarte
+ * Copyright 2013 Yuki Takahashi
+ *
+ * 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.gui;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.FileNameMap;
+import java.net.URI;
+import java.net.URLConnection;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import org.apache.commons.lang3.StringEscapeUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import com.evernote.edam.limits.Constants;
+import com.evernote.edam.type.Data;
+import com.evernote.edam.type.Note;
+import com.evernote.edam.type.Notebook;
+import com.evernote.edam.type.Resource;
+import com.evernote.edam.type.ResourceAttributes;
+import com.evernote.edam.type.Tag;
+import com.evernote.edam.type.User;
+import com.swabunga.spell.engine.Configuration;
+import com.swabunga.spell.engine.SpellDictionary;
+import com.swabunga.spell.engine.SpellDictionaryHashMap;
+import com.swabunga.spell.engine.Word;
+import com.swabunga.spell.event.SpellCheckEvent;
+import com.swabunga.spell.event.SpellCheckListener;
+import com.swabunga.spell.event.SpellChecker;
+import com.swabunga.spell.event.StringWordTokenizer;
+import com.trolltech.qt.core.QByteArray;
+import com.trolltech.qt.core.QCoreApplication;
+import com.trolltech.qt.core.QDataStream;
+import com.trolltech.qt.core.QDateTime;
+import com.trolltech.qt.core.QEvent;
+import com.trolltech.qt.core.QEvent.Type;
+import com.trolltech.qt.core.QFile;
+import com.trolltech.qt.core.QFileSystemWatcher;
+import com.trolltech.qt.core.QIODevice;
+import com.trolltech.qt.core.QMimeData;
+import com.trolltech.qt.core.QSize;
+import com.trolltech.qt.core.QTextCodec;
+import com.trolltech.qt.core.QTimer;
+import com.trolltech.qt.core.QUrl;
+import com.trolltech.qt.core.Qt;
+import com.trolltech.qt.core.Qt.Key;
+import com.trolltech.qt.core.Qt.KeyboardModifier;
+import com.trolltech.qt.core.Qt.KeyboardModifiers;
+import com.trolltech.qt.gui.QAction;
+import com.trolltech.qt.gui.QApplication;
+import com.trolltech.qt.gui.QCalendarWidget;
+import com.trolltech.qt.gui.QClipboard;
+import com.trolltech.qt.gui.QClipboard.Mode;
+import com.trolltech.qt.gui.QColor;
+import com.trolltech.qt.gui.QComboBox;
+import com.trolltech.qt.gui.QDateEdit;
+import com.trolltech.qt.gui.QDesktopServices;
+import com.trolltech.qt.gui.QFileDialog;
+import com.trolltech.qt.gui.QFileDialog.AcceptMode;
+import com.trolltech.qt.gui.QFileDialog.FileMode;
+import com.trolltech.qt.gui.QFont;
+import com.trolltech.qt.gui.QFontDatabase;
+import com.trolltech.qt.gui.QFormLayout;
+import com.trolltech.qt.gui.QGridLayout;
+import com.trolltech.qt.gui.QHBoxLayout;
+import com.trolltech.qt.gui.QIcon;
+import com.trolltech.qt.gui.QImage;
+import com.trolltech.qt.gui.QKeyEvent;
+import com.trolltech.qt.gui.QKeySequence;
+import com.trolltech.qt.gui.QLabel;
+import com.trolltech.qt.gui.QLineEdit;
+import com.trolltech.qt.gui.QListWidgetItem;
+import com.trolltech.qt.gui.QMatrix;
+import com.trolltech.qt.gui.QMessageBox;
+import com.trolltech.qt.gui.QPalette;
+import com.trolltech.qt.gui.QPalette.ColorRole;
+import com.trolltech.qt.gui.QPushButton;
+import com.trolltech.qt.gui.QShortcut;
+import com.trolltech.qt.gui.QSplitter;
+import com.trolltech.qt.gui.QTextEdit;
+import com.trolltech.qt.gui.QTextEdit.LineWrapMode;
+import com.trolltech.qt.gui.QTimeEdit;
+import com.trolltech.qt.gui.QToolButton;
+import com.trolltech.qt.gui.QToolButton.ToolButtonPopupMode;
+import com.trolltech.qt.gui.QVBoxLayout;
+import com.trolltech.qt.gui.QWidget;
+import com.trolltech.qt.network.QNetworkAccessManager;
+import com.trolltech.qt.network.QNetworkReply;
+import com.trolltech.qt.network.QNetworkReply.NetworkError;
+import com.trolltech.qt.network.QNetworkRequest;
+import com.trolltech.qt.webkit.QWebPage;
+import com.trolltech.qt.webkit.QWebPage.WebAction;
+import com.trolltech.qt.webkit.QWebSettings;
+import com.trolltech.qt.webkit.QWebView;
+
+import cx.fbn.nevernote.Global;
+import cx.fbn.nevernote.dialog.EnCryptDialog;
+import cx.fbn.nevernote.dialog.EnDecryptDialog;
+import cx.fbn.nevernote.dialog.GeoDialog;
+import cx.fbn.nevernote.dialog.InsertLatexImage;
+import cx.fbn.nevernote.dialog.InsertLinkDialog;
+import cx.fbn.nevernote.dialog.NoteQuickLinkDialog;
+import cx.fbn.nevernote.dialog.SpellCheck;
+import cx.fbn.nevernote.dialog.TableDialog;
+import cx.fbn.nevernote.dialog.TagAssign;
+import cx.fbn.nevernote.evernote.EnCrypt;
+import cx.fbn.nevernote.filters.FilterEditorTags;
+import cx.fbn.nevernote.neighbornote.ClipBoardObserver;
+import cx.fbn.nevernote.signals.NoteResourceSignal;
+import cx.fbn.nevernote.signals.NoteSignal;
+import cx.fbn.nevernote.sql.DatabaseConnection;
+import cx.fbn.nevernote.utilities.ApplicationLogger;
+import cx.fbn.nevernote.utilities.FileUtils;
+import cx.fbn.nevernote.utilities.Pair;
+import cx.fbn.nevernote.xml.HtmlTagModifier;
+
+public class BrowserWindow extends QWidget {
+
+ public final QLineEdit titleLabel;
+ private final QLineEdit urlText;
+ private final QLabel authorLabel;
+ private final QLineEdit authorText;
+ private final QComboBox geoBox;
+ public final TagLineEdit tagEdit;
+ public final QLabel tagLabel;
+ private final QPushButton urlLabel;
+ private final QLabel alteredLabel;
+ private final QDateEdit alteredDate;
+ private final QTimeEdit alteredTime;
+ private final QDateEdit createdDate;
+ private final QTimeEdit createdTime;
+ private final QLabel subjectLabel;
+ private final QDateEdit subjectDate;
+ private final QTimeEdit subjectTime;
+ public final QComboBox notebookBox;
+ private final QLabel notebookLabel;
+ private final QLabel createdLabel;
+ public final QComboBox fontSize;
+ public final QAction fontSizeAction;
+ private boolean extendedOn;
+ public boolean buttonsVisible;
+ private final String iconPath;
+ public final ContentView browser;
+ private final QTextEdit sourceEdit;
+ private String sourceEditHeader;
+ Highlighter syntaxHighlighter;
+ private List<Tag> allTags;
+ private List<String> currentTags;
+ public NoteSignal noteSignal;
+ public Signal2<String,String> evernoteLinkClicked;
+ private List<Notebook> notebookList;
+ private Note currentNote;
+ private String saveNoteTitle;
+ private String saveTagList;
+ private boolean insideList;
+ private final DatabaseConnection conn;
+ private final QCalendarWidget createdCalendarWidget;
+ private final QCalendarWidget alteredCalendarWidget;
+ private final QCalendarWidget subjectCalendarWidget;
+
+ public final QPushButton undoButton;
+ public final QAction undoAction;
+ public final QPushButton redoButton;
+ public final QAction redoAction;
+ public final QPushButton cutButton;
+ public final QAction cutAction;
+ public final QPushButton copyButton;
+ public final QAction copyAction;
+ public final QPushButton pasteButton;
+ public final QAction pasteAction;
+ public final QPushButton boldButton;
+ public final QAction boldAction;
+ public final QPushButton underlineButton;
+ public final QAction underlineAction;
+ public final QPushButton italicButton;
+ public final QAction italicAction;
+ public final Signal0 focusLost;
+ public final NoteResourceSignal resourceSignal;
+
+ public QPushButton rightAlignButton;
+ public final QAction rightAlignAction;
+ public QPushButton leftAlignButton;
+ public final QAction leftAlignAction;
+ public QPushButton centerAlignButton;
+ public final QAction centerAlignAction;
+
+ public final QPushButton strikethroughButton;
+ public final QAction strikethroughAction;
+ public final QPushButton hlineButton;
+ public final QAction hlineAction;
+ public final QPushButton indentButton;
+ public final QAction indentAction;
+ public final QPushButton outdentButton;
+ public final QAction outdentAction;
+ public final QPushButton bulletListButton;
+ public final QAction bulletListAction;
+ public final QPushButton numberListButton;
+ public final QAction numberListAction;
+ public final QPushButton spellCheckButton;
+ public final QAction spellCheckAction;
+ public final QPushButton todoButton;
+ public final QAction todoAction;
+
+ public final QShortcut focusTitleShortcut;
+ public final QShortcut focusTagShortcut;
+ public final QShortcut focusNoteShortcut;
+ public final QShortcut focusUrlShortcut;
+ public final QShortcut focusAuthorShortcut;
+
+ public EditorButtonBar buttonLayout;
+ public final QComboBox fontList;
+ public final QAction fontListAction;
+ public final QToolButton fontColor;
+ public final QAction fontColorAction;
+ private final ColorMenu fontColorMenu;
+ public final QToolButton fontHilight;
+ public final QAction fontHilightAction;
+ private final ColorMenu fontHilightColorMenu;
+ public final QFileSystemWatcher fileWatcher;
+ public int cursorPosition;
+ private boolean forceTextPaste;
+ private String selectedFile;
+ private String currentHyperlink;
+ public boolean keepPDFNavigationHidden;
+ private final ApplicationLogger logger;
+ SpellDictionary dictionary;
+ SpellDictionary userDictionary;
+ SpellChecker spellChecker;
+ SuggestionListener spellListener;
+ private final HashMap<String,Integer> previewPageList;
+ boolean insertHyperlink;
+ boolean insideTable;
+ boolean insideEncryption;
+ public Signal1<BrowserWindow> blockApplication;
+ public Signal0 unblockApplication;
+ public boolean awaitingHttpResponse;
+ public long unblockTime;
+ private final QTimer setSourceTimer;
+ String latexGuid; // This is set if we are editing an existing LaTeX formula. Useful to track guid.
+
+ // ICHANGED
+ private final ClipBoardObserver cbObserver;
+
+ public static class SuggestionListener implements SpellCheckListener {
+ public boolean abortSpellCheck = false;
+ public boolean errorsFound = false;
+ private final SpellCheck spellCheckDialog;
+
+
+ private final BrowserWindow parent;
+ public SuggestionListener(BrowserWindow parent, SpellChecker checker) {
+ this.parent = parent;
+ spellCheckDialog = new SpellCheck(checker);
+ }
+ public void spellingError(SpellCheckEvent event) {
+ errorsFound = true;
+ spellCheckDialog.setWord(event.getInvalidWord());
+
+ @SuppressWarnings("unchecked")
+ List<Word> suggestions = event.getSuggestions();
+ spellCheckDialog.clearSuggestions();
+ if (!suggestions.isEmpty()) {
+// spellCheckDialog.setCurrentSuggestion(suggestions.get(0).getWord());
+ for (int i=0; i<suggestions.size(); i++) {
+ spellCheckDialog.addSuggestion(suggestions.get(i).getWord());
+ }
+ spellCheckDialog.setSelectedSuggestion(0);
+ }
+ spellCheckDialog.exec();
+ if (spellCheckDialog.cancelPressed()) {
+ abortSpellCheck = true;
+ event.cancel();
+ return;
+ }
+ if (spellCheckDialog.replacePressed()) {
+ QClipboard clipboard = QApplication.clipboard();
+ clipboard.setText(spellCheckDialog.getReplacementWord());
+ parent.pasteClicked();
+ }
+ event.cancel();
+ }
+ }
+
+
+ // ICHANGED 引数にcbObserverを追加
+ public BrowserWindow(DatabaseConnection c, ClipBoardObserver cbObserver) {
+ logger = new ApplicationLogger("browser.log");
+ logger.log(logger.HIGH, "Setting up browser");
+ iconPath = new String("classpath:cx/fbn/nevernote/icons/");
+ forceTextPaste = false;
+ insertHyperlink = true;
+ insideTable = false;
+ insideEncryption = false;
+
+ fileWatcher = new QFileSystemWatcher();
+// fileWatcher.fileChanged.connect(this, "fileChanged(String)");
+ noteSignal = new NoteSignal();
+ titleLabel = new QLineEdit();
+ evernoteLinkClicked = new Signal2<String,String>();
+ titleLabel.setMaxLength(Constants.EDAM_NOTE_TITLE_LEN_MAX);
+ urlText = new QLineEdit();
+ authorText = new QLineEdit();
+ geoBox = new QComboBox();
+ urlLabel = new QPushButton();
+ urlLabel.clicked.connect(this, "sourceUrlClicked()");
+ authorLabel = new QLabel();
+ conn = c;
+
+ // ICHANGED
+ this.cbObserver = cbObserver;
+
+ focusLost = new Signal0();
+
+ tagEdit = new TagLineEdit(allTags);
+ tagLabel = new QLabel(tr("Tags:"));
+ tagEdit.focusLost.connect(this, "modifyTagsTyping()");
+
+ createdCalendarWidget = new QCalendarWidget();
+ createdDate = new QDateEdit();
+ createdDate.setDisplayFormat(Global.getDateFormat());
+ createdDate.setCalendarPopup(true);
+ createdDate.setCalendarWidget(createdCalendarWidget);
+ createdTime = new QTimeEdit();
+ createdDate.dateChanged.connect(this, "createdChanged()");
+ createdTime.timeChanged.connect(this, "createdChanged()");
+
+ alteredCalendarWidget = new QCalendarWidget();
+ alteredDate = new QDateEdit();
+ alteredDate.setDisplayFormat(Global.getDateFormat());
+ alteredDate.setCalendarPopup(true);
+ alteredDate.setCalendarWidget(alteredCalendarWidget);
+ alteredTime = new QTimeEdit();
+ alteredLabel = new QLabel(tr("Altered:"));
+ alteredDate.dateChanged.connect(this, "alteredChanged()");
+ alteredTime.timeChanged.connect(this, "alteredChanged()");
+
+ subjectCalendarWidget = new QCalendarWidget();
+ subjectDate = new QDateEdit();
+ subjectDate.setDisplayFormat(Global.getDateFormat());
+ subjectDate.setCalendarPopup(true);
+ subjectDate.setCalendarWidget(subjectCalendarWidget);
+ subjectTime = new QTimeEdit();
+ subjectLabel = new QLabel(tr("Subject Date:"));
+ subjectDate.dateChanged.connect(this, "subjectDateTimeChanged()");
+ subjectTime.timeChanged.connect(this, "subjectDateTimeChanged()");
+ authorText.textChanged.connect(this, "authorChanged()");
+ urlText.textChanged.connect(this, "sourceUrlChanged()");
+
+ notebookBox = new QComboBox();
+ notebookLabel = new QLabel(tr("Notebook"));
+ createdLabel = new QLabel(tr("Created:"));
+ // selectedText = new String();
+
+ urlLabel.setVisible(false);
+ urlText.setVisible(false);
+ authorLabel.setVisible(false);
+
+ geoBox.setVisible(false);
+ geoBox.addItem(new QIcon(iconPath+"globe.png"), "");
+ geoBox.addItem(new String(tr("Set")));
+ geoBox.addItem(new String(tr("Clear")));
+ geoBox.addItem(new String(tr("View On Map")));
+ geoBox.activated.connect(this, "geoBoxChanged()");
+
+ authorText.setVisible(false);
+ createdDate.setVisible(false);
+ alteredLabel.setVisible(false);
+ //notebookBox.setVisible(false);
+ notebookLabel.setVisible(false);
+ createdLabel.setVisible(false);
+ createdTime.setVisible(false);
+ alteredDate.setVisible(false);
+ alteredTime.setVisible(false);
+ subjectLabel.setVisible(false);
+ subjectDate.setVisible(false);
+ subjectTime.setVisible(false);
+ extendedOn = false;
+ buttonsVisible = true;
+ setAcceptDrops(true);
+
+ browser = new ContentView(this);
+
+ browser.page().setLinkDelegationPolicy(
+ QWebPage.LinkDelegationPolicy.DelegateAllLinks);
+ browser.linkClicked.connect(this, "linkClicked(QUrl)");
+ currentHyperlink = "";
+
+ //Setup the source editor
+ sourceEdit = new QTextEdit(this);
+ sourceEdit.setVisible(false);
+ sourceEdit.setTabChangesFocus(true);
+ sourceEdit.setLineWrapMode(LineWrapMode.NoWrap);
+ QFont font = new QFont();
+ font.setFamily("Courier");
+ font.setFixedPitch(true);
+ font.setPointSize(10);
+ sourceEdit.setFont(font);
+ syntaxHighlighter = new Highlighter(sourceEdit.document());
+ sourceEdit.textChanged.connect(this, "sourceEdited()");
+
+ QVBoxLayout v = new QVBoxLayout();
+ QFormLayout notebookLayout = new QFormLayout();
+ QGridLayout dateLayout = new QGridLayout();
+ titleLabel.setReadOnly(false);
+ titleLabel.editingFinished.connect(this, "titleEdited()");
+ browser.page().contentsChanged.connect(this, "contentChanged()");
+ browser.page().selectionChanged.connect(this, "selectionChanged()");
+ browser.page().mainFrame().javaScriptWindowObjectCleared.connect(this,
+ "exposeToJavascript()");
+
+ notebookBox.activated.connect(this, "notebookChanged()");
+ resourceSignal = new NoteResourceSignal();
+
+ QHBoxLayout tagLayout = new QHBoxLayout();
+ v.addWidget(titleLabel, 0);
+ notebookLayout.addRow(notebookLabel, notebookBox);
+ tagLayout.addLayout(notebookLayout, 0);
+ tagLayout.stretch(4);
+ tagLayout.addWidget(tagLabel, 0);
+ tagLayout.addWidget(tagEdit, 1);
+ v.addLayout(tagLayout);
+
+ QHBoxLayout urlLayout = new QHBoxLayout();
+ urlLayout.addWidget(urlLabel, 0);
+ urlLayout.addWidget(urlText, 0);
+ v.addLayout(urlLayout);
+
+ QHBoxLayout authorLayout = new QHBoxLayout();
+ authorLayout.addWidget(authorLabel, 0);
+ authorLayout.addWidget(authorText, 0);
+ authorLayout.addWidget(geoBox);
+ v.addLayout(authorLayout);
+
+ dateLayout.addWidget(createdLabel, 0, 0);
+ dateLayout.addWidget(createdDate, 0, 1);
+ dateLayout.addWidget(createdTime, 0, 2);
+ dateLayout.setColumnStretch(9, 100);
+ dateLayout.addWidget(alteredLabel, 0, 3);
+ dateLayout.addWidget(alteredDate, 0, 4);
+ dateLayout.addWidget(alteredTime, 0, 5);
+ dateLayout.addWidget(subjectLabel, 0, 6);
+ dateLayout.addWidget(subjectDate, 0, 7);
+ dateLayout.addWidget(subjectTime, 0, 8);
+ v.addLayout(dateLayout, 0);
+
+ undoButton = newEditorButton("undo", tr("Undo Change"));
+ redoButton = newEditorButton("redo", tr("Redo Change"));
+ cutButton = newEditorButton("cut", tr("Cut"));
+ copyButton = newEditorButton("copy", tr("Copy"));
+ pasteButton = newEditorButton("paste", tr("Paste"));
+ boldButton = newEditorButton("bold", tr("Bold"));
+ underlineButton = newEditorButton("underline", tr("Underline"));
+ italicButton = newEditorButton("italic", tr("Italic"));
+
+ rightAlignButton = newEditorButton("justifyRight", tr("Right Align"));
+ leftAlignButton = newEditorButton("justifyLeft", tr("Left Align"));
+ centerAlignButton = newEditorButton("justifyCenter", tr("Center Align"));
+
+ strikethroughButton = newEditorButton("strikethrough", tr("Strikethrough"));
+ hlineButton = newEditorButton("hline", tr("Insert Horizontal Line"));
+ indentButton = newEditorButton("indent", tr("Shift Right"));
+ outdentButton = newEditorButton("outdent", tr("Shift Left"));
+ bulletListButton = newEditorButton("bulletList", tr("Bullet List"));
+ numberListButton = newEditorButton("numberList", tr("Number List"));
+ spellCheckButton = newEditorButton("spellCheck", tr("Spell Check"));
+ todoButton = newEditorButton("todo", tr("To-do"));
+
+
+ buttonLayout = new EditorButtonBar();
+ v.addWidget(buttonLayout);
+
+ undoAction = buttonLayout.addWidget(undoButton);
+ buttonLayout.toggleUndoVisible.triggered.connect(this, "toggleUndoVisible(Boolean)");
+ redoAction = buttonLayout.addWidget(redoButton);
+ buttonLayout.toggleRedoVisible.triggered.connect(this, "toggleRedoVisible(Boolean)");
+
+ buttonLayout.addWidget(newSeparator());
+ cutAction = buttonLayout.addWidget(cutButton);
+ buttonLayout.toggleCutVisible.triggered.connect(this, "toggleCutVisible(Boolean)");
+ copyAction = buttonLayout.addWidget(copyButton);
+ buttonLayout.toggleCopyVisible.triggered.connect(this, "toggleCopyVisible(Boolean)");
+ pasteAction = buttonLayout.addWidget(pasteButton);
+ buttonLayout.togglePasteVisible.triggered.connect(this, "togglePasteVisible(Boolean)");
+
+ buttonLayout.addWidget(newSeparator());
+ boldAction = buttonLayout.addWidget(boldButton);
+ buttonLayout.toggleBoldVisible.triggered.connect(this, "toggleBoldVisible(Boolean)");
+ italicAction = buttonLayout.addWidget(italicButton);
+ buttonLayout.toggleItalicVisible.triggered.connect(this, "toggleItalicVisible(Boolean)");
+ underlineAction = buttonLayout.addWidget(underlineButton);
+ buttonLayout.toggleUnderlineVisible.triggered.connect(this, "toggleUnderlineVisible(Boolean)");
+ strikethroughAction = buttonLayout.addWidget(strikethroughButton);
+ buttonLayout.toggleStrikethroughVisible.triggered.connect(this, "toggleStrikethroughVisible(Boolean)");
+
+
+ buttonLayout.addWidget(newSeparator());
+ leftAlignAction = buttonLayout.addWidget(leftAlignButton);
+ buttonLayout.toggleLeftAlignVisible.triggered.connect(this, "toggleLeftAlignVisible(Boolean)");
+ centerAlignAction = buttonLayout.addWidget(centerAlignButton);
+ buttonLayout.toggleCenterAlignVisible.triggered.connect(this, "toggleCenterAlignVisible(Boolean)");
+ rightAlignAction = buttonLayout.addWidget(rightAlignButton);
+ buttonLayout.toggleRightAlignVisible.triggered.connect(this, "toggleRightAlignVisible(Boolean)");
+
+ buttonLayout.addWidget(newSeparator());
+ hlineAction = buttonLayout.addWidget(hlineButton);
+ buttonLayout.toggleHLineVisible.triggered.connect(this, "toggleHLineVisible(Boolean)");
+
+ indentAction = buttonLayout.addWidget(indentButton);
+ buttonLayout.toggleIndentVisible.triggered.connect(this, "toggleIndentVisible(Boolean)");
+ outdentAction = buttonLayout.addWidget(outdentButton);
+ buttonLayout.toggleOutdentVisible.triggered.connect(this, "toggleOutdentVisible(Boolean)");
+ bulletListAction = buttonLayout.addWidget(bulletListButton);
+ buttonLayout.toggleBulletListVisible.triggered.connect(this, "toggleBulletListVisible(Boolean)");
+ numberListAction = buttonLayout.addWidget(numberListButton);
+ buttonLayout.toggleNumberListVisible.triggered.connect(this, "toggleNumberListVisible(Boolean)");
+
+ // Setup the font & font size combo boxes
+ buttonLayout.addWidget(newSeparator());
+ fontList = new QComboBox();
+ fontSize = new QComboBox();
+ fontList.setMaximumWidth(130);
+ fontSize.setMaximumWidth(45);
+ fontList.setToolTip("Font");
+ fontSize.setToolTip("Font Size");
+ fontList.activated.connect(this, "fontChanged(String)");
+ fontSize.activated.connect(this, "fontSizeChanged(String)");
+ fontListAction = buttonLayout.addWidget(fontList);
+ buttonLayout.toggleFontVisible.triggered.connect(this, "toggleFontListVisible(Boolean)");
+ fontSizeAction = buttonLayout.addWidget(fontSize);
+ buttonLayout.toggleFontSizeVisible.triggered.connect(this, "toggleFontSizeVisible(Boolean)");
+ QFontDatabase fonts = new QFontDatabase();
+ List<String> fontFamilies = fonts.families();
+ for (int i = 0; i < fontFamilies.size(); i++) {
+ fontList.addItem(fontFamilies.get(i));
+ if (i == 0) {
+ loadFontSize(fontFamilies.get(i));
+ }
+ }
+
+// buttonLayout.addWidget(newSeparator(), 0);
+ fontColor = newToolButton("fontColor", tr("Font Color"));
+ fontColorMenu = new ColorMenu(this);
+ fontColor.setMenu(fontColorMenu.getMenu());
+ fontColor.setPopupMode(ToolButtonPopupMode.MenuButtonPopup);
+ fontColor.setAutoRaise(false);
+ fontColorMenu.getMenu().triggered.connect(this, "fontColorClicked()");
+ fontColorAction = buttonLayout.addWidget(fontColor);
+ buttonLayout.toggleFontColorVisible.triggered.connect(this, "toggleFontColorVisible(Boolean)");
+ fontHilight = newToolButton("fontHilight", tr("Font Hilight Color"));
+ fontHilight.setPopupMode(ToolButtonPopupMode.MenuButtonPopup);
+ fontHilight.setAutoRaise(false);
+ fontHilightColorMenu = new ColorMenu(this);
+ fontHilightColorMenu.setDefault(QColor.yellow);
+ fontHilight.setMenu(fontHilightColorMenu.getMenu());
+ fontHilightColorMenu.getMenu().triggered.connect(this, "fontHilightClicked()");
+ fontHilightAction = buttonLayout.addWidget(fontHilight);
+ fontHilightColorMenu.setDefault(QColor.yellow);
+ buttonLayout.toggleFontHilight.triggered.connect(this, "toggleFontHilightVisible(Boolean)");
+
+ spellCheckAction = buttonLayout.addWidget(spellCheckButton);
+ buttonLayout.toggleNumberListVisible.triggered.connect(this, "spellCheckClicked()");
+ buttonLayout.toggleSpellCheck.triggered.connect(this, "toggleSpellCheckVisible(Boolean)");
+
+ todoAction = buttonLayout.addWidget(todoButton);
+ buttonLayout.toggleNumberListVisible.triggered.connect(this, "todoClicked()");
+ buttonLayout.toggleTodo.triggered.connect(this, "toggleTodoVisible(Boolean)");
+
+ // Setup the source browser);
+
+// buttonLayout.addWidget(new QLabel(), 1);
+ QSplitter editSplitter = new QSplitter(this);
+ editSplitter.addWidget(browser);
+ editSplitter.setOrientation(Qt.Orientation.Vertical);
+ editSplitter.addWidget(sourceEdit);
+
+
+
+// v.addWidget(browser, 1);
+// v.addWidget(sourceEdit);
+ v.addWidget(editSplitter);
+ setLayout(v);
+
+ browser.downloadAttachmentRequested.connect(this,
+ "downloadAttachment(QNetworkRequest)");
+ browser.downloadImageRequested.connect(this,
+ "downloadImage(QNetworkRequest)");
+ setTabOrder(notebookBox, tagEdit);
+ setTabOrder(tagEdit, browser);
+
+ focusNoteShortcut = new QShortcut(this);
+ setupShortcut(focusNoteShortcut, "Focus_Note");
+ focusNoteShortcut.activated.connect(this, "focusNote()");
+ focusTitleShortcut = new QShortcut(this);
+ setupShortcut(focusTitleShortcut, "Focus_Title");
+ focusTitleShortcut.activated.connect(this, "focusTitle()");
+ focusTagShortcut = new QShortcut(this);
+ setupShortcut(focusTagShortcut, "Focus_Tag");
+ focusTagShortcut.activated.connect(this, "focusTag()");
+ focusAuthorShortcut = new QShortcut(this);
+ setupShortcut(focusAuthorShortcut, "Focus_Author");
+ focusAuthorShortcut.activated.connect(this, "focusAuthor()");
+ focusUrlShortcut = new QShortcut(this);
+ setupShortcut(focusUrlShortcut, "Focus_Url");
+ focusUrlShortcut.activated.connect(this, "focusUrl()");
+
+ browser.page().mainFrame().setTextSizeMultiplier(Global.getTextSizeMultiplier());
+ browser.page().mainFrame().setZoomFactor(Global.getZoomFactor());
+
+ previewPageList = new HashMap<String,Integer>();
+
+ browser.page().microFocusChanged.connect(this, "microFocusChanged()");
+
+ //Setup colors
+
+ QPalette pal = new QPalette();
+ pal.setColor(ColorRole.Text, QColor.black);
+ titleLabel.setPalette(pal);
+ authorText.setPalette(pal);
+ authorLabel.setPalette(pal);
+ urlLabel.setPalette(pal);
+ urlText.setPalette(pal);
+ createdDate.setPalette(pal);
+ createdTime.setPalette(pal);
+ alteredDate.setPalette(pal);
+ alteredTime.setPalette(pal);
+ subjectDate.setPalette(pal);
+ subjectTime.setPalette(pal);
+ tagEdit.setPalette(pal);
+ notebookBox.setPalette(pal);
+
+ blockApplication = new Signal1<BrowserWindow>();
+ unblockApplication = new Signal0();
+
+ setSourceTimer = new QTimer();
+ setSourceTimer.timeout.connect(this, "setSource()");
+
+ logger.log(logger.HIGH, "Browser setup complete");
+ }
+
+
+
+ private void setupShortcut(QShortcut action, String text) {
+ if (!Global.shortcutKeys.containsAction(text))
+ return;
+ action.setKey(new QKeySequence(Global.shortcutKeys.getShortcut(text)));
+ }
+
+
+
+
+ // Getter for the QWebView
+ public QWebView getBrowser() {
+ return browser;
+ }
+
+ // Block signals while loading data or things are flagged as dirty by
+ // mistake
+ public void loadingData(boolean val) {
+ logger.log(logger.EXTREME, "Entering BrowserWindow.loadingData() " +val);
+ notebookBox.blockSignals(val);
+ browser.page().blockSignals(val);
+ browser.page().mainFrame().blockSignals(val);
+ titleLabel.blockSignals(val);
+ alteredDate.blockSignals(val);
+ alteredTime.blockSignals(val);
+ createdTime.blockSignals(val);
+ createdDate.blockSignals(val);
+ subjectDate.blockSignals(val);
+ subjectTime.blockSignals(val);
+ urlText.blockSignals(val);
+ authorText.blockSignals(val);
+ if (!val)
+ exposeToJavascript();
+ logger.log(logger.EXTREME, "Exiting BrowserWindow.loadingData() " +val);
+ }
+
+ // Enable/disable
+ public void setReadOnly(boolean v) {
+ setEnabled(true);
+ titleLabel.setEnabled(!v);
+ notebookBox.setEnabled(!v);
+ tagEdit.setEnabled(!v);
+ authorLabel.setEnabled(!v);
+ geoBox.setEnabled(!v);
+ urlText.setEnabled(!v);
+ createdDate.setEnabled(!v);
+ subjectDate.setEnabled(!v);
+ alteredDate.setEnabled(!v);
+ authorText.setEnabled(!v);
+ createdTime.setEnabled(!v);
+ alteredTime.setEnabled(!v);
+ subjectTime.setEnabled(!v);
+ getBrowser().setEnabled(true);
+ getBrowser().page().setContentEditable(!v);
+// getBrowser().setEnabled(!v);
+ }
+
+ // expose this class to Javascript on the web page
+ private void exposeToJavascript() {
+ browser.page().mainFrame().addToJavaScriptWindowObject("jambi", this);
+ }
+
+ // Custom event queue
+ @Override
+ public boolean event(QEvent e) {
+ if (e.type().equals(QEvent.Type.FocusOut)) {
+ logger.log(logger.EXTREME, "Focus lost");
+ focusLost.emit();
+ }
+ return super.event(e);
+ }
+
+ // clear out browser
+ public void clear() {
+ logger.log(logger.EXTREME, "Entering BrowserWindow.clear()");
+ setNote(null);
+ setContent(new QByteArray());
+ tagEdit.setText("");
+ tagEdit.tagCompleter.reset();
+ urlLabel.setText(tr("Source URL:"));
+ titleLabel.setText("");
+ logger.log(logger.EXTREME, "Exiting BrowserWindow.clear()");
+ }
+
+ public void setContent(QByteArray data) {
+ sourceEdit.blockSignals(true);
+ browser.setContent(data);
+ setSource();
+ }
+ // get/set current note
+ public void setNote(Note n) {
+ currentNote = n;
+ if (n == null)
+ n = new Note();
+ saveNoteTitle = n.getTitle();
+
+ }
+
+ public Note getNote() {
+ return currentNote;
+ }
+
+ // New Editor Button
+ private QPushButton newEditorButton(String name, String toolTip) {
+ QPushButton button = new QPushButton();
+// QIcon icon = new QIcon(iconPath + name + ".gif");
+ QIcon icon = new QIcon(iconPath + name + ".png");
+ button.setIcon(icon);
+ // ICHANGED
+ button.setIconSize(new QSize(16, 16));
+
+ button.setToolTip(toolTip);
+ button.clicked.connect(this, name + "Clicked()");
+ return button;
+ }
+ // New Editor Button
+ private QToolButton newToolButton(String name, String toolTip) {
+ QToolButton button = new QToolButton();
+// QIcon icon = new QIcon(iconPath + name + ".gif");
+ QIcon icon = new QIcon(iconPath + name + ".png");
+ button.setIcon(icon);
+ // ICHANGED
+ button.setIconSize(new QSize(16, 16));
+
+ button.setToolTip(toolTip);
+ button.clicked.connect(this, name + "Clicked()");
+ return button;
+ }
+
+ // New Separator
+ private QLabel newSeparator() {
+ return new QLabel(" ");
+ }
+
+ // Set the title in the window
+ public void setTitle(String t) {
+ titleLabel.setText(t);
+ saveNoteTitle = t;
+ checkNoteTitle();
+ }
+
+ // Return the current text title
+ public String getTitle() {
+ return titleLabel.text();
+ }
+
+ // Set the tag name string
+ public void setTag(String t) {
+ saveTagList = t;
+ tagEdit.setText(t);
+ tagEdit.tagCompleter.reset();
+ }
+
+ // Set the source URL
+ public void setUrl(String t) {
+ urlLabel.setText(tr("Source URL:\t"));
+ urlText.setText(t);
+ }
+
+ // The user want's to launch a web browser on the source of the URL
+ public void sourceUrlClicked() {
+ // Make sure we have a valid URL
+ if (urlText.text().trim().equals(""))
+ return;
+
+ String url = urlText.text();
+ if (!url.toLowerCase().startsWith(tr("http://")))
+ url = tr("http://") +url;
+
+ if (!QDesktopServices.openUrl(new QUrl(url))) {
+ logger.log(logger.LOW, "Error opening file :" +url);
+ }
+ }
+
+ public void setAuthor(String t) {
+ authorLabel.setText(tr("Author:\t"));
+ authorText.setText(t);
+ }
+
+ // Set the creation date
+ public void setCreation(long date) {
+ QDateTime dt = new QDateTime();
+ dt.setTime_t((int) (date / 1000));
+ createdDate.setDateTime(dt);
+ createdTime.setDateTime(dt);
+ createdDate.setDisplayFormat(Global.getDateFormat());
+ createdTime.setDisplayFormat(Global.getTimeFormat());
+ }
+
+ // Set the creation date
+ public void setAltered(long date) {
+ QDateTime dt = new QDateTime();
+ dt.setTime_t((int) (date / 1000));
+ alteredDate.setDateTime(dt);
+ alteredTime.setDateTime(dt);
+ alteredDate.setDisplayFormat(Global.getDateFormat());
+ alteredTime.setDisplayFormat(Global.getTimeFormat());
+ }
+
+ // Set the subject date
+ public void setSubjectDate(long date) {
+ QDateTime dt = new QDateTime();
+ dt.setTime_t((int) (date / 1000));
+ subjectDate.setDateTime(dt);
+ subjectTime.setDateTime(dt);
+ subjectDate.setDisplayFormat(Global.getDateFormat());
+ subjectTime.setDisplayFormat(Global.getTimeFormat());
+ }
+
+ // Toggle the extended attribute information
+ public void toggleInformation() {
+ if (extendedOn) {
+ extendedOn = false;
+ } else {
+ extendedOn = true;
+ }
+ urlLabel.setVisible(extendedOn);
+ urlText.setVisible(extendedOn);
+ authorText.setVisible(extendedOn);
+ geoBox.setVisible(extendedOn);
+ authorLabel.setVisible(extendedOn);
+ createdDate.setVisible(extendedOn);
+ createdTime.setVisible(extendedOn);
+ createdLabel.setVisible(extendedOn);
+ alteredLabel.setVisible(extendedOn);
+ alteredDate.setVisible(extendedOn);
+ alteredTime.setVisible(extendedOn);
+ //notebookBox.setVisible(extendedOn);
+ notebookLabel.setVisible(extendedOn);
+ subjectLabel.setVisible(extendedOn);
+ subjectDate.setVisible(extendedOn);
+ subjectTime.setVisible(extendedOn);
+ }
+
+ public void hideButtons() {
+
+ undoButton.parentWidget().setVisible(false);
+ buttonsVisible = false;
+ }
+
+
+ // Is the extended view on?
+ public boolean isExtended() {
+ return extendedOn;
+ }
+
+ // Listener for when a link is clicked
+ @SuppressWarnings("unused")
+ private void openFile() {
+ logger.log(logger.EXTREME, "Starting openFile()");
+ File fileHandle = new File(selectedFile);
+ URI fileURL = fileHandle.toURI();
+ String localURL = fileURL.toString();
+ QUrl url = new QUrl(localURL);
+ QFile file = new QFile(selectedFile);
+
+ logger.log(logger.EXTREME, "Adding to fileWatcher:"+file.fileName());
+ fileWatcher.addPath(file.fileName());
+
+ if (!QDesktopServices.openUrl(url)) {
+ logger.log(logger.LOW, "Error opening file :" +url);
+ }
+ }
+
+
+ // Listener for when a link is clicked
+ @SuppressWarnings("unused")
+ private void linkClicked(QUrl url) {
+ logger.log(logger.EXTREME, "URL Clicked: " +url.toString());
+ if (url.toString().startsWith("latex:")) {
+ int position = url.toString().lastIndexOf(".");
+ String guid = url.toString().substring(0,position);
+ position = guid.lastIndexOf("/");
+ guid = guid.substring(position+1);
+ editLatex(guid);
+ return;
+ }
+ if (url.toString().startsWith("evernote:/view/")) {
+ StringTokenizer tokens = new StringTokenizer(url.toString().replace("evernote:/view/", ""), "/");
+ tokens.nextToken();
+ tokens.nextToken();
+ String sid = tokens.nextToken();
+ String lid = tokens.nextToken();
+
+ // Emit that we want to switch to a new note
+ evernoteLinkClicked.emit(sid, lid);
+
+ return;
+ }
+ if (url.toString().startsWith("nnres://")) {
+ logger.log(logger.EXTREME, "URL is NN resource");
+ if (url.toString().endsWith("/vnd.evernote.ink")) {
+ logger.log(logger.EXTREME, "Unable to open ink note");
+ QMessageBox.information(this, tr("Unable Open"), tr("This is an ink note.\n"+
+ "Ink notes are not supported since Evernote has not\n published any specifications on them\n" +
+ "and I'm too lazy to figure them out by myself."));
+ return;
+ }
+ String fullName = url.toString().substring(8);
+ int index = fullName.indexOf(".");
+ String guid = "";
+ String type = "";
+ if (index >-1) {
+ type = fullName.substring(index+1);
+ guid = fullName.substring(0,index);
+ }
+ index = guid.indexOf(Global.attachmentNameDelimeter);
+ if (index > -1) {
+ guid = guid.substring(0,index);
+ }
+ List<Resource> resList = currentNote.getResources();
+ Resource res = null;
+ for (int i=0; i<resList.size(); i++) {
+ if (resList.get(i).getGuid().equals(guid)) {
+ res = resList.get(i);
+ i=resList.size();
+ }
+ }
+ if (res == null) {
+ String resGuid = Global.resourceMap.get(guid);
+ if (resGuid != null)
+ res = conn.getNoteTable().noteResourceTable.getNoteResource(resGuid, true);
+ }
+ if (res != null) {
+ String fileName;
+ if (res.getAttributes() != null &&
+ res.getAttributes().getFileName() != null &&
+ !res.getAttributes().getFileName().trim().equals(""))
+ fileName = res.getGuid()+Global.attachmentNameDelimeter+res.getAttributes().getFileName();
+ else
+ fileName = res.getGuid()+"."+type;
+ QFile file = new QFile(Global.getFileManager().getResDirPath(fileName));
+ QFile.OpenMode mode = new QFile.OpenMode();
+ mode.set(QFile.OpenModeFlag.WriteOnly);
+ boolean openResult = file.open(mode);
+ logger.log(logger.EXTREME, "File opened:" +openResult);
+ QDataStream out = new QDataStream(file);
+ Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(res.getGuid(), true);
+ QByteArray binData = new QByteArray(resBinary.getData().getBody());
+ resBinary = null;
+ logger.log(logger.EXTREME, "Writing resource");
+ out.writeBytes(binData.toByteArray());
+ file.close();
+
+ String whichOS = System.getProperty("os.name");
+ if (whichOS.contains("Windows"))
+ url.setUrl("file:///"+file.fileName());
+ else
+ url.setUrl("file://"+file.fileName());
+ // fileWatcher.removePath(file.fileName());
+ logger.log(logger.EXTREME, "Adding file watcher " +file.fileName());
+ fileWatcher.addPath(file.fileName());
+
+ // If we can't open it, then prompt the user to save it.
+ if (!QDesktopServices.openUrl(url)) {
+ logger.log(logger.EXTREME, "We can't handle this. Where do we put it?");
+ QFileDialog dialog = new QFileDialog();
+ dialog.show();
+ if (dialog.exec()!=0) {
+ List<String> fileNames = dialog.selectedFiles(); //gets all selected filenames
+ if (fileNames.size() == 0)
+ return;
+ String sf = fileNames.get(0);
+ QFile saveFile = new QFile(sf);
+ mode.set(QFile.OpenModeFlag.WriteOnly);
+ saveFile.open(mode);
+ QDataStream saveOut = new QDataStream(saveFile);
+ saveOut.writeBytes(binData.toByteArray());
+ saveFile.close();
+ return;
+ }
+ }
+ }
+ return;
+ }
+ logger.log(logger.EXTREME, "Launching URL");
+ QDesktopServices.openUrl(url);
+ }
+
+ // Listener for when BOLD is clicked
+ @SuppressWarnings("unused")
+ private void undoClicked() {
+ browser.page().triggerAction(WebAction.Undo);
+ browser.setFocus();
+ }
+
+ // Listener for when BOLD is clicked
+ @SuppressWarnings("unused")
+ private void redoClicked() {
+ browser.page().triggerAction(WebAction.Redo);
+ browser.setFocus();
+ }
+
+ // Listener for when BOLD is clicked
+ @SuppressWarnings("unused")
+ private void boldClicked() {
+ browser.page().triggerAction(WebAction.ToggleBold);
+ microFocusChanged();
+ browser.setFocus();
+ }
+
+ // Listener for when Italics is clicked
+ @SuppressWarnings("unused")
+ private void italicClicked() {
+ browser.page().triggerAction(WebAction.ToggleItalic);
+ microFocusChanged();
+ browser.setFocus();
+ }
+
+ // Listener for when UNDERLINE is clicked
+ @SuppressWarnings("unused")
+ private void underlineClicked() {
+ browser.page().triggerAction(WebAction.ToggleUnderline);
+ microFocusChanged();
+ browser.setFocus();
+ }
+
+ // Listener for when Strikethrough is clicked
+ @SuppressWarnings("unused")
+ private void strikethroughClicked() {
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('strikeThrough', false, '');");
+ browser.setFocus();
+ }
+
+ // Listener for when cut is clicked
+ @SuppressWarnings("unused")
+ private void cutClicked() {
+ // ICHANGED
+ cbObserver.setCopySourceGuid(currentNote.getGuid(), browser.page().selectedText());
+
+ browser.page().triggerAction(WebAction.Cut);
+ browser.setFocus();
+ }
+
+ // Listener when COPY is clicked
+ @SuppressWarnings("unused")
+ private void copyClicked() {
+ // ICHANGED
+ cbObserver.setCopySourceGuid(currentNote.getGuid(), browser.page().selectedText());
+
+ browser.page().triggerAction(WebAction.Copy);
+ browser.setFocus();
+ }
+
+ // Listener when PASTE is clicked
+ public void pasteClicked() {
+ logger.log(logger.EXTREME, "Paste Clicked");
+ if (forceTextPaste) {
+ pasteWithoutFormattingClicked();
+ return;
+ }
+
+ // ICHANGED コピー&ペーストの操作履歴をデータベースに登録
+ String srcGuid = cbObserver.getSourceGuid();
+ String dstGuid = currentNote.getGuid();
+ if(srcGuid != null && dstGuid != null){
+ if(!srcGuid.equals(dstGuid)){
+ conn.getHistoryTable().addHistory("copy & paste", srcGuid, dstGuid);
+ }
+ }
+
+ QClipboard clipboard = QApplication.clipboard();
+ QMimeData mime = clipboard.mimeData();
+
+ if (mime.hasImage()) {
+ logger.log(logger.EXTREME, "Image paste found");
+ browser.setFocus();
+ insertImage(mime);
+ browser.setFocus();
+ return;
+ }
+
+ if (mime.hasUrls()) {
+ logger.log(logger.EXTREME, "URL paste found");
+ if (mime.text().startsWith("evernote:")) {
+ handleNoteLink(mime);
+ } else {
+ handleUrls(mime);
+ browser.setFocus();
+ }
+ return;
+ }
+
+ String text = mime.html();
+ if (text.contains("en-tag") && mime.hasHtml()) {
+ logger.log(logger.EXTREME, "Intra-note paste found");
+ text = fixInternotePaste(text);
+ mime.setHtml(text);
+ clipboard.setMimeData(mime);
+ }
+
+ logger.log(logger.EXTREME, "Final paste choice encountered");
+ browser.page().triggerAction(WebAction.Paste);
+ browser.setFocus();
+
+ }
+
+ // Paste text without formatting
+ private void pasteWithoutFormattingClicked() {
+ logger.log(logger.EXTREME, "Paste without format clipped");
+ QClipboard clipboard = QApplication.clipboard();
+ QMimeData mime = clipboard.mimeData();
+ if (!mime.hasText())
+ return;
+
+ // ICHANGED コピー&ペーストの操作履歴をデータベースに登録
+ String srcGuid = cbObserver.getSourceGuid();
+ String dstGuid = currentNote.getGuid();
+ if(srcGuid != null && dstGuid != null){
+ if(!srcGuid.equals(dstGuid)){
+ conn.getHistoryTable().addHistory("copy & paste", srcGuid, dstGuid);
+ }
+ }
+
+ String text = mime.text();
+ clipboard.clear();
+ clipboard.setText(text, Mode.Clipboard);
+ browser.page().triggerAction(WebAction.Paste);
+
+ // This is done because pasting into an encryption block
+ // can cause multiple cells (which can't happen). It
+ // just goes through the table, extracts the data, &
+ // puts it back as one table cell.
+ if (insideEncryption) {
+ String js = new String( "function fixEncryption() { "
+ +" var selObj = window.getSelection();"
+ +" var selRange = selObj.getRangeAt(0);"
+ +" var workingNode = window.getSelection().anchorNode;"
+ +" while(workingNode != null && workingNode.nodeName.toLowerCase() != 'table') { "
+ +" workingNode = workingNode.parentNode;"
+ +" } "
+ +" workingNode.innerHTML = window.jambi.fixEncryptionPaste(workingNode.innerHTML);"
+ +"} fixEncryption();");
+ browser.page().mainFrame().evaluateJavaScript(js);
+ }
+ }
+
+ // This basically removes all the table tags and returns just the contents.
+ // This is called by JavaScript to fix encryption pastes.
+ public String fixEncryptionPaste(String data) {
+ data = data.replace("<tbody>", "");
+ data = data.replace("</tbody>", "");
+ data = data.replace("<tr>", "");
+ data = data.replace("</tr>", "");
+ data = data.replace("<td>", "");
+ data = data.replace("</td>", "<br>");
+ data = data.replace("<br><br>", "<br>");
+
+ return "<tbody><tr><td>"+data+"</td></tr></tbody>";
+ }
+
+ // insert date/time
+ @SuppressWarnings("unused")
+ private void insertDateTime() {
+ String fmt = Global.getDateFormat() + " " + Global.getTimeFormat();
+ String dateTimeFormat = new String(fmt);
+ SimpleDateFormat simple = new SimpleDateFormat(dateTimeFormat);
+ Calendar cal = Calendar.getInstance();
+
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('insertHtml', false, '"+simple.format(cal.getTime())+"');");
+
+ browser.setFocus();
+
+ }
+
+ // Listener when Left is clicked
+ @SuppressWarnings("unused")
+ private void justifyLeftClicked() {
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('JustifyLeft', false, '');");
+ browser.setFocus();
+ }
+
+ // Listener when Center is clicked
+ @SuppressWarnings("unused")
+ private void justifyCenterClicked() {
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('JustifyCenter', false, '');");
+ browser.setFocus();
+ }
+
+ // Listener when Left is clicked
+ @SuppressWarnings("unused")
+ private void justifyRightClicked() {
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('JustifyRight', false, '');");
+ browser.setFocus();
+ }
+
+ // Listener when HLINE is clicked
+ @SuppressWarnings("unused")
+ private void hlineClicked() {
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('insertHorizontalRule', false, '');");
+ browser.setFocus();
+ }
+
+ // Listener when outdent is clicked
+ private void outdentClicked() {
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('outdent', false, '');");
+ browser.setFocus();
+ }
+
+ // Listener when a bullet list is clicked
+ @SuppressWarnings("unused")
+ private void bulletListClicked() {
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('InsertUnorderedList', false, '');");
+ browser.setFocus();
+ }
+
+ // Listener when a bullet list is clicked
+ @SuppressWarnings("unused")
+ private void numberListClicked() {
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('InsertOrderedList', false, '');");
+ browser.setFocus();
+ }
+
+ // Listener when indent is clicked
+ private void indentClicked() {
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('indent', false, '');");
+ browser.setFocus();
+ }
+
+ // Listener when the font name is changed
+ @SuppressWarnings("unused")
+ private void fontChanged(String font) {
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('fontName',false,'" + font + "');");
+ browser.setFocus();
+ }
+
+ // Listener when a font size is changed
+ @SuppressWarnings("unused")
+ private void fontSizeChanged(String font) {
+ String text = browser.selectedText();
+ if (text.trim().equalsIgnoreCase(""))
+ return;
+
+ String selectedText = browser.selectedText();
+ String url = "<span style=\"font-size:" +font +"pt; \">"+selectedText +"</a>";
+ String script = "document.execCommand('insertHtml', false, '"+url+"');";
+ browser.page().mainFrame().evaluateJavaScript(script);
+/* browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('fontSize',false,'"
+ + font + "');");
+*/
+ browser.setFocus();
+ }
+
+ // Load the font combo box based upon the font selected
+ private void loadFontSize(String name) {
+ QFontDatabase db = new QFontDatabase();
+ fontSize.clear();
+ List<Integer> points = db.pointSizes(name);
+ for (int i=0; i<points.size(); i++) {
+ fontSize.addItem(points.get(i).toString());
+ }
+ /*
+ fontSize.addItem("x-small");
+ fontSize.addItem("small");
+ fontSize.addItem("medium");
+ fontSize.addItem("large");
+ fontSize.addItem("x-large");
+ fontSize.addItem("xx-large");
+ fontSize.addItem("xxx-large");
+ */
+ }
+
+ // Listener when a font size is changed
+ @SuppressWarnings("unused")
+ private void fontColorClicked() {
+// QColorDialog dialog = new QColorDialog();
+// QColor color = QColorDialog.getColor();
+ QColor color = fontColorMenu.getColor();
+ if (color.isValid())
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('foreColor',false,'" + color.name()
+ + "');");
+ browser.setFocus();
+ }
+
+ // Listener for when a background color change is requested
+ @SuppressWarnings("unused")
+ private void fontHilightClicked() {
+// QColorDialog dialog = new QColorDialog();
+// QColor color = QColorDialog.getColor();
+ QColor color = fontHilightColorMenu.getColor();
+ if (color.isValid())
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('backColor',false,'" + color.name()
+ + "');");
+ browser.setFocus();
+ }
+
+ // Listener for when a background color change is requested
+ @SuppressWarnings("unused")
+ private void superscriptClicked() {
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('superscript');");
+ browser.setFocus();
+ }
+
+ // Listener for when a background color change is requested
+ @SuppressWarnings("unused")
+ private void subscriptClicked() {
+ browser.page().mainFrame().evaluateJavaScript(
+ "document.execCommand('subscript');");
+ browser.setFocus();
+ }
+ // Insert a to-do checkbox
+ @SuppressWarnings("unused")
+ private void todoClicked() {
+ FileNameMap fileNameMap = URLConnection.getFileNameMap();
+ String script_start = new String(
+ "document.execCommand('insertHtml', false, '");
+ String script_end = new String("');");
+ String todo = new String(
+ "<input TYPE=\"CHECKBOX\" value=\"false\" " +
+ "onMouseOver=\"style.cursor=\\'hand\\'\" " +
+ "onClick=\"value=checked; window.jambi.contentChanged(); \" />");
+ browser.page().mainFrame().evaluateJavaScript(
+ script_start + todo + script_end);
+ browser.setFocus();
+ }
+
+ // Encrypt the selected text
+ @SuppressWarnings("unused")
+ private void encryptText() {
+ String text = browser.selectedText();
+ if (text.trim().equalsIgnoreCase(""))
+ return;
+ text = new String(text.replaceAll("\n", "<br/>"));
+
+ EnCryptDialog dialog = new EnCryptDialog();
+ dialog.exec();
+ if (!dialog.okPressed()) {
+ return;
+ }
+
+ EnCrypt crypt = new EnCrypt();
+ String encrypted = crypt.encrypt(text, dialog.getPassword().trim(), 64);
+ String decrypted = crypt.decrypt(encrypted, dialog.getPassword().trim(), 64);
+
+ if (encrypted.trim().equals("")) {
+ QMessageBox.information(this, tr("Error"), tr("Error Encrypting String"));
+ return;
+ }
+ StringBuffer buffer = new StringBuffer(encrypted.length() + 100);
+ buffer.append("<img en-tag=\"en-crypt\" cipher=\"RC2\" hint=\""
+ + dialog.getHint().replace("'","\\'") + "\" length=\"64\" ");
+ buffer.append("contentEditable=\"false\" alt=\"");
+ buffer.append(encrypted);
+ buffer.append("\" src=\"").append(FileUtils.toForwardSlashedPath(Global.getFileManager().getImageDirPath("encrypt.png") +"\""));
+ Global.cryptCounter++;
+ buffer.append(" id=\"crypt"+Global.cryptCounter.toString() +"\"");
+ buffer.append(" onMouseOver=\"style.cursor=\\'hand\\'\"");
+ buffer.append(" onClick=\"window.jambi.decryptText(\\'crypt"+Global.cryptCounter.toString()
+ +"\\', \\'"+encrypted+"\\', \\'"+dialog.getHint().replace("'", "\\&apos;")+"\\');\"");
+ buffer.append("style=\"display:block\" />");
+
+ String script_start = new String(
+ "document.execCommand('insertHtml', false, '");
+ String script_end = new String("');");
+ browser.page().mainFrame().evaluateJavaScript(
+ script_start + buffer.toString() + script_end);
+ }
+
+
+ // Insert a Quick hyperlink
+ public void insertQuickLink() {
+ logger.log(logger.EXTREME, "Inserting link");
+ String text = browser.selectedText();
+ if (text.trim().equalsIgnoreCase(""))
+ return;
+
+ // ICHANGED
+ NoteQuickLinkDialog dialog = new NoteQuickLinkDialog(logger, conn, text, cbObserver);
+
+ if (dialog.getResults().size() == 0) {
+ QMessageBox.critical(null, tr("No Matches Found") ,tr("No matching notes found."));
+ return;
+ }
+ if (dialog.getResults().size() > 1) {
+ dialog.exec();
+ if (!dialog.okPressed) {
+ logger.log(logger.EXTREME, "Insert link canceled");
+ return;
+ }
+ }
+
+ User user = Global.getUserInformation();
+ String dUrl = new String("evernote:///view/") + new String(user.getId() + "/" +user.getShardId() +"/"
+ +dialog.getSelectedNote()+"/"+dialog.getSelectedNote() +"/ " +"style=\"color:#69aa35\"");
+
+ String url = "<a title=\"" +dUrl
+ +"\" href=" +dUrl
+ +" >"+text +"</a>";
+ String script = "document.execCommand('insertHtml', false, '"+url+"');";
+ browser.page().mainFrame().evaluateJavaScript(script);
+ contentChanged();
+ }
+
+ // Insert a hyperlink
+ public void insertLink() {
+ logger.log(logger.EXTREME, "Inserting link");
+ String text = browser.selectedText();
+ if (text.trim().equalsIgnoreCase(""))
+ return;
+
+ InsertLinkDialog dialog = new InsertLinkDialog(insertHyperlink);
+ if (currentHyperlink != null && currentHyperlink != "") {
+ dialog.setUrl(currentHyperlink);
+ }
+ dialog.exec();
+ if (!dialog.okPressed()) {
+ logger.log(logger.EXTREME, "Insert link canceled");
+ return;
+ }
+
+ // Take care of inserting new links
+ if (insertHyperlink) {
+ String selectedText = browser.selectedText();
+ if (dialog.getUrl().trim().equals(""))
+ return;
+ logger.log(logger.EXTREME, "Inserting link on text "+selectedText);
+ logger.log(logger.EXTREME, "URL Link " +dialog.getUrl().trim());
+ String dUrl = StringUtils.replace(dialog.getUrl().trim(), "'", "\\'");
+ String url = "<a href=\"" +dUrl
+ +"\" title=" +dUrl
+ +" >"+selectedText +"</a>";
+ String script = "document.execCommand('insertHtml', false, '"+url+"');";
+ browser.page().mainFrame().evaluateJavaScript(script);
+ return;
+ }
+
+ // Edit existing links
+ String js = new String( "function getCursorPos() {"
+ +"var cursorPos;"
+ +"if (window.getSelection) {"
+ +" var selObj = window.getSelection();"
+ +" var selRange = selObj.getRangeAt(0);"
+ +" var workingNode = window.getSelection().anchorNode.parentNode;"
+ +" while(workingNode != null) { "
+ +" if (workingNode.nodeName.toLowerCase()=='a') workingNode.setAttribute('href','" +dialog.getUrl() +"');"
+ +" workingNode = workingNode.parentNode;"
+ +" }"
+ +"}"
+ +"} getCursorPos();");
+ browser.page().mainFrame().evaluateJavaScript(js);
+
+ if (!dialog.getUrl().trim().equals("")) {
+ contentChanged();
+ return;
+ }
+
+ // Remove URL
+ js = new String( "function getCursorPos() {"
+ +"var cursorPos;"
+ +"if (window.getSelection) {"
+ +" var selObj = window.getSelection();"
+ +" var selRange = selObj.getRangeAt(0);"
+ +" var workingNode = window.getSelection().anchorNode.parentNode;"
+ +" while(workingNode != null) { "
+ +" if (workingNode.nodeName.toLowerCase()=='a') { "
+ +" workingNode.removeAttribute('href');"
+ +" workingNode.removeAttribute('title');"
+ +" var text = document.createTextNode(workingNode.innerText);"
+ +" workingNode.parentNode.insertBefore(text, workingNode);"
+ +" workingNode.parentNode.removeChild(workingNode);"
+ +" }"
+ +" workingNode = workingNode.parentNode;"
+ +" }"
+ +"}"
+ +"} getCursorPos();");
+ browser.page().mainFrame().evaluateJavaScript(js);
+
+ contentChanged();
+
+
+ }
+
+
+ // Insert a hyperlink
+ public void insertLatex() {
+ editLatex(null);
+ }
+ public void editLatex(String guid) {
+ logger.log(logger.EXTREME, "Inserting latex");
+ String text = browser.selectedText();
+ if (text.trim().equalsIgnoreCase("\n") || text.trim().equalsIgnoreCase("")) {
+ InsertLatexImage dialog = new InsertLatexImage();
+ if (guid != null) {
+ String formula = conn.getNoteTable().noteResourceTable.getNoteSourceUrl(guid).replace("http://latex.codecogs.com/gif.latex?", "");
+ dialog.setFormula(formula);
+ }
+ dialog.exec();
+ if (!dialog.okPressed()) {
+ logger.log(logger.EXTREME, "Edit LaTex canceled");
+ return;
+ }
+ text = dialog.getFormula().trim();
+ }
+ blockApplication.emit(this);
+ logger.log(logger.EXTREME, "Inserting LaTeX formula:" +text);
+ latexGuid = guid;
+ text = StringUtils.replace(text, "'", "\\'");
+ String url = "http://latex.codecogs.com/gif.latex?" +text;
+ logger.log(logger.EXTREME, "Sending request to codecogs --> " + url);
+ QNetworkAccessManager manager = new QNetworkAccessManager(this);
+ manager.finished.connect(this, "insertLatexImageReady(QNetworkReply)");
+ unblockTime = new GregorianCalendar().getTimeInMillis()+5000;
+ awaitingHttpResponse = true;
+ manager.get(new QNetworkRequest(new QUrl(url)));
+ }
+
+ public void insertLatexImageReady(QNetworkReply reply) {
+ logger.log(logger.EXTREME, "Response received from CodeCogs");
+ if (reply.error() != NetworkError.NoError)
+ return;
+
+ unblockTime = -1;
+ if (!awaitingHttpResponse)
+ return;
+
+ awaitingHttpResponse = false;
+ QUrl replyUrl = reply.url();
+ QByteArray image = reply.readAll();
+ reply.close();
+ logger.log(logger.EXTREME, "New image size: " +image.size());
+
+ Resource newRes = null;
+ QFile tfile;
+ String path;
+ if (latexGuid == null) {
+ logger.log(logger.EXTREME, "Creating temporary gif");
+ path = Global.getFileManager().getResDirPath("latex-temp.gif");
+ tfile = new QFile(path);
+ tfile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.WriteOnly));
+ logger.log(logger.EXTREME, "File Open: " +tfile.errorString());
+ tfile.write(image);
+ logger.log(logger.EXTREME, "Bytes writtes: "+tfile.size());
+ tfile.close();
+ logger.log(logger.EXTREME, "Creating resource");
+ int sequence = 0;
+ if (currentNote.getResources() != null || currentNote.getResources().size() > 0)
+ sequence = currentNote.getResources().size();
+ newRes = createResource(path,sequence ,"image/gif", false);
+ QImage pix = new QImage();
+ pix.loadFromData(image);
+ newRes.setHeight(new Integer(pix.height()).shortValue());
+ newRes.setWidth(new Integer(pix.width()).shortValue());
+ logger.log(logger.EXTREME, "Renaming temporary file to " +newRes.getGuid()+".gif");
+ path = Global.getFileManager().getResDirPath(newRes.getGuid()+".gif");
+ tfile.rename(path);
+ } else {
+ newRes = conn.getNoteTable().noteResourceTable.getNoteResource(latexGuid, false);
+ path = Global.getFileManager().getResDirPath(newRes.getGuid()+".gif");
+ tfile = new QFile(path);
+ tfile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.WriteOnly));
+ tfile.write(image);
+ tfile.close();
+ newRes.getData().setBody(image.toByteArray());
+ // Calculate the new hash value
+ MessageDigest md;
+
+ logger.log(logger.EXTREME, "Generating MD5");
+ try {
+ md = MessageDigest.getInstance("MD5");
+ md.update(image.toByteArray());
+ byte[] hash = md.digest();
+ newRes.getData().setBodyHash(hash);
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ }
+ QImage pix = new QImage();
+ pix.loadFromData(image);
+ newRes.setHeight(new Integer(pix.height()).shortValue());
+ newRes.setWidth(new Integer(pix.width()).shortValue());
+ conn.getNoteTable().noteResourceTable.updateNoteResource(newRes, true);
+ }
+
+ logger.log(logger.EXTREME, "Setting source: " +replyUrl.toString());
+ newRes.getAttributes().setSourceURL(replyUrl.toString());
+ conn.getNoteTable().noteResourceTable.updateNoteSourceUrl(newRes.getGuid(), replyUrl.toString(), true);
+
+ for(int i=0; i<currentNote.getResourcesSize(); i++) {
+ if (currentNote.getResources().get(i).getGuid().equals(newRes.getGuid())) {
+ currentNote.getResources().remove(i);
+ i=currentNote.getResourcesSize();
+ }
+ }
+ currentNote.getResources().add(newRes);
+
+
+ // do the actual insert into the note. We only do this on new formulas.
+ if (latexGuid == null) {
+ StringBuffer buffer = new StringBuffer(100);
+ String formula = replyUrl.toString().toLowerCase().replace("http://latex.codecogs.com/gif.latex?", "");
+ buffer.append("<a href=\"latex://"+path.replace("\\", "/")+"\" title=\""+formula+"\""
+ +"><img src=\"");
+ buffer.append(path.replace("\\", "/"));
+ buffer.append("\" en-tag=\"en-latex\" type=\"image/gif\""
+ +" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\""
+ +" guid=\"" +newRes.getGuid() +"\""
+ + " /></a>");
+
+ String script_start = new String("document.execCommand('insertHTML', false, '");
+ String script_end = new String("');");
+ browser.page().mainFrame().evaluateJavaScript(
+ script_start + buffer + script_end);
+ } else {
+ HtmlTagModifier modifier = new HtmlTagModifier(getContent());
+ modifier.modifyLatexTagHash(newRes);
+ String newContent = modifier.getHtml();
+ setContent(new QByteArray(newContent));
+ }
+
+ logger.log(logger.EXTREME, "New HTML set\n" +browser.page().currentFrame().toHtml());
+ QWebSettings.setMaximumPagesInCache(0);
+ QWebSettings.setObjectCacheCapacities(0, 0, 0);
+
+ browser.page().mainFrame().setHtml(browser.page().mainFrame().toHtml());
+ browser.reload();
+ contentChanged();
+// resourceSignal.contentChanged.emit(path);
+ unblockTime = -1;
+ unblockApplication.emit();
+ return;
+
+ }
+
+
+
+ // Insert a table
+ public void insertTable() {
+ TableDialog dialog = new TableDialog();
+ dialog.exec();
+ if (!dialog.okPressed()) {
+ return;
+ }
+
+ int cols = dialog.getCols();
+ int rows = dialog.getRows();
+ int width = dialog.getWidth();
+ boolean percent = dialog.isPercent();
+
+ String newHTML = "<table border=\"1\" width=\"" +new Integer(width).toString();
+ if (percent)
+ newHTML = newHTML +"%";
+ newHTML = newHTML + "\"><tbody>";
+
+ for (int i=0; i<rows; i++) {
+ newHTML = newHTML +"<tr>";
+ for (int j=0; j<cols; j++) {
+ newHTML = newHTML +"<td> </td>";
+ }
+ newHTML = newHTML +"</tr>";
+ }
+ newHTML = newHTML+"</tbody></table>";
+
+ String script = "document.execCommand('insertHtml', false, '"+newHTML+"');";
+ browser.page().mainFrame().evaluateJavaScript(script);
+ }
+
+
+ // Text content changed
+ @SuppressWarnings("unused")
+ private void selectionChanged() {
+ browser.encryptAction.setEnabled(true);
+ browser.insertLinkAction.setEnabled(true);
+ browser.insertQuickLinkAction.setEnabled(true);
+ String scriptStart = "var selection_text = (window.getSelection()).toString();"
+ + "var range = (window.getSelection()).getRangeAt(0);"
+ + "var parent_html = range.commonAncestorContainer.innerHTML;"
+ + "if (parent_html == undefined) {window.jambi.saveSelectedText(selection_text); return;}"
+ + "var first_text = range.startContainer.nodeValue.substr(range.startOffset);"
+ + "var last_text = (range.endContainer.nodeValue).substring(0,range.endOffset);"
+ + "var start = parent_html.indexOf(first_text);"
+ + "var end = parent_html.indexOf(last_text,start+1)+last_text.length;"
+ + "var value = parent_html.substring(start,end);"
+ + "window.jambi.saveSelectedText(value);" ;
+ browser.page().mainFrame().evaluateJavaScript(scriptStart);
+
+ }
+
+ public void saveSelectedText(String text) {
+ boolean enabled = true;
+ if (text.trim().length() == 0)
+ enabled=false;
+ if (text.indexOf("en-tag=\"en-crypt\"") >= 0)
+ enabled=false;
+ if (text.indexOf("<img en-tag=\"en-media\"") >= 0)
+ enabled=false;
+ if (text.indexOf("<a en-tag=\"en-media\"") >= 0)
+ enabled=false;
+ if (text.indexOf("<input ") >= 0)
+ enabled=false;
+
+ browser.encryptAction.setEnabled(enabled);
+ browser.insertLinkAction.setEnabled(enabled);
+ browser.insertQuickLinkAction.setEnabled(enabled);
+// selectedText = text;
+ }
+
+ // Decrypt clicked text
+ public void decryptText(String id, String text, String hint) {
+ EnCrypt crypt = new EnCrypt();
+ String plainText = null;
+ Calendar currentTime = new GregorianCalendar();
+ Long l = new Long(currentTime.getTimeInMillis());
+ String slot = new String(Long.toString(l));
+
+ // First, try to decrypt with any keys we already have
+ for (int i=0; i<Global.passwordRemember.size(); i++) {
+ plainText = crypt.decrypt(text, Global.passwordRemember.get(i).getFirst(), 64);
+ if (plainText != null) {
+ slot = new String(Long.toString(l));
+ Global.passwordSafe.put(slot, Global.passwordRemember.get(i));
+ removeEncryption(id, plainText, false, slot);
+ return;
+ }
+ }
+
+
+ EnDecryptDialog dialog = new EnDecryptDialog();
+ dialog.setHint(hint);
+ while (plainText == null || !dialog.okPressed()) {
+ dialog.exec();
+ if (!dialog.okPressed()) {
+ return;
+ }
+ plainText = crypt.decrypt(text, dialog.getPassword().trim(), 64);
+ if (plainText == null) {
+ QMessageBox.warning(this, tr("Incorrect Password"), tr("The password entered is not correct"));
+ }
+ }
+ Pair<String,String> passwordPair = new Pair<String,String>();
+ passwordPair.setFirst(dialog.getPassword());
+ passwordPair.setSecond(dialog.getHint());
+ Global.passwordSafe.put(slot, passwordPair);
+// removeEncryption(id, plainText.replaceAll("\n", "<br/>"), dialog.permanentlyDecrypt(), slot);
+ removeEncryption(id, plainText, dialog.permanentlyDecrypt(), slot);
+ if (dialog.rememberPassword()) {
+ Pair<String, String> pair = new Pair<String,String>();
+ pair.setFirst(dialog.getPassword());
+ pair.setSecond(dialog.getHint());
+ Global.passwordRemember.add(pair);
+ }
+
+ }
+
+ // Get the editor tag line
+ public TagLineEdit getTagLine() {
+ return tagEdit;
+ }
+
+ // Modify a note's tags
+ @SuppressWarnings("unused")
+ private void modifyTags() {
+ TagAssign tagWindow = new TagAssign(allTags, currentTags, !conn.getNotebookTable().isLinked(currentNote.getNotebookGuid()));
+ tagWindow.exec();
+ if (tagWindow.okClicked()) {
+ currentTags.clear();
+ StringBuffer tagDisplay = new StringBuffer();
+
+ List<QListWidgetItem> newTags = tagWindow.getTagList()
+ .selectedItems();
+ for (int i = 0; i < newTags.size(); i++) {
+ currentTags.add(newTags.get(i).text());
+ tagDisplay.append(newTags.get(i).text());
+ if (i < newTags.size() - 1) {
+ tagDisplay.append(Global.tagDelimeter + " ");
+ }
+ }
+ tagEdit.setText(tagDisplay.toString());
+ noteSignal.tagsChanged.emit(currentNote.getGuid(), currentTags);
+ }
+ }
+
+ // Tag line has been modified by typing text
+ @SuppressWarnings("unused")
+ private void modifyTagsTyping() {
+ String completionText = "";
+ if (tagEdit.currentCompleterSelection != null && !tagEdit.currentCompleterSelection.equals("")) {
+ completionText = tagEdit.currentCompleterSelection;
+ tagEdit.currentCompleterSelection = "";
+ }
+
+ if (tagEdit.text().equalsIgnoreCase(saveTagList))
+ return;
+
+ // We know something has changed...
+ String oldTagArray[] = saveTagList.split(Global.tagDelimeter);
+ String newTagArray[];
+ if (!completionText.equals("")) {
+ String before = tagEdit.text().substring(0,tagEdit.cursorPosition());
+ int lastDelimiter = before.lastIndexOf(Global.tagDelimeter);
+ if (lastDelimiter > 0)
+ before = before.substring(0,before.lastIndexOf(Global.tagDelimeter));
+ else
+ before = "";
+ String after = tagEdit.text().substring(tagEdit.cursorPosition());
+ newTagArray = (before+Global.tagDelimeter+completionText+Global.tagDelimeter+after).split(Global.tagDelimeter);
+ }
+ else {
+ newTagArray = tagEdit.text().split(Global.tagDelimeter);
+ }
+
+ // Remove any traling or leading blanks
+ for (int i=0; i<newTagArray.length; i++)
+ newTagArray[i] = newTagArray[i].trim().replaceAll("^\\s+", "");;
+
+ // Remove any potential duplicates from the new list
+ for (int i=0; i<newTagArray.length; i++) {
+ boolean foundOnce = false;
+ for (int j=0; j<newTagArray.length; j++) {
+ if (newTagArray[j].equalsIgnoreCase(newTagArray[i])) {
+ if (!foundOnce) {
+ foundOnce = true;
+ } else
+ newTagArray[j] = "";
+ }
+ }
+ }
+
+ List<String> newTagList = new ArrayList<String>();
+ List<String> oldTagList = new ArrayList<String>();
+
+ for (int i = 0; i < oldTagArray.length; i++)
+ if (!oldTagArray[i].trim().equals(""))
+ oldTagList.add(oldTagArray[i]);
+ for (int i = 0; i < newTagArray.length; i++)
+ if (!newTagArray[i].trim().equals(""))
+ newTagList.add(newTagArray[i]);
+
+ if (conn.getNotebookTable().isLinked(currentNote.getNotebookGuid())) {
+ for (int i=newTagList.size()-1; i>=0; i--) {
+ boolean found = false;
+ for (int j=0; j<allTags.size(); j++) {
+ if (allTags.get(j).getName().equalsIgnoreCase(newTagList.get(i))) {
+ found = true;
+ j=allTags.size();
+ }
+ }
+ if (!found)
+ newTagList.remove(i);
+ }
+ }
+
+ // Let's cleanup the appearance of the tag list
+ Collections.sort(newTagList);
+ String newDisplay = "";
+ for (int i=0; i<newTagList.size(); i++) {
+ newDisplay = newDisplay+newTagList.get(i);
+ if (i<newTagList.size()-1)
+ newDisplay = newDisplay+Global.tagDelimeter +" ";
+ }
+ tagEdit.blockSignals(true);
+ tagEdit.setText(newDisplay);
+ tagEdit.blockSignals(false);
+
+ // We now have lists of the new & old. Remove duplicates. If all
+ // are removed from both then nothing has really changed
+ for (int i = newTagList.size() - 1; i >= 0; i--) {
+ String nTag = newTagList.get(i);
+ for (int j = oldTagList.size() - 1; j >= 0; j--) {
+ String oTag = oldTagList.get(j);
+ if (oTag.equalsIgnoreCase(nTag)) {
+ oldTagList.remove(j);
+ newTagList.remove(i);
+ j = -1;
+ }
+ }
+ }
+
+ if (oldTagList.size() != 0 || newTagList.size() != 0) {
+ currentTags.clear();
+ newTagArray = tagEdit.text().split(Global.tagDelimeter);
+ for (int i = 0; i < newTagArray.length; i++)
+ if (!newTagArray[i].trim().equals(""))
+ currentTags.add(newTagArray[i].trim());
+
+ noteSignal.tagsChanged.emit(currentNote.getGuid(), currentTags);
+ }
+
+ }
+
+ // Tab button was pressed
+ public void tabPressed() {
+ if (insideEncryption)
+ return;
+ if (!insideList && !insideTable) {
+ String script_start = new String(
+ "document.execCommand('insertHtml', false, ' ');");
+ browser.page().mainFrame().evaluateJavaScript(script_start);
+ return;
+ }
+ if (insideList) {
+ indentClicked();
+ }
+ if (insideTable) {
+ String js = new String( "function getCursorPosition() { "
+ +" var selObj = window.getSelection();"
+ +" var selRange = selObj.getRangeAt(0);"
+ +" var workingNode = window.getSelection().anchorNode;"
+ +" var rowCount = 0;"
+ +" var colCount = 0;"
+ +" while(workingNode != null && workingNode.nodeName.toLowerCase() != 'table') { "
+ +" if (workingNode.nodeName.toLowerCase()=='tr') {"
+ +" rowCount = rowCount+1;"
+ +" }"
+ +" if (workingNode.nodeName.toLowerCase() == 'td') {"
+ +" colCount = colCount+1;"
+ +" }"
+ +" if (workingNode.previousSibling != null)"
+ +" workingNode = workingNode.previousSibling;"
+ +" else "
+ +" workingNode = workingNode.parentNode;"
+ +" }"
+ +" var nodes = workingNode.getElementsByTagName('tr');"
+ +" var tableRows = nodes.length;"
+ +" nodes = nodes[0].getElementsByTagName('td');"
+ +" var tableColumns = nodes.length;"
+ +" window.jambi.setTableCursorPositionTab(rowCount, colCount, tableRows, tableColumns);"
+ +"} getCursorPosition();");
+ browser.page().mainFrame().evaluateJavaScript(js);
+ }
+ }
+
+ // If a user presses tab from within a table
+ public void setTableCursorPositionTab(int currentRow, int currentCol, int tableRows, int tableColumns) {
+ if (tableRows == currentRow && currentCol == tableColumns) {
+ insertTableRow();
+ }
+ KeyboardModifiers modifiers = new KeyboardModifiers(KeyboardModifier.NoModifier);
+ QKeyEvent right = new QKeyEvent(Type.KeyPress, Qt.Key.Key_Right.value(), modifiers);
+ QKeyEvent end = new QKeyEvent(Type.KeyPress, Qt.Key.Key_End.value(), modifiers);
+ QKeyEvent end2 = new QKeyEvent(Type.KeyPress, Qt.Key.Key_End.value(), modifiers);
+ getBrowser().focusWidget();
+ QCoreApplication.postEvent(getBrowser(), end);
+ QCoreApplication.postEvent(getBrowser(), right);
+ QCoreApplication.postEvent(getBrowser(), end2);
+ }
+
+ public void backtabPressed() {
+ if (insideEncryption)
+ return;
+ if (insideList)
+ outdentClicked();
+ if (insideTable) {
+ String js = new String( "function getCursorPosition() { "
+ +" var selObj = window.getSelection();"
+ +" var selRange = selObj.getRangeAt(0);"
+ +" var workingNode = window.getSelection().anchorNode;"
+ +" var rowCount = 0;"
+ +" var colCount = 0;"
+ +" while(workingNode != null && workingNode.nodeName.toLowerCase() != 'table') { "
+ +" if (workingNode.nodeName.toLowerCase()=='tr') {"
+ +" rowCount = rowCount+1;"
+ +" }"
+ +" if (workingNode.nodeName.toLowerCase() == 'td') {"
+ +" colCount = colCount+1;"
+ +" }"
+ +" if (workingNode.previousSibling != null)"
+ +" workingNode = workingNode.previousSibling;"
+ +" else "
+ +" workingNode = workingNode.parentNode;"
+ +" }"
+ +" var nodes = workingNode.getElementsByTagName('tr');"
+ +" var tableRows = nodes.length;"
+ +" nodes = nodes[0].getElementsByTagName('td');"
+ +" var tableColumns = nodes.length;"
+ +" window.jambi.setTableCursorPositionBackTab(rowCount, colCount, tableRows, tableColumns);"
+ +"} getCursorPosition();");
+ browser.page().mainFrame().evaluateJavaScript(js);
+
+ }
+ }
+
+ // If a user presses backtab from within a table
+ public void setTableCursorPositionBackTab(int currentRow, int currentCol, int tableRows, int tableColumns) {
+ if (currentRow == 1 && currentCol == 1) {
+ return;
+ }
+ KeyboardModifiers modifiers = new KeyboardModifiers(KeyboardModifier.NoModifier);
+ QKeyEvent left = new QKeyEvent(Type.KeyPress, Qt.Key.Key_Left.value(), modifiers);
+ QKeyEvent home = new QKeyEvent(Type.KeyPress, Qt.Key.Key_Home.value(), modifiers);
+ getBrowser().focusWidget();
+ QCoreApplication.postEvent(getBrowser(), home);
+ QCoreApplication.postEvent(getBrowser(), left);
+ }
+
+
+ public void setInsideList() {
+ insideList = true;
+ }
+
+ // The title has been edited
+ @SuppressWarnings("unused")
+ private void titleEdited() {
+ // If we don't have a good note, or if the current title
+ // matches the old title then we don't need to do anything
+ if (currentNote == null)
+ return;
+ if (currentNote.getTitle().trim().equals(titleLabel.text().trim()))
+ return;
+
+ // If we have a real change, we need to save it.
+ String text = titleLabel.text().trim();
+ if (text.equals(""))
+ text = tr("Untitled Note");
+ noteSignal.titleChanged.emit(currentNote.getGuid(), text);
+ currentNote.setTitle(text);
+ saveNoteTitle = text;
+ checkNoteTitle();
+ }
+
+ // Set the list of note tags
+ public void setAllTags(List<Tag> l) {
+ allTags = l;
+ tagEdit.setTagList(l);
+ }
+
+ // Setter for the current tags
+ public void setCurrentTags(List<String> s) {
+ currentTags = s;
+ }
+
+ // Save the list of notebooks
+ public void setNotebookList(List<Notebook> n) {
+ notebookList = n;
+ loadNotebookList();
+ }
+
+ // Load the notebook list and select the current notebook
+ private void loadNotebookList() {
+ if (notebookBox.count() != 0)
+ notebookBox.clear();
+ if (notebookList == null)
+ return;
+
+ for (int i = 0; i < notebookList.size(); i++) {
+ notebookBox.addItem(notebookList.get(i).getName());
+ if (currentNote != null) {
+ if (currentNote.getNotebookGuid().equals(
+ notebookList.get(i).getGuid())) {
+ notebookBox.setCurrentIndex(i);
+ }
+ }
+ }
+ }
+
+
+ // Set the notebook for a note
+ public void setNotebook(String notebook) {
+ currentNote.setNotebookGuid(notebook);
+ loadNotebookList();
+ }
+
+ // Get the contents of the editor
+ public String getContent() {
+ return browser.page().currentFrame().toHtml();
+ }
+
+ // The note contents have changed
+ public void contentChanged() {
+ String content = getContent();
+
+ // This puts in a 1/2 second delay
+ // before updating the source editor.
+ // It improves response when someone is doing
+ // frequent updates on a large note.
+ // If the source editor isn't visible, then there
+ // is no point to doing any of this.
+ if (sourceEdit.isVisible()) {
+ setSourceTimer.stop();
+ setSourceTimer.setInterval(500);
+ setSourceTimer.setSingleShot(true);
+ setSourceTimer.start();
+ }
+
+ checkNoteTitle();
+ noteSignal.noteChanged.emit(currentNote.getGuid(), content);
+ }
+
+ // The notebook selection has changed
+ @SuppressWarnings("unused")
+ private void notebookChanged() {
+ boolean changed = false;
+ String n = notebookBox.currentText();
+ for (int i = 0; i < notebookList.size(); i++) {
+ if (n.equals(notebookList.get(i).getName())) {
+ if (!notebookList.get(i).getGuid().equals(currentNote.getNotebookGuid())) {
+ String guid = conn.getNotebookTable().findNotebookByName(n);
+ if (conn.getNotebookTable().isLinked(guid)) {
+ tagEdit.setText("");
+ noteSignal.tagsChanged.emit(currentNote.getGuid(), new ArrayList<String>());
+ FilterEditorTags t = new FilterEditorTags(conn, logger);
+ setAllTags(t.getValidTags(currentNote));
+ }
+ currentNote.setNotebookGuid(notebookList.get(i).getGuid());
+ changed = true;
+ }
+ i = notebookList.size();
+ }
+ }
+
+ // If the notebook changed, signal the update
+ if (changed)
+ noteSignal.notebookChanged.emit(currentNote.getGuid(), currentNote
+ .getNotebookGuid());
+ }
+
+ // Check the note title
+ private void checkNoteTitle() {
+ String text = browser.page().currentFrame().toPlainText();
+ if (saveNoteTitle == null)
+ saveNoteTitle = new String();
+ text = text.trim();
+ if (!saveNoteTitle.trim().equals("") && !saveNoteTitle.trim().equals("Untitled Note"))
+ text = saveNoteTitle.trim();
+ int newLine = text.indexOf("\n");
+ if (newLine > 0)
+ text = text.substring(0,newLine);
+ if (saveNoteTitle.trim().equals("") || saveNoteTitle.trim().equals("Untitled Note")) {
+ if (text.trim().equals(""))
+ text = tr("Untitled Note");
+ titleLabel.setText(text);
+ } else {
+ if (text.length() > Constants.EDAM_NOTE_TITLE_LEN_MAX)
+ titleLabel.setText(text.substring(0, Constants.EDAM_NOTE_TITLE_LEN_MAX));
+ else {
+ titleLabel.blockSignals(true);
+ if (text.trim().equals(""))
+ titleLabel.setText(tr("Untitled Note"));
+ else
+ titleLabel.setText(text);
+ titleLabel.blockSignals(false);
+ }
+ }
+ if (currentNote != null && titleLabel != null && !currentNote.getTitle().equals(text))
+ noteSignal.titleChanged.emit(currentNote.getGuid(), text);
+ }
+
+ // Return the note contents so we can email them
+ public String getContentsToEmail() {
+ return browser.page().currentFrame().toPlainText().trim();
+ /*
+ * int body = browser.page().currentFrame().toHtml().indexOf("<body>");
+ * String temp = browser.page().currentFrame().toHtml(); if (body == -1)
+ * temp = "<html><body><b>Test</b></body></html>"; else temp =
+ * "<html>"+temp.substring(body); return temp; // return
+ * urlEncode(browser.page().currentFrame().toHtml());
+ */
+ }
+
+ // Insert an image into the editor
+ private void insertImage(QMimeData mime) {
+ logger.log(logger.EXTREME, "Entering insertImage");
+ QImage img = (QImage) mime.imageData();
+ String script_start = new String(
+ "document.execCommand('insertHTML', false, '");
+ String script_end = new String("');");
+
+ long now = new Date().getTime();
+ String path = Global.getFileManager().getResDirPath(
+ (new Long(now).toString()) + ".jpg");
+
+ // This block is just a hack to make sure we wait at least 1ms so we
+ // don't
+ // have collisions on image names
+ long i = new Date().getTime();
+ while (now == i)
+ i = new Date().getTime();
+
+ // Open the file & write the data
+ QFile tfile = new QFile(path);
+ tfile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.WriteOnly));
+ if (!img.save(tfile)) {
+ tfile.close();
+ return;
+ }
+ tfile.close();
+
+ Resource newRes = createResource(QUrl.fromLocalFile(path).toString(), 0, "image/jpeg", false);
+ if (newRes == null)
+ return;
+ currentNote.getResources().add(newRes);
+
+ // do the actual insert into the note
+ StringBuffer buffer = new StringBuffer(100);
+ buffer.append("<img src=\"");
+ buffer.append(tfile.fileName());
+ buffer.append("\" en-tag=en-media type=\"image/jpeg\""
+ +" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\""
+ +" guid=\"" +newRes.getGuid() +"\""
+ +" onContextMenu=\"window.jambi.imageContextMenu(&." +tfile.fileName() +"&.);\""
+ + " />");
+
+ browser.page().mainFrame().evaluateJavaScript(
+ script_start + buffer + script_end);
+
+ return;
+ }
+
+ // Handle pasting of a note-to-note link
+ private void handleNoteLink(QMimeData mime) {
+ for (int i=0; i<mime.urls().size(); i++) {
+ StringTokenizer tokens = new StringTokenizer(mime.urls().get(i).toString().replace("evernote:///view/", ""), "/");
+ tokens.nextToken();
+ tokens.nextToken();
+ String sid = tokens.nextToken();
+ String lid = tokens.nextToken();
+
+ if (!sid.equals(currentNote.getGuid()) && !lid.equals(currentNote.getGuid())) {
+
+ Note note = conn.getNoteTable().getNote(sid, false, false, false, false, false);
+ if (note == null)
+ note = conn.getNoteTable().getNote(lid, false, false, false, false, false);
+
+ if (note == null)
+ return;
+
+ // If we've gotten this far, we have a bunch of values. We need to build the link.
+ StringBuffer url = new StringBuffer(100);
+ String script_start = new String(
+ "document.execCommand('insertHtml', false, '");
+ String script_end = new String("');");
+
+ url.append("<a href=\""+mime.urls().get(i).toString() +"\" style=\"color:#69aa35\">");
+ url.append(note.getTitle());
+ url.append("</a>");
+ if (mime.urls().size() > 1)
+ url.append(" ");
+ browser.page().mainFrame().evaluateJavaScript(
+ script_start + url + script_end);
+ }
+ }
+ }
+
+ // Handle URLs that are trying to be pasted
+ public void handleUrls(QMimeData mime) {
+ logger.log(logger.EXTREME, "Starting handleUrls");
+ FileNameMap fileNameMap = URLConnection.getFileNameMap();
+
+ List<QUrl> urlList = mime.urls();
+ String url = new String();
+ String script_start = new String(
+ "document.execCommand('createLink', false, '");
+ String script_end = new String("');");
+
+ for (int i = 0; i < urlList.size(); i++) {
+ url = urlList.get(i).toString();
+ // Find out what type of file we have
+ String mimeType = fileNameMap.getContentTypeFor(url);
+
+ // If null returned, we need to guess at the file type
+ if (mimeType == null)
+ mimeType = "application/"
+ + url.substring(url.lastIndexOf(".") + 1);
+
+ // Check if we have an image or some other type of file
+ if (url.substring(0, 5).equalsIgnoreCase("file:")
+ && mimeType.substring(0, 5).equalsIgnoreCase("image")) {
+ handleLocalImageURLPaste(mime, mimeType);
+ return;
+ }
+
+ boolean smallEnough = checkFileAttachmentSize(url);
+ if (smallEnough
+ && url.substring(0, 5).equalsIgnoreCase("file:")
+ && !mimeType.substring(0, 5).equalsIgnoreCase("image")) {
+ handleLocalAttachment(mime, mimeType);
+ return;
+ }
+ browser.page().mainFrame().evaluateJavaScript(
+ script_start + url + script_end);
+ }
+ return;
+ }
+
+ // If a URL being pasted is an image URL, then attach the image
+ private void handleLocalImageURLPaste(QMimeData mime, String mimeType) {
+ List<QUrl> urlList = mime.urls();
+ String url = new String();
+ String script_start_image = new String(
+ "document.execCommand('insertHtml', false, '");
+ String script_end = new String("');");
+ StringBuffer buffer;
+
+ // Copy the image over into the resource directory and create a new resource
+ // record for each url pasted
+ for (int i = 0; i < urlList.size(); i++) {
+ url = urlList.get(i).toString();
+
+ Resource newRes = createResource(url, i, mimeType, false);
+ if (newRes == null)
+ return;
+ currentNote.getResources().add(newRes);
+ buffer = new StringBuffer(100);
+
+ // Open the file & write the data
+ String fileName = Global.getFileManager().getResDirPath(newRes.getGuid());
+ QFile tfile = new QFile(fileName);
+ tfile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.WriteOnly));
+ tfile.write(newRes.getData().getBody());
+ tfile.close();
+ buffer.append(script_start_image);
+ buffer.append("<img src=\"" + FileUtils.toForwardSlashedPath(fileName));
+// if (mimeType.equalsIgnoreCase("image/jpg"))
+// mimeType = "image/jpeg";
+ buffer.append("\" en-tag=\"en-media\" type=\"" + mimeType +"\""
+ +" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\""
+ +" guid=\"" +newRes.getGuid() +"\""
+ +" onContextMenu=\"window.jambi.imageContextMenu('" +tfile.fileName() +"');\""
+ + " />");
+ buffer.append(script_end);
+ browser.page().mainFrame().evaluateJavaScript(buffer.toString());
+ }
+ return;
+ }
+
+
+ // If a URL being pasted is a local file URL, then attach the file
+ private void handleLocalAttachment(QMimeData mime, String mimeType) {
+ logger.log(logger.EXTREME, "Attaching local file");
+ List<QUrl> urlList = mime.urls();
+ String script_start = new String(
+ "document.execCommand('insertHtml', false, '");
+ String script_end = new String("');");
+ StringBuffer buffer;
+
+ String[] type = mimeType.split("/");
+ String icon = findIcon(type[1]);
+ if (icon.equals("attachment.png"))
+ icon = findIcon(type[0]);
+ buffer = new StringBuffer(100);
+
+ for (int i = 0; i < urlList.size(); i++) {
+ String url = urlList.get(i).toString();
+
+ // Start building the HTML
+ if (icon.equals("attachment.png"))
+ icon = findIcon(url.substring(url.lastIndexOf(".")+1));
+ String imageURL = FileUtils.toFileURLString(Global.getFileManager().getImageDirFile(icon));
+
+ logger.log(logger.EXTREME, "Creating resource ");
+ Resource newRes = createResource(url, i, mimeType, true);
+ if (newRes == null)
+ return;
+ logger.log(logger.EXTREME, "New resource size: " +newRes.getData().getSize());
+ currentNote.getResources().add(newRes);
+
+ String fileName = newRes.getGuid() + Global.attachmentNameDelimeter+newRes.getAttributes().getFileName();
+ // If we have a PDF, we need to setup the preview.
+ if (icon.equalsIgnoreCase("pdf.png") && Global.pdfPreview()) {
+ logger.log(logger.EXTREME, "Setting up PDF preview");
+ if (newRes.getAttributes() != null &&
+ newRes.getAttributes().getFileName() != null &&
+ !newRes.getAttributes().getFileName().trim().equals(""))
+ fileName = newRes.getGuid()+Global.attachmentNameDelimeter+
+ newRes.getAttributes().getFileName();
+ else
+ fileName = newRes.getGuid()+".pdf";
+ QFile file = new QFile(Global.getFileManager().getResDirPath(fileName));
+ QFile.OpenMode mode = new QFile.OpenMode();
+ mode.set(QFile.OpenModeFlag.WriteOnly);
+ file.open(mode);
+ QDataStream out = new QDataStream(file);
+// Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(newRes.getGuid(), true);
+ QByteArray binData = new QByteArray(newRes.getData().getBody());
+// resBinary = null;
+ out.writeBytes(binData.toByteArray());
+ file.close();
+
+ PDFPreview pdfPreview = new PDFPreview();
+ if (pdfPreview.setupPreview(Global.getFileManager().getResDirPath(fileName), "pdf",0)) {
+ imageURL = file.fileName() + ".png";
+ }
+ }
+
+ logger.log(logger.EXTREME, "Generating link tags");
+ buffer.delete(0, buffer.length());
+ buffer.append("<a en-tag=\"en-media\" guid=\"" +newRes.getGuid()+"\" ");
+ buffer.append(" onContextMenu=\"window.jambi.imageContextMenu('")
+ .append(Global.getFileManager().getResDirPath(fileName))
+ .append("');\" ");
+ buffer.append("type=\"" + mimeType + "\" href=\"nnres://" + fileName +"\" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\" >");
+ buffer.append("<img src=\"" + imageURL + "\" title=\"" +newRes.getAttributes().getFileName());
+ buffer.append("\"></img>");
+ buffer.append("</a>");
+ browser.page().mainFrame().evaluateJavaScript(
+ script_start + buffer.toString() + script_end);
+ }
+ return;
+ }
+
+ private Resource createResource(String url, int sequence, String mime, boolean attachment) {
+ logger.log(logger.EXTREME, "Inside create resource");
+ QFile resourceFile;
+ //These two lines are added to handle odd characters in the name like #. Without it
+ // toLocalFile() chokes and returns the wrong name.
+ logger.log(logger.EXTREME, "File URL:" +url);
+ String whichOS = System.getProperty("os.name");
+ if (whichOS.contains("Windows"))
+ url = url.replace("file:///", "");
+ else
+ url = url.replace("file://", "");
+ String urlTest = new QUrl(url).toLocalFile();
+ logger.log(logger.EXTREME, "File URL toLocalFile():" +urlTest);
+ urlTest = url;
+ if (!urlTest.equals(""))
+ url = urlTest;
+// url = url.replace("/", File.separator);
+ logger.log(logger.EXTREME, "Reading from file to create resource:" +url);
+ resourceFile = new QFile(url);
+ resourceFile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly));
+ logger.log(logger.EXTREME, "Error opening file "+url.toString() +": "+resourceFile.errorString());
+ byte[] fileData = resourceFile.readAll().toByteArray();
+ resourceFile.close();
+ logger.log(logger.EXTREME, "File Length: " +fileData.length);
+ if (fileData.length == 0)
+ return null;
+ MessageDigest md;
+ try {
+ logger.log(logger.EXTREME, "Generating MD5");
+ md = MessageDigest.getInstance("MD5");
+ md.update(fileData);
+ byte[] hash = md.digest();
+
+ Resource r = new Resource();
+ Calendar time = new GregorianCalendar();
+ long prevTime = time.getTimeInMillis();
+ while (prevTime == time.getTimeInMillis()) {
+ time = new GregorianCalendar();
+ }
+ r.setGuid(time.getTimeInMillis()+new Integer(sequence).toString());
+ r.setNoteGuid(currentNote.getGuid());
+ r.setMime(mime);
+ r.setActive(true);
+ r.setUpdateSequenceNum(0);
+ r.setWidth((short) 0);
+ r.setHeight((short) 0);
+ r.setDuration((short) 0);
+
+ Data d = new Data();
+ d.setBody(fileData);
+ d.setBodyIsSet(true);
+ d.setBodyHash(hash);
+ d.setBodyHashIsSet(true);
+ r.setData(d);
+ d.setSize(fileData.length);
+
+ int fileNamePos = url.lastIndexOf(File.separator);
+ if (fileNamePos == -1)
+ fileNamePos = url.lastIndexOf("/");
+ String fileName = url.substring(fileNamePos+1);
+ ResourceAttributes a = new ResourceAttributes();
+ a.setAltitude(0);
+ a.setAltitudeIsSet(false);
+ a.setLongitude(0);
+ a.setLongitudeIsSet(false);
+ a.setLatitude(0);
+ a.setLatitudeIsSet(false);
+ a.setCameraMake("");
+ a.setCameraMakeIsSet(false);
+ a.setCameraModel("");
+ a.setCameraModelIsSet(false);
+ a.setAttachment(attachment);
+ a.setAttachmentIsSet(true);
+ a.setClientWillIndex(false);
+ a.setClientWillIndexIsSet(true);
+ a.setRecoType("");
+ a.setRecoTypeIsSet(false);
+ a.setSourceURL(url);
+ a.setSourceURLIsSet(true);
+ a.setTimestamp(0);
+ a.setTimestampIsSet(false);
+ a.setFileName(fileName);
+ a.setFileNameIsSet(true);
+ r.setAttributes(a);
+
+ conn.getNoteTable().noteResourceTable.saveNoteResource(r, true);
+ logger.log(logger.EXTREME, "Resource created");
+ return r;
+ } catch (NoSuchAlgorithmException e1) {
+ e1.printStackTrace();
+ }
+ return null;
+ }
+
+
+ // find the appropriate icon for an attachment
+ private String findIcon(String appl) {
+ appl = appl.toLowerCase();
+ File f = Global.getFileManager().getImageDirFile(appl + ".png");
+ if (f.exists())
+ return appl+".png";
+ return "attachment.png";
+ }
+
+
+
+ // Check the file attachment to be sure it isn't over 25 mb
+ private boolean checkFileAttachmentSize(String url) {
+ String fileName = url.substring(8);
+ QFile resourceFile = new QFile(fileName);
+ resourceFile.open(new QIODevice.OpenMode(
+ QIODevice.OpenModeFlag.ReadOnly));
+ long size = resourceFile.size();
+ resourceFile.close();
+ size = size / 1024 / 1024;
+ if (size < 50 && Global.isPremium())
+ return true;
+ if (size < 25)
+ return true;
+
+ String error = tr("A file attachment may not exceed 25MB.");
+ QMessageBox.information(this, tr("Attachment Size"), error);
+ return false;
+ }
+
+
+ @SuppressWarnings("unused")
+ private void createdChanged() {
+ QDateTime dt = new QDateTime();
+ dt.setDate(createdDate.date());
+ dt.setTime(createdTime.time());
+ noteSignal.createdDateChanged.emit(currentNote.getGuid(), dt);
+
+ }
+
+ @SuppressWarnings("unused")
+ private void alteredChanged() {
+ QDateTime dt = new QDateTime();
+ dt.setDate(alteredDate.date());
+ dt.setTime(alteredTime.time());
+ noteSignal.alteredDateChanged.emit(currentNote.getGuid(), dt);
+ }
+
+ @SuppressWarnings("unused")
+ private void subjectDateTimeChanged() {
+ QDateTime dt = new QDateTime();
+ dt.setDate(subjectDate.date());
+ dt.setTime(subjectTime.time());
+ noteSignal.subjectDateChanged.emit(currentNote.getGuid(), dt);
+
+ }
+
+ @SuppressWarnings("unused")
+ private void sourceUrlChanged() {
+ noteSignal.sourceUrlChanged.emit(currentNote.getGuid(), urlText.text());
+ }
+
+ @SuppressWarnings("unused")
+ private void authorChanged() {
+ noteSignal.authorChanged.emit(currentNote.getGuid(), authorText.text());
+ }
+
+ @SuppressWarnings("unused")
+ private void geoBoxChanged() {
+ int index = geoBox.currentIndex();
+ geoBox.setCurrentIndex(0);
+ if (index == 1) {
+ GeoDialog box = new GeoDialog();
+ box.setLongitude(currentNote.getAttributes().getLongitude());
+ box.setLatitude(currentNote.getAttributes().getLatitude());
+ box.setAltitude(currentNote.getAttributes().getAltitude());
+ box.exec();
+ if (!box.okPressed())
+ return;
+ double alt = box.getAltitude();
+ double lat = box.getLatitude();
+ double lon = box.getLongitude();
+ if (alt != currentNote.getAttributes().getAltitude() ||
+ lon != currentNote.getAttributes().getLongitude() ||
+ lat != currentNote.getAttributes().getLatitude()) {
+ noteSignal.geoChanged.emit(currentNote.getGuid(), lon, lat, alt);
+ currentNote.getAttributes().setAltitude(alt);
+ currentNote.getAttributes().setLongitude(lon);
+ currentNote.getAttributes().setLatitude(lat);
+ }
+ }
+
+ if (index == 2) {
+ noteSignal.geoChanged.emit(currentNote.getGuid(), 0.0, 0.0, 0.0);
+ currentNote.getAttributes().setAltitude(0.0);
+ currentNote.getAttributes().setLongitude(0.0);
+ currentNote.getAttributes().setLatitude(0.0);
+ }
+
+ if (index == 3 || index == 0) {
+ QDesktopServices.openUrl(new QUrl("http://maps.google.com/maps?z=6&q="+currentNote.getAttributes().getLatitude() +"," +currentNote.getAttributes().getLongitude()));
+ }
+ }
+
+ // ************************************************************
+ // * User chose to save an attachment. Pares out the request *
+ // * into a guid & file. Save the result. *
+ // ************************************************************
+ public void downloadAttachment(QNetworkRequest request) {
+ String guid;
+ QFileDialog fd = new QFileDialog(this);
+ fd.setFileMode(FileMode.AnyFile);
+ fd.setConfirmOverwrite(true);
+ fd.setWindowTitle(tr("Save File"));
+ fd.setAcceptMode(AcceptMode.AcceptSave);
+ fd.setDirectory(System.getProperty("user.home"));
+ String name = request.url().toString();
+
+ int pos = name.lastIndexOf(Global.attachmentNameDelimeter);
+ if (pos > -1) {
+ guid = name.substring(0, pos).replace("nnres://", "");
+ name = name.substring(pos +Global.attachmentNameDelimeter.length());
+ fd.selectFile(name);
+ pos = name.lastIndexOf('.');
+ if (pos > -1) {
+ String mimeType = "(*." + name.substring(pos + 1)
+ + ");; All Files (*)";
+ fd.setFilter(tr(mimeType));
+ }
+ } else {
+ guid = name;
+ }
+
+ // Strip URL prefix and base dir
+ guid = guid.replace("nnres://", "")
+ .replace(FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath()), "");
+ guid = guid.replace("file://", "").replace("/", "")
+ .replace(FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath()), "");
+
+ pos = guid.lastIndexOf('.');
+ if (pos > 0)
+ guid = guid.substring(0,pos);
+ if (fd.exec() != 0 && fd.selectedFiles().size() > 0) {
+ name = name.replace('\\', '/');
+ Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);
+ QFile saveFile = new QFile(fd.selectedFiles().get(0));
+ QFile.OpenMode mode = new QFile.OpenMode();
+ mode.set(QFile.OpenModeFlag.WriteOnly);
+ saveFile.open(mode);
+ QDataStream saveOut = new QDataStream(saveFile);
+ QByteArray binData = new QByteArray(resBinary.getData().getBody());
+ saveOut.writeBytes(binData.toByteArray());
+ saveFile.close();
+
+ }
+ }
+
+
+ // ************************************************************
+ // * User chose to save an attachment. Pares out the request *
+ // * into a guid & file. Save the result. --- DONE FROM downloadAttachment now!!!!!
+ // ************************************************************
+ public void downloadImage(QNetworkRequest request) {
+ QFileDialog fd = new QFileDialog(this);
+ fd.setFileMode(FileMode.AnyFile);
+ fd.setConfirmOverwrite(true);
+ fd.setWindowTitle(tr("Save File"));
+ fd.setAcceptMode(AcceptMode.AcceptSave);
+ fd.setDirectory(System.getProperty("user.home"));
+ String name = request.url().toString();
+ name = name.replace("nnres://", "");
+ String dPath = FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath());
+ name = name.replace(dPath, "");
+ int pos = name.lastIndexOf('.');
+ String guid = name;
+ if (pos > -1) {
+ String mimeType = "(*." + name.substring(pos + 1)
+ + ");; All Files (*)";
+ fd.setFilter(tr(mimeType));
+ guid = guid.substring(0,pos);
+ }
+ pos = name.lastIndexOf(Global.attachmentNameDelimeter);
+ if (pos > -1) {
+ guid = name.substring(0, pos);
+ fd.selectFile(name.substring(pos+Global.attachmentNameDelimeter.length()));
+ }
+ if (fd.exec() != 0 && fd.selectedFiles().size() > 0) {
+ Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);
+ String fileName = fd.selectedFiles().get(0);
+ QFile saveFile = new QFile(fileName);
+ QFile.OpenMode mode = new QFile.OpenMode();
+ mode.set(QFile.OpenModeFlag.WriteOnly);
+ saveFile.open(mode);
+ QDataStream saveOut = new QDataStream(saveFile);
+ QByteArray binData = new QByteArray(resBinary.getData().getBody());
+ saveOut.writeBytes(binData.toByteArray());
+ saveFile.close();
+ }
+ }
+
+
+ // *************************************************************
+ // * decrypt any hidden text. We could do an XML parse, but
+ // * it is quicker here just to scan for an <img tag & do the fix
+ // * the manual way
+ // *************************************************************
+ private void removeEncryption(String id, String plainText, boolean permanent, String slot) {
+ if (!permanent) {
+ plainText = " <table class=\"en-crypt-temp\" slot=\""
+ +slot
+ +"\""
+ +"border=1 width=100%><tbody><tr><td>"
+ +plainText+"</td></tr></tbody></table>";
+ }
+
+ String html = browser.page().mainFrame().toHtml();
+ String text = html;
+ int imagePos = html.indexOf("<img");
+ int endPos;
+ for ( ;imagePos>0; ) {
+ // Find the end tag
+ endPos = text.indexOf(">", imagePos);
+ String tag = text.substring(imagePos-1,endPos);
+ if (tag.indexOf("id=\""+id+"\"") > -1) {
+ text = text.substring(0,imagePos) +plainText+text.substring(endPos+1);
+ QTextCodec codec = QTextCodec.codecForName("UTF-8");
+ QByteArray unicode = codec.fromUnicode(text);
+ setContent(unicode);
+ if (permanent)
+ contentChanged();
+ }
+ imagePos = text.indexOf("<img", imagePos+1);
+ }
+ }
+
+
+ //****************************************************************
+ //* Focus shortcuts
+ //****************************************************************
+ @SuppressWarnings("unused")
+ private void focusTitle() {
+ titleLabel.setFocus();
+ }
+ @SuppressWarnings("unused")
+ private void focusTag() {
+ tagEdit.setFocus();
+ }
+ @SuppressWarnings("unused")
+ private void focusNote() {
+ browser.setFocus();
+ }
+ @SuppressWarnings("unused")
+ private void focusAuthor() {
+ authorLabel.setFocus();
+ }
+ @SuppressWarnings("unused")
+ private void focusUrl() {
+ urlLabel.setFocus();
+ }
+
+
+ //*****************************************************************
+ //* Set the document background color
+ //*****************************************************************
+ public void setBackgroundColor(String color) {
+ String js = "function changeBackground(color) {"
+ +"document.body.style.background = color;"
+ +"}"
+ +"changeBackground('" +color+"');";
+ browser.page().mainFrame().evaluateJavaScript(js);
+ contentChanged();
+ }
+
+
+ //****************************************************************
+ //* MicroFocus changed
+ //****************************************************************
+ private void microFocusChanged() {
+ boldButton.setDown(false);
+ italicButton.setDown(false);
+ underlineButton.setDown(false);
+ browser.openAction.setEnabled(false);
+ browser.downloadAttachment.setEnabled(false);
+ browser.downloadImage.setEnabled(false);
+ browser.rotateImageLeft.setEnabled(false);
+ browser.rotateImageRight.setEnabled(false);
+ browser.insertTableAction.setEnabled(true);
+ browser.deleteTableColumnAction.setEnabled(false);
+ browser.insertTableRowAction.setEnabled(false);
+ browser.insertTableColumnAction.setEnabled(false);
+ browser.deleteTableRowAction.setEnabled(false);
+ browser.insertLinkAction.setText(tr("Insert Hyperlink"));
+ insertHyperlink = true;
+ browser.insertQuickLinkAction.setEnabled(true);
+ currentHyperlink ="";
+ insideList = false;
+ insideTable = false;
+ insideEncryption = false;
+ forceTextPaste = false;
+
+ String js = new String( "function getCursorPos() {"
+ +"var cursorPos;"
+ +"if (window.getSelection) {"
+ +" var selObj = window.getSelection();"
+ +" var selRange = selObj.getRangeAt(0);"
+ +" var workingNode = window.getSelection().anchorNode.parentNode;"
+ +" while(workingNode != null) { "
+// +" window.jambi.printNode(workingNode.nodeName);"
+ +" if (workingNode.nodeName=='TABLE') { if (workingNode.getAttribute('class').toLowerCase() == 'en-crypt-temp') window.jambi.insideEncryption(); }"
+ +" if (workingNode.nodeName=='B') window.jambi.boldActive();"
+ +" if (workingNode.nodeName=='I') window.jambi.italicActive();"
+ +" if (workingNode.nodeName=='U') window.jambi.underlineActive();"
+ +" if (workingNode.nodeName=='UL') window.jambi.setInsideList();"
+ +" if (workingNode.nodeName=='OL') window.jambi.setInsideList();"
+ +" if (workingNode.nodeName=='LI') window.jambi.setInsideList();"
+ +" if (workingNode.nodeName=='TBODY') window.jambi.setInsideTable();"
+ +" if (workingNode.nodeName=='A') {for(var x = 0; x < workingNode.attributes.length; x++ ) {if (workingNode.attributes[x].nodeName.toLowerCase() == 'href') window.jambi.setInsideLink(workingNode.attributes[x].nodeValue);}}"
+ +" if (workingNode.nodeName=='SPAN') {"
+ +" if (workingNode.getAttribute('style') == 'text-decoration: underline;') window.jambi.underlineActive();"
+ +" }"
+ +" workingNode = workingNode.parentNode;"
+ +" }"
+ +"}"
+ +"} getCursorPos();");
+ browser.page().mainFrame().evaluateJavaScript(js);
+ }
+
+ public void printNode(String n) {
+ System.out.println("Node Vaule: " +n);
+ }
+
+ public void insideEncryption() {
+ insideEncryption = true;
+ forceTextPaste();
+ }
+
+ //****************************************************************
+ //* Insert a table row
+ //****************************************************************
+ public void insertTableRow() {
+
+ String js = new String( "function insertTableRow() {"
+ +" var selObj = window.getSelection();"
+ +" var selRange = selObj.getRangeAt(0);"
+ +" var workingNode = window.getSelection().anchorNode.parentNode;"
+ +" var cellCount = 0;"
+ +" while(workingNode != null) { "
+ +" if (workingNode.nodeName.toLowerCase()=='tr') {"
+ +" row = document.createElement('TR');"
+ +" var nodes = workingNode.getElementsByTagName('td');"
+ +" for (j=0; j<nodes.length; j=j+1) {"
+ +" cell = document.createElement('TD');"
+ +" cell.innerHTML=' ';"
+ +" row.appendChild(cell);"
+ +" }"
+ +" workingNode.parentNode.insertBefore(row,workingNode.nextSibling);"
+ +" return;"
+ +" }"
+ +" workingNode = workingNode.parentNode;"
+ +" }"
+ +"} insertTableRow();");
+ browser.page().mainFrame().evaluateJavaScript(js);
+ contentChanged();
+ }
+
+ public void insertTableColumn() {
+ String js = new String( "function insertTableColumn() {"
+ +" var selObj = window.getSelection();"
+ +" var selRange = selObj.getRangeAt(0);"
+ +" var workingNode = window.getSelection().anchorNode.parentNode;"
+ +" var current = 0;"
+ +" while (workingNode.nodeName.toLowerCase() != 'table' && workingNode != null) {"
+ +" if (workingNode.nodeName.toLowerCase() == 'td') {"
+ +" var td = workingNode;"
+ +" while (td.previousSibling != null) { "
+ +" current = current+1; td = td.previousSibling;"
+ +" }"
+ +" }"
+ +" workingNode = workingNode.parentNode; "
+ +" }"
+ +" if (workingNode == null) return;"
+ +" for (var i=0; i<workingNode.rows.length; i++) { "
+ +" var cell = workingNode.rows[i].insertCell(current+1); "
+ +" cell.innerHTML = ' '; "
+ +" }"
+ +"} insertTableColumn();");
+ browser.page().mainFrame().evaluateJavaScript(js);
+ contentChanged();
+ }
+
+ //****************************************************************
+ //* Delete a table row
+ //****************************************************************
+ public void deleteTableRow() {
+
+ String js = new String( "function deleteTableRow() {"
+ +" var selObj = window.getSelection();"
+ +" var selRange = selObj.getRangeAt(0);"
+ +" var workingNode = window.getSelection().anchorNode.parentNode;"
+ +" var cellCount = 0;"
+ +" while(workingNode != null) { "
+ +" if (workingNode.nodeName.toLowerCase()=='tr') {"
+ +" workingNode.parentNode.removeChild(workingNode);"
+ +" return;"
+ +" }"
+ +" workingNode = workingNode.parentNode;"
+ +" }"
+ +"} deleteTableRow();");
+ browser.page().mainFrame().evaluateJavaScript(js);
+ contentChanged();
+ }
+
+ public void deleteTableColumn() {
+ String js = new String( "function deleteTableColumn() {"
+ +" var selObj = window.getSelection();"
+ +" var selRange = selObj.getRangeAt(0);"
+ +" var workingNode = window.getSelection().anchorNode.parentNode;"
+ +" var current = 0;"
+ +" while (workingNode.nodeName.toLowerCase() != 'table' && workingNode != null) {"
+ +" if (workingNode.nodeName.toLowerCase() == 'td') {"
+ +" var td = workingNode;"
+ +" while (td.previousSibling != null) { "
+ +" current = current+1; td = td.previousSibling;"
+ +" }"
+ +" }"
+ +" workingNode = workingNode.parentNode; "
+ +" }"
+ +" if (workingNode == null) return;"
+ +" for (var i=0; i<workingNode.rows.length; i++) { "
+ +" workingNode.rows[i].deleteCell(current); "
+ +" }"
+ +"} deleteTableColumn();");
+ browser.page().mainFrame().evaluateJavaScript(js);
+ contentChanged();
+ }
+
+
+ public void setInsideTable() {
+ browser.insertTableRowAction.setEnabled(true);
+ browser.insertTableColumnAction.setEnabled(true);
+ browser.deleteTableRowAction.setEnabled(true);
+ browser.deleteTableColumnAction.setEnabled(true);
+ browser.insertTableAction.setEnabled(false);
+ browser.encryptAction.setEnabled(false);
+ insideTable = true;
+ }
+
+ public void setInsideLink(String link) {
+ browser.insertLinkAction.setText(tr("Edit Hyperlink"));
+ currentHyperlink = link;
+ insertHyperlink = false;
+ }
+
+ public void italicActive() {
+ italicButton.setDown(true);
+ }
+ public void boldActive() {
+ boldButton.setDown(true);
+ }
+ public void underlineActive() {
+ underlineButton.setDown(true);
+ }
+ public void forceTextPaste() {
+ forceTextPaste = true;
+ }
+ public void imageContextMenu(String f) {
+ browser.downloadImage.setEnabled(true);
+ browser.rotateImageRight.setEnabled(true);
+ browser.rotateImageLeft.setEnabled(true);
+ browser.openAction.setEnabled(true);
+ selectedFile = f;
+ }
+ public void rotateImageRight() {
+ QWebSettings.setMaximumPagesInCache(0);
+ QWebSettings.setObjectCacheCapacities(0, 0, 0);
+ QImage image = new QImage(selectedFile);
+ QMatrix matrix = new QMatrix();
+ matrix.rotate( 90.0 );
+ image = image.transformed(matrix);
+ image.save(selectedFile);
+ QWebSettings.setMaximumPagesInCache(0);
+ QWebSettings.setObjectCacheCapacities(0, 0, 0);
+ browser.setHtml(browser.page().mainFrame().toHtml());
+ browser.reload();
+ contentChanged();
+ resourceSignal.contentChanged.emit(selectedFile);
+
+ }
+ public void rotateImageLeft() {
+ QImage image = new QImage(selectedFile);
+ QMatrix matrix = new QMatrix();
+ matrix.rotate( -90.0 );
+ image = image.transformed(matrix);
+ image.save(selectedFile);
+ browser.setHtml(browser.page().mainFrame().toHtml());
+ browser.reload();
+ contentChanged();
+ resourceSignal.contentChanged.emit(selectedFile);
+ }
+ public void resourceContextMenu(String f) {
+ browser.downloadAttachment.setEnabled(true);
+ browser.openAction.setEnabled(true);
+ selectedFile = f;
+ }
+ public void latexContextMenu(String f) {
+ browser.downloadImage.setEnabled(true);
+ browser.rotateImageRight.setEnabled(true);
+ browser.rotateImageLeft.setEnabled(true);
+ browser.openAction.setEnabled(true);
+ selectedFile = f;
+ }
+
+ //****************************************************************
+ //* Apply CSS style to specified word
+ //****************************************************************
+/* public void applyStyleToWords(String word, String style) {
+ QFile script = new QFile("D:\\NeverNote\\js\\hilight1.js");
+ script.open(OpenModeFlag.ReadOnly);
+ String s = script.readAll().toString();
+ String js = new String(s +" findit('"+word+"', '"+style+"');");
+ browser.page().mainFrame().evaluateJavaScript(js);
+ System.out.println(getContent());
+ }
+*/
+ //****************************************************************
+ //* Someone tried to paste a resource between notes, so we need *
+ //* to do some special handling. *
+ //****************************************************************
+ private String fixInternotePaste(String text) {
+ logger.log(logger.EXTREME, "Fixing internote paste");
+ String returnValue = fixInternotePasteSearch(text, "<img", "src=\"");
+ return fixInternotePasteSearch(returnValue, "<a", "href=\"nnres://");
+ }
+ private String fixInternotePasteSearch(String text, String type, String locTag) {
+
+ // First, let's fix the images.
+ int startPos = text.indexOf(type);
+ int endPos;
+ for (; startPos>=0;) {
+ endPos = text.indexOf(">", startPos+1);
+ String segment = text.substring(startPos, endPos);
+ if (segment.indexOf("en-tag") > -1) {
+ String newSegment = segment;
+
+ int guidStartPos = segment.indexOf("guid=\"");
+ int guidEndPos = segment.indexOf("\"", guidStartPos+7);
+ String guid = segment.substring(guidStartPos+6,guidEndPos);
+
+ int mimeStartPos = segment.indexOf("type");
+ int mimeEndPos = segment.indexOf("\"", mimeStartPos+7);
+ String mime = segment.substring(mimeStartPos+6,mimeEndPos);
+
+ int srcStartPos = segment.indexOf("src");
+ int srcEndPos = segment.indexOf("\"", srcStartPos+6);
+ String src = segment.substring(srcStartPos+5,srcEndPos);
+
+ Calendar currentTime = new GregorianCalendar();
+ Long l = new Long(currentTime.getTimeInMillis());
+ long prevTime = l;
+ while (l==prevTime) {
+ currentTime = new GregorianCalendar();
+ l= new Long(currentTime.getTimeInMillis());
+ }
+
+ Resource r = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);
+ // if r==null, then the image doesn't exist (it was probably cut out of another note, so
+ // we need to recereate it
+ if (r==null) {
+ r = createResource(src, 1, mime, false);
+ if (r==null)
+ return "";
+ }
+ String randint = new String(Long.toString(l));
+ String extension = null;
+ if (r.getMime()!= null) {
+ extension = r.getMime().toLowerCase();
+ if (extension.indexOf("/")>-1)
+ extension = extension.substring(extension.indexOf("/")+1);
+ }
+ String newFile = randint;
+ if (r.getAttributes().getFileName() != null && r.getAttributes().getFileName() != "")
+ if (!locTag.startsWith("src"))
+ newFile = newFile+Global.attachmentNameDelimeter+r.getAttributes().getFileName();
+ r.setNoteGuid(currentNote.getGuid());
+
+ r.setGuid(randint);
+ conn.getNoteTable().noteResourceTable.saveNoteResource(r, true);
+ QFile f = new QFile(Global.getFileManager().getResDirPath(newFile));
+ QByteArray bin = new QByteArray(r.getData().getBody());
+ f.open(QFile.OpenModeFlag.WriteOnly);
+ f.write(bin);
+ f.close();
+ newSegment = newSegment.replace("guid=\""+guid, "guid=\""+randint);
+ currentNote.getResources().add(r);
+
+ int startSrcPos = newSegment.indexOf(locTag);
+ int endSrcPos = newSegment.indexOf("\"",startSrcPos+locTag.length()+1);
+ String source;
+ if (locTag.startsWith("src")) {
+ source = newSegment.substring(startSrcPos+locTag.length(),endSrcPos);
+ newSegment = newSegment.replace(source,
+ FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath(newFile)));
+ } else {
+ source = newSegment.substring(startSrcPos+locTag.length(),endSrcPos);
+ newSegment = newSegment.replace(source, newFile);
+ }
+
+ text = text.substring(0,startPos) + newSegment + text.substring(endPos);
+ }
+ startPos = text.indexOf(type, startPos+1);
+ }
+ return text;
+ }
+
+
+ public void nextPage(String file) {
+ logger.log(logger.EXTREME, "Starting nextPage()");
+
+ Integer pageNumber;
+ if (previewPageList.containsKey(file))
+ pageNumber = previewPageList.get(file)+1;
+ else
+ pageNumber = 2;
+ previewPageList.remove(file);
+ previewPageList.put(file, pageNumber);
+ PDFPreview pdfPreview = new PDFPreview();
+ boolean goodPreview = pdfPreview.setupPreview(file, "pdf", pageNumber);
+ if (goodPreview) {
+
+// String html = getContent();
+ QWebSettings.setMaximumPagesInCache(0);
+ QWebSettings.setObjectCacheCapacities(0, 0, 0);
+// browser.setContent(new QByteArray());
+ browser.setHtml(browser.page().mainFrame().toHtml());
+ browser.reload();
+// browser.setContent(new QByteArray(html));
+// browser.triggerPageAction(WebAction.Reload);
+// pdfMouseOver(selectedFile);
+ }
+ }
+
+ public void previousPage(String file) {
+ logger.log(logger.EXTREME, "Starting previousPage()");
+
+ Integer pageNumber;
+ if (previewPageList.containsKey(file))
+ pageNumber = previewPageList.get(file)-1;
+ else
+ pageNumber = 1;
+ previewPageList.remove(file);
+ previewPageList.put(file, pageNumber);
+ PDFPreview pdfPreview = new PDFPreview();
+ boolean goodPreview = pdfPreview.setupPreview(file, "pdf", pageNumber);
+ if (goodPreview) {
+
+// String html = getContent();
+ QWebSettings.setMaximumPagesInCache(0);
+ QWebSettings.setObjectCacheCapacities(0, 0, 0);
+ browser.setHtml(browser.page().mainFrame().toHtml());
+ browser.reload();
+// browser.setContent(new QByteArray(html));
+// browser.triggerPageAction(WebAction.Reload);
+ }
+ }
+
+/* public void pdfMouseOver(String name) {
+ int pageNumber;
+ if (previewPageList.containsKey(selectedFile))
+ pageNumber = previewPageList.get(selectedFile)+1;
+ else
+ pageNumber = 1;
+
+ if (pageNumber <= 1)
+ browser.previousPageAction.setEnabled(false);
+ else
+ browser.previousPageAction.setEnabled(true);
+
+ PDFPreview pdf = new PDFPreview();
+ int totalPages = pdf.getPageCount(name);
+ if (previewPageList.containsKey(selectedFile))
+ pageNumber = previewPageList.get(selectedFile)+1;
+ else
+ pageNumber = 1;
+ if (totalPages > pageNumber)
+ browser.nextPageAction.setEnabled(true);
+ else
+ browser.nextPageAction.setEnabled(false);
+ }
+
+
+ public void pdfMouseOut() {
+// browser.nextPageAction.setVisible(false);
+// browser.previousPageAction.setVisible(false);
+ }
+*/
+
+ @SuppressWarnings("unused")
+ private void toggleUndoVisible(Boolean toggle) {
+ undoAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("undo", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleRedoVisible(Boolean toggle) {
+ redoAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("redo", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleCutVisible(Boolean toggle) {
+ cutAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("cut", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleCopyVisible(Boolean toggle) {
+ copyAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("copy", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void togglePasteVisible(Boolean toggle) {
+ pasteAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("paste", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleBoldVisible(Boolean toggle) {
+ boldAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("bold", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleItalicVisible(Boolean toggle) {
+ italicAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("italic", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleUnderlineVisible(Boolean toggle) {
+ underlineAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("underline", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleStrikethroughVisible(Boolean toggle) {
+ strikethroughAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("strikethrough", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleLeftAlignVisible(Boolean toggle) {
+ leftAlignAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("alignLeft", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleRightAlignVisible(Boolean toggle) {
+ rightAlignAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("alignRight", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleCenterAlignVisible(Boolean toggle) {
+ centerAlignAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("alignCenter", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleHLineVisible(Boolean toggle) {
+ hlineAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("hline", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleIndentVisible(Boolean toggle) {
+ indentAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("indent", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleTodoVisible(Boolean toggle) {
+ todoAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("todo", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleOutdentVisible(Boolean toggle) {
+ outdentAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("outdent", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleBulletListVisible(Boolean toggle) {
+ bulletListAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("bulletList", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleNumberListVisible(Boolean toggle) {
+ numberListAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("numberList", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleFontListVisible(Boolean toggle) {
+ fontListAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("font", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleFontColorVisible(Boolean toggle) {
+ fontColorAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("fontColor", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleFontSizeVisible(Boolean toggle) {
+ fontSizeAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("fontSize", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleFontHilightVisible(Boolean toggle) {
+ fontHilightAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("fontHilight", toggle);
+ }
+ @SuppressWarnings("unused")
+ private void toggleSpellCheckVisible(Boolean toggle) {
+ spellCheckAction.setVisible(toggle);
+ Global.saveEditorButtonsVisible("spellCheck", toggle);
+ }
+
+
+ private void setupDictionary() {
+ File wordList = new File(Global.getFileManager().getSpellDirPath()+Locale.getDefault()+".dic");
+ try {
+ dictionary = new SpellDictionaryHashMap(wordList);
+ spellChecker = new SpellChecker(dictionary);
+
+ File userWordList;
+ userWordList = new File(Global.getFileManager().getSpellDirPathUser()+"user.dic");
+
+ // Get the local user spell dictionary
+ try {
+ userDictionary = new SpellDictionaryHashMap(userWordList);
+ } catch (FileNotFoundException e) {
+ userWordList.createNewFile();
+ userDictionary = new SpellDictionaryHashMap(userWordList);
+ } catch (IOException e) {
+ userWordList.createNewFile();
+ userDictionary = new SpellDictionaryHashMap(userWordList);
+ }
+
+ spellListener = new SuggestionListener(this, spellChecker);
+
+ // Add the user dictionary
+ spellChecker.addSpellCheckListener(spellListener);
+ spellChecker.setUserDictionary(userDictionary);
+
+ } catch (FileNotFoundException e) {
+ QMessageBox.critical(this, tr("Spell Check Error"),
+ tr("Dictionary ")+ Global.getFileManager().getSpellDirPath()+Locale.getDefault()+
+ tr(".dic was not found."));
+ } catch (IOException e) {
+ QMessageBox.critical(this, tr("Spell Check Error"),
+ tr("Dictionary ")+ Global.getFileManager().getSpellDirPath()+Locale.getDefault()+
+ tr(".dic is invalid."));
+ }
+
+ }
+
+ // Invoke spell checker dialog
+ @SuppressWarnings("unused")
+ private void spellCheckClicked() {
+
+ if (spellChecker == null) {
+ setupDictionary();
+ }
+
+ // Read user settings
+ spellChecker.getConfiguration().setBoolean(Configuration.SPELL_IGNOREDIGITWORDS,
+ Global.getSpellSetting(Configuration.SPELL_IGNOREDIGITWORDS));
+ spellChecker.getConfiguration().setBoolean(Configuration.SPELL_IGNOREINTERNETADDRESSES,
+ Global.getSpellSetting(Configuration.SPELL_IGNOREINTERNETADDRESSES));
+ spellChecker.getConfiguration().setBoolean(Configuration.SPELL_IGNOREMIXEDCASE,
+ Global.getSpellSetting(Configuration.SPELL_IGNOREMIXEDCASE));
+ spellChecker.getConfiguration().setBoolean(Configuration.SPELL_IGNOREUPPERCASE,
+ Global.getSpellSetting(Configuration.SPELL_IGNOREUPPERCASE));
+ spellChecker.getConfiguration().setBoolean(Configuration.SPELL_IGNORESENTENCECAPITALIZATION,
+ Global.getSpellSetting(Configuration.SPELL_IGNORESENTENCECAPITALIZATION));
+
+ spellListener.abortSpellCheck = false;
+ spellListener.errorsFound = false;
+ String content = getBrowser().page().mainFrame().toPlainText();
+ StringWordTokenizer tokenizer = new StringWordTokenizer(content);
+ if (!tokenizer.hasMoreWords())
+ return;
+ getBrowser().page().action(WebAction.MoveToStartOfDocument);
+
+ getBrowser().setFocus();
+ boolean found;
+
+ // Move to the start of page
+ KeyboardModifiers ctrl = new KeyboardModifiers(KeyboardModifier.ControlModifier.value());
+ QKeyEvent home = new QKeyEvent(Type.KeyPress, Key.Key_Home.value(), ctrl);
+ browser.keyPressEvent(home);
+ getBrowser().setFocus();
+
+ tokenizer = new StringWordTokenizer(content);
+ String word;
+
+ while(tokenizer.hasMoreWords()) {
+ word = tokenizer.nextWord();
+ found = getBrowser().page().findText(word);
+ if (found && !spellListener.abortSpellCheck) {
+ spellChecker.checkSpelling(new StringWordTokenizer(word));
+ getBrowser().setFocus();
+ }
+ }
+
+ // Go to the end of the document & finish up.
+ home = new QKeyEvent(Type.KeyPress, Key.Key_End.value(), ctrl);
+ browser.keyPressEvent(home);
+ if (!spellListener.errorsFound)
+ QMessageBox.information(this, tr("Spell Check Complete"),
+ tr("No Errors Found"));
+
+ }
+
+ // Source edited
+ @SuppressWarnings("unused")
+ private void sourceEdited() {
+ QTextCodec codec = QTextCodec.codecForLocale();
+ codec = QTextCodec.codecForName("UTF-8");
+ String content = codec.fromUnicode(sourceEdit.toHtml()).toString();
+ content = StringEscapeUtils.unescapeHtml4(removeTags(content));
+ QByteArray data = new QByteArray(sourceEditHeader+content+"</body></html>");
+ getBrowser().setContent(data);
+ checkNoteTitle();
+ if (currentNote != null && sourceEdit != null)
+ noteSignal.noteChanged.emit(currentNote.getGuid(), sourceEdit.toPlainText());
+ }
+
+ private void setSource() {
+ String text = getContent();
+ sourceEdit.blockSignals(true);
+ int body = text.indexOf("<body");
+ if (body > 0) {
+ body = text.indexOf(">",body);
+ if (body > 0) {
+ sourceEditHeader =text.substring(0, body+1);
+ text = text.substring(body+1);
+ }
+ }
+ text = text.replace("</body></html>", "");
+ sourceEdit.setPlainText(text);
+ sourceEdit.setReadOnly(!getBrowser().page().isContentEditable());
+ //syntaxHighlighter.rehighlight();
+ sourceEdit.blockSignals(false);
+ }
+
+ // show/hide view source window
+ public void showSource(boolean value) {
+ setSource();
+ sourceEdit.setVisible(value);
+ }
+
+ // Remove HTML tags
+ private String removeTags(String text) {
+ StringBuffer buffer = new StringBuffer(text);
+ boolean inTag = false;
+ int bodyPosition = text.indexOf("<body");
+ for (int i=buffer.length()-1; i>=0; i--) {
+ if (buffer.charAt(i) == '>')
+ inTag = true;
+ if (buffer.charAt(i) == '<')
+ inTag = false;
+ if (inTag || buffer.charAt(i) == '<' || i<bodyPosition)
+ buffer.deleteCharAt(i);
+ }
+
+ return buffer.toString();
+ }
+}