import java.util.Locale;\r
import java.util.StringTokenizer;\r
\r
-import org.apache.commons.lang.StringEscapeUtils;\r
-import org.apache.commons.lang.StringUtils;\r
+import org.apache.commons.lang3.StringEscapeUtils;\r
+import org.apache.commons.lang3.StringUtils;\r
\r
import com.evernote.edam.limits.Constants;\r
import com.evernote.edam.type.Data;\r
import com.evernote.edam.type.Resource;\r
import com.evernote.edam.type.ResourceAttributes;\r
import com.evernote.edam.type.Tag;\r
+import com.evernote.edam.type.User;\r
import com.swabunga.spell.engine.Configuration;\r
import com.swabunga.spell.engine.SpellDictionary;\r
import com.swabunga.spell.engine.SpellDictionaryHashMap;\r
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.QTimer;\r
import com.trolltech.qt.core.QUrl;\r
import com.trolltech.qt.core.Qt;\r
import com.trolltech.qt.core.Qt.Key;\r
import cx.fbn.nevernote.dialog.GeoDialog;\r
import cx.fbn.nevernote.dialog.InsertLatexImage;\r
import cx.fbn.nevernote.dialog.InsertLinkDialog;\r
+import cx.fbn.nevernote.dialog.NoteQuickLinkDialog;\r
import cx.fbn.nevernote.dialog.SpellCheck;\r
import cx.fbn.nevernote.dialog.TableDialog;\r
import cx.fbn.nevernote.dialog.TagAssign;\r
private boolean extendedOn;\r
public boolean buttonsVisible;\r
private final String iconPath;\r
- private final ContentView browser;\r
+ public final ContentView browser;\r
private final QTextEdit sourceEdit;\r
private String sourceEditHeader;\r
Highlighter syntaxHighlighter;\r
public Signal0 unblockApplication;\r
public boolean awaitingHttpResponse;\r
public long unblockTime;\r
+ private final QTimer setSourceTimer;\r
String latexGuid; // This is set if we are editing an existing LaTeX formula. Useful to track guid.\r
\r
\r
blockApplication = new Signal1<BrowserWindow>();\r
unblockApplication = new Signal0();\r
\r
+ setSourceTimer = new QTimer();\r
+ setSourceTimer.timeout.connect(this, "setSource()");\r
+ \r
logger.log(logger.HIGH, "Browser setup complete");\r
}\r
\r
alteredTime.setEnabled(!v);\r
subjectTime.setEnabled(!v);\r
getBrowser().setEnabled(true);\r
+ getBrowser().page().setContentEditable(!v);\r
// getBrowser().setEnabled(!v);\r
}\r
\r
public void setContent(QByteArray data) {\r
sourceEdit.blockSignals(true);\r
browser.setContent(data);\r
- setSource(getBrowser().page().mainFrame().toHtml());\r
+ setSource();\r
}\r
// get/set current note\r
public void setNote(Note n) {\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
\r
if (mime.hasUrls()) {\r
logger.log(logger.EXTREME, "URL paste found");\r
- if (!mime.text().startsWith("evernote:")) {\r
+ if (mime.text().startsWith("evernote:")) {\r
handleNoteLink(mime);\r
} else {\r
handleUrls(mime);\r
script_start + buffer.toString() + script_end);\r
}\r
\r
- \r
+\r
+ // Insert a Quick hyperlink\r
+ public void insertQuickLink() {\r
+ logger.log(logger.EXTREME, "Inserting link");\r
+ String text = browser.selectedText();\r
+ if (text.trim().equalsIgnoreCase(""))\r
+ return;\r
+\r
+ NoteQuickLinkDialog dialog = new NoteQuickLinkDialog(logger, conn, text);\r
+ if (dialog.getResults().size() == 0) {\r
+ QMessageBox.critical(null, tr("No Matches Found") ,tr("No matching notes found."));\r
+ return;\r
+ }\r
+ if (dialog.getResults().size() > 1) {\r
+ dialog.exec();\r
+ if (!dialog.okPressed) {\r
+ logger.log(logger.EXTREME, "Insert link canceled");\r
+ return;\r
+ }\r
+ }\r
+\r
+ User user = Global.getUserInformation();\r
+ String dUrl = new String("evernote:///view/") + new String(user.getId() + "/" +user.getShardId() +"/"\r
+ +dialog.getSelectedNote()+"/"+dialog.getSelectedNote() +"/ " +"style=\"color:#69aa35\"");\r
+ \r
+ String url = "<a title=\"" +dUrl\r
+ +"\" href=" +dUrl \r
+ +" >"+text +"</a>";\r
+ String script = "document.execCommand('insertHtml', false, '"+url+"');";\r
+ browser.page().mainFrame().evaluateJavaScript(script); \r
+ contentChanged();\r
+ }\r
+\r
// Insert a hyperlink\r
public void insertLink() {\r
logger.log(logger.EXTREME, "Inserting link");\r
public void editLatex(String guid) {\r
logger.log(logger.EXTREME, "Inserting latex");\r
String text = browser.selectedText();\r
- if (text.trim().equalsIgnoreCase(" ") || text.trim().equalsIgnoreCase("")) {\r
+ if (text.trim().equalsIgnoreCase("\n") || text.trim().equalsIgnoreCase("")) {\r
InsertLatexImage dialog = new InsertLatexImage();\r
if (guid != null) {\r
String formula = conn.getNoteTable().noteResourceTable.getNoteSourceUrl(guid).replace("http://latex.codecogs.com/gif.latex?", "");\r
private void selectionChanged() {\r
browser.encryptAction.setEnabled(true);\r
browser.insertLinkAction.setEnabled(true);\r
+ browser.insertQuickLinkAction.setEnabled(true);\r
String scriptStart = "var selection_text = (window.getSelection()).toString();"\r
+ "var range = (window.getSelection()).getRangeAt(0);"\r
+ "var parent_html = range.commonAncestorContainer.innerHTML;"\r
\r
browser.encryptAction.setEnabled(enabled);\r
browser.insertLinkAction.setEnabled(enabled);\r
+ browser.insertQuickLinkAction.setEnabled(enabled);\r
// selectedText = text;\r
}\r
\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
+ String text = titleLabel.text().trim();\r
+ if (text.equals("")) \r
+ text = tr("Untitled Note");\r
+ noteSignal.titleChanged.emit(currentNote.getGuid(), text);\r
+ currentNote.setTitle(text);\r
+ saveNoteTitle = text;\r
checkNoteTitle();\r
}\r
\r
// The note contents have changed\r
public void contentChanged() {\r
String content = getContent();\r
- setSource(content);\r
+ \r
+ // This puts in a 1/2 second delay\r
+ // before updating the source editor.\r
+ // It improves response when someone is doing\r
+ // frequent updates on a large note.\r
+ // If the source editor isn't visible, then there\r
+ // is no point to doing any of this.\r
+ if (sourceEdit.isVisible()) {\r
+ setSourceTimer.stop();\r
+ setSourceTimer.setInterval(500);\r
+ setSourceTimer.setSingleShot(true);\r
+ setSourceTimer.start();\r
+ }\r
\r
checkNoteTitle();\r
noteSignal.noteChanged.emit(currentNote.getGuid(), content); \r
// Check the note title\r
private void checkNoteTitle() {\r
String text = browser.page().currentFrame().toPlainText();\r
+ if (saveNoteTitle == null)\r
+ saveNoteTitle = new String();\r
+ text = text.trim();\r
+ if (!saveNoteTitle.trim().equals("") && !saveNoteTitle.trim().equals("Untitled Note"))\r
+ text = saveNoteTitle.trim();\r
+ int newLine = text.indexOf("\n");\r
+ if (newLine > 0)\r
+ text = text.substring(0,newLine);\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
+ 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
+ } 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
- noteSignal.titleChanged.emit(currentNote.getGuid(), titleLabel\r
- .text());\r
}\r
+ if (currentNote != null && titleLabel != null && !currentNote.getTitle().equals(text))\r
+ noteSignal.titleChanged.emit(currentNote.getGuid(), text);\r
}\r
\r
// Return the note contents so we can email them\r
handleLocalImageURLPaste(mime, mimeType);\r
return;\r
}\r
- String[] type = mimeType.split("/");\r
- boolean valid = validAttachment(type[1]);\r
+\r
boolean smallEnough = checkFileAttachmentSize(url);\r
- if (smallEnough && valid\r
+ if (smallEnough \r
&& url.substring(0, 5).equalsIgnoreCase("file:")\r
&& !mimeType.substring(0, 5).equalsIgnoreCase("image")) {\r
handleLocalAttachment(mime, mimeType);\r
imageURL = file.fileName() + ".png";\r
}\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
+ .append("');\" "); \r
+ 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
\r
private Resource createResource(String url, int sequence, String mime, boolean attachment) {\r
logger.log(logger.EXTREME, "Inside create resource");\r
- QFile resourceFile;\r
+ QFile resourceFile; \r
+ //These two lines are added to handle odd characters in the name like #. Without it\r
+ // toLocalFile() chokes and returns the wrong name.\r
+ logger.log(logger.EXTREME, "File URL:" +url);\r
+ String whichOS = System.getProperty("os.name");\r
+ if (whichOS.contains("Windows")) \r
+ url = url.replace("file:///", "");\r
+ else\r
+ url = url.replace("file://", "");\r
String urlTest = new QUrl(url).toLocalFile();\r
+ logger.log(logger.EXTREME, "File URL toLocalFile():" +urlTest);\r
+ urlTest = url;\r
if (!urlTest.equals(""))\r
url = urlTest;\r
- url = url.replace("/", File.separator);\r
- logger.log(logger.EXTREME, "Reading from file to create resource");\r
- resourceFile = new QFile(url); \r
+// url = url.replace("/", File.separator);\r
+ logger.log(logger.EXTREME, "Reading from file to create resource:" +url);\r
+ resourceFile = new QFile(url); \r
resourceFile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly));\r
-// logger.log(logger.EXTREME, "Error opening file "+url.toString() +": "+resourceFile.errorString());\r
+ logger.log(logger.EXTREME, "Error opening file "+url.toString() +": "+resourceFile.errorString());\r
byte[] fileData = resourceFile.readAll().toByteArray();\r
resourceFile.close();\r
+ logger.log(logger.EXTREME, "File Length: " +fileData.length);\r
if (fileData.length == 0)\r
return null;\r
MessageDigest md;\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
browser.deleteTableRowAction.setEnabled(false);\r
browser.insertLinkAction.setText(tr("Insert Hyperlink"));\r
insertHyperlink = true;\r
+ browser.insertQuickLinkAction.setEnabled(true);\r
currentHyperlink ="";\r
insideList = false;\r
insideTable = false;\r
QTextCodec codec = QTextCodec.codecForLocale();\r
codec = QTextCodec.codecForName("UTF-8");\r
String content = codec.fromUnicode(sourceEdit.toHtml()).toString();\r
- content = StringEscapeUtils.unescapeHtml(removeTags(content));\r
+ content = StringEscapeUtils.unescapeHtml4(removeTags(content));\r
QByteArray data = new QByteArray(sourceEditHeader+content+"</body></html>");\r
getBrowser().setContent(data);\r
checkNoteTitle();\r
- noteSignal.noteChanged.emit(currentNote.getGuid(), sourceEdit.toPlainText()); \r
+ if (currentNote != null && sourceEdit != null)\r
+ noteSignal.noteChanged.emit(currentNote.getGuid(), sourceEdit.toPlainText()); \r
}\r
\r
- private void setSource(String text) {\r
+ private void setSource() {\r
+ String text = getContent();\r
sourceEdit.blockSignals(true);\r
int body = text.indexOf("<body");\r
if (body > 0) {\r
text = text.replace("</body></html>", "");\r
sourceEdit.setPlainText(text);\r
sourceEdit.setReadOnly(!getBrowser().page().isContentEditable());\r
- syntaxHighlighter.rehighlight();\r
+ //syntaxHighlighter.rehighlight();\r
sourceEdit.blockSignals(false);\r
}\r
\r
// show/hide view source window\r
public void showSource(boolean value) {\r
+ setSource();\r
sourceEdit.setVisible(value);\r
}\r
\r