OSDN Git Service

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