OSDN Git Service

cf1ca2778228d95728f960731a285fd078b2a4a3
[neighbornote/NeighborNote.git] / src / cx / fbn / nevernote / gui / BrowserWindow.java
1 /*\r
2  * This file is part of NeverNote \r
3  * Copyright 2009 Randy Baumgarte\r
4  * \r
5  * This file may be licensed under the terms of of the\r
6  * GNU General Public License Version 2 (the ``GPL'').\r
7  *\r
8  * Software distributed under the License is distributed\r
9  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either\r
10  * express or implied. See the GPL for the specific language\r
11  * governing rights and limitations.\r
12  *\r
13  * You should have received a copy of the GPL along with this\r
14  * program. If not, go to http://www.gnu.org/licenses/gpl.html\r
15  * or write to the Free Software Foundation, Inc.,\r
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
17  *\r
18  */\r
19 \r
20 package cx.fbn.nevernote.gui;\r
21 \r
22 import java.io.File;\r
23 import java.net.FileNameMap;\r
24 import java.net.URI;\r
25 import java.net.URLConnection;\r
26 import java.security.MessageDigest;\r
27 import java.security.NoSuchAlgorithmException;\r
28 import java.text.SimpleDateFormat;\r
29 import java.util.ArrayList;\r
30 import java.util.Calendar;\r
31 import java.util.Date;\r
32 import java.util.GregorianCalendar;\r
33 import java.util.HashMap;\r
34 import java.util.List;\r
35 \r
36 import com.evernote.edam.limits.Constants;\r
37 import com.evernote.edam.type.Data;\r
38 import com.evernote.edam.type.Note;\r
39 import com.evernote.edam.type.Notebook;\r
40 import com.evernote.edam.type.Resource;\r
41 import com.evernote.edam.type.ResourceAttributes;\r
42 import com.evernote.edam.type.Tag;\r
43 import com.trolltech.qt.core.QByteArray;\r
44 import com.trolltech.qt.core.QDataStream;\r
45 import com.trolltech.qt.core.QDateTime;\r
46 import com.trolltech.qt.core.QEvent;\r
47 import com.trolltech.qt.core.QFile;\r
48 import com.trolltech.qt.core.QFileSystemWatcher;\r
49 import com.trolltech.qt.core.QIODevice;\r
50 import com.trolltech.qt.core.QMimeData;\r
51 import com.trolltech.qt.core.QUrl;\r
52 import com.trolltech.qt.gui.QApplication;\r
53 import com.trolltech.qt.gui.QCalendarWidget;\r
54 import com.trolltech.qt.gui.QClipboard;\r
55 import com.trolltech.qt.gui.QColor;\r
56 import com.trolltech.qt.gui.QComboBox;\r
57 import com.trolltech.qt.gui.QDateEdit;\r
58 import com.trolltech.qt.gui.QDesktopServices;\r
59 import com.trolltech.qt.gui.QFileDialog;\r
60 import com.trolltech.qt.gui.QFontDatabase;\r
61 import com.trolltech.qt.gui.QFormLayout;\r
62 import com.trolltech.qt.gui.QGridLayout;\r
63 import com.trolltech.qt.gui.QHBoxLayout;\r
64 import com.trolltech.qt.gui.QIcon;\r
65 import com.trolltech.qt.gui.QImage;\r
66 import com.trolltech.qt.gui.QKeySequence;\r
67 import com.trolltech.qt.gui.QLabel;\r
68 import com.trolltech.qt.gui.QLineEdit;\r
69 import com.trolltech.qt.gui.QListWidgetItem;\r
70 import com.trolltech.qt.gui.QMatrix;\r
71 import com.trolltech.qt.gui.QMessageBox;\r
72 import com.trolltech.qt.gui.QPushButton;\r
73 import com.trolltech.qt.gui.QShortcut;\r
74 import com.trolltech.qt.gui.QTimeEdit;\r
75 import com.trolltech.qt.gui.QVBoxLayout;\r
76 import com.trolltech.qt.gui.QWidget;\r
77 import com.trolltech.qt.gui.QFileDialog.AcceptMode;\r
78 import com.trolltech.qt.gui.QFileDialog.FileMode;\r
79 import com.trolltech.qt.network.QNetworkRequest;\r
80 import com.trolltech.qt.webkit.QWebPage;\r
81 import com.trolltech.qt.webkit.QWebSettings;\r
82 import com.trolltech.qt.webkit.QWebView;\r
83 import com.trolltech.qt.webkit.QWebPage.WebAction;\r
84 \r
85 import cx.fbn.nevernote.Global;\r
86 import cx.fbn.nevernote.dialog.EnCryptDialog;\r
87 import cx.fbn.nevernote.dialog.EnDecryptDialog;\r
88 import cx.fbn.nevernote.dialog.InsertLinkDialog;\r
89 import cx.fbn.nevernote.dialog.TableDialog;\r
90 import cx.fbn.nevernote.dialog.TagAssign;\r
91 import cx.fbn.nevernote.evernote.EnCrypt;\r
92 import cx.fbn.nevernote.signals.NoteResourceSignal;\r
93 import cx.fbn.nevernote.signals.NoteSignal;\r
94 import cx.fbn.nevernote.sql.DatabaseConnection;\r
95 import cx.fbn.nevernote.utilities.ApplicationLogger;\r
96 \r
97 public class BrowserWindow extends QWidget {\r
98 \r
99         public final QLineEdit titleLabel;\r
100         private final QLineEdit urlText;\r
101         private final QLabel authorLabel;\r
102         private final QLineEdit authorText;\r
103         public final TagLineEdit tagEdit;\r
104         public final QLabel tagLabel;\r
105         private final QLabel urlLabel;\r
106         private final QLabel alteredLabel;\r
107         private final QDateEdit alteredDate;\r
108         private final QTimeEdit alteredTime;\r
109         private final QDateEdit createdDate;\r
110         private final QTimeEdit createdTime;\r
111         private final QLabel subjectLabel;\r
112         private final QDateEdit subjectDate;\r
113         private final QTimeEdit subjectTime;\r
114         public final QComboBox notebookBox;\r
115         private final QLabel notebookLabel;\r
116         private final QLabel createdLabel;\r
117         public final QComboBox fontSize;\r
118         private boolean extendedOn;\r
119         public boolean buttonsVisible;\r
120         private final String iconPath = new String("classpath:cx/fbn/nevernote/icons/");\r
121         private final ContentView browser;\r
122         private List<Tag> allTags;\r
123         private List<String> currentTags;\r
124         public NoteSignal noteSignal;\r
125         private List<Notebook> notebookList;\r
126         private Note currentNote;\r
127         private String saveNoteTitle;\r
128         private String saveTagList;\r
129         private boolean insideList;\r
130 //      private String selectedText;\r
131         private final DatabaseConnection conn;\r
132         private final QCalendarWidget createdCalendarWidget;\r
133         private final QCalendarWidget alteredCalendarWidget;\r
134         private final QCalendarWidget subjectCalendarWidget;\r
135 \r
136         public final QPushButton undoButton;\r
137         public final QPushButton redoButton;\r
138         public final QPushButton cutButton;\r
139         public final QPushButton copyButton;\r
140         public final QPushButton pasteButton;\r
141         public final QPushButton boldButton;\r
142         public final QPushButton underlineButton;\r
143         public final QPushButton italicButton;\r
144         public final Signal0 focusLost;\r
145         public final NoteResourceSignal resourceSignal;\r
146 \r
147         public QPushButton rightAlignButton;\r
148         public QPushButton leftAlignButton;\r
149         public QPushButton centerAlignButton;\r
150 \r
151         public final QPushButton strikethroughButton;\r
152         public final QPushButton hlineButton;\r
153         public final QPushButton indentButton;\r
154         public final QPushButton outdentButton;\r
155         public final QPushButton bulletListButton;\r
156         public final QPushButton numberListButton;\r
157 \r
158         public final QShortcut focusTitleShortcut;\r
159         public final QShortcut focusTagShortcut;\r
160         public final QShortcut focusNoteShortcut;\r
161         public final QShortcut focusUrlShortcut;\r
162         public final QShortcut focusAuthorShortcut;\r
163         \r
164         public final QComboBox fontList;\r
165         public final QPushButton fontColor;\r
166         private final ColorMenu fontColorMenu;\r
167         public final QPushButton fontHilight;\r
168 //      public final ColorComboBox fontHilight;\r
169         private final ColorMenu fontHilightColorMenu;\r
170         public final QFileSystemWatcher fileWatcher;\r
171         public int cursorPosition;\r
172         private boolean forceTextPaste = false;\r
173         private String selectedFile;\r
174         private String currentHyperlink;\r
175         public boolean keepPDFNavigationHidden;\r
176         private final ApplicationLogger logger;\r
177         \r
178         private final HashMap<String,Integer> previewPageList; \r
179         \r
180         \r
181         public BrowserWindow(DatabaseConnection c) {\r
182                 logger = new ApplicationLogger("browser.log");\r
183                 logger.log(logger.HIGH, "Setting up browser");\r
184                 \r
185                 fileWatcher = new QFileSystemWatcher();\r
186 //              fileWatcher.fileChanged.connect(this, "fileChanged(String)");\r
187                 noteSignal = new NoteSignal();\r
188                 titleLabel = new QLineEdit();\r
189                 titleLabel.setMaxLength(Constants.EDAM_NOTE_TITLE_LEN_MAX);\r
190                 urlText = new QLineEdit();\r
191                 authorText = new QLineEdit();\r
192                 urlLabel = new QLabel();\r
193                 authorLabel = new QLabel();\r
194                 conn = c;\r
195                 \r
196                 focusLost = new Signal0();\r
197 \r
198                 tagEdit = new TagLineEdit(allTags);\r
199                 tagLabel = new QLabel("Tags:");\r
200                 tagEdit.focusLost.connect(this, "modifyTagsTyping()");\r
201 \r
202                 createdCalendarWidget = new QCalendarWidget();\r
203                 createdDate = new QDateEdit();\r
204                 createdDate.setDisplayFormat(Global.getDateFormat());\r
205                 createdDate.setCalendarPopup(true);\r
206                 createdDate.setCalendarWidget(createdCalendarWidget);\r
207                 createdTime = new QTimeEdit();\r
208                 createdDate.dateChanged.connect(this, "createdChanged()");\r
209                 createdTime.timeChanged.connect(this, "createdChanged()");\r
210 \r
211                 alteredCalendarWidget = new QCalendarWidget();\r
212                 alteredDate = new QDateEdit();\r
213                 alteredDate.setDisplayFormat(Global.getDateFormat());\r
214                 alteredDate.setCalendarPopup(true);\r
215                 alteredDate.setCalendarWidget(alteredCalendarWidget);\r
216                 alteredTime = new QTimeEdit();\r
217                 alteredLabel = new QLabel("Altered:");\r
218                 alteredDate.dateChanged.connect(this, "alteredChanged()");\r
219                 alteredTime.timeChanged.connect(this, "alteredChanged()");\r
220 \r
221                 subjectCalendarWidget = new QCalendarWidget();\r
222                 subjectDate = new QDateEdit();\r
223                 subjectDate.setDisplayFormat(Global.getDateFormat());\r
224                 subjectDate.setCalendarPopup(true);\r
225                 subjectDate.setCalendarWidget(subjectCalendarWidget);\r
226                 subjectTime = new QTimeEdit();\r
227                 subjectLabel = new QLabel("Subject Date:");\r
228                 subjectDate.dateChanged.connect(this, "subjectDateTimeChanged()");\r
229                 subjectTime.timeChanged.connect(this, "subjectDateTimeChanged()");\r
230                 authorText.textChanged.connect(this, "authorChanged()");\r
231                 urlText.textChanged.connect(this, "sourceUrlChanged()");\r
232 \r
233                 notebookBox = new QComboBox();\r
234                 notebookLabel = new QLabel("Notebook");\r
235                 createdLabel = new QLabel("Created:");\r
236                 // selectedText = new String();\r
237 \r
238                 urlLabel.setVisible(false);\r
239                 urlText.setVisible(false);\r
240                 authorLabel.setVisible(false);\r
241                 authorText.setVisible(false);\r
242                 createdDate.setVisible(false);\r
243                 alteredLabel.setVisible(false);\r
244                 //notebookBox.setVisible(false);\r
245                 notebookLabel.setVisible(false);\r
246                 createdLabel.setVisible(false);\r
247                 createdTime.setVisible(false);\r
248                 alteredDate.setVisible(false);\r
249                 alteredTime.setVisible(false);\r
250                 subjectLabel.setVisible(false);\r
251                 subjectDate.setVisible(false);\r
252                 subjectTime.setVisible(false);\r
253                 extendedOn = false;\r
254                 buttonsVisible = true;\r
255                 setAcceptDrops(true);\r
256 \r
257                 browser = new ContentView(this);\r
258                 browser.page().setLinkDelegationPolicy(\r
259                                 QWebPage.LinkDelegationPolicy.DelegateAllLinks);\r
260                 browser.linkClicked.connect(this, "linkClicked(QUrl)");\r
261                 currentHyperlink = "";\r
262                 \r
263                 QVBoxLayout v = new QVBoxLayout();\r
264                 QFormLayout notebookLayout = new QFormLayout();\r
265                 QGridLayout dateLayout = new QGridLayout();\r
266                 titleLabel.setReadOnly(false);\r
267                 titleLabel.editingFinished.connect(this, "titleEdited()");\r
268                 browser.page().contentsChanged.connect(this, "contentChanged()");\r
269                 browser.page().selectionChanged.connect(this, "selectionChanged()");\r
270                 browser.page().mainFrame().javaScriptWindowObjectCleared.connect(this,\r
271                                 "exposeToJavascript()");\r
272 \r
273                 notebookBox.activated.connect(this, "notebookChanged()");\r
274                 resourceSignal = new NoteResourceSignal();\r
275                 \r
276                 QHBoxLayout tagLayout = new QHBoxLayout();\r
277                 v.addWidget(titleLabel, 0);\r
278                 notebookLayout.addRow(notebookLabel, notebookBox);\r
279                 tagLayout.addLayout(notebookLayout, 0);\r
280                 tagLayout.stretch(4);\r
281                 tagLayout.addWidget(tagLabel, 0);\r
282                 tagLayout.addWidget(tagEdit, 1);\r
283                 v.addLayout(tagLayout);\r
284 \r
285                 QHBoxLayout urlLayout = new QHBoxLayout();\r
286                 urlLayout.addWidget(urlLabel, 0);\r
287                 urlLayout.addWidget(urlText, 0);\r
288                 v.addLayout(urlLayout);\r
289 \r
290                 QHBoxLayout authorLayout = new QHBoxLayout();\r
291                 authorLayout.addWidget(authorLabel, 0);\r
292                 authorLayout.addWidget(authorText, 0);\r
293                 v.addLayout(authorLayout);\r
294 \r
295                 dateLayout.addWidget(createdLabel, 0, 0);\r
296                 dateLayout.addWidget(createdDate, 0, 1);\r
297                 dateLayout.addWidget(createdTime, 0, 2);\r
298                 dateLayout.setColumnStretch(9, 100);\r
299                 dateLayout.addWidget(alteredLabel, 0, 3);\r
300                 dateLayout.addWidget(alteredDate, 0, 4);\r
301                 dateLayout.addWidget(alteredTime, 0, 5);\r
302                 dateLayout.addWidget(subjectLabel, 0, 6);\r
303                 dateLayout.addWidget(subjectDate, 0, 7);\r
304                 dateLayout.addWidget(subjectTime, 0, 8);\r
305                 v.addLayout(dateLayout, 0);\r
306 \r
307                 undoButton = newEditorButton("undo", "Undo Change");\r
308                 redoButton = newEditorButton("redo", "Redo Change");\r
309                 cutButton = newEditorButton("cut", "Cut");\r
310                 copyButton = newEditorButton("copy", "Copy");\r
311                 pasteButton = newEditorButton("paste", "Paste");\r
312                 boldButton = newEditorButton("bold", "Bold");\r
313                 underlineButton = newEditorButton("underline", "Underline");\r
314                 italicButton = newEditorButton("italic", "Italic");\r
315 \r
316                 rightAlignButton = newEditorButton("justifyRight", "Right Align");\r
317                 leftAlignButton = newEditorButton("justifyLeft", "Left Align");\r
318                 centerAlignButton = newEditorButton("justifyCenter", "Center Align");\r
319 \r
320                 strikethroughButton = newEditorButton("strikethrough", "Strikethrough");\r
321                 hlineButton = newEditorButton("hline", "Insert Horizontal Line");\r
322                 indentButton = newEditorButton("indent", "Shift Right");\r
323                 outdentButton = newEditorButton("outdent", "Shift Left");\r
324                 bulletListButton = newEditorButton("bulletList", "Bullet List");\r
325                 numberListButton = newEditorButton("numberList", "Number List");\r
326 \r
327 \r
328                 QHBoxLayout buttonLayout;\r
329                 buttonLayout = new QHBoxLayout();\r
330                 buttonLayout.setSpacing(0);\r
331                 v.addLayout(buttonLayout);\r
332                 \r
333                 buttonLayout.addWidget(undoButton);\r
334                 buttonLayout.addWidget(redoButton);\r
335 \r
336                 buttonLayout.addWidget(newSeparator(), 0);\r
337                 buttonLayout.addWidget(cutButton);\r
338                 buttonLayout.addWidget(copyButton);\r
339                 buttonLayout.addWidget(pasteButton);\r
340 \r
341                 buttonLayout.addWidget(newSeparator(), 0);\r
342                 buttonLayout.addWidget(boldButton);\r
343                 buttonLayout.addWidget(italicButton);\r
344                 buttonLayout.addWidget(underlineButton);\r
345                 buttonLayout.addWidget(strikethroughButton);\r
346                 \r
347                 buttonLayout.addWidget(newSeparator(), 0);\r
348                 buttonLayout.addWidget(leftAlignButton);\r
349                 buttonLayout.addWidget(centerAlignButton);\r
350                 buttonLayout.addWidget(rightAlignButton);\r
351 \r
352                 buttonLayout.addWidget(newSeparator(), 0);\r
353                 buttonLayout.addWidget(hlineButton);\r
354 \r
355                 buttonLayout.addWidget(indentButton);\r
356                 buttonLayout.addWidget(outdentButton);\r
357                 buttonLayout.addWidget(bulletListButton);\r
358                 buttonLayout.addWidget(numberListButton);\r
359 \r
360                 // Setup the font & font size combo boxes\r
361                 buttonLayout.addWidget(newSeparator(), 0);\r
362                 fontList = new QComboBox();\r
363                 fontSize = new QComboBox();\r
364                 fontList.setToolTip("Font");\r
365                 fontSize.setToolTip("Font Size");\r
366                 fontList.activated.connect(this, "fontChanged(String)");\r
367                 fontSize.activated.connect(this, "fontSizeChanged(String)");\r
368                 buttonLayout.addWidget(fontList, 0);\r
369                 buttonLayout.addWidget(fontSize, 0);\r
370                 QFontDatabase fonts = new QFontDatabase();\r
371                 List<String> fontFamilies = fonts.families();\r
372                 for (int i = 0; i < fontFamilies.size(); i++) {\r
373                         fontList.addItem(fontFamilies.get(i));\r
374                         if (i == 0) {\r
375                                 loadFontSize(fontFamilies.get(i));\r
376                         }\r
377                 }\r
378 \r
379                 buttonLayout.addWidget(newSeparator(), 0);\r
380                 fontColor = newEditorButton("fontColor", "Font Color");\r
381                 fontColorMenu = new ColorMenu(this);\r
382                 fontColor.setMenu(fontColorMenu.getMenu());\r
383                 fontColorMenu.getMenu().triggered.connect(this, "fontColorClicked()");\r
384                 buttonLayout.addWidget(fontColor);\r
385                 fontHilight = newEditorButton("fontHilight", "Font Hilight Color");\r
386                 fontHilightColorMenu = new ColorMenu(this);\r
387                 fontHilight.setMenu(fontHilightColorMenu.getMenu());\r
388                 fontHilightColorMenu.getMenu().triggered.connect(this, "fontHilightClicked()");\r
389                 buttonLayout.addWidget(fontHilight);\r
390 \r
391                 buttonLayout.addWidget(new QLabel(), 1);\r
392                 v.addWidget(browser, 1);\r
393 //              v.addLayout(buttonLayout,0);\r
394                 setLayout(v);\r
395 \r
396                 browser.downloadAttachmentRequested.connect(this,\r
397                                 "downloadAttachment(QNetworkRequest)");\r
398                 browser.downloadImageRequested.connect(this,\r
399                                 "downloadImage(QNetworkRequest)");\r
400                 setTabOrder(notebookBox, tagEdit);\r
401                 setTabOrder(tagEdit, browser);\r
402                 \r
403                 focusNoteShortcut = new QShortcut(this);\r
404                 setupShortcut(focusNoteShortcut, "Focus_Note");\r
405                 focusNoteShortcut.activated.connect(this, "focusNote()");\r
406                 focusTitleShortcut = new QShortcut(this);\r
407                 setupShortcut(focusTitleShortcut, "Focus_Title");\r
408                 focusTitleShortcut.activated.connect(this, "focusTitle()");\r
409                 focusTagShortcut = new QShortcut(this);\r
410                 setupShortcut(focusTagShortcut, "Focus_Tag");\r
411                 focusTagShortcut.activated.connect(this, "focusTag()");\r
412                 focusAuthorShortcut = new QShortcut(this);\r
413                 setupShortcut(focusAuthorShortcut, "Focus_Author");\r
414                 focusAuthorShortcut.activated.connect(this, "focusAuthor()");\r
415                 focusUrlShortcut = new QShortcut(this);\r
416                 setupShortcut(focusUrlShortcut, "Focus_Url");\r
417                 focusUrlShortcut.activated.connect(this, "focusUrl()");\r
418                 \r
419                 browser.page().mainFrame().setTextSizeMultiplier(Global.getTextSizeMultiplier());\r
420                 browser.page().mainFrame().setZoomFactor(Global.getZoomFactor());\r
421                 \r
422                  previewPageList = new HashMap<String,Integer>();\r
423                 \r
424                 browser.page().microFocusChanged.connect(this, "microFocusChanged()");\r
425                 logger.log(logger.HIGH, "Browser setup complete");\r
426         }\r
427 \r
428         \r
429         private void setupShortcut(QShortcut action, String text) {\r
430                 if (!Global.shortcutKeys.containsAction(text))\r
431                         return;\r
432                 action.setKey(new QKeySequence(Global.shortcutKeys.getShortcut(text)));\r
433         }\r
434         \r
435         \r
436 \r
437         \r
438         // Getter for the QWebView\r
439         public QWebView getBrowser() {\r
440                 return browser;\r
441         }\r
442 \r
443         // Block signals while loading data or things are flagged as dirty by\r
444         // mistake\r
445         public void loadingData(boolean val) {\r
446                 logger.log(logger.EXTREME, "Entering BrowserWindow.loadingData() " +val);\r
447                 notebookBox.blockSignals(val);\r
448                 browser.page().blockSignals(val);\r
449                 browser.page().mainFrame().blockSignals(val);\r
450                 titleLabel.blockSignals(val);\r
451                 alteredDate.blockSignals(val);\r
452                 alteredTime.blockSignals(val);\r
453                 createdTime.blockSignals(val);\r
454                 createdDate.blockSignals(val);\r
455                 subjectDate.blockSignals(val);\r
456                 subjectTime.blockSignals(val);\r
457                 urlText.blockSignals(val);\r
458                 authorText.blockSignals(val);\r
459                 if (!val)\r
460                         exposeToJavascript();\r
461                 logger.log(logger.EXTREME, "Exiting BrowserWindow.loadingData() " +val);\r
462         }\r
463 \r
464         // Enable/disable\r
465         public void setReadOnly(boolean v) {\r
466                 setEnabled(true);\r
467                 titleLabel.setEnabled(!v);\r
468                 notebookBox.setEnabled(!v);\r
469                 tagEdit.setEnabled(!v);\r
470                 authorLabel.setEnabled(!v);\r
471                 urlText.setEnabled(!v);\r
472                 createdDate.setEnabled(!v);\r
473                 subjectDate.setEnabled(!v);\r
474                 alteredDate.setEnabled(!v);\r
475                 getBrowser().setEnabled(true);\r
476         }\r
477         \r
478         // expose this class to Javascript on the web page\r
479         private void exposeToJavascript() {\r
480                 browser.page().mainFrame().addToJavaScriptWindowObject("jambi", this);\r
481         }\r
482 \r
483         // Custom event queue\r
484         @Override\r
485         public boolean event(QEvent e) {\r
486                 if (e.type().equals(QEvent.Type.FocusOut)) {\r
487                         logger.log(logger.EXTREME, "Focus lost");\r
488                         focusLost.emit();\r
489                 }\r
490                 return super.event(e);\r
491         }\r
492 \r
493         // clear out browser\r
494         public void clear() {\r
495                 logger.log(logger.EXTREME, "Entering BrowserWindow.clear()");\r
496                 setNote(null);\r
497                 browser.setContent(new QByteArray());\r
498                 tagEdit.setText("");\r
499                 urlLabel.setText("Source URL:");\r
500                 titleLabel.setText("");\r
501                 logger.log(logger.EXTREME, "Exiting BrowserWindow.clear()");\r
502         }\r
503 \r
504         // get/set current note\r
505         public void setNote(Note n) {\r
506                 currentNote = n;\r
507                 if (n == null)\r
508                         n = new Note();\r
509                 saveNoteTitle = n.getTitle();\r
510 \r
511         }\r
512 \r
513         public Note getNote() {\r
514                 return currentNote;\r
515         }\r
516 \r
517         // New Editor Button\r
518         private QPushButton newEditorButton(String name, String toolTip) {\r
519                 QPushButton button = new QPushButton();\r
520                 QIcon icon = new QIcon(iconPath + name + ".gif");\r
521                 button.setIcon(icon);\r
522                 button.setToolTip(toolTip);\r
523                 button.clicked.connect(this, name + "Clicked()");\r
524                 return button;\r
525         }\r
526 \r
527         // New Separator\r
528         private QLabel newSeparator() {\r
529                 return new QLabel("   ");\r
530         }\r
531 \r
532         // Set the title in the window\r
533         public void setTitle(String t) {\r
534                 titleLabel.setText(t);\r
535                 saveNoteTitle = t;\r
536                 checkNoteTitle();\r
537         }\r
538 \r
539         // Return the current text title\r
540         public String getTitle() {\r
541                 return titleLabel.text();\r
542         }\r
543 \r
544         // Set the tag name string\r
545         public void setTag(String t) {\r
546                 saveTagList = t;\r
547                 tagEdit.setText(t);\r
548         }\r
549 \r
550         // Set the source URL\r
551         public void setUrl(String t) {\r
552                 urlLabel.setText("Source URL:\t");\r
553                 urlText.setText(t);\r
554         }\r
555 \r
556         public void setAuthor(String t) {\r
557                 authorLabel.setText("Author:\t");\r
558                 authorText.setText(t);\r
559         }\r
560 \r
561         // Set the creation date\r
562         public void setCreation(long date) {\r
563                 QDateTime dt = new QDateTime();\r
564                 dt.setTime_t((int) (date / 1000));\r
565                 createdDate.setDateTime(dt);\r
566                 createdTime.setDateTime(dt);\r
567                 createdDate.setDisplayFormat(Global.getDateFormat());\r
568                 createdTime.setDisplayFormat(Global.getTimeFormat());\r
569         }\r
570 \r
571         // Set the creation date\r
572         public void setAltered(long date) {\r
573                 QDateTime dt = new QDateTime();\r
574                 dt.setTime_t((int) (date / 1000));\r
575                 alteredDate.setDateTime(dt);\r
576                 alteredTime.setDateTime(dt);\r
577                 alteredDate.setDisplayFormat(Global.getDateFormat());\r
578                 alteredTime.setDisplayFormat(Global.getTimeFormat());\r
579         }\r
580 \r
581         // Set the subject date\r
582         public void setSubjectDate(long date) {\r
583                 QDateTime dt = new QDateTime();\r
584                 dt.setTime_t((int) (date / 1000));\r
585                 subjectDate.setDateTime(dt);\r
586                 subjectTime.setDateTime(dt);\r
587                 subjectDate.setDisplayFormat(Global.getDateFormat());\r
588                 subjectTime.setDisplayFormat(Global.getTimeFormat());\r
589         }\r
590 \r
591         // Toggle the extended attribute information\r
592         public void toggleInformation() {\r
593                 if (extendedOn) {\r
594                         extendedOn = false;\r
595                 } else {\r
596                         extendedOn = true;\r
597                 }\r
598                 urlLabel.setVisible(extendedOn);\r
599                 urlText.setVisible(extendedOn);\r
600                 authorText.setVisible(extendedOn);\r
601                 authorLabel.setVisible(extendedOn);\r
602                 createdDate.setVisible(extendedOn);\r
603                 createdTime.setVisible(extendedOn);\r
604                 createdLabel.setVisible(extendedOn);\r
605                 alteredLabel.setVisible(extendedOn);\r
606                 alteredDate.setVisible(extendedOn);\r
607                 alteredTime.setVisible(extendedOn);\r
608                 //notebookBox.setVisible(extendedOn);\r
609                 notebookLabel.setVisible(extendedOn);\r
610                 subjectLabel.setVisible(extendedOn);\r
611                 subjectDate.setVisible(extendedOn);\r
612                 subjectTime.setVisible(extendedOn);\r
613         }\r
614 \r
615         public void hideButtons() {\r
616 \r
617                 buttonsVisible = false;\r
618                 \r
619                 undoButton.setVisible(false);\r
620                 redoButton.setVisible(false);\r
621                 cutButton.setVisible(false);\r
622                 copyButton.setVisible(false);\r
623                 pasteButton.setVisible(false);\r
624                 boldButton.setVisible(false);\r
625                 underlineButton.setVisible(false);\r
626                 italicButton.setVisible(false);\r
627 \r
628                 rightAlignButton.setVisible(false);\r
629                 leftAlignButton.setVisible(false);\r
630                 centerAlignButton.setVisible(false);\r
631 \r
632                 strikethroughButton.setVisible(false);\r
633                 hlineButton.setVisible(false);\r
634                 indentButton.setVisible(false);\r
635                 outdentButton.setVisible(false);\r
636                 bulletListButton.setVisible(false);\r
637                 numberListButton.setVisible(false);\r
638 \r
639                 fontList.setVisible(false);\r
640                 fontSize.setVisible(false);\r
641                 fontColor.setVisible(false);\r
642                 fontHilight.setVisible(false);\r
643 \r
644         }\r
645 \r
646 \r
647         // Is the extended view on?\r
648         public boolean isExtended() {\r
649                 return extendedOn;\r
650         }\r
651 \r
652         // Listener for when a link is clicked\r
653         @SuppressWarnings("unused")\r
654         private void openFile() {\r
655                 logger.log(logger.EXTREME, "Starting openFile()");\r
656                 File fileHandle = new File(selectedFile);\r
657                 URI fileURL = fileHandle.toURI();\r
658                 String localURL = fileURL.toString();\r
659                 QUrl url = new QUrl(localURL);\r
660                 QFile file = new QFile(selectedFile);\r
661                 \r
662                 logger.log(logger.EXTREME, "Adding to fileWatcher:"+file.fileName());\r
663                 fileWatcher.addPath(file.fileName());\r
664         \r
665         if (!QDesktopServices.openUrl(url)) {\r
666                 logger.log(logger.LOW, "Error opening file :" +url);\r
667         }\r
668         }\r
669         \r
670         \r
671         // Listener for when a link is clicked\r
672         @SuppressWarnings("unused")\r
673         private void linkClicked(QUrl url) {\r
674                 logger.log(logger.EXTREME, "URL Clicked: " +url.toString());\r
675                 if (url.toString().substring(0,8).equals("nnres://")) {\r
676                         logger.log(logger.EXTREME, "URL is NN resource");\r
677                         if (url.toString().endsWith("/vnd.evernote.ink")) {\r
678                                 logger.log(logger.EXTREME, "Unable to open ink note");\r
679                                 QMessageBox.information(this, "Unable Open", "This is an ink note.\n"+\r
680                                         "Ink notes are not supported since Evernote has not\n published any specifications on them\n" +\r
681                                         "and I'm too lazy to figure them out by myself.");\r
682                                 return;\r
683                         }\r
684                         String fullName = url.toString().substring(8);\r
685                         int index = fullName.indexOf(".");\r
686                         String guid = "";\r
687                         String type = "";\r
688                         if (index >-1) {\r
689                                 type = fullName.substring(index+1);\r
690                                 guid = fullName.substring(0,index);\r
691                         }\r
692                         index = guid.indexOf(Global.attachmentNameDelimeter);\r
693                         if (index > -1) {\r
694                                 guid = guid.substring(0,index);\r
695                         }\r
696                         List<Resource> resList = currentNote.getResources();\r
697                         Resource res = null;\r
698                         for (int i=0; i<resList.size(); i++) {\r
699                                 if (resList.get(i).getGuid().equals(guid)) {\r
700                                         res = resList.get(i);\r
701                                         i=resList.size();\r
702                                 }\r
703                         }\r
704                         if (res == null) {\r
705                                 String resGuid = Global.resourceMap.get(guid);\r
706                                 if (resGuid != null) \r
707                                         res = conn.getNoteTable().noteResourceTable.getNoteResource(resGuid, true);\r
708                         }\r
709                         if (res != null) {\r
710                                 String fileName;\r
711                                 if (res.getAttributes() != null && \r
712                                                 res.getAttributes().getFileName() != null && \r
713                                                 !res.getAttributes().getFileName().trim().equals(""))\r
714                                         fileName = res.getGuid()+Global.attachmentNameDelimeter+res.getAttributes().getFileName();\r
715                                 else\r
716                                         fileName = res.getGuid()+"."+type;\r
717                                 QFile file = new QFile(Global.getDirectoryPath() +"res/"+fileName);\r
718                         QFile.OpenMode mode = new QFile.OpenMode();\r
719                         mode.set(QFile.OpenModeFlag.WriteOnly);\r
720                         boolean openResult = file.open(mode);\r
721                                 logger.log(logger.EXTREME, "File opened:" +openResult);\r
722                         QDataStream out = new QDataStream(file);\r
723                         Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(res.getGuid(), true);\r
724                                 QByteArray binData = new QByteArray(resBinary.getData().getBody());\r
725                                 resBinary = null;\r
726                                 logger.log(logger.EXTREME, "Writing resource");\r
727                         out.writeBytes(binData.toByteArray());\r
728                         file.close();\r
729                                 \r
730                         String whichOS = System.getProperty("os.name");\r
731                                 if (whichOS.contains("Windows")) \r
732                                 url.setUrl("file:///"+file.fileName());\r
733                         else\r
734                                 url.setUrl("file://"+file.fileName());\r
735                  //       fileWatcher.removePath(file.fileName());\r
736                                 logger.log(logger.EXTREME, "Adding file watcher " +file.fileName());\r
737                                 fileWatcher.addPath(file.fileName());\r
738                         \r
739                         // If we can't open it, then prompt the user to save it.\r
740                         if (!QDesktopServices.openUrl(url)) {\r
741                                         logger.log(logger.EXTREME, "We can't handle this.  Where do we put it?");\r
742                                 QFileDialog dialog = new QFileDialog();\r
743                                 dialog.show();\r
744                                 if (dialog.exec()!=0) {\r
745                                         List<String> fileNames = dialog.selectedFiles(); //gets all selected filenames\r
746                                         if (fileNames.size() == 0) \r
747                                                 return;\r
748                                         String sf = fileNames.get(0);\r
749                                         QFile saveFile = new QFile(sf);\r
750                                         mode.set(QFile.OpenModeFlag.WriteOnly);\r
751                                         saveFile.open(mode);\r
752                                         QDataStream saveOut = new QDataStream(saveFile);\r
753                                         saveOut.writeBytes(binData.toByteArray());\r
754                                         saveFile.close();\r
755                                         return;\r
756                                 }\r
757                                 }\r
758                         }\r
759                         return;\r
760                 }\r
761                 logger.log(logger.EXTREME, "Launching URL");\r
762                 QDesktopServices.openUrl(url);\r
763         }\r
764 \r
765         // Listener for when BOLD is clicked\r
766         @SuppressWarnings("unused")\r
767         private void undoClicked() {\r
768                 browser.page().triggerAction(WebAction.Undo);\r
769                 browser.setFocus();\r
770         }\r
771 \r
772         // Listener for when BOLD is clicked\r
773         @SuppressWarnings("unused")\r
774         private void redoClicked() {\r
775                 browser.page().triggerAction(WebAction.Redo);\r
776                 browser.setFocus();\r
777         }\r
778 \r
779         // Listener for when BOLD is clicked\r
780         @SuppressWarnings("unused")\r
781         private void boldClicked() {\r
782                 browser.page().triggerAction(WebAction.ToggleBold);\r
783                 microFocusChanged();\r
784                 browser.setFocus();\r
785         }\r
786 \r
787         // Listener for when Italics is clicked\r
788         @SuppressWarnings("unused")\r
789         private void italicClicked() {\r
790                 browser.page().triggerAction(WebAction.ToggleItalic);\r
791                 microFocusChanged();\r
792                 browser.setFocus();\r
793         }\r
794 \r
795         // Listener for when UNDERLINE is clicked\r
796         @SuppressWarnings("unused")\r
797         private void underlineClicked() {\r
798                 browser.page().triggerAction(WebAction.ToggleUnderline);\r
799                 microFocusChanged();\r
800                 browser.setFocus();\r
801         }\r
802 \r
803         // Listener for when Strikethrough is clicked\r
804         @SuppressWarnings("unused")\r
805         private void strikethroughClicked() {\r
806                 browser.page().mainFrame().evaluateJavaScript(\r
807                                 "document.execCommand('strikeThrough', false, '');");\r
808                 browser.setFocus();\r
809         }\r
810 \r
811         // Listener for when cut is clicked\r
812         @SuppressWarnings("unused")\r
813         private void cutClicked() {\r
814                 browser.page().triggerAction(WebAction.Cut);\r
815                 browser.setFocus();\r
816         }\r
817 \r
818         // Listener when COPY is clicked\r
819         @SuppressWarnings("unused")\r
820         private void copyClicked() {\r
821                 browser.page().triggerAction(WebAction.Copy);\r
822                 browser.setFocus();\r
823         }\r
824 \r
825         // Listener when PASTE is clicked\r
826         void pasteClicked() {\r
827                 logger.log(logger.EXTREME, "Paste Clicked");\r
828                 if (forceTextPaste) {\r
829                         pasteWithoutFormattingClicked();\r
830                         return;\r
831                 }\r
832                 QClipboard clipboard = QApplication.clipboard();\r
833                 QMimeData mime = clipboard.mimeData();\r
834                 \r
835 //               String x = mime.html();\r
836 \r
837                 if (mime.hasImage()) {\r
838                         logger.log(logger.EXTREME, "Image paste found");\r
839                         insertImage(mime);\r
840                         browser.setFocus();\r
841                         return;\r
842                 }\r
843 \r
844                 if (mime.hasUrls()) {\r
845                         logger.log(logger.EXTREME, "URL paste found");\r
846                         handleUrls(mime);\r
847                         browser.setFocus();\r
848                         return;\r
849                 }\r
850                 \r
851                 String text = mime.html();\r
852                 if (text.contains("en-tag") && mime.hasHtml()) {\r
853                         logger.log(logger.EXTREME, "Intra-note paste found");\r
854                         text = fixInternotePaste(text);\r
855                         mime.setHtml(text);\r
856                         clipboard.setMimeData(mime);\r
857                 }\r
858 \r
859                 logger.log(logger.EXTREME, "Final paste choice encountered");\r
860                 browser.page().triggerAction(WebAction.Paste);\r
861                 browser.setFocus();\r
862 \r
863         }\r
864 \r
865         // Paste text without formatting\r
866         private void pasteWithoutFormattingClicked() {\r
867                 logger.log(logger.EXTREME, "Paste without format clipped");\r
868                 QClipboard clipboard = QApplication.clipboard();\r
869                 QMimeData mime = clipboard.mimeData();\r
870                 if (!mime.hasText())\r
871                         return;\r
872                 String text = mime.text();\r
873                 clipboard.setText(text);\r
874                 browser.page().triggerAction(WebAction.Paste);\r
875                 QApplication.clipboard().setMimeData(mime);\r
876                 browser.setFocus();\r
877 \r
878         }\r
879         \r
880         // insert date/time\r
881         @SuppressWarnings("unused")\r
882         private void insertDateTime() {\r
883                 String fmt = Global.getDateFormat() + " " + Global.getTimeFormat();\r
884                 String dateTimeFormat = new String(fmt);\r
885                 SimpleDateFormat simple = new SimpleDateFormat(dateTimeFormat);\r
886                 Calendar cal = Calendar.getInstance();\r
887                 \r
888                 browser.page().mainFrame().evaluateJavaScript(\r
889                         "document.execCommand('insertHtml', false, '"+simple.format(cal.getTime())+"');");\r
890                 \r
891                 browser.setFocus();\r
892 \r
893         }\r
894 \r
895         // Listener when Left is clicked\r
896         @SuppressWarnings("unused")\r
897         private void justifyLeftClicked() {\r
898                 browser.page().mainFrame().evaluateJavaScript(\r
899                                 "document.execCommand('JustifyLeft', false, '');");\r
900                 browser.setFocus();\r
901         }\r
902 \r
903         // Listener when Center is clicked\r
904         @SuppressWarnings("unused")\r
905         private void justifyCenterClicked() {\r
906                 browser.page().mainFrame().evaluateJavaScript(\r
907                                 "document.execCommand('JustifyCenter', false, '');");\r
908                 browser.setFocus();\r
909         }\r
910 \r
911         // Listener when Left is clicked\r
912         @SuppressWarnings("unused")\r
913         private void justifyRightClicked() {\r
914                 browser.page().mainFrame().evaluateJavaScript(\r
915                                 "document.execCommand('JustifyRight', false, '');");\r
916                 browser.setFocus();\r
917         }\r
918 \r
919         // Listener when HLINE is clicked\r
920         @SuppressWarnings("unused")\r
921         private void hlineClicked() {\r
922                 browser.page().mainFrame().evaluateJavaScript(\r
923                                 "document.execCommand('insertHorizontalRule', false, '');");\r
924                 browser.setFocus();\r
925         }\r
926 \r
927         // Listener when outdent is clicked\r
928         private void outdentClicked() {\r
929                 browser.page().mainFrame().evaluateJavaScript(\r
930                                 "document.execCommand('outdent', false, '');");\r
931                 browser.setFocus();\r
932         }\r
933 \r
934         // Listener when a bullet list is clicked\r
935         @SuppressWarnings("unused")\r
936         private void bulletListClicked() {\r
937                 browser.page().mainFrame().evaluateJavaScript(\r
938                                 "document.execCommand('InsertUnorderedList', false, '');");\r
939                 browser.setFocus();\r
940         }\r
941 \r
942         // Listener when a bullet list is clicked\r
943         @SuppressWarnings("unused")\r
944         private void numberListClicked() {\r
945                 browser.page().mainFrame().evaluateJavaScript(\r
946                                 "document.execCommand('InsertOrderedList', false, '');");\r
947                 browser.setFocus();\r
948         }\r
949 \r
950         // Listener when indent is clicked\r
951         private void indentClicked() {\r
952                 browser.page().mainFrame().evaluateJavaScript(\r
953                                 "document.execCommand('indent', false, '');");\r
954                 browser.setFocus();\r
955         }\r
956 \r
957         // Listener when the font name is changed\r
958         @SuppressWarnings("unused")\r
959         private void fontChanged(String font) {\r
960                 browser.page().mainFrame().evaluateJavaScript(\r
961                                 "document.execCommand('fontName',false,'" + font + "');");\r
962                 browser.setFocus();\r
963         }\r
964 \r
965         // Listener when a font size is changed\r
966         @SuppressWarnings("unused")\r
967         private void fontSizeChanged(String font) {\r
968                 String text = browser.selectedText();\r
969                 if (text.trim().equalsIgnoreCase(""))\r
970                         return;\r
971 \r
972                 String selectedText = browser.selectedText();\r
973                 String url = "<span style=\"font-size:" +font +"pt; \">"+selectedText +"</a>";\r
974                 String script = "document.execCommand('insertHtml', false, '"+url+"');";\r
975                 browser.page().mainFrame().evaluateJavaScript(script);\r
976 /*              browser.page().mainFrame().evaluateJavaScript(\r
977                                 "document.execCommand('fontSize',false,'"\r
978                                                 + font + "');");\r
979 */\r
980                 browser.setFocus();\r
981         }\r
982 \r
983         // Load the font combo box based upon the font selected\r
984         private void loadFontSize(String name) {        \r
985                 QFontDatabase db = new QFontDatabase(); \r
986                 fontSize.clear();\r
987                 List<Integer> points = db.pointSizes(name); \r
988                 for (int i=0; i<points.size(); i++) { \r
989                         fontSize.addItem(points.get(i).toString()); \r
990                 }\r
991                 /*\r
992                 fontSize.addItem("x-small");\r
993                 fontSize.addItem("small");\r
994                 fontSize.addItem("medium");\r
995                 fontSize.addItem("large");\r
996                 fontSize.addItem("x-large");\r
997                 fontSize.addItem("xx-large");\r
998                 fontSize.addItem("xxx-large");\r
999                 */\r
1000         }\r
1001 \r
1002         // Listener when a font size is changed\r
1003         @SuppressWarnings("unused")\r
1004         private void fontColorClicked() {\r
1005 //              QColorDialog dialog = new QColorDialog();\r
1006 //              QColor color = QColorDialog.getColor();\r
1007                 QColor color = fontColorMenu.getColor();\r
1008                 if (color.isValid())\r
1009                         browser.page().mainFrame().evaluateJavaScript(\r
1010                                         "document.execCommand('foreColor',false,'" + color.name()\r
1011                                                         + "');");\r
1012                 browser.setFocus();\r
1013         }\r
1014 \r
1015         // Listener for when a background color change is requested\r
1016         @SuppressWarnings("unused")\r
1017         private void fontHilightClicked() {\r
1018 //              QColorDialog dialog = new QColorDialog();\r
1019 //              QColor color = QColorDialog.getColor();\r
1020                 QColor color = fontHilightColorMenu.getColor();\r
1021                 if (color.isValid())\r
1022                         browser.page().mainFrame().evaluateJavaScript(\r
1023                                         "document.execCommand('backColor',false,'" + color.name()\r
1024                                                         + "');");\r
1025                 browser.setFocus();\r
1026         }\r
1027         \r
1028         // Listener for when a background color change is requested\r
1029         @SuppressWarnings("unused")\r
1030         private void superscriptClicked() {\r
1031                 browser.page().mainFrame().evaluateJavaScript(\r
1032                                         "document.execCommand('superscript');");\r
1033                 browser.setFocus();\r
1034         }\r
1035         \r
1036         // Listener for when a background color change is requested\r
1037         @SuppressWarnings("unused")\r
1038         private void subscriptClicked() {\r
1039                 browser.page().mainFrame().evaluateJavaScript(\r
1040                                         "document.execCommand('subscript');");\r
1041                 browser.setFocus();\r
1042         }\r
1043         // Insert a to-do checkbox\r
1044         @SuppressWarnings("unused")\r
1045         private void todoClicked() {\r
1046                 FileNameMap fileNameMap = URLConnection.getFileNameMap();\r
1047                 String script_start = new String(\r
1048                                 "document.execCommand('insertHtml', false, '");\r
1049                 String script_end = new String("');");\r
1050                 String todo = new String(\r
1051                                 "<input TYPE=\"CHECKBOX\" value=\"false\" onClick=\"value=checked; window.jambi.contentChanged(); \" />");\r
1052                 browser.page().mainFrame().evaluateJavaScript(\r
1053                                 script_start + todo + script_end);\r
1054                 browser.setFocus();\r
1055         }\r
1056 \r
1057         // Encrypt the selected text\r
1058         @SuppressWarnings("unused")\r
1059         private void encryptText() {\r
1060                 String text = browser.selectedText();\r
1061                 if (text.trim().equalsIgnoreCase(""))\r
1062                         return;\r
1063 \r
1064                 EnCryptDialog dialog = new EnCryptDialog();\r
1065                 dialog.exec();\r
1066                 if (!dialog.okPressed()) {\r
1067                         return;\r
1068                 }\r
1069 \r
1070                 EnCrypt crypt = new EnCrypt();\r
1071                 String encrypted = crypt.encrypt(text, dialog.getPassword().trim(), 64);\r
1072 \r
1073                 if (encrypted.trim().equals("")) {\r
1074                         QMessageBox.information(this, "Error", "Error Encrypting String");\r
1075                         return;\r
1076                 }\r
1077                 StringBuffer imgPath = new StringBuffer(Global.getDirectoryPath());\r
1078                 for (int i = 0; i < imgPath.length(); i++)\r
1079                         if (imgPath.charAt(i) == '\\')\r
1080                                 imgPath.setCharAt(i, '/');\r
1081                 StringBuffer buffer = new StringBuffer(encrypted.length() + 100);\r
1082                 buffer.append("<img en-tag=\"en-crypt\" cipher=\"RC2\" hint=\""\r
1083                                 + dialog.getHint().replace("'","\\'") + "\" length=\"64\" ");\r
1084                 buffer.append("contentEditable=\"false\" alt=\"");\r
1085                 buffer.append(encrypted);\r
1086                 buffer.append("\" src=\"" + imgPath.toString()\r
1087                                 + "images/encrypt.png\" ");\r
1088                 Global.cryptCounter++;\r
1089                 buffer.append(" id=\"crypt"+Global.cryptCounter.toString() +"\"");\r
1090                 buffer.append(" onMouseOver=\"style.cursor=\\'hand\\'\"");\r
1091                 buffer.append(" onClick=\"window.jambi.decryptText(\\'crypt"+Global.cryptCounter.toString() \r
1092                                 +"\\', \\'"+encrypted+"\\', \\'"+dialog.getHint().replace("'", "\\&amp;apos;")+"\\');\"");\r
1093                 buffer.append("style=\"display:block\" />");\r
1094 \r
1095                 String script_start = new String(\r
1096                                 "document.execCommand('insertHtml', false, '");\r
1097                 String script_end = new String("');");\r
1098                 browser.page().mainFrame().evaluateJavaScript(\r
1099                                 script_start + buffer.toString() + script_end);\r
1100         }\r
1101 \r
1102         \r
1103         // Insert a hyperlink\r
1104         public void insertLink() {\r
1105                 logger.log(logger.EXTREME, "Inserting link");\r
1106                 String text = browser.selectedText();\r
1107                 if (text.trim().equalsIgnoreCase(""))\r
1108                         return;\r
1109 \r
1110                 InsertLinkDialog dialog = new InsertLinkDialog();\r
1111                 if (currentHyperlink != null && currentHyperlink != "") {\r
1112                         dialog.setUrl(currentHyperlink);\r
1113                 }\r
1114                 dialog.exec();\r
1115                 if (!dialog.okPressed()) {\r
1116                         logger.log(logger.EXTREME, "Insert link canceled");\r
1117                         return;\r
1118                 }\r
1119                 if (browser.insertLinkAction.text().equalsIgnoreCase("Insert Hyperlink")) {\r
1120                         String selectedText = browser.selectedText();\r
1121                         logger.log(logger.EXTREME, "Inserting link on text "+selectedText);\r
1122                         logger.log(logger.EXTREME, "URL Link " +dialog.getUrl().trim());\r
1123                         String url = "<a href=\"" +dialog.getUrl().trim()+"\" >"+selectedText +"</a>";\r
1124                         String script = "document.execCommand('insertHtml', false, '"+url+"');";\r
1125                         browser.page().mainFrame().evaluateJavaScript(script);\r
1126                         return;\r
1127                 } else {\r
1128                         String js = new String( "function getCursorPos() {"\r
1129                                         +"var cursorPos;"\r
1130                                         +"if (window.getSelection) {"\r
1131                                         +"   var selObj = window.getSelection();"\r
1132                                         +"   var selRange = selObj.getRangeAt(0);"\r
1133                                         +"   var workingNode = window.getSelection().anchorNode.parentNode;"\r
1134                                         +"   while(workingNode != null) { " \r
1135                                         +"      if (workingNode.nodeName.toLowerCase()=='a') workingNode.setAttribute('href','" +dialog.getUrl() +"');"\r
1136                                         +"      workingNode = workingNode.parentNode;"\r
1137                                         +"   }"\r
1138                                         +"}"\r
1139                                         +"} getCursorPos();");\r
1140                                 browser.page().mainFrame().evaluateJavaScript(js);\r
1141                                 contentChanged();\r
1142                 }\r
1143                 \r
1144         }\r
1145         \r
1146         // Insert a table\r
1147         public void insertTable() {\r
1148                 TableDialog dialog = new TableDialog();\r
1149                 dialog.exec();\r
1150                 if (!dialog.okPressed()) {\r
1151                         return;\r
1152                 }\r
1153                 \r
1154                 int cols = dialog.getCols();\r
1155                 int rows = dialog.getRows();\r
1156                 int width = dialog.getWidth();\r
1157                 boolean percent = dialog.isPercent();\r
1158                 \r
1159                 String newHTML = "<table border=\"1\" width=\"" +new Integer(width).toString();\r
1160                 if (percent)\r
1161                         newHTML = newHTML +"%";\r
1162                 newHTML = newHTML + "\"><tbody>";\r
1163 \r
1164                 for (int i=0; i<rows; i++) {\r
1165                         newHTML = newHTML +"<tr>";\r
1166                         for (int j=0; j<cols; j++) {\r
1167                                 newHTML = newHTML +"<td>&nbsp;</td>";\r
1168                         }\r
1169                         newHTML = newHTML +"</tr>";\r
1170                 }\r
1171                 newHTML = newHTML+"</tbody></table>";   \r
1172         \r
1173                 String script = "document.execCommand('insertHtml', false, '"+newHTML+"');";\r
1174                 browser.page().mainFrame().evaluateJavaScript(script);\r
1175         }\r
1176         \r
1177         \r
1178         // Text content changed\r
1179         @SuppressWarnings("unused")\r
1180         private void selectionChanged() {\r
1181                 browser.encryptAction.setEnabled(true);\r
1182                 browser.insertLinkAction.setEnabled(true);\r
1183                 String scriptStart = "var selection_text = (window.getSelection()).toString();"\r
1184                                 + "var range = (window.getSelection()).getRangeAt(0);"\r
1185                                 + "var parent_html = range.commonAncestorContainer.innerHTML;"\r
1186                                 + "if (parent_html == undefined) {window.jambi.saveSelectedText(selection_text); return;}"\r
1187                                 + "var first_text = range.startContainer.nodeValue.substr(range.startOffset);"\r
1188                                 + "var last_text = (range.endContainer.nodeValue).substring(0,range.endOffset);"\r
1189                                 + "var start = parent_html.indexOf(first_text);"\r
1190                                 + "var end = parent_html.indexOf(last_text,start+1)+last_text.length;"\r
1191                                 + "var value = parent_html.substring(start,end);"\r
1192                                 + "window.jambi.saveSelectedText(value);" ;\r
1193                 browser.page().mainFrame().evaluateJavaScript(scriptStart);\r
1194 \r
1195         }\r
1196 \r
1197         public void saveSelectedText(String text) {\r
1198                 boolean enabled = true;\r
1199                 if (text.trim().length() == 0)\r
1200                         enabled=false;\r
1201                 if (text.indexOf("en-tag=\"en-crypt\"") >= 0)\r
1202                         enabled=false;\r
1203                 if (text.indexOf("<img en-tag=\"en-media\"") >= 0)\r
1204                         enabled=false;\r
1205                 if (text.indexOf("<a en-tag=\"en-media\"") >= 0)\r
1206                         enabled=false;\r
1207                 if (text.indexOf("<input ") >= 0)\r
1208                         enabled=false;\r
1209                 \r
1210                 browser.encryptAction.setEnabled(enabled);\r
1211                 browser.insertLinkAction.setEnabled(enabled);\r
1212 //              selectedText = text;\r
1213         }\r
1214 \r
1215         // Decrypt clicked text\r
1216         public void decryptText(String id, String text, String hint) {\r
1217                 EnCrypt crypt = new EnCrypt();\r
1218                 String plainText = null;\r
1219                 Calendar currentTime = new GregorianCalendar();\r
1220                 Long l = new Long(currentTime.getTimeInMillis());\r
1221                 String slot = new String(Long.toString(l));\r
1222                 \r
1223                 // First, try to decrypt with any keys we already have\r
1224                 for (int i=0; i<Global.passwordRemember.size(); i++) {\r
1225                         plainText = crypt.decrypt(text, Global.passwordRemember.get(i), 64);\r
1226                         if (plainText != null) {\r
1227                                 slot = new String(Long.toString(l));\r
1228                                 Global.passwordSafe.put(slot, Global.passwordRemember.get(i));\r
1229                                 removeEncryption(id, plainText, false, slot);   \r
1230                                 return;\r
1231                         }\r
1232                 }\r
1233                 \r
1234                 \r
1235                 EnDecryptDialog dialog = new EnDecryptDialog();\r
1236                 dialog.setHint(hint);\r
1237                 while (plainText == null || !dialog.okPressed()) {\r
1238                         dialog.exec();\r
1239                         if (!dialog.okPressed()) {\r
1240                                 return;\r
1241                         }\r
1242                         plainText = crypt.decrypt(text, dialog.getPassword().trim(), 64);\r
1243                         if (plainText == null) {\r
1244                                 QMessageBox.warning(this, "Incorrect Password", "The password entered is not correct");\r
1245                         }\r
1246                 }\r
1247                 Global.passwordSafe.put(slot, dialog.getPassword());\r
1248                 removeEncryption(id, plainText, dialog.permanentlyDecrypt(), slot);\r
1249                 if (dialog.rememberPassword())\r
1250                         Global.passwordRemember.add(dialog.getPassword());\r
1251 \r
1252         }\r
1253 \r
1254         // Get the editor tag line\r
1255         public TagLineEdit getTagLine() {\r
1256                 return tagEdit;\r
1257         }\r
1258 \r
1259         // Modify a note's tags\r
1260         @SuppressWarnings("unused")\r
1261         private void modifyTags() {\r
1262                 TagAssign tagWindow = new TagAssign(allTags, currentTags);\r
1263                 tagWindow.exec();\r
1264                 if (tagWindow.okClicked()) {\r
1265                         currentTags.clear();\r
1266                         StringBuffer tagDisplay = new StringBuffer();\r
1267 \r
1268                         List<QListWidgetItem> newTags = tagWindow.getTagList()\r
1269                                         .selectedItems();\r
1270                         for (int i = 0; i < newTags.size(); i++) {\r
1271                                 currentTags.add(newTags.get(i).text());\r
1272                                 tagDisplay.append(newTags.get(i).text());\r
1273                                 if (i < newTags.size() - 1) {\r
1274                                         tagDisplay.append(Global.tagDelimeter + " ");\r
1275                                 }\r
1276                         }\r
1277                         tagEdit.setText(tagDisplay.toString());\r
1278                         noteSignal.tagsChanged.emit(currentNote.getGuid(), currentTags);\r
1279                 }\r
1280         }\r
1281 \r
1282         // Tag line has been modified by typing text\r
1283         @SuppressWarnings("unused")\r
1284         private void modifyTagsTyping() {\r
1285 \r
1286                 String newTags = tagEdit.text();\r
1287                 List<String> test = tagEdit.tagCompleter.getTagList();\r
1288                 if (newTags.equalsIgnoreCase(saveTagList))\r
1289                         return;\r
1290 \r
1291                 // We know something has changed...\r
1292                 String oldTagArray[] = saveTagList.split(Global.tagDelimeter);\r
1293                 String newTagArray[] = newTags.split(Global.tagDelimeter);\r
1294 \r
1295                 List<String> newTagList = new ArrayList<String>();\r
1296                 List<String> oldTagList = new ArrayList<String>();\r
1297 \r
1298                 for (int i = 0; i < oldTagArray.length; i++)\r
1299                         if (!oldTagArray[i].trim().equals(""))\r
1300                                 oldTagList.add(oldTagArray[i]);\r
1301                 for (int i = 0; i < newTagArray.length; i++)\r
1302                         if (!newTagArray[i].trim().equals(""))\r
1303                                 newTagList.add(newTagArray[i]);\r
1304 \r
1305                 // We now have lists of the new & old. Remove duplicates. If all\r
1306                 // are removed from both then nothing has really changed\r
1307                 for (int i = newTagList.size() - 1; i >= 0; i--) {\r
1308                         String nTag = newTagList.get(i);\r
1309                         for (int j = oldTagList.size() - 1; j >= 0; j--) {\r
1310                                 String oTag = oldTagList.get(j);\r
1311                                 if (oTag.equalsIgnoreCase(nTag)) {\r
1312                                         oldTagList.remove(j);\r
1313                                         newTagList.remove(i);\r
1314                                         j = -1;\r
1315                                 }\r
1316                         }\r
1317                 }\r
1318 \r
1319                 if (oldTagList.size() != 0 || newTagList.size() != 0) {\r
1320                         currentTags.clear();\r
1321                         for (int i = 0; i < newTagArray.length; i++)\r
1322                                 if (!newTagArray[i].trim().equals(""))\r
1323                                         currentTags.add(newTagArray[i].trim());\r
1324 \r
1325                         noteSignal.tagsChanged.emit(currentNote.getGuid(), currentTags);\r
1326                 }\r
1327 \r
1328         }\r
1329 \r
1330         // Tab button was pressed\r
1331         public void tabPressed() {\r
1332                 if (!insideList) {\r
1333                         String script_start = new String(\r
1334                         "document.execCommand('insertHtml', false, '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;');");\r
1335                         browser.page().mainFrame().evaluateJavaScript(script_start);\r
1336                 } else \r
1337                         indentClicked();\r
1338         }\r
1339         \r
1340         public void backtabPressed() {\r
1341                 if (insideList)\r
1342                         outdentClicked();\r
1343         }\r
1344         \r
1345         public void setInsideList() {\r
1346                 insideList = true;\r
1347         }\r
1348         \r
1349         // The title has been edited\r
1350         @SuppressWarnings("unused")\r
1351         private void titleEdited() {\r
1352                 // If we don't have a good note, or if the current title\r
1353                 // matches the old title then we don't need to do anything\r
1354                 if (currentNote == null)\r
1355                         return;\r
1356                 if (currentNote.getTitle().trim().equals(titleLabel.text().trim()))\r
1357                         return;\r
1358                 \r
1359                 // If we have a real change, we need to save it.\r
1360                 noteSignal.titleChanged.emit(currentNote.getGuid(), titleLabel.text());\r
1361                 currentNote.setTitle(titleLabel.text());\r
1362                 saveNoteTitle = titleLabel.text();\r
1363                 checkNoteTitle();\r
1364         }\r
1365 \r
1366         // Set the list of note tags\r
1367         public void setAllTags(List<Tag> l) {\r
1368                 allTags = l;\r
1369                 tagEdit.setTagList(l);\r
1370         }\r
1371 \r
1372         // Setter for the current tags\r
1373         public void setCurrentTags(List<String> s) {\r
1374                 currentTags = s;\r
1375         }\r
1376 \r
1377         // Save the list of notebooks\r
1378         public void setNotebookList(List<Notebook> n) {\r
1379                 notebookList = n;\r
1380                 loadNotebookList();\r
1381         }\r
1382 \r
1383         // Load the notebook list and select the current notebook\r
1384         private void loadNotebookList() {\r
1385                 if (notebookBox.count() != 0)\r
1386                         notebookBox.clear();\r
1387                 if (notebookList == null)\r
1388                         return;\r
1389 \r
1390                 for (int i = 0; i < notebookList.size(); i++) {\r
1391                         notebookBox.addItem(notebookList.get(i).getName());\r
1392                         if (currentNote != null) {\r
1393                                 if (currentNote.getNotebookGuid().equals(\r
1394                                                 notebookList.get(i).getGuid())) {\r
1395                                         notebookBox.setCurrentIndex(i);\r
1396                                 }\r
1397                         }\r
1398                 }\r
1399         }\r
1400 \r
1401         // Get the contents of the editor\r
1402         public String getContent() {\r
1403                 return browser.page().currentFrame().toHtml();\r
1404         }\r
1405 \r
1406         // The note contents have changed\r
1407         public void contentChanged() {\r
1408                 String content = getContent();\r
1409                 checkNoteTitle();\r
1410                 noteSignal.noteChanged.emit(currentNote.getGuid(), content); \r
1411                 \r
1412                 \r
1413 //        noteSignal.noteChanged.emit(currentNote.getGuid(), unicode);\r
1414         }\r
1415 \r
1416         // The notebook selection has changed\r
1417         @SuppressWarnings("unused")\r
1418         private void notebookChanged() {\r
1419                 boolean changed = false;\r
1420                 String n = notebookBox.currentText();\r
1421                 for (int i = 0; i < notebookList.size(); i++) {\r
1422                         if (n.equals(notebookList.get(i).getName())) {\r
1423                                 if (!notebookList.get(i).getGuid().equals(currentNote.getNotebookGuid())) {\r
1424                                         currentNote.setNotebookGuid(notebookList.get(i).getGuid());\r
1425                                         changed = true;\r
1426                                 }\r
1427                                 i = notebookList.size();\r
1428                         }\r
1429                 }\r
1430                 \r
1431                 // If the notebook changed, signal the update\r
1432                 if (changed)\r
1433                         noteSignal.notebookChanged.emit(currentNote.getGuid(), currentNote\r
1434                                         .getNotebookGuid());\r
1435         }\r
1436 \r
1437         // Check the note title\r
1438         private void checkNoteTitle() {\r
1439                 String text = browser.page().currentFrame().toPlainText();\r
1440                 if (saveNoteTitle.trim().equals("")) {\r
1441                         int newLine = text.indexOf("\n");\r
1442                         if (newLine > 0) {\r
1443                                 text = text.substring(0, newLine);\r
1444                                 if (text.trim().equals(""))\r
1445                                         text = "Untitled Note";\r
1446                                 titleLabel.setText(text);\r
1447                         } else {\r
1448                                 if (text.length() > 20)\r
1449                                         titleLabel.setText(text.substring(0, 20));\r
1450                                 else {\r
1451                                         if (text.trim().equals(""))\r
1452                                                 titleLabel.setText("Untitled Note");\r
1453                                         else\r
1454                                                 titleLabel.setText(text);\r
1455                                 }\r
1456                         }\r
1457                         noteSignal.titleChanged.emit(currentNote.getGuid(), titleLabel\r
1458                                         .text());\r
1459                 }\r
1460         }\r
1461 \r
1462         // Return the note contents so we can email them\r
1463         public String getContentsToEmail() {\r
1464                 return browser.page().currentFrame().toPlainText().trim();\r
1465                 /*\r
1466                  * int body = browser.page().currentFrame().toHtml().indexOf("<body>");\r
1467                  * String temp = browser.page().currentFrame().toHtml(); if (body == -1)\r
1468                  * temp = "<html><body><b>Test</b></body></html>"; else temp =\r
1469                  * "<html>"+temp.substring(body); return temp; // return\r
1470                  * urlEncode(browser.page().currentFrame().toHtml());\r
1471                  */\r
1472         }\r
1473 \r
1474         // Insert an image into the editor\r
1475         private void insertImage(QMimeData mime) {\r
1476                 logger.log(logger.EXTREME, "Entering insertImage");\r
1477                 QImage img = (QImage) mime.imageData();\r
1478                 String script_start = new String(\r
1479                                 "document.execCommand('insertHTML', false, '");\r
1480                 String script_end = new String("');");\r
1481 \r
1482                 long now = new Date().getTime();\r
1483                 String path = Global.getDirectoryPath() + "res/"\r
1484                                 + (new Long(now).toString()) + ".jpg";\r
1485 \r
1486                 // This block is just a hack to make sure we wait at least 1ms so we\r
1487                 // don't\r
1488                 // have collisions on image names\r
1489                 long i = new Date().getTime();\r
1490                 while (now == i)\r
1491                         i = new Date().getTime();\r
1492 \r
1493                 // Open the file & write the data\r
1494                 QFile tfile = new QFile(path);\r
1495                 tfile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.WriteOnly));\r
1496                 img.save(tfile);\r
1497                 tfile.close();\r
1498                 \r
1499                 Resource newRes = createResource(QUrl.fromLocalFile(path).toString(), 0, "image/jpeg", false);\r
1500                 if (newRes == null)\r
1501                         return;\r
1502                 currentNote.getResources().add(newRes);\r
1503 \r
1504                 // do the actual insert into the note\r
1505                 StringBuffer buffer = new StringBuffer(100);\r
1506                 buffer.append("<img src=\"");\r
1507                 buffer.append(tfile.fileName());\r
1508                 buffer.append("\" en-tag=en-media type=\"image/jpeg\""\r
1509                                 +" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\""\r
1510                                 +" guid=\"" +newRes.getGuid() +"\""\r
1511                                 +" onContextMenu=\"window.jambi.imageContextMenu('" +tfile.fileName() +"');\""\r
1512                                 + " />");\r
1513                 browser.page().mainFrame().evaluateJavaScript(\r
1514                                 script_start + buffer + script_end);\r
1515 \r
1516                 return;\r
1517         }\r
1518 \r
1519         // Handle URLs that are trying to be pasted\r
1520         public void handleUrls(QMimeData mime) {\r
1521                 logger.log(logger.EXTREME, "Starting handleUrls");\r
1522                 FileNameMap fileNameMap = URLConnection.getFileNameMap();\r
1523 \r
1524                 List<QUrl> urlList = mime.urls();\r
1525                 String url = new String();\r
1526                 String script_start = new String(\r
1527                                 "document.execCommand('createLink', false, '");\r
1528                 String script_end = new String("');");\r
1529 \r
1530                 for (int i = 0; i < urlList.size(); i++) {\r
1531                         url = urlList.get(i).toString();\r
1532                         // Find out what type of file we have\r
1533                         String mimeType = fileNameMap.getContentTypeFor(url);\r
1534 \r
1535                         // If null returned, we need to guess at the file type\r
1536                         if (mimeType == null)\r
1537                                 mimeType = "application/"\r
1538                                                 + url.substring(url.lastIndexOf(".") + 1);\r
1539 \r
1540                         // Check if we have an image or some other type of file\r
1541                         if (url.substring(0, 5).equalsIgnoreCase("file:")\r
1542                                         && mimeType.substring(0, 5).equalsIgnoreCase("image")) {\r
1543                                 handleLocalImageURLPaste(mime, mimeType);\r
1544                                 return;\r
1545                         }\r
1546                         String[] type = mimeType.split("/");\r
1547                         boolean valid = validAttachment(type[1]);\r
1548                         boolean smallEnough = checkFileAttachmentSize(url);\r
1549                         if (smallEnough && valid\r
1550                                         && url.substring(0, 5).equalsIgnoreCase("file:")\r
1551                                         && !mimeType.substring(0, 5).equalsIgnoreCase("image")) {\r
1552                                 handleLocalAttachment(mime, mimeType);\r
1553                                 return;\r
1554                         }\r
1555                         browser.page().mainFrame().evaluateJavaScript(\r
1556                                         script_start + url + script_end);\r
1557                 }\r
1558                 return;\r
1559         }\r
1560 \r
1561         // If a URL being pasted is an image URL, then attach the image\r
1562         private void handleLocalImageURLPaste(QMimeData mime, String mimeType) {\r
1563                 List<QUrl> urlList = mime.urls();\r
1564                 String url = new String();\r
1565                 String script_start_image = new String(\r
1566                                 "document.execCommand('insertHtml', false, '");\r
1567                 String script_end = new String("');");\r
1568                 StringBuffer buffer;\r
1569 \r
1570                 // Copy the image over into the resource directory and create a new resource \r
1571                 // record for each url pasted\r
1572                 for (int i = 0; i < urlList.size(); i++) {\r
1573                         url = urlList.get(i).toString();\r
1574 \r
1575                         Resource newRes = createResource(url, i, mimeType, false);\r
1576                         if (newRes == null)\r
1577                                 return;\r
1578                         currentNote.getResources().add(newRes);\r
1579                         buffer = new StringBuffer(100);\r
1580                         \r
1581                         // Open the file & write the data\r
1582                         String fileName = Global.getDirectoryPath()+"res/"+newRes.getGuid();\r
1583                         QFile tfile = new QFile(fileName);\r
1584                         tfile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.WriteOnly));\r
1585                         tfile.write(newRes.getData().getBody());\r
1586                         tfile.close();\r
1587                         fileName = fileName.replace('\\', '/');\r
1588                         buffer.append(script_start_image);\r
1589                         buffer.append("<img src=\"" +fileName);\r
1590 //                      if (mimeType.equalsIgnoreCase("image/jpg"))\r
1591 //                              mimeType = "image/jpeg";\r
1592                         buffer.append("\" en-tag=\"en-media\" type=\"" + mimeType +"\""\r
1593                                         +" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\""\r
1594                                         +" guid=\"" +newRes.getGuid() +"\""\r
1595                                         +" onContextMenu=\"window.jambi.imageContextMenu(&apos;" +tfile.fileName() +"&apos;);\""\r
1596                                         + " />");\r
1597                         buffer.append(script_end);\r
1598                         browser.page().mainFrame().evaluateJavaScript(buffer.toString());\r
1599                 }\r
1600                 return;\r
1601         }\r
1602         \r
1603 \r
1604         // If a URL being pasted is a local file URL, then attach the file\r
1605         private void handleLocalAttachment(QMimeData mime, String mimeType) {\r
1606                 logger.log(logger.EXTREME, "Attaching local file");\r
1607                 List<QUrl> urlList = mime.urls();\r
1608                 String script_start = new String(\r
1609                                 "document.execCommand('insertHtml', false, '");\r
1610                 String script_end = new String("');");\r
1611                 StringBuffer buffer;\r
1612 \r
1613                 for (int i = 0; i < urlList.size(); i++) {\r
1614                         buffer = new StringBuffer(100);\r
1615                         String url = urlList.get(i).toString();\r
1616 \r
1617                         // Start building the HTML\r
1618                         String[] type = mimeType.split("/");\r
1619                         String icon = findIcon(type[1]);\r
1620                         if (icon.equals("attachment.png"))\r
1621                                 icon = findIcon(type[0]);\r
1622                         if (icon.equals("attachment.png"))\r
1623                                 icon = findIcon(url.substring(url.lastIndexOf(".")+1));\r
1624                         StringBuffer imageBuffer = new StringBuffer();\r
1625                         String whichOS = System.getProperty("os.name");\r
1626                         if (whichOS.contains("Windows")) \r
1627                                 imageBuffer.append("file:///" + Global.getDirectoryPath()\r
1628                                                 + "images/" + icon);\r
1629                         else\r
1630                                 imageBuffer.append("file://" + Global.getDirectoryPath()\r
1631                                                 + "images/" + icon);\r
1632                         // Fix stupid Windows file separation characters\r
1633                         if (whichOS.contains("Windows")) {\r
1634                                 for (int z = imageBuffer.indexOf("\\"); z > 0; z = imageBuffer\r
1635                                                 .indexOf("\\")) {\r
1636                                         int w = imageBuffer.indexOf("\\");\r
1637                                         imageBuffer.replace(w, w + 1, "/");\r
1638                                 }\r
1639 \r
1640                         }\r
1641                         logger.log(logger.EXTREME, "Creating resource ");\r
1642                         Resource newRes = createResource(url, i, mimeType, true);\r
1643                         if (newRes == null)\r
1644                                 return;\r
1645                         logger.log(logger.EXTREME, "New resource size: " +newRes.getData().getSize());\r
1646                         currentNote.getResources().add(newRes);\r
1647                         \r
1648                         String fileName = newRes.getGuid() + Global.attachmentNameDelimeter+newRes.getAttributes().getFileName();\r
1649                         // If we have a PDF, we need to setup the preview.\r
1650                         if (icon.equalsIgnoreCase("pdf.png") && Global.pdfPreview()) {\r
1651                                 logger.log(logger.EXTREME, "Setting up PDF preview");\r
1652                                 if (newRes.getAttributes() != null && \r
1653                                                 newRes.getAttributes().getFileName() != null && \r
1654                                                 !newRes.getAttributes().getFileName().trim().equals(""))\r
1655                                         fileName = newRes.getGuid()+Global.attachmentNameDelimeter+\r
1656                                                 newRes.getAttributes().getFileName();\r
1657                                 else\r
1658                                         fileName = newRes.getGuid()+".pdf";\r
1659                                 QFile file = new QFile(Global.getDirectoryPath() +"res/"+fileName);\r
1660                         QFile.OpenMode mode = new QFile.OpenMode();\r
1661                         mode.set(QFile.OpenModeFlag.WriteOnly);\r
1662                         file.open(mode);\r
1663                         QDataStream out = new QDataStream(file);\r
1664 //                      Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(newRes.getGuid(), true);\r
1665                                 QByteArray binData = new QByteArray(newRes.getData().getBody());\r
1666 //                              resBinary = null;\r
1667                         out.writeBytes(binData.toByteArray());\r
1668                         file.close();\r
1669 \r
1670                                 PDFPreview pdfPreview = new PDFPreview();\r
1671                                 if (pdfPreview.setupPreview(Global.currentDir+"res/"+fileName, "pdf",0));\r
1672                                         imageBuffer = new StringBuffer(file.fileName()+".png");\r
1673                         }\r
1674                                                 \r
1675                         logger.log(logger.EXTREME, "Generating link tags");\r
1676                         buffer.append("<a en-tag=\"en-media\" guid=\"" +newRes.getGuid()+"\" ");\r
1677                         buffer.append(" onContextMenu=\"window.jambi.imageContextMenu(&apos;" +Global.getDirectoryPath() +"res/"+fileName +"&apos;);\" ");\r
1678                         buffer.append("type=\"" + mimeType + "\" href=\"nnres://" + fileName +"\" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\" >");\r
1679                         buffer.append("<img src=\"" + imageBuffer.toString()+"\" title=\"" +newRes.getAttributes().getFileName());\r
1680                         buffer.append("\"></img>");\r
1681                         buffer.append("</a>");\r
1682                         browser.page().mainFrame().evaluateJavaScript(\r
1683                                         script_start + buffer.toString() + script_end);\r
1684                 }\r
1685                 return;\r
1686         }\r
1687         private Resource createResource(String url, int sequence, String mime, boolean attachment) {\r
1688                 logger.log(logger.EXTREME, "Inside create resource");\r
1689                 QFile resourceFile;\r
1690                 url = new QUrl(url).toLocalFile();\r
1691                 url = url.replace("/", File.separator);\r
1692         resourceFile = new QFile(url); \r
1693         resourceFile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly));\r
1694         byte[] fileData = resourceFile.readAll().toByteArray();\r
1695         resourceFile.close();\r
1696         if (fileData.length == 0)\r
1697                 return null;\r
1698         MessageDigest md;\r
1699         try {\r
1700                 md = MessageDigest.getInstance("MD5");\r
1701                 md.update(fileData);\r
1702                 byte[] hash = md.digest();\r
1703   \r
1704                 Resource r = new Resource();\r
1705                 Calendar time = new GregorianCalendar();\r
1706                 long prevTime = time.getTimeInMillis();\r
1707                 while (prevTime == time.getTimeInMillis()) {\r
1708                         time = new GregorianCalendar();\r
1709                 }\r
1710                 r.setGuid(time.getTimeInMillis()+new Integer(sequence).toString());\r
1711                 r.setNoteGuid(currentNote.getGuid());\r
1712                 r.setMime(mime);\r
1713                 r.setActive(true);\r
1714                 r.setUpdateSequenceNum(0);\r
1715                 r.setWidth((short) 0);\r
1716                 r.setHeight((short) 0);\r
1717                 r.setDuration((short) 0);\r
1718                                 \r
1719                 Data d = new Data();\r
1720                 d.setBody(fileData);\r
1721                 d.setBodyIsSet(true);\r
1722                 d.setBodyHash(hash);\r
1723                 d.setBodyHashIsSet(true);\r
1724                 r.setData(d);\r
1725                 d.setSize(fileData.length);\r
1726                 \r
1727                 int fileNamePos = url.lastIndexOf(File.separator);\r
1728                 if (fileNamePos == -1)\r
1729                         fileNamePos = url.lastIndexOf("/");\r
1730                         String fileName = url.substring(fileNamePos+1);\r
1731                 ResourceAttributes a = new ResourceAttributes();\r
1732                 a.setAltitude(0);\r
1733                 a.setAltitudeIsSet(false);\r
1734                 a.setLongitude(0);\r
1735                 a.setLongitudeIsSet(false);\r
1736                 a.setLatitude(0);\r
1737                 a.setLatitudeIsSet(false);\r
1738                 a.setCameraMake("");\r
1739                 a.setCameraMakeIsSet(false);\r
1740                 a.setCameraModel("");\r
1741                 a.setCameraModelIsSet(false);\r
1742                 a.setAttachment(attachment);\r
1743                 a.setAttachmentIsSet(true);\r
1744                 a.setClientWillIndex(false);\r
1745                 a.setClientWillIndexIsSet(true);\r
1746                 a.setRecoType("");\r
1747                 a.setRecoTypeIsSet(false);\r
1748                 a.setSourceURL(url);\r
1749                 a.setSourceURLIsSet(true);\r
1750                 a.setTimestamp(0);\r
1751                 a.setTimestampIsSet(false);\r
1752                 a.setFileName(fileName);\r
1753                 a.setFileNameIsSet(true);\r
1754                 r.setAttributes(a);\r
1755                 \r
1756                 conn.getNoteTable().noteResourceTable.saveNoteResource(r, true);\r
1757                 return r;\r
1758         } catch (NoSuchAlgorithmException e1) {\r
1759                 e1.printStackTrace();\r
1760                 }\r
1761         return null;\r
1762         }\r
1763         \r
1764 \r
1765     // find the appropriate icon for an attachment\r
1766     private String findIcon(String appl) {\r
1767         appl = appl.toLowerCase();\r
1768         File f = new File(Global.getDirectoryPath()+"images"+File.separator +appl +".png");\r
1769         if (f.exists())\r
1770                 return appl+".png";\r
1771         return "attachment.png";\r
1772     }\r
1773 \r
1774         // Check if the account supports this type of attachment\r
1775         private boolean validAttachment(String type) {\r
1776                 if (Global.isPremium())\r
1777                         return true;\r
1778                 if (type.equalsIgnoreCase("JPG"))\r
1779                         return true;\r
1780                 if (type.equalsIgnoreCase("PNG"))\r
1781                         return true;\r
1782                 if (type.equalsIgnoreCase("GIF"))\r
1783                         return true;\r
1784                 if (type.equalsIgnoreCase("MP3"))\r
1785                         return true;\r
1786                 if (type.equalsIgnoreCase("WAV"))\r
1787                         return true;\r
1788                 if (type.equalsIgnoreCase("AMR"))\r
1789                         return true;\r
1790                 if (type.equalsIgnoreCase("PDF"))\r
1791                         return true;\r
1792                 String error = "Non-premium accounts can only attach JPG, PNG, GIF, MP3, WAV, AMR, or PDF files.";\r
1793                 QMessageBox.information(this, "Non-Premium Account", error);\r
1794 \r
1795                 return false;\r
1796         }\r
1797 \r
1798         // Check the file attachment to be sure it isn't over 25 mb\r
1799         private boolean checkFileAttachmentSize(String url) {\r
1800                 String fileName = url.substring(8);\r
1801                 QFile resourceFile = new QFile(fileName);\r
1802                 resourceFile.open(new QIODevice.OpenMode(\r
1803                                 QIODevice.OpenModeFlag.ReadOnly));\r
1804                 long size = resourceFile.size();\r
1805                 resourceFile.close();\r
1806                 size = size / 1024 / 1024;\r
1807                 if (size < 50 && Global.isPremium())\r
1808                         return true;\r
1809                 if (size < 25)\r
1810                         return true;\r
1811 \r
1812                 String error = "A file attachment may not exceed 25MB.";\r
1813                 QMessageBox.information(this, "Attachment Size", error);\r
1814                 return false;\r
1815         }\r
1816 \r
1817 \r
1818         @SuppressWarnings("unused")\r
1819         private void createdChanged() {\r
1820                 QDateTime dt = new QDateTime();\r
1821                 dt.setDate(createdDate.date());\r
1822                 dt.setTime(createdTime.time());\r
1823                 noteSignal.createdDateChanged.emit(currentNote.getGuid(), dt);\r
1824 \r
1825         }\r
1826 \r
1827         @SuppressWarnings("unused")\r
1828         private void alteredChanged() {\r
1829                 QDateTime dt = new QDateTime();\r
1830                 dt.setDate(alteredDate.date());\r
1831                 dt.setTime(alteredTime.time());\r
1832                 noteSignal.alteredDateChanged.emit(currentNote.getGuid(), dt);\r
1833         }\r
1834 \r
1835         @SuppressWarnings("unused")\r
1836         private void subjectDateTimeChanged() {\r
1837                 QDateTime dt = new QDateTime();\r
1838                 dt.setDate(subjectDate.date());\r
1839                 dt.setTime(subjectTime.time());\r
1840                 noteSignal.subjectDateChanged.emit(currentNote.getGuid(), dt);\r
1841 \r
1842         }\r
1843 \r
1844         @SuppressWarnings("unused")\r
1845         private void sourceUrlChanged() {\r
1846                 noteSignal.sourceUrlChanged.emit(currentNote.getGuid(), urlText.text());\r
1847         }\r
1848 \r
1849         @SuppressWarnings("unused")\r
1850         private void authorChanged() {\r
1851                 noteSignal.authorChanged.emit(currentNote.getGuid(), authorText.text());\r
1852         }\r
1853 \r
1854         // ************************************************************\r
1855         // * User chose to save an attachment. Pares out the request *\r
1856         // * into a guid & file. Save the result. *\r
1857         // ************************************************************\r
1858         public void downloadAttachment(QNetworkRequest request) {\r
1859                 String guid;\r
1860                 QFileDialog fd = new QFileDialog(this);\r
1861                 fd.setFileMode(FileMode.AnyFile);\r
1862                 fd.setConfirmOverwrite(true);\r
1863                 fd.setWindowTitle("Save File");\r
1864                 fd.setAcceptMode(AcceptMode.AcceptSave);\r
1865                 fd.setDirectory(System.getProperty("user.home"));\r
1866                 String name = request.url().toString();\r
1867 \r
1868                 int pos = name.lastIndexOf(Global.attachmentNameDelimeter);\r
1869                 if (pos > -1) {\r
1870                         guid = name.substring(0, pos).replace("nnres://", "");\r
1871                         name = name.substring(pos +Global.attachmentNameDelimeter.length());\r
1872                         fd.selectFile(name);\r
1873                         pos = name.lastIndexOf('.');\r
1874                         if (pos > -1) {\r
1875                                 String mimeType = "(*." + name.substring(pos + 1)\r
1876                                                 + ");; All Files (*)";\r
1877                                 fd.setFilter(tr(mimeType));\r
1878                         }\r
1879                 } else {\r
1880                         guid = name;\r
1881                 }\r
1882                 guid = guid.replace("nnres://", "").replace(Global.currentDir.replace("\\","/")+"res/", "");\r
1883                 pos = guid.lastIndexOf('.');\r
1884                 if (pos > 0)\r
1885                         guid = guid.substring(0,pos);\r
1886                 if (fd.exec() != 0 && fd.selectedFiles().size() > 0) {\r
1887                         name = name.replace('\\', '/');\r
1888                         Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);\r
1889                         QFile saveFile = new QFile(fd.selectedFiles().get(0));\r
1890                         QFile.OpenMode mode = new QFile.OpenMode();\r
1891                         mode.set(QFile.OpenModeFlag.WriteOnly);\r
1892                         saveFile.open(mode);\r
1893                         QDataStream saveOut = new QDataStream(saveFile);\r
1894                         QByteArray binData = new QByteArray(resBinary.getData().getBody());\r
1895                         saveOut.writeBytes(binData.toByteArray());\r
1896                         saveFile.close();\r
1897 \r
1898                 }\r
1899         }\r
1900 \r
1901         \r
1902         // ************************************************************\r
1903         // * User chose to save an attachment. Pares out the request *\r
1904         // * into a guid & file. Save the result. --- DONE FROM downloadAttachment now!!!!!   \r
1905         // ************************************************************\r
1906         public void downloadImage(QNetworkRequest request) {\r
1907                 QFileDialog fd = new QFileDialog(this);\r
1908                 fd.setFileMode(FileMode.AnyFile);\r
1909                 fd.setConfirmOverwrite(true);\r
1910                 fd.setWindowTitle("Save File");\r
1911                 fd.setAcceptMode(AcceptMode.AcceptSave);\r
1912                 fd.setDirectory(System.getProperty("user.home"));\r
1913                 String name = request.url().toString();\r
1914                 name = name.replace("nnres://", "");\r
1915                 String dPath = Global.getDirectoryPath() + "res/";\r
1916                 dPath = dPath.replace('\\', '/');\r
1917                 name = name.replace(dPath, "");\r
1918                 int pos = name.lastIndexOf('.');\r
1919                 String guid = name;\r
1920                 if (pos > -1) {\r
1921                         String mimeType = "(*." + name.substring(pos + 1)\r
1922                         + ");; All Files (*)";\r
1923                                 fd.setFilter(tr(mimeType));\r
1924                         guid = guid.substring(0,pos);\r
1925                 }\r
1926                 pos = name.lastIndexOf(Global.attachmentNameDelimeter);\r
1927                 if (pos > -1) {\r
1928                         guid = name.substring(0, pos);\r
1929                         fd.selectFile(name.substring(pos+Global.attachmentNameDelimeter.length()));             \r
1930                 }\r
1931                 if (fd.exec() != 0 && fd.selectedFiles().size() > 0) {\r
1932                         Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);\r
1933                         String fileName = fd.selectedFiles().get(0);\r
1934                         QFile saveFile = new QFile(fileName);\r
1935                         QFile.OpenMode mode = new QFile.OpenMode();\r
1936                         mode.set(QFile.OpenModeFlag.WriteOnly);\r
1937                         saveFile.open(mode);\r
1938                         QDataStream saveOut = new QDataStream(saveFile);\r
1939                         QByteArray binData = new QByteArray(resBinary.getData().getBody());\r
1940                         saveOut.writeBytes(binData.toByteArray());\r
1941                         saveFile.close();\r
1942                 }\r
1943         }\r
1944 \r
1945         \r
1946         // *************************************************************\r
1947         // * decrypt any hidden text.  We could do an XML parse, but \r
1948         // * it is quicker here just to scan for an <img tag & do the fix\r
1949         // * the manual way\r
1950         // *************************************************************\r
1951         private void removeEncryption(String id, String plainText, boolean permanent, String slot) {\r
1952                 if (!permanent) {\r
1953                         plainText = " <en-crypt-temp slot=\""+slot  +"\">" +plainText+"</en-crypt-temp> ";\r
1954                 }\r
1955                 \r
1956                 String html = browser.page().mainFrame().toHtml();\r
1957                 String text = html;\r
1958                 int imagePos = html.indexOf("<img");\r
1959                 int endPos;\r
1960                 for ( ;imagePos>0; ) {\r
1961                         // Find the end tag\r
1962                         endPos = text.indexOf(">", imagePos);\r
1963                         String tag = text.substring(imagePos-1,endPos);\r
1964                         if (tag.indexOf("id=\""+id+"\"") > -1) {\r
1965                                         text = text.substring(0,imagePos) +plainText+text.substring(endPos+1);\r
1966                                                                                 \r
1967                                         browser.setContent(new QByteArray(text));\r
1968                                         contentChanged();\r
1969                         }\r
1970                         imagePos = text.indexOf("<img", imagePos+1);\r
1971                 }\r
1972         }\r
1973         \r
1974         \r
1975         //****************************************************************\r
1976         //* Focus shortcuts\r
1977         //****************************************************************\r
1978         @SuppressWarnings("unused")\r
1979         private void focusTitle() {\r
1980                 titleLabel.setFocus();\r
1981         }\r
1982         @SuppressWarnings("unused")\r
1983         private void focusTag() {\r
1984                 tagEdit.setFocus();\r
1985         }\r
1986         @SuppressWarnings("unused")\r
1987         private void focusNote() {\r
1988                 browser.setFocus();\r
1989         }\r
1990         @SuppressWarnings("unused")\r
1991         private void focusAuthor() {\r
1992                 authorLabel.setFocus();\r
1993         }\r
1994         @SuppressWarnings("unused")\r
1995         private void focusUrl() {\r
1996                 urlLabel.setFocus();\r
1997         }\r
1998         \r
1999 \r
2000         //*****************************************************************\r
2001         //* Set the document background color\r
2002         //*****************************************************************\r
2003         public void setBackgroundColor(String color) {\r
2004                 String js = "function changeBackground(color) {"\r
2005                         +"document.body.style.background = color;"\r
2006                         +"}" \r
2007                         +"changeBackground('" +color+"');";\r
2008                 browser.page().mainFrame().evaluateJavaScript(js);\r
2009                 contentChanged();\r
2010         }\r
2011         \r
2012         \r
2013         //****************************************************************\r
2014         //* MicroFocus changed\r
2015         //****************************************************************\r
2016         private void microFocusChanged() {\r
2017                 \r
2018                 boldButton.setDown(false);\r
2019                 italicButton.setDown(false);\r
2020                 underlineButton.setDown(false);\r
2021                 browser.openAction.setEnabled(false);\r
2022                 browser.downloadAttachment.setEnabled(false);\r
2023                 browser.downloadImage.setEnabled(false);\r
2024                 browser.rotateImageLeft.setEnabled(false);\r
2025                 browser.rotateImageRight.setEnabled(false);\r
2026                 browser.insertTableAction.setEnabled(true);\r
2027                 browser.insertTableRowAction.setEnabled(false);\r
2028                 browser.deleteTableRowAction.setEnabled(false);\r
2029                 browser.insertLinkAction.setText("Insert Hyperlink");\r
2030                 currentHyperlink ="";\r
2031                 insideList = false;\r
2032                 forceTextPaste = false;\r
2033                 \r
2034                 String js = new String( "function getCursorPos() {"\r
2035                         +"var cursorPos;"\r
2036                         +"if (window.getSelection) {"\r
2037                         +"   var selObj = window.getSelection();"\r
2038                         +"   var selRange = selObj.getRangeAt(0);"\r
2039                         +"   var workingNode = window.getSelection().anchorNode.parentNode;"\r
2040                         +"   while(workingNode != null) { " \r
2041 //                      +"      window.jambi.printNode(workingNode.nodeName);"\r
2042                         +"      if (workingNode.nodeName=='EN-CRYPT-TEMP') window.jambi.forceTextPaste();"\r
2043                         +"      if (workingNode.nodeName=='B') window.jambi.boldActive();"\r
2044                         +"      if (workingNode.nodeName=='I') window.jambi.italicActive();"\r
2045                         +"      if (workingNode.nodeName=='U') window.jambi.underlineActive();"\r
2046                         +"      if (workingNode.nodeName=='UL') window.jambi.setInsideList();"\r
2047                         +"      if (workingNode.nodeName=='OL') window.jambi.setInsideList();"\r
2048                         +"      if (workingNode.nodeName=='LI') window.jambi.setInsideList();"\r
2049                         +"      if (workingNode.nodeName=='TBODY') window.jambi.setInsideTable();"\r
2050                         +"      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
2051                         +"      if (workingNode.nodeName=='SPAN') {"\r
2052                         +"         if (workingNode.getAttribute('style') == 'text-decoration: underline;') window.jambi.underlineActive();"\r
2053                         +"      }"\r
2054                         +"      workingNode = workingNode.parentNode;"\r
2055                         +"   }"\r
2056                         +"}"\r
2057                         +"} getCursorPos();");\r
2058                 browser.page().mainFrame().evaluateJavaScript(js);\r
2059         }\r
2060         \r
2061         public void printNode(String n) {\r
2062                 System.out.println("Node Vaule: " +n);\r
2063         }\r
2064         \r
2065         \r
2066         //****************************************************************\r
2067         //* Insert a table row\r
2068         //****************************************************************\r
2069         public void insertTableRow() {\r
2070                 \r
2071                 String js = new String( "function insertTableRow() {"\r
2072                         +"   var selObj = window.getSelection();"\r
2073                         +"   var selRange = selObj.getRangeAt(0);"\r
2074                         +"   var workingNode = window.getSelection().anchorNode.parentNode;"\r
2075                         +"   var cellCount = 0;"\r
2076                         +"   while(workingNode != null) { " \r
2077                         +"      if (workingNode.nodeName.toLowerCase()=='tr') {"\r
2078                         +"           row = document.createElement('TR');"\r
2079                         +"           var nodes = workingNode.getElementsByTagName('td');"\r
2080                         +"           for (j=0; j<nodes.length; j=j+1) {"\r
2081                         +"              cell = document.createElement('TD');"\r
2082                         +"              cell.innerHTML='&nbsp;';"\r
2083                         +"              row.appendChild(cell);"\r
2084                         +"           }"                 \r
2085                         +"           workingNode.parentNode.insertBefore(row,workingNode.nextSibling);"\r
2086                         +"           return;"\r
2087                         +"      }"\r
2088                         +"      workingNode = workingNode.parentNode;"\r
2089                         +"   }"\r
2090                         +"} insertTableRow();");\r
2091                 browser.page().mainFrame().evaluateJavaScript(js);\r
2092                 contentChanged();\r
2093         }\r
2094         //****************************************************************\r
2095         //* Insert a table row\r
2096         //****************************************************************\r
2097         public void deleteTableRow() {\r
2098                 \r
2099                 String js = new String( "function deleteTableRow() {"\r
2100                         +"   var selObj = window.getSelection();"\r
2101                         +"   var selRange = selObj.getRangeAt(0);"\r
2102                         +"   var workingNode = window.getSelection().anchorNode.parentNode;"\r
2103                         +"   var cellCount = 0;"\r
2104                         +"   while(workingNode != null) { " \r
2105                         +"      if (workingNode.nodeName.toLowerCase()=='tr') {"\r
2106                         +"           workingNode.parentNode.removeChild(workingNode);"\r
2107                         +"           return;"\r
2108                         +"      }"\r
2109                         +"      workingNode = workingNode.parentNode;"\r
2110                         +"   }"\r
2111                         +"} deleteTableRow();");\r
2112                 browser.page().mainFrame().evaluateJavaScript(js);\r
2113                 contentChanged();\r
2114         }\r
2115         public void setInsideTable() {\r
2116                 browser.insertTableRowAction.setEnabled(true);\r
2117                 browser.deleteTableRowAction.setEnabled(true);\r
2118                 browser.insertTableAction.setEnabled(false);\r
2119                 browser.encryptAction.setEnabled(false);\r
2120         }\r
2121         \r
2122         public void setInsideLink(String link) {\r
2123                 browser.insertLinkAction.setText("Edit Hyperlink");\r
2124                 currentHyperlink = link;\r
2125         }\r
2126         \r
2127         public void italicActive() {\r
2128                 italicButton.setDown(true);\r
2129         }\r
2130         public void boldActive() {\r
2131                 boldButton.setDown(true);\r
2132         }\r
2133         public void underlineActive() {\r
2134                 underlineButton.setDown(true);\r
2135         }\r
2136         public void forceTextPaste() {\r
2137                 forceTextPaste = true;\r
2138         }\r
2139         public void imageContextMenu(String f) {\r
2140                 browser.downloadImage.setEnabled(true);\r
2141                 browser.rotateImageRight.setEnabled(true);\r
2142                 browser.rotateImageLeft.setEnabled(true);\r
2143                 browser.openAction.setEnabled(true);\r
2144                 selectedFile = f;\r
2145         }\r
2146         public void rotateImageRight() {\r
2147                 QWebSettings.setMaximumPagesInCache(0);\r
2148                 QWebSettings.setObjectCacheCapacities(0, 0, 0);\r
2149                 QImage image = new QImage(selectedFile);\r
2150                 QMatrix matrix = new QMatrix();\r
2151                 matrix.rotate( 90.0 );\r
2152                 image = image.transformed(matrix);\r
2153                 image.save(selectedFile);\r
2154                 QWebSettings.setMaximumPagesInCache(0);\r
2155                 QWebSettings.setObjectCacheCapacities(0, 0, 0);\r
2156                 browser.setHtml(browser.page().mainFrame().toHtml());\r
2157                 browser.reload();\r
2158                 contentChanged();\r
2159 //              resourceSignal.contentChanged.emit(selectedFile);\r
2160 \r
2161         }\r
2162         public void rotateImageLeft() {\r
2163                 QImage image = new QImage(selectedFile);\r
2164                 QMatrix matrix = new QMatrix();\r
2165                 matrix.rotate( -90.0 );\r
2166                 image = image.transformed(matrix);\r
2167                 image.save(selectedFile);\r
2168                 browser.setHtml(browser.page().mainFrame().toHtml());\r
2169                 browser.reload();\r
2170                 contentChanged();\r
2171 //              resourceSignal.contentChanged.emit(selectedFile);\r
2172         }\r
2173         public void resourceContextMenu(String f) {\r
2174                 browser.downloadAttachment.setEnabled(true);\r
2175                 browser.openAction.setEnabled(true);\r
2176                 selectedFile = f;\r
2177         }\r
2178         \r
2179         \r
2180         //****************************************************************\r
2181         //* Apply CSS style to specified word\r
2182         //****************************************************************\r
2183 /*      public void applyStyleToWords(String word, String style) {\r
2184                 QFile script = new QFile("D:\\NeverNote\\js\\hilight1.js");\r
2185                 script.open(OpenModeFlag.ReadOnly);\r
2186                 String s = script.readAll().toString();\r
2187                 String js = new String(s +" findit('"+word+"', '"+style+"');");\r
2188                 browser.page().mainFrame().evaluateJavaScript(js);\r
2189                 System.out.println(getContent());\r
2190         }\r
2191 */      \r
2192         //****************************************************************\r
2193         //* Someone tried to paste a resource between notes, so we need  *\r
2194         //* to do some special handling.                                 *\r
2195         //****************************************************************\r
2196         private String fixInternotePaste(String text) {\r
2197                 logger.log(logger.EXTREME, "Fixing internote paste");\r
2198                 String returnValue = fixInternotePasteSearch(text, "<img", "src=\"");\r
2199                 return fixInternotePasteSearch(returnValue, "<a", "href=\"nnres://");\r
2200         }\r
2201         private String fixInternotePasteSearch(String text, String type, String locTag) {\r
2202                 \r
2203                 // First, let's fix the images.\r
2204                 int startPos = text.indexOf(type);\r
2205                 int endPos;\r
2206                 for (; startPos>=0;) {\r
2207                         endPos = text.indexOf(">", startPos+1);\r
2208                         String segment = text.substring(startPos, endPos);\r
2209                         if (segment.indexOf("en-tag") > -1) {\r
2210                                 String newSegment = segment;\r
2211                                 \r
2212                                 int guidStartPos = segment.indexOf("guid=\"");\r
2213                                 int guidEndPos = segment.indexOf("\"", guidStartPos+7);\r
2214                                 String guid = segment.substring(guidStartPos+6,guidEndPos);\r
2215                                 \r
2216                                 Calendar currentTime = new GregorianCalendar();\r
2217                                 Long l = new Long(currentTime.getTimeInMillis());\r
2218                                 long prevTime = l;\r
2219                                 while (l==prevTime) {\r
2220                                         currentTime = new GregorianCalendar();\r
2221                                         l= new Long(currentTime.getTimeInMillis());\r
2222                                 }\r
2223                                 \r
2224                                 Resource r = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);\r
2225                                 if (r==null)\r
2226                                         return "";\r
2227                         String randint = new String(Long.toString(l));\r
2228                         String extension = null;\r
2229                         if (r.getMime()!= null) {\r
2230                                 extension = r.getMime().toLowerCase();\r
2231                                 if (extension.indexOf("/")>-1)\r
2232                                         extension = extension.substring(extension.indexOf("/")+1);\r
2233                         }\r
2234                         String newFile = randint;\r
2235                         if (r.getAttributes().getFileName() != null && r.getAttributes().getFileName() != "")\r
2236                                 if (!locTag.startsWith("src"))\r
2237                                         newFile = newFile+Global.attachmentNameDelimeter+r.getAttributes().getFileName();\r
2238                         r.setNoteGuid(currentNote.getGuid());\r
2239                         \r
2240                         r.setGuid(randint);\r
2241                         conn.getNoteTable().noteResourceTable.saveNoteResource(r, true);\r
2242                                 QFile f = new QFile(Global.getDirectoryPath() +"res/" +newFile);\r
2243                                 QByteArray bin = new QByteArray(r.getData().getBody());\r
2244                                 f.open(QFile.OpenModeFlag.WriteOnly);\r
2245                                 f.write(bin);\r
2246                                 f.close();\r
2247                                 newSegment = newSegment.replace("guid=\""+guid, "guid=\""+randint);\r
2248                                 currentNote.getResources().add(r);\r
2249                                 \r
2250                                 int startSrcPos = newSegment.indexOf(locTag);\r
2251                                 int endSrcPos = newSegment.indexOf("\"",startSrcPos+locTag.length()+1);\r
2252                                 String source; \r
2253                                 if (locTag.startsWith("src")) {\r
2254                                          source = newSegment.substring(startSrcPos+locTag.length(),endSrcPos);\r
2255                                         newSegment = newSegment.replace(source, Global.getDirectoryPath().replace("\\", "/")+"res/"+newFile);\r
2256                                 } else {\r
2257                                         source = newSegment.substring(startSrcPos+locTag.length(),endSrcPos);\r
2258                                         newSegment = newSegment.replace(source, newFile);\r
2259                                 }\r
2260                                 \r
2261                                 text = text.substring(0,startPos) + newSegment + text.substring(endPos);\r
2262                         }\r
2263                         startPos = text.indexOf(type, startPos+1);\r
2264                 }\r
2265                 return text;\r
2266         }\r
2267 \r
2268 \r
2269         public void nextPage(String file) {\r
2270                 logger.log(logger.EXTREME, "Starting nextPage()");\r
2271                 \r
2272                 Integer pageNumber;\r
2273                 if (previewPageList.containsKey(file))\r
2274                         pageNumber = previewPageList.get(file)+1;\r
2275                 else\r
2276                         pageNumber = 2;\r
2277                 previewPageList.remove(file);\r
2278                 previewPageList.put(file, pageNumber);\r
2279                 PDFPreview pdfPreview = new PDFPreview();\r
2280                 boolean goodPreview = pdfPreview.setupPreview(file, "pdf", pageNumber);\r
2281                 if (goodPreview) {\r
2282 \r
2283 //                      String html = getContent();\r
2284                         QWebSettings.setMaximumPagesInCache(0);\r
2285                         QWebSettings.setObjectCacheCapacities(0, 0, 0);\r
2286 //                      browser.setContent(new QByteArray());\r
2287                         browser.setHtml(browser.page().mainFrame().toHtml());\r
2288                         browser.reload();\r
2289 //                      browser.setContent(new QByteArray(html));\r
2290 //                      browser.triggerPageAction(WebAction.Reload);\r
2291 //                      pdfMouseOver(selectedFile);\r
2292                 }\r
2293         }\r
2294 \r
2295         public void previousPage(String file) {\r
2296                 logger.log(logger.EXTREME, "Starting previousPage()");\r
2297                 \r
2298                 Integer pageNumber;\r
2299                 if (previewPageList.containsKey(file))\r
2300                         pageNumber = previewPageList.get(file)-1;\r
2301                 else\r
2302                         pageNumber = 1;\r
2303                 previewPageList.remove(file);\r
2304                 previewPageList.put(file, pageNumber);\r
2305                 PDFPreview pdfPreview = new PDFPreview();\r
2306                 boolean goodPreview = pdfPreview.setupPreview(file, "pdf", pageNumber);\r
2307                 if (goodPreview) {\r
2308 \r
2309 //                      String html = getContent();\r
2310                         QWebSettings.setMaximumPagesInCache(0);\r
2311                         QWebSettings.setObjectCacheCapacities(0, 0, 0);\r
2312                         browser.setHtml(browser.page().mainFrame().toHtml());\r
2313                         browser.reload();\r
2314 //                      browser.setContent(new QByteArray(html));\r
2315 //                      browser.triggerPageAction(WebAction.Reload);\r
2316                 }\r
2317         }\r
2318         \r
2319 /*      public void pdfMouseOver(String name) { \r
2320                 int pageNumber;\r
2321                 if (previewPageList.containsKey(selectedFile))\r
2322                         pageNumber = previewPageList.get(selectedFile)+1;\r
2323                 else\r
2324                         pageNumber = 1;\r
2325                 \r
2326                 if (pageNumber <= 1)\r
2327                         browser.previousPageAction.setEnabled(false);\r
2328                 else\r
2329                         browser.previousPageAction.setEnabled(true);\r
2330                 \r
2331                 PDFPreview pdf = new PDFPreview();\r
2332                 int totalPages = pdf.getPageCount(name);\r
2333                 if (previewPageList.containsKey(selectedFile))\r
2334                         pageNumber = previewPageList.get(selectedFile)+1;\r
2335                 else\r
2336                         pageNumber = 1;\r
2337                 if (totalPages > pageNumber)\r
2338                         browser.nextPageAction.setEnabled(true);\r
2339                 else\r
2340                         browser.nextPageAction.setEnabled(false);\r
2341         }\r
2342         \r
2343 \r
2344         public void pdfMouseOut() { \r
2345 //              browser.nextPageAction.setVisible(false);\r
2346 //              browser.previousPageAction.setVisible(false);\r
2347         }\r
2348 */\r
2349 }