2 * This file is part of NeverNote
\r
3 * Copyright 2009 Randy Baumgarte
\r
5 * This file may be licensed under the terms of of the
\r
6 * GNU General Public License Version 2 (the ``GPL'').
\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
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
20 package cx.fbn.nevernote.gui;
\r
22 import java.io.File;
\r
23 import java.io.FileNotFoundException;
\r
24 import java.io.IOException;
\r
25 import java.net.FileNameMap;
\r
26 import java.net.URI;
\r
27 import java.net.URLConnection;
\r
28 import java.security.MessageDigest;
\r
29 import java.security.NoSuchAlgorithmException;
\r
30 import java.text.SimpleDateFormat;
\r
31 import java.util.ArrayList;
\r
32 import java.util.Calendar;
\r
33 import java.util.Collections;
\r
34 import java.util.Date;
\r
35 import java.util.GregorianCalendar;
\r
36 import java.util.HashMap;
\r
37 import java.util.List;
\r
38 import java.util.Locale;
\r
40 import org.apache.commons.lang.StringUtils;
\r
42 import com.evernote.edam.limits.Constants;
\r
43 import com.evernote.edam.type.Data;
\r
44 import com.evernote.edam.type.Note;
\r
45 import com.evernote.edam.type.Notebook;
\r
46 import com.evernote.edam.type.Resource;
\r
47 import com.evernote.edam.type.ResourceAttributes;
\r
48 import com.evernote.edam.type.Tag;
\r
49 import com.swabunga.spell.engine.Configuration;
\r
50 import com.swabunga.spell.engine.SpellDictionary;
\r
51 import com.swabunga.spell.engine.SpellDictionaryHashMap;
\r
52 import com.swabunga.spell.engine.Word;
\r
53 import com.swabunga.spell.event.SpellCheckEvent;
\r
54 import com.swabunga.spell.event.SpellCheckListener;
\r
55 import com.swabunga.spell.event.SpellChecker;
\r
56 import com.swabunga.spell.event.StringWordTokenizer;
\r
57 import com.trolltech.qt.core.QByteArray;
\r
58 import com.trolltech.qt.core.QDataStream;
\r
59 import com.trolltech.qt.core.QDateTime;
\r
60 import com.trolltech.qt.core.QEvent;
\r
61 import com.trolltech.qt.core.QEvent.Type;
\r
62 import com.trolltech.qt.core.QFile;
\r
63 import com.trolltech.qt.core.QFileSystemWatcher;
\r
64 import com.trolltech.qt.core.QIODevice;
\r
65 import com.trolltech.qt.core.QMimeData;
\r
66 import com.trolltech.qt.core.QTextCodec;
\r
67 import com.trolltech.qt.core.QUrl;
\r
68 import com.trolltech.qt.core.Qt.Key;
\r
69 import com.trolltech.qt.core.Qt.KeyboardModifier;
\r
70 import com.trolltech.qt.core.Qt.KeyboardModifiers;
\r
71 import com.trolltech.qt.gui.QAction;
\r
72 import com.trolltech.qt.gui.QApplication;
\r
73 import com.trolltech.qt.gui.QCalendarWidget;
\r
74 import com.trolltech.qt.gui.QClipboard;
\r
75 import com.trolltech.qt.gui.QColor;
\r
76 import com.trolltech.qt.gui.QComboBox;
\r
77 import com.trolltech.qt.gui.QDateEdit;
\r
78 import com.trolltech.qt.gui.QDesktopServices;
\r
79 import com.trolltech.qt.gui.QFileDialog;
\r
80 import com.trolltech.qt.gui.QFileDialog.AcceptMode;
\r
81 import com.trolltech.qt.gui.QFileDialog.FileMode;
\r
82 import com.trolltech.qt.gui.QFontDatabase;
\r
83 import com.trolltech.qt.gui.QFormLayout;
\r
84 import com.trolltech.qt.gui.QGridLayout;
\r
85 import com.trolltech.qt.gui.QHBoxLayout;
\r
86 import com.trolltech.qt.gui.QIcon;
\r
87 import com.trolltech.qt.gui.QImage;
\r
88 import com.trolltech.qt.gui.QKeyEvent;
\r
89 import com.trolltech.qt.gui.QKeySequence;
\r
90 import com.trolltech.qt.gui.QLabel;
\r
91 import com.trolltech.qt.gui.QLineEdit;
\r
92 import com.trolltech.qt.gui.QListWidgetItem;
\r
93 import com.trolltech.qt.gui.QMatrix;
\r
94 import com.trolltech.qt.gui.QMessageBox;
\r
95 import com.trolltech.qt.gui.QPalette;
\r
96 import com.trolltech.qt.gui.QPalette.ColorRole;
\r
97 import com.trolltech.qt.gui.QPushButton;
\r
98 import com.trolltech.qt.gui.QShortcut;
\r
99 import com.trolltech.qt.gui.QTimeEdit;
\r
100 import com.trolltech.qt.gui.QToolButton;
\r
101 import com.trolltech.qt.gui.QToolButton.ToolButtonPopupMode;
\r
102 import com.trolltech.qt.gui.QVBoxLayout;
\r
103 import com.trolltech.qt.gui.QWidget;
\r
104 import com.trolltech.qt.network.QNetworkRequest;
\r
105 import com.trolltech.qt.webkit.QWebPage;
\r
106 import com.trolltech.qt.webkit.QWebPage.WebAction;
\r
107 import com.trolltech.qt.webkit.QWebSettings;
\r
108 import com.trolltech.qt.webkit.QWebView;
\r
110 import cx.fbn.nevernote.Global;
\r
111 import cx.fbn.nevernote.dialog.EnCryptDialog;
\r
112 import cx.fbn.nevernote.dialog.EnDecryptDialog;
\r
113 import cx.fbn.nevernote.dialog.GeoDialog;
\r
114 import cx.fbn.nevernote.dialog.InsertLinkDialog;
\r
115 import cx.fbn.nevernote.dialog.SpellCheck;
\r
116 import cx.fbn.nevernote.dialog.TableDialog;
\r
117 import cx.fbn.nevernote.dialog.TagAssign;
\r
118 import cx.fbn.nevernote.evernote.EnCrypt;
\r
119 import cx.fbn.nevernote.filters.FilterEditorTags;
\r
120 import cx.fbn.nevernote.signals.NoteResourceSignal;
\r
121 import cx.fbn.nevernote.signals.NoteSignal;
\r
122 import cx.fbn.nevernote.sql.DatabaseConnection;
\r
123 import cx.fbn.nevernote.utilities.ApplicationLogger;
\r
124 import cx.fbn.nevernote.utilities.FileUtils;
\r
125 import cx.fbn.nevernote.utilities.Pair;
\r
127 public class BrowserWindow extends QWidget {
\r
129 public final QLineEdit titleLabel;
\r
130 private final QLineEdit urlText;
\r
131 private final QLabel authorLabel;
\r
132 private final QLineEdit authorText;
\r
133 private final QComboBox geoBox;
\r
134 public final TagLineEdit tagEdit;
\r
135 public final QLabel tagLabel;
\r
136 private final QPushButton urlLabel;
\r
137 private final QLabel alteredLabel;
\r
138 private final QDateEdit alteredDate;
\r
139 private final QTimeEdit alteredTime;
\r
140 private final QDateEdit createdDate;
\r
141 private final QTimeEdit createdTime;
\r
142 private final QLabel subjectLabel;
\r
143 private final QDateEdit subjectDate;
\r
144 private final QTimeEdit subjectTime;
\r
145 public final QComboBox notebookBox;
\r
146 private final QLabel notebookLabel;
\r
147 private final QLabel createdLabel;
\r
148 public final QComboBox fontSize;
\r
149 public final QAction fontSizeAction;
\r
150 private boolean extendedOn;
\r
151 public boolean buttonsVisible;
\r
152 private final String iconPath = new String("classpath:cx/fbn/nevernote/icons/");
\r
153 private final ContentView browser;
\r
154 private List<Tag> allTags;
\r
155 private List<String> currentTags;
\r
156 public NoteSignal noteSignal;
\r
157 private List<Notebook> notebookList;
\r
158 private Note currentNote;
\r
159 private String saveNoteTitle;
\r
160 private String saveTagList;
\r
161 private boolean insideList;
\r
162 // private String selectedText;
\r
163 private final DatabaseConnection conn;
\r
164 private final QCalendarWidget createdCalendarWidget;
\r
165 private final QCalendarWidget alteredCalendarWidget;
\r
166 private final QCalendarWidget subjectCalendarWidget;
\r
168 public final QPushButton undoButton;
\r
169 public final QAction undoAction;
\r
170 public final QPushButton redoButton;
\r
171 public final QAction redoAction;
\r
172 public final QPushButton cutButton;
\r
173 public final QAction cutAction;
\r
174 public final QPushButton copyButton;
\r
175 public final QAction copyAction;
\r
176 public final QPushButton pasteButton;
\r
177 public final QAction pasteAction;
\r
178 public final QPushButton boldButton;
\r
179 public final QAction boldAction;
\r
180 public final QPushButton underlineButton;
\r
181 public final QAction underlineAction;
\r
182 public final QPushButton italicButton;
\r
183 public final QAction italicAction;
\r
184 public final Signal0 focusLost;
\r
185 public final NoteResourceSignal resourceSignal;
\r
187 public QPushButton rightAlignButton;
\r
188 public final QAction rightAlignAction;
\r
189 public QPushButton leftAlignButton;
\r
190 public final QAction leftAlignAction;
\r
191 public QPushButton centerAlignButton;
\r
192 public final QAction centerAlignAction;
\r
194 public final QPushButton strikethroughButton;
\r
195 public final QAction strikethroughAction;
\r
196 public final QPushButton hlineButton;
\r
197 public final QAction hlineAction;
\r
198 public final QPushButton indentButton;
\r
199 public final QAction indentAction;
\r
200 public final QPushButton outdentButton;
\r
201 public final QAction outdentAction;
\r
202 public final QPushButton bulletListButton;
\r
203 public final QAction bulletListAction;
\r
204 public final QPushButton numberListButton;
\r
205 public final QAction numberListAction;
\r
206 public final QPushButton spellCheckButton;
\r
207 public final QAction spellCheckAction;
\r
208 public final QPushButton todoButton;
\r
209 public final QAction todoAction;
\r
211 public final QShortcut focusTitleShortcut;
\r
212 public final QShortcut focusTagShortcut;
\r
213 public final QShortcut focusNoteShortcut;
\r
214 public final QShortcut focusUrlShortcut;
\r
215 public final QShortcut focusAuthorShortcut;
\r
217 public EditorButtonBar buttonLayout;
\r
218 public final QComboBox fontList;
\r
219 public final QAction fontListAction;
\r
220 public final QToolButton fontColor;
\r
221 public final QAction fontColorAction;
\r
222 private final ColorMenu fontColorMenu;
\r
223 public final QToolButton fontHilight;
\r
224 public final QAction fontHilightAction;
\r
225 private final ColorMenu fontHilightColorMenu;
\r
226 public final QFileSystemWatcher fileWatcher;
\r
227 public int cursorPosition;
\r
228 private boolean forceTextPaste = false;
\r
229 private String selectedFile;
\r
230 private String currentHyperlink;
\r
231 public boolean keepPDFNavigationHidden;
\r
232 private final ApplicationLogger logger;
\r
233 SpellDictionary dictionary;
\r
234 SpellDictionary userDictionary;
\r
235 SpellChecker spellChecker;
\r
236 SuggestionListener spellListener;
\r
237 private final HashMap<String,Integer> previewPageList;
\r
240 public static class SuggestionListener implements SpellCheckListener {
\r
241 public boolean abortSpellCheck = false;
\r
242 public boolean errorsFound = false;
\r
243 private final SpellCheck spellCheckDialog;
\r
246 private final BrowserWindow parent;
\r
247 public SuggestionListener(BrowserWindow parent, SpellChecker checker) {
\r
248 this.parent = parent;
\r
249 spellCheckDialog = new SpellCheck(checker);
\r
251 public void spellingError(SpellCheckEvent event) {
\r
252 errorsFound = true;
\r
253 spellCheckDialog.setWord(event.getInvalidWord());
\r
255 @SuppressWarnings("unchecked")
\r
256 List<Word> suggestions = event.getSuggestions();
\r
257 spellCheckDialog.clearSuggestions();
\r
258 if (!suggestions.isEmpty()) {
\r
259 // spellCheckDialog.setCurrentSuggestion(suggestions.get(0).getWord());
\r
260 for (int i=0; i<suggestions.size(); i++) {
\r
261 spellCheckDialog.addSuggestion(suggestions.get(i).getWord());
\r
263 spellCheckDialog.setSelectedSuggestion(0);
\r
265 spellCheckDialog.exec();
\r
266 if (spellCheckDialog.cancelPressed()) {
\r
267 abortSpellCheck = true;
\r
271 if (spellCheckDialog.replacePressed()) {
\r
272 QClipboard clipboard = QApplication.clipboard();
\r
273 clipboard.setText(spellCheckDialog.getReplacementWord());
\r
274 parent.pasteClicked();
\r
282 public BrowserWindow(DatabaseConnection c) {
\r
283 logger = new ApplicationLogger("browser.log");
\r
284 logger.log(logger.HIGH, "Setting up browser");
\r
286 fileWatcher = new QFileSystemWatcher();
\r
287 // fileWatcher.fileChanged.connect(this, "fileChanged(String)");
\r
288 noteSignal = new NoteSignal();
\r
289 titleLabel = new QLineEdit();
\r
290 titleLabel.setMaxLength(Constants.EDAM_NOTE_TITLE_LEN_MAX);
\r
291 urlText = new QLineEdit();
\r
292 authorText = new QLineEdit();
\r
293 geoBox = new QComboBox();
\r
294 urlLabel = new QPushButton();
\r
295 urlLabel.clicked.connect(this, "sourceUrlClicked()");
\r
296 authorLabel = new QLabel();
\r
299 focusLost = new Signal0();
\r
301 tagEdit = new TagLineEdit(allTags);
\r
302 tagLabel = new QLabel("Tags:");
\r
303 tagEdit.focusLost.connect(this, "modifyTagsTyping()");
\r
305 createdCalendarWidget = new QCalendarWidget();
\r
306 createdDate = new QDateEdit();
\r
307 createdDate.setDisplayFormat(Global.getDateFormat());
\r
308 createdDate.setCalendarPopup(true);
\r
309 createdDate.setCalendarWidget(createdCalendarWidget);
\r
310 createdTime = new QTimeEdit();
\r
311 createdDate.dateChanged.connect(this, "createdChanged()");
\r
312 createdTime.timeChanged.connect(this, "createdChanged()");
\r
314 alteredCalendarWidget = new QCalendarWidget();
\r
315 alteredDate = new QDateEdit();
\r
316 alteredDate.setDisplayFormat(Global.getDateFormat());
\r
317 alteredDate.setCalendarPopup(true);
\r
318 alteredDate.setCalendarWidget(alteredCalendarWidget);
\r
319 alteredTime = new QTimeEdit();
\r
320 alteredLabel = new QLabel("Altered:");
\r
321 alteredDate.dateChanged.connect(this, "alteredChanged()");
\r
322 alteredTime.timeChanged.connect(this, "alteredChanged()");
\r
324 subjectCalendarWidget = new QCalendarWidget();
\r
325 subjectDate = new QDateEdit();
\r
326 subjectDate.setDisplayFormat(Global.getDateFormat());
\r
327 subjectDate.setCalendarPopup(true);
\r
328 subjectDate.setCalendarWidget(subjectCalendarWidget);
\r
329 subjectTime = new QTimeEdit();
\r
330 subjectLabel = new QLabel(tr("Subject Date:"));
\r
331 subjectDate.dateChanged.connect(this, "subjectDateTimeChanged()");
\r
332 subjectTime.timeChanged.connect(this, "subjectDateTimeChanged()");
\r
333 authorText.textChanged.connect(this, "authorChanged()");
\r
334 urlText.textChanged.connect(this, "sourceUrlChanged()");
\r
336 notebookBox = new QComboBox();
\r
337 notebookLabel = new QLabel(tr("Notebook"));
\r
338 createdLabel = new QLabel(tr("Created:"));
\r
339 // selectedText = new String();
\r
341 urlLabel.setVisible(false);
\r
342 urlText.setVisible(false);
\r
343 authorLabel.setVisible(false);
\r
345 geoBox.setVisible(false);
\r
346 geoBox.addItem(new QIcon(iconPath+"globe.png"), "");
\r
347 geoBox.addItem(new String(tr("Set")));
\r
348 geoBox.addItem(new String(tr("Clear")));
\r
349 geoBox.addItem(new String(tr("View On Map")));
\r
350 geoBox.activated.connect(this, "geoBoxChanged()");
\r
352 authorText.setVisible(false);
\r
353 createdDate.setVisible(false);
\r
354 alteredLabel.setVisible(false);
\r
355 //notebookBox.setVisible(false);
\r
356 notebookLabel.setVisible(false);
\r
357 createdLabel.setVisible(false);
\r
358 createdTime.setVisible(false);
\r
359 alteredDate.setVisible(false);
\r
360 alteredTime.setVisible(false);
\r
361 subjectLabel.setVisible(false);
\r
362 subjectDate.setVisible(false);
\r
363 subjectTime.setVisible(false);
\r
364 extendedOn = false;
\r
365 buttonsVisible = true;
\r
366 setAcceptDrops(true);
\r
368 browser = new ContentView(this);
\r
369 browser.page().setLinkDelegationPolicy(
\r
370 QWebPage.LinkDelegationPolicy.DelegateAllLinks);
\r
371 browser.linkClicked.connect(this, "linkClicked(QUrl)");
\r
372 currentHyperlink = "";
\r
374 QVBoxLayout v = new QVBoxLayout();
\r
375 QFormLayout notebookLayout = new QFormLayout();
\r
376 QGridLayout dateLayout = new QGridLayout();
\r
377 titleLabel.setReadOnly(false);
\r
378 titleLabel.editingFinished.connect(this, "titleEdited()");
\r
379 browser.page().contentsChanged.connect(this, "contentChanged()");
\r
380 browser.page().selectionChanged.connect(this, "selectionChanged()");
\r
381 browser.page().mainFrame().javaScriptWindowObjectCleared.connect(this,
\r
382 "exposeToJavascript()");
\r
384 notebookBox.activated.connect(this, "notebookChanged()");
\r
385 resourceSignal = new NoteResourceSignal();
\r
387 QHBoxLayout tagLayout = new QHBoxLayout();
\r
388 v.addWidget(titleLabel, 0);
\r
389 notebookLayout.addRow(notebookLabel, notebookBox);
\r
390 tagLayout.addLayout(notebookLayout, 0);
\r
391 tagLayout.stretch(4);
\r
392 tagLayout.addWidget(tagLabel, 0);
\r
393 tagLayout.addWidget(tagEdit, 1);
\r
394 v.addLayout(tagLayout);
\r
396 QHBoxLayout urlLayout = new QHBoxLayout();
\r
397 urlLayout.addWidget(urlLabel, 0);
\r
398 urlLayout.addWidget(urlText, 0);
\r
399 v.addLayout(urlLayout);
\r
401 QHBoxLayout authorLayout = new QHBoxLayout();
\r
402 authorLayout.addWidget(authorLabel, 0);
\r
403 authorLayout.addWidget(authorText, 0);
\r
404 authorLayout.addWidget(geoBox);
\r
405 v.addLayout(authorLayout);
\r
407 dateLayout.addWidget(createdLabel, 0, 0);
\r
408 dateLayout.addWidget(createdDate, 0, 1);
\r
409 dateLayout.addWidget(createdTime, 0, 2);
\r
410 dateLayout.setColumnStretch(9, 100);
\r
411 dateLayout.addWidget(alteredLabel, 0, 3);
\r
412 dateLayout.addWidget(alteredDate, 0, 4);
\r
413 dateLayout.addWidget(alteredTime, 0, 5);
\r
414 dateLayout.addWidget(subjectLabel, 0, 6);
\r
415 dateLayout.addWidget(subjectDate, 0, 7);
\r
416 dateLayout.addWidget(subjectTime, 0, 8);
\r
417 v.addLayout(dateLayout, 0);
\r
419 undoButton = newEditorButton("undo", tr("Undo Change"));
\r
420 redoButton = newEditorButton("redo", tr("Redo Change"));
\r
421 cutButton = newEditorButton("cut", tr("Cut"));
\r
422 copyButton = newEditorButton("copy", tr("Copy"));
\r
423 pasteButton = newEditorButton("paste", tr("Paste"));
\r
424 boldButton = newEditorButton("bold", tr("Bold"));
\r
425 underlineButton = newEditorButton("underline", tr("Underline"));
\r
426 italicButton = newEditorButton("italic", tr("Italic"));
\r
428 rightAlignButton = newEditorButton("justifyRight", tr("Right Align"));
\r
429 leftAlignButton = newEditorButton("justifyLeft", tr("Left Align"));
\r
430 centerAlignButton = newEditorButton("justifyCenter", tr("Center Align"));
\r
432 strikethroughButton = newEditorButton("strikethrough", tr("Strikethrough"));
\r
433 hlineButton = newEditorButton("hline", tr("Insert Horizontal Line"));
\r
434 indentButton = newEditorButton("indent", tr("Shift Right"));
\r
435 outdentButton = newEditorButton("outdent", tr("Shift Left"));
\r
436 bulletListButton = newEditorButton("bulletList", tr("Bullet List"));
\r
437 numberListButton = newEditorButton("numberList", tr("Number List"));
\r
438 spellCheckButton = newEditorButton("spellCheck", tr("Spell Check"));
\r
439 todoButton = newEditorButton("todo", tr("To-do"));
\r
442 buttonLayout = new EditorButtonBar();
\r
443 v.addWidget(buttonLayout);
\r
445 undoAction = buttonLayout.addWidget(undoButton);
\r
446 buttonLayout.toggleUndoVisible.triggered.connect(this, "toggleUndoVisible(Boolean)");
\r
447 redoAction = buttonLayout.addWidget(redoButton);
\r
448 buttonLayout.toggleRedoVisible.triggered.connect(this, "toggleRedoVisible(Boolean)");
\r
450 buttonLayout.addWidget(newSeparator());
\r
451 cutAction = buttonLayout.addWidget(cutButton);
\r
452 buttonLayout.toggleCutVisible.triggered.connect(this, "toggleCutVisible(Boolean)");
\r
453 copyAction = buttonLayout.addWidget(copyButton);
\r
454 buttonLayout.toggleCopyVisible.triggered.connect(this, "toggleCopyVisible(Boolean)");
\r
455 pasteAction = buttonLayout.addWidget(pasteButton);
\r
456 buttonLayout.togglePasteVisible.triggered.connect(this, "togglePasteVisible(Boolean)");
\r
458 buttonLayout.addWidget(newSeparator());
\r
459 boldAction = buttonLayout.addWidget(boldButton);
\r
460 buttonLayout.toggleBoldVisible.triggered.connect(this, "toggleBoldVisible(Boolean)");
\r
461 italicAction = buttonLayout.addWidget(italicButton);
\r
462 buttonLayout.toggleItalicVisible.triggered.connect(this, "toggleItalicVisible(Boolean)");
\r
463 underlineAction = buttonLayout.addWidget(underlineButton);
\r
464 buttonLayout.toggleUnderlineVisible.triggered.connect(this, "toggleUnderlineVisible(Boolean)");
\r
465 strikethroughAction = buttonLayout.addWidget(strikethroughButton);
\r
466 buttonLayout.toggleStrikethroughVisible.triggered.connect(this, "toggleStrikethroughVisible(Boolean)");
\r
469 buttonLayout.addWidget(newSeparator());
\r
470 leftAlignAction = buttonLayout.addWidget(leftAlignButton);
\r
471 buttonLayout.toggleLeftAlignVisible.triggered.connect(this, "toggleLeftAlignVisible(Boolean)");
\r
472 centerAlignAction = buttonLayout.addWidget(centerAlignButton);
\r
473 buttonLayout.toggleCenterAlignVisible.triggered.connect(this, "toggleCenterAlignVisible(Boolean)");
\r
474 rightAlignAction = buttonLayout.addWidget(rightAlignButton);
\r
475 buttonLayout.toggleRightAlignVisible.triggered.connect(this, "toggleRightAlignVisible(Boolean)");
\r
477 buttonLayout.addWidget(newSeparator());
\r
478 hlineAction = buttonLayout.addWidget(hlineButton);
\r
479 buttonLayout.toggleHLineVisible.triggered.connect(this, "toggleHLineVisible(Boolean)");
\r
481 indentAction = buttonLayout.addWidget(indentButton);
\r
482 buttonLayout.toggleIndentVisible.triggered.connect(this, "toggleIndentVisible(Boolean)");
\r
483 outdentAction = buttonLayout.addWidget(outdentButton);
\r
484 buttonLayout.toggleOutdentVisible.triggered.connect(this, "toggleOutdentVisible(Boolean)");
\r
485 bulletListAction = buttonLayout.addWidget(bulletListButton);
\r
486 buttonLayout.toggleBulletListVisible.triggered.connect(this, "toggleBulletListVisible(Boolean)");
\r
487 numberListAction = buttonLayout.addWidget(numberListButton);
\r
488 buttonLayout.toggleNumberListVisible.triggered.connect(this, "toggleNumberListVisible(Boolean)");
\r
490 // Setup the font & font size combo boxes
\r
491 buttonLayout.addWidget(newSeparator());
\r
492 fontList = new QComboBox();
\r
493 fontSize = new QComboBox();
\r
494 fontList.setToolTip("Font");
\r
495 fontSize.setToolTip("Font Size");
\r
496 fontList.activated.connect(this, "fontChanged(String)");
\r
497 fontSize.activated.connect(this, "fontSizeChanged(String)");
\r
498 fontListAction = buttonLayout.addWidget(fontList);
\r
499 buttonLayout.toggleFontVisible.triggered.connect(this, "toggleFontListVisible(Boolean)");
\r
500 fontSizeAction = buttonLayout.addWidget(fontSize);
\r
501 buttonLayout.toggleFontSizeVisible.triggered.connect(this, "toggleFontSizeVisible(Boolean)");
\r
502 QFontDatabase fonts = new QFontDatabase();
\r
503 List<String> fontFamilies = fonts.families();
\r
504 for (int i = 0; i < fontFamilies.size(); i++) {
\r
505 fontList.addItem(fontFamilies.get(i));
\r
507 loadFontSize(fontFamilies.get(i));
\r
511 // buttonLayout.addWidget(newSeparator(), 0);
\r
512 fontColor = newToolButton("fontColor", tr("Font Color"));
\r
513 fontColorMenu = new ColorMenu(this);
\r
514 fontColor.setMenu(fontColorMenu.getMenu());
\r
515 fontColor.setPopupMode(ToolButtonPopupMode.MenuButtonPopup);
\r
516 fontColor.setAutoRaise(false);
\r
517 fontColorMenu.getMenu().triggered.connect(this, "fontColorClicked()");
\r
518 fontColorAction = buttonLayout.addWidget(fontColor);
\r
519 buttonLayout.toggleFontColorVisible.triggered.connect(this, "toggleFontColorVisible(Boolean)");
\r
520 fontHilight = newToolButton("fontHilight", tr("Font Hilight Color"));
\r
521 fontHilight.setPopupMode(ToolButtonPopupMode.MenuButtonPopup);
\r
522 fontHilight.setAutoRaise(false);
\r
523 fontHilightColorMenu = new ColorMenu(this);
\r
524 fontHilightColorMenu.setDefault(QColor.yellow);
\r
525 fontHilight.setMenu(fontHilightColorMenu.getMenu());
\r
526 fontHilightColorMenu.getMenu().triggered.connect(this, "fontHilightClicked()");
\r
527 fontHilightAction = buttonLayout.addWidget(fontHilight);
\r
528 fontHilightColorMenu.setDefault(QColor.yellow);
\r
529 buttonLayout.toggleFontHilight.triggered.connect(this, "toggleFontHilightVisible(Boolean)");
\r
531 spellCheckAction = buttonLayout.addWidget(spellCheckButton);
\r
532 buttonLayout.toggleNumberListVisible.triggered.connect(this, "spellCheckClicked()");
\r
533 buttonLayout.toggleSpellCheck.triggered.connect(this, "toggleSpellCheckVisible(Boolean)");
\r
535 todoAction = buttonLayout.addWidget(todoButton);
\r
536 buttonLayout.toggleNumberListVisible.triggered.connect(this, "todoClicked()");
\r
537 buttonLayout.toggleTodo.triggered.connect(this, "toggleTodoVisible(Boolean)");
\r
540 // buttonLayout.addWidget(new QLabel(), 1);
\r
541 v.addWidget(browser, 1);
\r
544 browser.downloadAttachmentRequested.connect(this,
\r
545 "downloadAttachment(QNetworkRequest)");
\r
546 browser.downloadImageRequested.connect(this,
\r
547 "downloadImage(QNetworkRequest)");
\r
548 setTabOrder(notebookBox, tagEdit);
\r
549 setTabOrder(tagEdit, browser);
\r
551 focusNoteShortcut = new QShortcut(this);
\r
552 setupShortcut(focusNoteShortcut, "Focus_Note");
\r
553 focusNoteShortcut.activated.connect(this, "focusNote()");
\r
554 focusTitleShortcut = new QShortcut(this);
\r
555 setupShortcut(focusTitleShortcut, "Focus_Title");
\r
556 focusTitleShortcut.activated.connect(this, "focusTitle()");
\r
557 focusTagShortcut = new QShortcut(this);
\r
558 setupShortcut(focusTagShortcut, "Focus_Tag");
\r
559 focusTagShortcut.activated.connect(this, "focusTag()");
\r
560 focusAuthorShortcut = new QShortcut(this);
\r
561 setupShortcut(focusAuthorShortcut, "Focus_Author");
\r
562 focusAuthorShortcut.activated.connect(this, "focusAuthor()");
\r
563 focusUrlShortcut = new QShortcut(this);
\r
564 setupShortcut(focusUrlShortcut, "Focus_Url");
\r
565 focusUrlShortcut.activated.connect(this, "focusUrl()");
\r
567 browser.page().mainFrame().setTextSizeMultiplier(Global.getTextSizeMultiplier());
\r
568 browser.page().mainFrame().setZoomFactor(Global.getZoomFactor());
\r
570 previewPageList = new HashMap<String,Integer>();
\r
572 browser.page().microFocusChanged.connect(this, "microFocusChanged()");
\r
576 QPalette pal = new QPalette();
\r
577 pal.setColor(ColorRole.Text, QColor.black);
\r
578 titleLabel.setPalette(pal);
\r
579 authorText.setPalette(pal);
\r
580 authorLabel.setPalette(pal);
\r
581 urlLabel.setPalette(pal);
\r
582 urlText.setPalette(pal);
\r
583 createdDate.setPalette(pal);
\r
584 createdTime.setPalette(pal);
\r
585 alteredDate.setPalette(pal);
\r
586 alteredTime.setPalette(pal);
\r
587 subjectDate.setPalette(pal);
\r
588 subjectTime.setPalette(pal);
\r
589 tagEdit.setPalette(pal);
\r
590 notebookBox.setPalette(pal);
\r
592 logger.log(logger.HIGH, "Browser setup complete");
\r
597 private void setupShortcut(QShortcut action, String text) {
\r
598 if (!Global.shortcutKeys.containsAction(text))
\r
600 action.setKey(new QKeySequence(Global.shortcutKeys.getShortcut(text)));
\r
606 // Getter for the QWebView
\r
607 public QWebView getBrowser() {
\r
611 // Block signals while loading data or things are flagged as dirty by
\r
613 public void loadingData(boolean val) {
\r
614 logger.log(logger.EXTREME, "Entering BrowserWindow.loadingData() " +val);
\r
615 notebookBox.blockSignals(val);
\r
616 browser.page().blockSignals(val);
\r
617 browser.page().mainFrame().blockSignals(val);
\r
618 titleLabel.blockSignals(val);
\r
619 alteredDate.blockSignals(val);
\r
620 alteredTime.blockSignals(val);
\r
621 createdTime.blockSignals(val);
\r
622 createdDate.blockSignals(val);
\r
623 subjectDate.blockSignals(val);
\r
624 subjectTime.blockSignals(val);
\r
625 urlText.blockSignals(val);
\r
626 authorText.blockSignals(val);
\r
628 exposeToJavascript();
\r
629 logger.log(logger.EXTREME, "Exiting BrowserWindow.loadingData() " +val);
\r
633 public void setReadOnly(boolean v) {
\r
635 titleLabel.setEnabled(!v);
\r
636 notebookBox.setEnabled(!v);
\r
637 tagEdit.setEnabled(!v);
\r
638 authorLabel.setEnabled(!v);
\r
639 geoBox.setEnabled(!v);
\r
640 urlText.setEnabled(!v);
\r
641 createdDate.setEnabled(!v);
\r
642 subjectDate.setEnabled(!v);
\r
643 alteredDate.setEnabled(!v);
\r
644 authorText.setEnabled(!v);
\r
645 createdTime.setEnabled(!v);
\r
646 alteredTime.setEnabled(!v);
\r
647 subjectTime.setEnabled(!v);
\r
648 getBrowser().setEnabled(true);
\r
651 // expose this class to Javascript on the web page
\r
652 private void exposeToJavascript() {
\r
653 browser.page().mainFrame().addToJavaScriptWindowObject("jambi", this);
\r
656 // Custom event queue
\r
658 public boolean event(QEvent e) {
\r
659 if (e.type().equals(QEvent.Type.FocusOut)) {
\r
660 logger.log(logger.EXTREME, "Focus lost");
\r
663 return super.event(e);
\r
666 // clear out browser
\r
667 public void clear() {
\r
668 logger.log(logger.EXTREME, "Entering BrowserWindow.clear()");
\r
670 browser.setContent(new QByteArray());
\r
671 tagEdit.setText("");
\r
672 tagEdit.tagCompleter.reset();
\r
673 urlLabel.setText(tr("Source URL:"));
\r
674 titleLabel.setText("");
\r
675 logger.log(logger.EXTREME, "Exiting BrowserWindow.clear()");
\r
678 // get/set current note
\r
679 public void setNote(Note n) {
\r
683 saveNoteTitle = n.getTitle();
\r
687 public Note getNote() {
\r
688 return currentNote;
\r
691 // New Editor Button
\r
692 private QPushButton newEditorButton(String name, String toolTip) {
\r
693 QPushButton button = new QPushButton();
\r
694 // QIcon icon = new QIcon(iconPath + name + ".gif");
\r
695 QIcon icon = new QIcon(iconPath + name + ".png");
\r
696 button.setIcon(icon);
\r
697 button.setToolTip(toolTip);
\r
698 button.clicked.connect(this, name + "Clicked()");
\r
701 // New Editor Button
\r
702 private QToolButton newToolButton(String name, String toolTip) {
\r
703 QToolButton button = new QToolButton();
\r
704 // QIcon icon = new QIcon(iconPath + name + ".gif");
\r
705 QIcon icon = new QIcon(iconPath + name + ".png");
\r
706 button.setIcon(icon);
\r
707 button.setToolTip(toolTip);
\r
708 button.clicked.connect(this, name + "Clicked()");
\r
713 private QLabel newSeparator() {
\r
714 return new QLabel(" ");
\r
717 // Set the title in the window
\r
718 public void setTitle(String t) {
\r
719 titleLabel.setText(t);
\r
724 // Return the current text title
\r
725 public String getTitle() {
\r
726 return titleLabel.text();
\r
729 // Set the tag name string
\r
730 public void setTag(String t) {
\r
732 tagEdit.setText(t);
\r
733 tagEdit.tagCompleter.reset();
\r
736 // Set the source URL
\r
737 public void setUrl(String t) {
\r
738 urlLabel.setText(tr("Source URL:\t"));
\r
739 urlText.setText(t);
\r
742 // The user want's to launch a web browser on the source of the URL
\r
743 public void sourceUrlClicked() {
\r
744 // Make sure we have a valid URL
\r
745 if (urlText.text().trim().equals(""))
\r
748 String url = urlText.text();
\r
749 if (!url.toLowerCase().startsWith(tr("http://")))
\r
750 url = tr("http://") +url;
\r
752 if (!QDesktopServices.openUrl(new QUrl(url))) {
\r
753 logger.log(logger.LOW, "Error opening file :" +url);
\r
757 public void setAuthor(String t) {
\r
758 authorLabel.setText(tr("Author:\t"));
\r
759 authorText.setText(t);
\r
762 // Set the creation date
\r
763 public void setCreation(long date) {
\r
764 QDateTime dt = new QDateTime();
\r
765 dt.setTime_t((int) (date / 1000));
\r
766 createdDate.setDateTime(dt);
\r
767 createdTime.setDateTime(dt);
\r
768 createdDate.setDisplayFormat(Global.getDateFormat());
\r
769 createdTime.setDisplayFormat(Global.getTimeFormat());
\r
772 // Set the creation date
\r
773 public void setAltered(long date) {
\r
774 QDateTime dt = new QDateTime();
\r
775 dt.setTime_t((int) (date / 1000));
\r
776 alteredDate.setDateTime(dt);
\r
777 alteredTime.setDateTime(dt);
\r
778 alteredDate.setDisplayFormat(Global.getDateFormat());
\r
779 alteredTime.setDisplayFormat(Global.getTimeFormat());
\r
782 // Set the subject date
\r
783 public void setSubjectDate(long date) {
\r
784 QDateTime dt = new QDateTime();
\r
785 dt.setTime_t((int) (date / 1000));
\r
786 subjectDate.setDateTime(dt);
\r
787 subjectTime.setDateTime(dt);
\r
788 subjectDate.setDisplayFormat(Global.getDateFormat());
\r
789 subjectTime.setDisplayFormat(Global.getTimeFormat());
\r
792 // Toggle the extended attribute information
\r
793 public void toggleInformation() {
\r
795 extendedOn = false;
\r
799 urlLabel.setVisible(extendedOn);
\r
800 urlText.setVisible(extendedOn);
\r
801 authorText.setVisible(extendedOn);
\r
802 geoBox.setVisible(extendedOn);
\r
803 authorLabel.setVisible(extendedOn);
\r
804 createdDate.setVisible(extendedOn);
\r
805 createdTime.setVisible(extendedOn);
\r
806 createdLabel.setVisible(extendedOn);
\r
807 alteredLabel.setVisible(extendedOn);
\r
808 alteredDate.setVisible(extendedOn);
\r
809 alteredTime.setVisible(extendedOn);
\r
810 //notebookBox.setVisible(extendedOn);
\r
811 notebookLabel.setVisible(extendedOn);
\r
812 subjectLabel.setVisible(extendedOn);
\r
813 subjectDate.setVisible(extendedOn);
\r
814 subjectTime.setVisible(extendedOn);
\r
817 public void hideButtons() {
\r
819 undoButton.parentWidget().setVisible(false);
\r
820 buttonsVisible = false;
\r
824 // Is the extended view on?
\r
825 public boolean isExtended() {
\r
829 // Listener for when a link is clicked
\r
830 @SuppressWarnings("unused")
\r
831 private void openFile() {
\r
832 logger.log(logger.EXTREME, "Starting openFile()");
\r
833 File fileHandle = new File(selectedFile);
\r
834 URI fileURL = fileHandle.toURI();
\r
835 String localURL = fileURL.toString();
\r
836 QUrl url = new QUrl(localURL);
\r
837 QFile file = new QFile(selectedFile);
\r
839 logger.log(logger.EXTREME, "Adding to fileWatcher:"+file.fileName());
\r
840 fileWatcher.addPath(file.fileName());
\r
842 if (!QDesktopServices.openUrl(url)) {
\r
843 logger.log(logger.LOW, "Error opening file :" +url);
\r
848 // Listener for when a link is clicked
\r
849 @SuppressWarnings("unused")
\r
850 private void linkClicked(QUrl url) {
\r
851 logger.log(logger.EXTREME, "URL Clicked: " +url.toString());
\r
852 if (url.toString().substring(0,8).equals("nnres://")) {
\r
853 logger.log(logger.EXTREME, "URL is NN resource");
\r
854 if (url.toString().endsWith("/vnd.evernote.ink")) {
\r
855 logger.log(logger.EXTREME, "Unable to open ink note");
\r
856 QMessageBox.information(this, tr("Unable Open"), tr("This is an ink note.\n"+
\r
857 "Ink notes are not supported since Evernote has not\n published any specifications on them\n" +
\r
858 "and I'm too lazy to figure them out by myself."));
\r
861 String fullName = url.toString().substring(8);
\r
862 int index = fullName.indexOf(".");
\r
866 type = fullName.substring(index+1);
\r
867 guid = fullName.substring(0,index);
\r
869 index = guid.indexOf(Global.attachmentNameDelimeter);
\r
871 guid = guid.substring(0,index);
\r
873 List<Resource> resList = currentNote.getResources();
\r
874 Resource res = null;
\r
875 for (int i=0; i<resList.size(); i++) {
\r
876 if (resList.get(i).getGuid().equals(guid)) {
\r
877 res = resList.get(i);
\r
882 String resGuid = Global.resourceMap.get(guid);
\r
883 if (resGuid != null)
\r
884 res = conn.getNoteTable().noteResourceTable.getNoteResource(resGuid, true);
\r
888 if (res.getAttributes() != null &&
\r
889 res.getAttributes().getFileName() != null &&
\r
890 !res.getAttributes().getFileName().trim().equals(""))
\r
891 fileName = res.getGuid()+Global.attachmentNameDelimeter+res.getAttributes().getFileName();
\r
893 fileName = res.getGuid()+"."+type;
\r
894 QFile file = new QFile(Global.getFileManager().getResDirPath(fileName));
\r
895 QFile.OpenMode mode = new QFile.OpenMode();
\r
896 mode.set(QFile.OpenModeFlag.WriteOnly);
\r
897 boolean openResult = file.open(mode);
\r
898 logger.log(logger.EXTREME, "File opened:" +openResult);
\r
899 QDataStream out = new QDataStream(file);
\r
900 Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(res.getGuid(), true);
\r
901 QByteArray binData = new QByteArray(resBinary.getData().getBody());
\r
903 logger.log(logger.EXTREME, "Writing resource");
\r
904 out.writeBytes(binData.toByteArray());
\r
907 String whichOS = System.getProperty("os.name");
\r
908 if (whichOS.contains("Windows"))
\r
909 url.setUrl("file:///"+file.fileName());
\r
911 url.setUrl("file://"+file.fileName());
\r
912 // fileWatcher.removePath(file.fileName());
\r
913 logger.log(logger.EXTREME, "Adding file watcher " +file.fileName());
\r
914 fileWatcher.addPath(file.fileName());
\r
916 // If we can't open it, then prompt the user to save it.
\r
917 if (!QDesktopServices.openUrl(url)) {
\r
918 logger.log(logger.EXTREME, "We can't handle this. Where do we put it?");
\r
919 QFileDialog dialog = new QFileDialog();
\r
921 if (dialog.exec()!=0) {
\r
922 List<String> fileNames = dialog.selectedFiles(); //gets all selected filenames
\r
923 if (fileNames.size() == 0)
\r
925 String sf = fileNames.get(0);
\r
926 QFile saveFile = new QFile(sf);
\r
927 mode.set(QFile.OpenModeFlag.WriteOnly);
\r
928 saveFile.open(mode);
\r
929 QDataStream saveOut = new QDataStream(saveFile);
\r
930 saveOut.writeBytes(binData.toByteArray());
\r
938 logger.log(logger.EXTREME, "Launching URL");
\r
939 QDesktopServices.openUrl(url);
\r
942 // Listener for when BOLD is clicked
\r
943 @SuppressWarnings("unused")
\r
944 private void undoClicked() {
\r
945 browser.page().triggerAction(WebAction.Undo);
\r
946 browser.setFocus();
\r
949 // Listener for when BOLD is clicked
\r
950 @SuppressWarnings("unused")
\r
951 private void redoClicked() {
\r
952 browser.page().triggerAction(WebAction.Redo);
\r
953 browser.setFocus();
\r
956 // Listener for when BOLD is clicked
\r
957 @SuppressWarnings("unused")
\r
958 private void boldClicked() {
\r
959 browser.page().triggerAction(WebAction.ToggleBold);
\r
960 microFocusChanged();
\r
961 browser.setFocus();
\r
964 // Listener for when Italics is clicked
\r
965 @SuppressWarnings("unused")
\r
966 private void italicClicked() {
\r
967 browser.page().triggerAction(WebAction.ToggleItalic);
\r
968 microFocusChanged();
\r
969 browser.setFocus();
\r
972 // Listener for when UNDERLINE is clicked
\r
973 @SuppressWarnings("unused")
\r
974 private void underlineClicked() {
\r
975 browser.page().triggerAction(WebAction.ToggleUnderline);
\r
976 microFocusChanged();
\r
977 browser.setFocus();
\r
980 // Listener for when Strikethrough is clicked
\r
981 @SuppressWarnings("unused")
\r
982 private void strikethroughClicked() {
\r
983 browser.page().mainFrame().evaluateJavaScript(
\r
984 "document.execCommand('strikeThrough', false, '');");
\r
985 browser.setFocus();
\r
988 // Listener for when cut is clicked
\r
989 @SuppressWarnings("unused")
\r
990 private void cutClicked() {
\r
991 browser.page().triggerAction(WebAction.Cut);
\r
992 browser.setFocus();
\r
995 // Listener when COPY is clicked
\r
996 @SuppressWarnings("unused")
\r
997 private void copyClicked() {
\r
998 browser.page().triggerAction(WebAction.Copy);
\r
999 browser.setFocus();
\r
1002 // Listener when PASTE is clicked
\r
1003 public void pasteClicked() {
\r
1004 logger.log(logger.EXTREME, "Paste Clicked");
\r
1005 if (forceTextPaste) {
\r
1006 pasteWithoutFormattingClicked();
\r
1009 QClipboard clipboard = QApplication.clipboard();
\r
1010 QMimeData mime = clipboard.mimeData();
\r
1012 // String x = mime.html();
\r
1014 if (mime.hasImage()) {
\r
1015 logger.log(logger.EXTREME, "Image paste found");
\r
1016 browser.setFocus();
\r
1017 insertImage(mime);
\r
1018 browser.setFocus();
\r
1022 if (mime.hasUrls()) {
\r
1023 logger.log(logger.EXTREME, "URL paste found");
\r
1025 browser.setFocus();
\r
1029 String text = mime.html();
\r
1030 if (text.contains("en-tag") && mime.hasHtml()) {
\r
1031 logger.log(logger.EXTREME, "Intra-note paste found");
\r
1032 text = fixInternotePaste(text);
\r
1033 mime.setHtml(text);
\r
1034 clipboard.setMimeData(mime);
\r
1037 logger.log(logger.EXTREME, "Final paste choice encountered");
\r
1038 browser.page().triggerAction(WebAction.Paste);
\r
1039 browser.setFocus();
\r
1043 // Paste text without formatting
\r
1044 private void pasteWithoutFormattingClicked() {
\r
1045 logger.log(logger.EXTREME, "Paste without format clipped");
\r
1046 QClipboard clipboard = QApplication.clipboard();
\r
1047 QMimeData mime = clipboard.mimeData();
\r
1048 if (!mime.hasText())
\r
1050 String text = mime.text();
\r
1051 clipboard.setText(text);
\r
1052 browser.page().triggerAction(WebAction.Paste);
\r
1053 QApplication.clipboard().setMimeData(mime);
\r
1054 browser.setFocus();
\r
1058 // insert date/time
\r
1059 @SuppressWarnings("unused")
\r
1060 private void insertDateTime() {
\r
1061 String fmt = Global.getDateFormat() + " " + Global.getTimeFormat();
\r
1062 String dateTimeFormat = new String(fmt);
\r
1063 SimpleDateFormat simple = new SimpleDateFormat(dateTimeFormat);
\r
1064 Calendar cal = Calendar.getInstance();
\r
1066 browser.page().mainFrame().evaluateJavaScript(
\r
1067 "document.execCommand('insertHtml', false, '"+simple.format(cal.getTime())+"');");
\r
1069 browser.setFocus();
\r
1073 // Listener when Left is clicked
\r
1074 @SuppressWarnings("unused")
\r
1075 private void justifyLeftClicked() {
\r
1076 browser.page().mainFrame().evaluateJavaScript(
\r
1077 "document.execCommand('JustifyLeft', false, '');");
\r
1078 browser.setFocus();
\r
1081 // Listener when Center is clicked
\r
1082 @SuppressWarnings("unused")
\r
1083 private void justifyCenterClicked() {
\r
1084 browser.page().mainFrame().evaluateJavaScript(
\r
1085 "document.execCommand('JustifyCenter', false, '');");
\r
1086 browser.setFocus();
\r
1089 // Listener when Left is clicked
\r
1090 @SuppressWarnings("unused")
\r
1091 private void justifyRightClicked() {
\r
1092 browser.page().mainFrame().evaluateJavaScript(
\r
1093 "document.execCommand('JustifyRight', false, '');");
\r
1094 browser.setFocus();
\r
1097 // Listener when HLINE is clicked
\r
1098 @SuppressWarnings("unused")
\r
1099 private void hlineClicked() {
\r
1100 browser.page().mainFrame().evaluateJavaScript(
\r
1101 "document.execCommand('insertHorizontalRule', false, '');");
\r
1102 browser.setFocus();
\r
1105 // Listener when outdent is clicked
\r
1106 private void outdentClicked() {
\r
1107 browser.page().mainFrame().evaluateJavaScript(
\r
1108 "document.execCommand('outdent', false, '');");
\r
1109 browser.setFocus();
\r
1112 // Listener when a bullet list is clicked
\r
1113 @SuppressWarnings("unused")
\r
1114 private void bulletListClicked() {
\r
1115 browser.page().mainFrame().evaluateJavaScript(
\r
1116 "document.execCommand('InsertUnorderedList', false, '');");
\r
1117 browser.setFocus();
\r
1120 // Listener when a bullet list is clicked
\r
1121 @SuppressWarnings("unused")
\r
1122 private void numberListClicked() {
\r
1123 browser.page().mainFrame().evaluateJavaScript(
\r
1124 "document.execCommand('InsertOrderedList', false, '');");
\r
1125 browser.setFocus();
\r
1128 // Listener when indent is clicked
\r
1129 private void indentClicked() {
\r
1130 browser.page().mainFrame().evaluateJavaScript(
\r
1131 "document.execCommand('indent', false, '');");
\r
1132 browser.setFocus();
\r
1135 // Listener when the font name is changed
\r
1136 @SuppressWarnings("unused")
\r
1137 private void fontChanged(String font) {
\r
1138 browser.page().mainFrame().evaluateJavaScript(
\r
1139 "document.execCommand('fontName',false,'" + font + "');");
\r
1140 browser.setFocus();
\r
1143 // Listener when a font size is changed
\r
1144 @SuppressWarnings("unused")
\r
1145 private void fontSizeChanged(String font) {
\r
1146 String text = browser.selectedText();
\r
1147 if (text.trim().equalsIgnoreCase(""))
\r
1150 String selectedText = browser.selectedText();
\r
1151 String url = "<span style=\"font-size:" +font +"pt; \">"+selectedText +"</a>";
\r
1152 String script = "document.execCommand('insertHtml', false, '"+url+"');";
\r
1153 browser.page().mainFrame().evaluateJavaScript(script);
\r
1154 /* browser.page().mainFrame().evaluateJavaScript(
\r
1155 "document.execCommand('fontSize',false,'"
\r
1158 browser.setFocus();
\r
1161 // Load the font combo box based upon the font selected
\r
1162 private void loadFontSize(String name) {
\r
1163 QFontDatabase db = new QFontDatabase();
\r
1165 List<Integer> points = db.pointSizes(name);
\r
1166 for (int i=0; i<points.size(); i++) {
\r
1167 fontSize.addItem(points.get(i).toString());
\r
1170 fontSize.addItem("x-small");
\r
1171 fontSize.addItem("small");
\r
1172 fontSize.addItem("medium");
\r
1173 fontSize.addItem("large");
\r
1174 fontSize.addItem("x-large");
\r
1175 fontSize.addItem("xx-large");
\r
1176 fontSize.addItem("xxx-large");
\r
1180 // Listener when a font size is changed
\r
1181 @SuppressWarnings("unused")
\r
1182 private void fontColorClicked() {
\r
1183 // QColorDialog dialog = new QColorDialog();
\r
1184 // QColor color = QColorDialog.getColor();
\r
1185 QColor color = fontColorMenu.getColor();
\r
1186 if (color.isValid())
\r
1187 browser.page().mainFrame().evaluateJavaScript(
\r
1188 "document.execCommand('foreColor',false,'" + color.name()
\r
1190 browser.setFocus();
\r
1193 // Listener for when a background color change is requested
\r
1194 @SuppressWarnings("unused")
\r
1195 private void fontHilightClicked() {
\r
1196 // QColorDialog dialog = new QColorDialog();
\r
1197 // QColor color = QColorDialog.getColor();
\r
1198 QColor color = fontHilightColorMenu.getColor();
\r
1199 if (color.isValid())
\r
1200 browser.page().mainFrame().evaluateJavaScript(
\r
1201 "document.execCommand('backColor',false,'" + color.name()
\r
1203 browser.setFocus();
\r
1206 // Listener for when a background color change is requested
\r
1207 @SuppressWarnings("unused")
\r
1208 private void superscriptClicked() {
\r
1209 browser.page().mainFrame().evaluateJavaScript(
\r
1210 "document.execCommand('superscript');");
\r
1211 browser.setFocus();
\r
1214 // Listener for when a background color change is requested
\r
1215 @SuppressWarnings("unused")
\r
1216 private void subscriptClicked() {
\r
1217 browser.page().mainFrame().evaluateJavaScript(
\r
1218 "document.execCommand('subscript');");
\r
1219 browser.setFocus();
\r
1221 // Insert a to-do checkbox
\r
1222 @SuppressWarnings("unused")
\r
1223 private void todoClicked() {
\r
1224 FileNameMap fileNameMap = URLConnection.getFileNameMap();
\r
1225 String script_start = new String(
\r
1226 "document.execCommand('insertHtml', false, '");
\r
1227 String script_end = new String("');");
\r
1228 String todo = new String(
\r
1229 "<input TYPE=\"CHECKBOX\" value=\"false\" onClick=\"value=checked; window.jambi.contentChanged(); \" />");
\r
1230 browser.page().mainFrame().evaluateJavaScript(
\r
1231 script_start + todo + script_end);
\r
1232 browser.setFocus();
\r
1235 // Encrypt the selected text
\r
1236 @SuppressWarnings("unused")
\r
1237 private void encryptText() {
\r
1238 String text = browser.selectedText();
\r
1239 if (text.trim().equalsIgnoreCase(""))
\r
1241 text = new String(text.replaceAll("\n", "<br/>"));
\r
1243 EnCryptDialog dialog = new EnCryptDialog();
\r
1245 if (!dialog.okPressed()) {
\r
1249 EnCrypt crypt = new EnCrypt();
\r
1250 String encrypted = crypt.encrypt(text, dialog.getPassword().trim(), 64);
\r
1251 String decrypted = crypt.decrypt(encrypted, dialog.getPassword().trim(), 64);
\r
1253 if (encrypted.trim().equals("")) {
\r
1254 QMessageBox.information(this, tr("Error"), tr("Error Encrypting String"));
\r
1257 StringBuffer buffer = new StringBuffer(encrypted.length() + 100);
\r
1258 buffer.append("<img en-tag=\"en-crypt\" cipher=\"RC2\" hint=\""
\r
1259 + dialog.getHint().replace("'","\\'") + "\" length=\"64\" ");
\r
1260 buffer.append("contentEditable=\"false\" alt=\"");
\r
1261 buffer.append(encrypted);
\r
1262 buffer.append("\" src=\"").append(FileUtils.toForwardSlashedPath(Global.getFileManager().getImageDirPath("encrypt.png") +"\""));
\r
1263 Global.cryptCounter++;
\r
1264 buffer.append(" id=\"crypt"+Global.cryptCounter.toString() +"\"");
\r
1265 buffer.append(" onMouseOver=\"style.cursor=\\'hand\\'\"");
\r
1266 buffer.append(" onClick=\"window.jambi.decryptText(\\'crypt"+Global.cryptCounter.toString()
\r
1267 +"\\', \\'"+encrypted+"\\', \\'"+dialog.getHint().replace("'", "\\&apos;")+"\\');\"");
\r
1268 buffer.append("style=\"display:block\" />");
\r
1270 String script_start = new String(
\r
1271 "document.execCommand('insertHtml', false, '");
\r
1272 String script_end = new String("');");
\r
1273 browser.page().mainFrame().evaluateJavaScript(
\r
1274 script_start + buffer.toString() + script_end);
\r
1278 // Insert a hyperlink
\r
1279 public void insertLink() {
\r
1280 logger.log(logger.EXTREME, "Inserting link");
\r
1281 String text = browser.selectedText();
\r
1282 if (text.trim().equalsIgnoreCase(""))
\r
1285 InsertLinkDialog dialog = new InsertLinkDialog();
\r
1286 if (currentHyperlink != null && currentHyperlink != "") {
\r
1287 dialog.setUrl(currentHyperlink);
\r
1290 if (!dialog.okPressed()) {
\r
1291 logger.log(logger.EXTREME, "Insert link canceled");
\r
1294 if (browser.insertLinkAction.text().equalsIgnoreCase("Insert Hyperlink")) {
\r
1295 String selectedText = browser.selectedText();
\r
1296 logger.log(logger.EXTREME, "Inserting link on text "+selectedText);
\r
1297 logger.log(logger.EXTREME, "URL Link " +dialog.getUrl().trim());
\r
1298 String dUrl = StringUtils.replace(dialog.getUrl().trim(), "'", "\\'");
\r
1299 String url = "<a href=\"" +dUrl
\r
1300 +"\" title=" +dUrl
\r
1301 +" >"+selectedText +"</a>";
\r
1302 String script = "document.execCommand('insertHtml', false, '"+url+"');";
\r
1303 browser.page().mainFrame().evaluateJavaScript(script);
\r
1306 String js = new String( "function getCursorPos() {"
\r
1308 +"if (window.getSelection) {"
\r
1309 +" var selObj = window.getSelection();"
\r
1310 +" var selRange = selObj.getRangeAt(0);"
\r
1311 +" var workingNode = window.getSelection().anchorNode.parentNode;"
\r
1312 +" while(workingNode != null) { "
\r
1313 +" if (workingNode.nodeName.toLowerCase()=='a') workingNode.setAttribute('href','" +dialog.getUrl() +"');"
\r
1314 +" workingNode = workingNode.parentNode;"
\r
1317 +"} getCursorPos();");
\r
1318 browser.page().mainFrame().evaluateJavaScript(js);
\r
1325 public void insertTable() {
\r
1326 TableDialog dialog = new TableDialog();
\r
1328 if (!dialog.okPressed()) {
\r
1332 int cols = dialog.getCols();
\r
1333 int rows = dialog.getRows();
\r
1334 int width = dialog.getWidth();
\r
1335 boolean percent = dialog.isPercent();
\r
1337 String newHTML = "<table border=\"1\" width=\"" +new Integer(width).toString();
\r
1339 newHTML = newHTML +"%";
\r
1340 newHTML = newHTML + "\"><tbody>";
\r
1342 for (int i=0; i<rows; i++) {
\r
1343 newHTML = newHTML +"<tr>";
\r
1344 for (int j=0; j<cols; j++) {
\r
1345 newHTML = newHTML +"<td> </td>";
\r
1347 newHTML = newHTML +"</tr>";
\r
1349 newHTML = newHTML+"</tbody></table>";
\r
1351 String script = "document.execCommand('insertHtml', false, '"+newHTML+"');";
\r
1352 browser.page().mainFrame().evaluateJavaScript(script);
\r
1356 // Text content changed
\r
1357 @SuppressWarnings("unused")
\r
1358 private void selectionChanged() {
\r
1359 browser.encryptAction.setEnabled(true);
\r
1360 browser.insertLinkAction.setEnabled(true);
\r
1361 String scriptStart = "var selection_text = (window.getSelection()).toString();"
\r
1362 + "var range = (window.getSelection()).getRangeAt(0);"
\r
1363 + "var parent_html = range.commonAncestorContainer.innerHTML;"
\r
1364 + "if (parent_html == undefined) {window.jambi.saveSelectedText(selection_text); return;}"
\r
1365 + "var first_text = range.startContainer.nodeValue.substr(range.startOffset);"
\r
1366 + "var last_text = (range.endContainer.nodeValue).substring(0,range.endOffset);"
\r
1367 + "var start = parent_html.indexOf(first_text);"
\r
1368 + "var end = parent_html.indexOf(last_text,start+1)+last_text.length;"
\r
1369 + "var value = parent_html.substring(start,end);"
\r
1370 + "window.jambi.saveSelectedText(value);" ;
\r
1371 browser.page().mainFrame().evaluateJavaScript(scriptStart);
\r
1375 public void saveSelectedText(String text) {
\r
1376 boolean enabled = true;
\r
1377 if (text.trim().length() == 0)
\r
1379 if (text.indexOf("en-tag=\"en-crypt\"") >= 0)
\r
1381 if (text.indexOf("<img en-tag=\"en-media\"") >= 0)
\r
1383 if (text.indexOf("<a en-tag=\"en-media\"") >= 0)
\r
1385 if (text.indexOf("<input ") >= 0)
\r
1388 browser.encryptAction.setEnabled(enabled);
\r
1389 browser.insertLinkAction.setEnabled(enabled);
\r
1390 // selectedText = text;
\r
1393 // Decrypt clicked text
\r
1394 public void decryptText(String id, String text, String hint) {
\r
1395 EnCrypt crypt = new EnCrypt();
\r
1396 String plainText = null;
\r
1397 Calendar currentTime = new GregorianCalendar();
\r
1398 Long l = new Long(currentTime.getTimeInMillis());
\r
1399 String slot = new String(Long.toString(l));
\r
1401 // First, try to decrypt with any keys we already have
\r
1402 for (int i=0; i<Global.passwordRemember.size(); i++) {
\r
1403 plainText = crypt.decrypt(text, Global.passwordRemember.get(i).getFirst(), 64);
\r
1404 if (plainText != null) {
\r
1405 slot = new String(Long.toString(l));
\r
1406 Global.passwordSafe.put(slot, Global.passwordRemember.get(i));
\r
1407 removeEncryption(id, plainText, false, slot);
\r
1413 EnDecryptDialog dialog = new EnDecryptDialog();
\r
1414 dialog.setHint(hint);
\r
1415 while (plainText == null || !dialog.okPressed()) {
\r
1417 if (!dialog.okPressed()) {
\r
1420 plainText = crypt.decrypt(text, dialog.getPassword().trim(), 64);
\r
1421 if (plainText == null) {
\r
1422 QMessageBox.warning(this, "Incorrect Password", "The password entered is not correct");
\r
1425 Pair<String,String> passwordPair = new Pair<String,String>();
\r
1426 passwordPair.setFirst(dialog.getPassword());
\r
1427 passwordPair.setSecond(dialog.getHint());
\r
1428 Global.passwordSafe.put(slot, passwordPair);
\r
1429 // removeEncryption(id, plainText.replaceAll("\n", "<br/>"), dialog.permanentlyDecrypt(), slot);
\r
1430 removeEncryption(id, plainText, dialog.permanentlyDecrypt(), slot);
\r
1431 if (dialog.rememberPassword()) {
\r
1432 Pair<String, String> pair = new Pair<String,String>();
\r
1433 pair.setFirst(dialog.getPassword());
\r
1434 pair.setSecond(dialog.getHint());
\r
1435 Global.passwordRemember.add(pair);
\r
1440 // Get the editor tag line
\r
1441 public TagLineEdit getTagLine() {
\r
1445 // Modify a note's tags
\r
1446 @SuppressWarnings("unused")
\r
1447 private void modifyTags() {
\r
1448 TagAssign tagWindow = new TagAssign(allTags, currentTags, !conn.getNotebookTable().isLinked(currentNote.getNotebookGuid()));
\r
1450 if (tagWindow.okClicked()) {
\r
1451 currentTags.clear();
\r
1452 StringBuffer tagDisplay = new StringBuffer();
\r
1454 List<QListWidgetItem> newTags = tagWindow.getTagList()
\r
1456 for (int i = 0; i < newTags.size(); i++) {
\r
1457 currentTags.add(newTags.get(i).text());
\r
1458 tagDisplay.append(newTags.get(i).text());
\r
1459 if (i < newTags.size() - 1) {
\r
1460 tagDisplay.append(Global.tagDelimeter + " ");
\r
1463 tagEdit.setText(tagDisplay.toString());
\r
1464 noteSignal.tagsChanged.emit(currentNote.getGuid(), currentTags);
\r
1468 // Tag line has been modified by typing text
\r
1469 @SuppressWarnings("unused")
\r
1470 private void modifyTagsTyping() {
\r
1471 String completionText = "";
\r
1472 if (tagEdit.currentCompleterSelection != null && !tagEdit.currentCompleterSelection.equals("")) {
\r
1473 completionText = tagEdit.currentCompleterSelection;
\r
1474 tagEdit.currentCompleterSelection = "";
\r
1477 if (tagEdit.text().equalsIgnoreCase(saveTagList))
\r
1480 // We know something has changed...
\r
1481 String oldTagArray[] = saveTagList.split(Global.tagDelimeter);
\r
1482 String newTagArray[];
\r
1483 if (!completionText.equals("")) {
\r
1484 String before = tagEdit.text().substring(0,tagEdit.cursorPosition());
\r
1485 int lastDelimiter = before.lastIndexOf(Global.tagDelimeter);
\r
1486 if (lastDelimiter > 0)
\r
1487 before = before.substring(0,before.lastIndexOf(Global.tagDelimeter));
\r
1490 String after = tagEdit.text().substring(tagEdit.cursorPosition());
\r
1491 newTagArray = (before+Global.tagDelimeter+completionText+Global.tagDelimeter+after).split(Global.tagDelimeter);
\r
1494 newTagArray = tagEdit.text().split(Global.tagDelimeter);
\r
1497 // Remove any traling or leading blanks
\r
1498 for (int i=0; i<newTagArray.length; i++)
\r
1499 newTagArray[i] = newTagArray[i].trim().replaceAll("^\\s+", "");;
\r
1501 // Remove any potential duplicates from the new list
\r
1502 for (int i=0; i<newTagArray.length; i++) {
\r
1503 boolean foundOnce = false;
\r
1504 for (int j=0; j<newTagArray.length; j++) {
\r
1505 if (newTagArray[j].equalsIgnoreCase(newTagArray[i])) {
\r
1509 newTagArray[j] = "";
\r
1514 List<String> newTagList = new ArrayList<String>();
\r
1515 List<String> oldTagList = new ArrayList<String>();
\r
1517 for (int i = 0; i < oldTagArray.length; i++)
\r
1518 if (!oldTagArray[i].trim().equals(""))
\r
1519 oldTagList.add(oldTagArray[i]);
\r
1520 for (int i = 0; i < newTagArray.length; i++)
\r
1521 if (!newTagArray[i].trim().equals(""))
\r
1522 newTagList.add(newTagArray[i]);
\r
1524 if (conn.getNotebookTable().isLinked(currentNote.getNotebookGuid())) {
\r
1525 for (int i=newTagList.size()-1; i>=0; i--) {
\r
1526 boolean found = false;
\r
1527 for (int j=0; j<allTags.size(); j++) {
\r
1528 if (allTags.get(j).getName().equalsIgnoreCase(newTagList.get(i))) {
\r
1534 newTagList.remove(i);
\r
1538 // Let's cleanup the appearance of the tag list
\r
1539 Collections.sort(newTagList);
\r
1540 String newDisplay = "";
\r
1541 for (int i=0; i<newTagList.size(); i++) {
\r
1542 newDisplay = newDisplay+newTagList.get(i);
\r
1543 if (i<newTagList.size()-1)
\r
1544 newDisplay = newDisplay+Global.tagDelimeter +" ";
\r
1546 tagEdit.blockSignals(true);
\r
1547 tagEdit.setText(newDisplay);
\r
1548 tagEdit.blockSignals(false);
\r
1550 // We now have lists of the new & old. Remove duplicates. If all
\r
1551 // are removed from both then nothing has really changed
\r
1552 for (int i = newTagList.size() - 1; i >= 0; i--) {
\r
1553 String nTag = newTagList.get(i);
\r
1554 for (int j = oldTagList.size() - 1; j >= 0; j--) {
\r
1555 String oTag = oldTagList.get(j);
\r
1556 if (oTag.equalsIgnoreCase(nTag)) {
\r
1557 oldTagList.remove(j);
\r
1558 newTagList.remove(i);
\r
1564 if (oldTagList.size() != 0 || newTagList.size() != 0) {
\r
1565 currentTags.clear();
\r
1566 newTagArray = tagEdit.text().split(Global.tagDelimeter);
\r
1567 for (int i = 0; i < newTagArray.length; i++)
\r
1568 if (!newTagArray[i].trim().equals(""))
\r
1569 currentTags.add(newTagArray[i].trim());
\r
1571 noteSignal.tagsChanged.emit(currentNote.getGuid(), currentTags);
\r
1576 // Tab button was pressed
\r
1577 public void tabPressed() {
\r
1578 if (!insideList) {
\r
1579 String script_start = new String(
\r
1580 "document.execCommand('insertHtml', false, ' ');");
\r
1581 browser.page().mainFrame().evaluateJavaScript(script_start);
\r
1586 public void backtabPressed() {
\r
1591 public void setInsideList() {
\r
1592 insideList = true;
\r
1595 // The title has been edited
\r
1596 @SuppressWarnings("unused")
\r
1597 private void titleEdited() {
\r
1598 // If we don't have a good note, or if the current title
\r
1599 // matches the old title then we don't need to do anything
\r
1600 if (currentNote == null)
\r
1602 if (currentNote.getTitle().trim().equals(titleLabel.text().trim()))
\r
1605 // If we have a real change, we need to save it.
\r
1606 noteSignal.titleChanged.emit(currentNote.getGuid(), titleLabel.text());
\r
1607 currentNote.setTitle(titleLabel.text());
\r
1608 saveNoteTitle = titleLabel.text();
\r
1612 // Set the list of note tags
\r
1613 public void setAllTags(List<Tag> l) {
\r
1615 tagEdit.setTagList(l);
\r
1618 // Setter for the current tags
\r
1619 public void setCurrentTags(List<String> s) {
\r
1623 // Save the list of notebooks
\r
1624 public void setNotebookList(List<Notebook> n) {
\r
1626 loadNotebookList();
\r
1629 // Load the notebook list and select the current notebook
\r
1630 private void loadNotebookList() {
\r
1631 if (notebookBox.count() != 0)
\r
1632 notebookBox.clear();
\r
1633 if (notebookList == null)
\r
1636 for (int i = 0; i < notebookList.size(); i++) {
\r
1637 notebookBox.addItem(notebookList.get(i).getName());
\r
1638 if (currentNote != null) {
\r
1639 if (currentNote.getNotebookGuid().equals(
\r
1640 notebookList.get(i).getGuid())) {
\r
1641 notebookBox.setCurrentIndex(i);
\r
1648 // Set the notebook for a note
\r
1649 public void setNotebook(String notebook) {
\r
1650 currentNote.setNotebookGuid(notebook);
\r
1651 loadNotebookList();
\r
1654 // Get the contents of the editor
\r
1655 public String getContent() {
\r
1656 return browser.page().currentFrame().toHtml();
\r
1659 // The note contents have changed
\r
1660 public void contentChanged() {
\r
1661 String content = getContent();
\r
1663 noteSignal.noteChanged.emit(currentNote.getGuid(), content);
\r
1666 // The notebook selection has changed
\r
1667 @SuppressWarnings("unused")
\r
1668 private void notebookChanged() {
\r
1669 boolean changed = false;
\r
1670 String n = notebookBox.currentText();
\r
1671 for (int i = 0; i < notebookList.size(); i++) {
\r
1672 if (n.equals(notebookList.get(i).getName())) {
\r
1673 if (!notebookList.get(i).getGuid().equals(currentNote.getNotebookGuid())) {
\r
1674 String guid = conn.getNotebookTable().findNotebookByName(n);
\r
1675 if (conn.getNotebookTable().isLinked(guid)) {
\r
1676 tagEdit.setText("");
\r
1677 noteSignal.tagsChanged.emit(currentNote.getGuid(), new ArrayList<String>());
\r
1678 FilterEditorTags t = new FilterEditorTags(conn, logger);
\r
1679 setAllTags(t.getValidTags(currentNote));
\r
1681 currentNote.setNotebookGuid(notebookList.get(i).getGuid());
\r
1684 i = notebookList.size();
\r
1688 // If the notebook changed, signal the update
\r
1690 noteSignal.notebookChanged.emit(currentNote.getGuid(), currentNote
\r
1691 .getNotebookGuid());
\r
1694 // Check the note title
\r
1695 private void checkNoteTitle() {
\r
1696 String text = browser.page().currentFrame().toPlainText();
\r
1697 if (saveNoteTitle.trim().equals("") || saveNoteTitle.trim().equals("Untitled Note")) {
\r
1698 int newLine = text.indexOf("\n");
\r
1699 if (newLine > 0) {
\r
1700 text = text.substring(0, newLine);
\r
1701 if (text.trim().equals(""))
\r
1702 text = tr("Untitled Note");
\r
1703 titleLabel.setText(text);
\r
1705 if (text.length() > Constants.EDAM_NOTE_TITLE_LEN_MAX)
\r
1706 titleLabel.setText(text.substring(0, Constants.EDAM_NOTE_TITLE_LEN_MAX));
\r
1708 titleLabel.blockSignals(true);
\r
1709 if (text.trim().equals(""))
\r
1710 titleLabel.setText(tr("Untitled Note"));
\r
1712 titleLabel.setText(text);
\r
1713 titleLabel.blockSignals(false);
\r
1716 noteSignal.titleChanged.emit(currentNote.getGuid(), titleLabel
\r
1721 // Return the note contents so we can email them
\r
1722 public String getContentsToEmail() {
\r
1723 return browser.page().currentFrame().toPlainText().trim();
\r
1725 * int body = browser.page().currentFrame().toHtml().indexOf("<body>");
\r
1726 * String temp = browser.page().currentFrame().toHtml(); if (body == -1)
\r
1727 * temp = "<html><body><b>Test</b></body></html>"; else temp =
\r
1728 * "<html>"+temp.substring(body); return temp; // return
\r
1729 * urlEncode(browser.page().currentFrame().toHtml());
\r
1733 // Insert an image into the editor
\r
1734 private void insertImage(QMimeData mime) {
\r
1735 logger.log(logger.EXTREME, "Entering insertImage");
\r
1736 QImage img = (QImage) mime.imageData();
\r
1737 String script_start = new String(
\r
1738 "document.execCommand('insertHTML', false, '");
\r
1739 String script_end = new String("');");
\r
1741 long now = new Date().getTime();
\r
1742 String path = Global.getFileManager().getResDirPath(
\r
1743 (new Long(now).toString()) + ".jpg");
\r
1745 // This block is just a hack to make sure we wait at least 1ms so we
\r
1747 // have collisions on image names
\r
1748 long i = new Date().getTime();
\r
1750 i = new Date().getTime();
\r
1752 // Open the file & write the data
\r
1753 QFile tfile = new QFile(path);
\r
1754 tfile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.WriteOnly));
\r
1755 if (!img.save(tfile)) {
\r
1761 Resource newRes = createResource(QUrl.fromLocalFile(path).toString(), 0, "image/jpeg", false);
\r
1762 if (newRes == null)
\r
1764 currentNote.getResources().add(newRes);
\r
1766 // do the actual insert into the note
\r
1767 StringBuffer buffer = new StringBuffer(100);
\r
1768 buffer.append("<img src=\"");
\r
1769 buffer.append(tfile.fileName());
\r
1770 buffer.append("\" en-tag=en-media type=\"image/jpeg\""
\r
1771 +" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\""
\r
1772 +" guid=\"" +newRes.getGuid() +"\""
\r
1773 // +" onContextMenu=\"window.jambi.imageContextMenu('" +tfile.fileName() +"');\""
\r
1774 +" onContextMenu=\"window.jambi.imageContextMenu(&." +tfile.fileName() +"&.);\""
\r
1777 browser.page().mainFrame().evaluateJavaScript(
\r
1778 script_start + buffer + script_end);
\r
1783 // Handle URLs that are trying to be pasted
\r
1784 public void handleUrls(QMimeData mime) {
\r
1785 logger.log(logger.EXTREME, "Starting handleUrls");
\r
1786 FileNameMap fileNameMap = URLConnection.getFileNameMap();
\r
1788 List<QUrl> urlList = mime.urls();
\r
1789 String url = new String();
\r
1790 String script_start = new String(
\r
1791 "document.execCommand('createLink', false, '");
\r
1792 String script_end = new String("');");
\r
1794 for (int i = 0; i < urlList.size(); i++) {
\r
1795 url = urlList.get(i).toString();
\r
1796 // Find out what type of file we have
\r
1797 String mimeType = fileNameMap.getContentTypeFor(url);
\r
1799 // If null returned, we need to guess at the file type
\r
1800 if (mimeType == null)
\r
1801 mimeType = "application/"
\r
1802 + url.substring(url.lastIndexOf(".") + 1);
\r
1804 // Check if we have an image or some other type of file
\r
1805 if (url.substring(0, 5).equalsIgnoreCase("file:")
\r
1806 && mimeType.substring(0, 5).equalsIgnoreCase("image")) {
\r
1807 handleLocalImageURLPaste(mime, mimeType);
\r
1810 String[] type = mimeType.split("/");
\r
1811 boolean valid = validAttachment(type[1]);
\r
1812 boolean smallEnough = checkFileAttachmentSize(url);
\r
1813 if (smallEnough && valid
\r
1814 && url.substring(0, 5).equalsIgnoreCase("file:")
\r
1815 && !mimeType.substring(0, 5).equalsIgnoreCase("image")) {
\r
1816 handleLocalAttachment(mime, mimeType);
\r
1819 browser.page().mainFrame().evaluateJavaScript(
\r
1820 script_start + url + script_end);
\r
1825 // If a URL being pasted is an image URL, then attach the image
\r
1826 private void handleLocalImageURLPaste(QMimeData mime, String mimeType) {
\r
1827 List<QUrl> urlList = mime.urls();
\r
1828 String url = new String();
\r
1829 String script_start_image = new String(
\r
1830 "document.execCommand('insertHtml', false, '");
\r
1831 String script_end = new String("');");
\r
1832 StringBuffer buffer;
\r
1834 // Copy the image over into the resource directory and create a new resource
\r
1835 // record for each url pasted
\r
1836 for (int i = 0; i < urlList.size(); i++) {
\r
1837 url = urlList.get(i).toString();
\r
1839 Resource newRes = createResource(url, i, mimeType, false);
\r
1840 if (newRes == null)
\r
1842 currentNote.getResources().add(newRes);
\r
1843 buffer = new StringBuffer(100);
\r
1845 // Open the file & write the data
\r
1846 String fileName = Global.getFileManager().getResDirPath(newRes.getGuid());
\r
1847 QFile tfile = new QFile(fileName);
\r
1848 tfile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.WriteOnly));
\r
1849 tfile.write(newRes.getData().getBody());
\r
1851 buffer.append(script_start_image);
\r
1852 buffer.append("<img src=\"" + FileUtils.toForwardSlashedPath(fileName));
\r
1853 // if (mimeType.equalsIgnoreCase("image/jpg"))
\r
1854 // mimeType = "image/jpeg";
\r
1855 buffer.append("\" en-tag=\"en-media\" type=\"" + mimeType +"\""
\r
1856 +" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\""
\r
1857 +" guid=\"" +newRes.getGuid() +"\""
\r
1858 +" onContextMenu=\"window.jambi.imageContextMenu('" +tfile.fileName() +"');\""
\r
1860 buffer.append(script_end);
\r
1861 browser.page().mainFrame().evaluateJavaScript(buffer.toString());
\r
1867 // If a URL being pasted is a local file URL, then attach the file
\r
1868 private void handleLocalAttachment(QMimeData mime, String mimeType) {
\r
1869 logger.log(logger.EXTREME, "Attaching local file");
\r
1870 List<QUrl> urlList = mime.urls();
\r
1871 String script_start = new String(
\r
1872 "document.execCommand('insertHtml', false, '");
\r
1873 String script_end = new String("');");
\r
1874 StringBuffer buffer;
\r
1876 String[] type = mimeType.split("/");
\r
1877 String icon = findIcon(type[1]);
\r
1878 if (icon.equals("attachment.png"))
\r
1879 icon = findIcon(type[0]);
\r
1880 buffer = new StringBuffer(100);
\r
1882 for (int i = 0; i < urlList.size(); i++) {
\r
1883 String url = urlList.get(i).toString();
\r
1885 // Start building the HTML
\r
1886 if (icon.equals("attachment.png"))
\r
1887 icon = findIcon(url.substring(url.lastIndexOf(".")+1));
\r
1888 String imageURL = FileUtils.toFileURLString(Global.getFileManager().getImageDirFile(icon));
\r
1890 logger.log(logger.EXTREME, "Creating resource ");
\r
1891 Resource newRes = createResource(url, i, mimeType, true);
\r
1892 if (newRes == null)
\r
1894 logger.log(logger.EXTREME, "New resource size: " +newRes.getData().getSize());
\r
1895 currentNote.getResources().add(newRes);
\r
1897 String fileName = newRes.getGuid() + Global.attachmentNameDelimeter+newRes.getAttributes().getFileName();
\r
1898 // If we have a PDF, we need to setup the preview.
\r
1899 if (icon.equalsIgnoreCase("pdf.png") && Global.pdfPreview()) {
\r
1900 logger.log(logger.EXTREME, "Setting up PDF preview");
\r
1901 if (newRes.getAttributes() != null &&
\r
1902 newRes.getAttributes().getFileName() != null &&
\r
1903 !newRes.getAttributes().getFileName().trim().equals(""))
\r
1904 fileName = newRes.getGuid()+Global.attachmentNameDelimeter+
\r
1905 newRes.getAttributes().getFileName();
\r
1907 fileName = newRes.getGuid()+".pdf";
\r
1908 QFile file = new QFile(Global.getFileManager().getResDirPath(fileName));
\r
1909 QFile.OpenMode mode = new QFile.OpenMode();
\r
1910 mode.set(QFile.OpenModeFlag.WriteOnly);
\r
1912 QDataStream out = new QDataStream(file);
\r
1913 // Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(newRes.getGuid(), true);
\r
1914 QByteArray binData = new QByteArray(newRes.getData().getBody());
\r
1915 // resBinary = null;
\r
1916 out.writeBytes(binData.toByteArray());
\r
1919 PDFPreview pdfPreview = new PDFPreview();
\r
1920 if (pdfPreview.setupPreview(Global.getFileManager().getResDirPath(fileName), "pdf",0)) {
\r
1921 imageURL = file.fileName() + ".png";
\r
1925 logger.log(logger.EXTREME, "Generating link tags");
\r
1926 buffer.delete(0, buffer.length());
\r
1927 buffer.append("<a en-tag=\"en-media\" guid=\"" +newRes.getGuid()+"\" ");
\r
1928 buffer.append(" onContextMenu=\"window.jambi.imageContextMenu('")
\r
1929 .append(Global.getFileManager().getResDirPath(fileName))
\r
1930 .append("');\" "); buffer.append("type=\"" + mimeType + "\" href=\"nnres://" + fileName +"\" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\" >");
\r
1931 buffer.append("<img src=\"" + imageURL + "\" title=\"" +newRes.getAttributes().getFileName());
\r
1932 buffer.append("\"></img>");
\r
1933 buffer.append("</a>");
\r
1934 browser.page().mainFrame().evaluateJavaScript(
\r
1935 script_start + buffer.toString() + script_end);
\r
1940 private Resource createResource(String url, int sequence, String mime, boolean attachment) {
\r
1941 logger.log(logger.EXTREME, "Inside create resource");
\r
1942 QFile resourceFile;
\r
1943 String urlTest = new QUrl(url).toLocalFile();
\r
1944 if (!urlTest.equals(""))
\r
1946 url = url.replace("/", File.separator);
\r
1947 resourceFile = new QFile(url);
\r
1948 resourceFile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly));
\r
1949 byte[] fileData = resourceFile.readAll().toByteArray();
\r
1950 resourceFile.close();
\r
1951 if (fileData.length == 0)
\r
1955 md = MessageDigest.getInstance("MD5");
\r
1956 md.update(fileData);
\r
1957 byte[] hash = md.digest();
\r
1959 Resource r = new Resource();
\r
1960 Calendar time = new GregorianCalendar();
\r
1961 long prevTime = time.getTimeInMillis();
\r
1962 while (prevTime == time.getTimeInMillis()) {
\r
1963 time = new GregorianCalendar();
\r
1965 r.setGuid(time.getTimeInMillis()+new Integer(sequence).toString());
\r
1966 r.setNoteGuid(currentNote.getGuid());
\r
1968 r.setActive(true);
\r
1969 r.setUpdateSequenceNum(0);
\r
1970 r.setWidth((short) 0);
\r
1971 r.setHeight((short) 0);
\r
1972 r.setDuration((short) 0);
\r
1974 Data d = new Data();
\r
1975 d.setBody(fileData);
\r
1976 d.setBodyIsSet(true);
\r
1977 d.setBodyHash(hash);
\r
1978 d.setBodyHashIsSet(true);
\r
1980 d.setSize(fileData.length);
\r
1982 int fileNamePos = url.lastIndexOf(File.separator);
\r
1983 if (fileNamePos == -1)
\r
1984 fileNamePos = url.lastIndexOf("/");
\r
1985 String fileName = url.substring(fileNamePos+1);
\r
1986 ResourceAttributes a = new ResourceAttributes();
\r
1988 a.setAltitudeIsSet(false);
\r
1989 a.setLongitude(0);
\r
1990 a.setLongitudeIsSet(false);
\r
1992 a.setLatitudeIsSet(false);
\r
1993 a.setCameraMake("");
\r
1994 a.setCameraMakeIsSet(false);
\r
1995 a.setCameraModel("");
\r
1996 a.setCameraModelIsSet(false);
\r
1997 a.setAttachment(attachment);
\r
1998 a.setAttachmentIsSet(true);
\r
1999 a.setClientWillIndex(false);
\r
2000 a.setClientWillIndexIsSet(true);
\r
2001 a.setRecoType("");
\r
2002 a.setRecoTypeIsSet(false);
\r
2003 a.setSourceURL(url);
\r
2004 a.setSourceURLIsSet(true);
\r
2005 a.setTimestamp(0);
\r
2006 a.setTimestampIsSet(false);
\r
2007 a.setFileName(fileName);
\r
2008 a.setFileNameIsSet(true);
\r
2009 r.setAttributes(a);
\r
2011 conn.getNoteTable().noteResourceTable.saveNoteResource(r, true);
\r
2013 } catch (NoSuchAlgorithmException e1) {
\r
2014 e1.printStackTrace();
\r
2020 // find the appropriate icon for an attachment
\r
2021 private String findIcon(String appl) {
\r
2022 appl = appl.toLowerCase();
\r
2023 File f = Global.getFileManager().getImageDirFile(appl + ".png");
\r
2025 return appl+".png";
\r
2026 return "attachment.png";
\r
2029 // Check if the account supports this type of attachment
\r
2030 private boolean validAttachment(String type) {
\r
2031 if (Global.isPremium())
\r
2033 if (type.equalsIgnoreCase("JPG"))
\r
2035 if (type.equalsIgnoreCase("PNG"))
\r
2037 if (type.equalsIgnoreCase("GIF"))
\r
2039 if (type.equalsIgnoreCase("MP3"))
\r
2041 if (type.equalsIgnoreCase("WAV"))
\r
2043 if (type.equalsIgnoreCase("AMR"))
\r
2045 if (type.equalsIgnoreCase("PDF"))
\r
2047 String error = tr("Non-premium accounts can only attach JPG, PNG, GIF, MP3, WAV, AMR, or PDF files.");
\r
2048 QMessageBox.information(this, tr("Non-Premium Account"), error);
\r
2053 // Check the file attachment to be sure it isn't over 25 mb
\r
2054 private boolean checkFileAttachmentSize(String url) {
\r
2055 String fileName = url.substring(8);
\r
2056 QFile resourceFile = new QFile(fileName);
\r
2057 resourceFile.open(new QIODevice.OpenMode(
\r
2058 QIODevice.OpenModeFlag.ReadOnly));
\r
2059 long size = resourceFile.size();
\r
2060 resourceFile.close();
\r
2061 size = size / 1024 / 1024;
\r
2062 if (size < 50 && Global.isPremium())
\r
2067 String error = tr("A file attachment may not exceed 25MB.");
\r
2068 QMessageBox.information(this, tr("Attachment Size"), error);
\r
2073 @SuppressWarnings("unused")
\r
2074 private void createdChanged() {
\r
2075 QDateTime dt = new QDateTime();
\r
2076 dt.setDate(createdDate.date());
\r
2077 dt.setTime(createdTime.time());
\r
2078 noteSignal.createdDateChanged.emit(currentNote.getGuid(), dt);
\r
2082 @SuppressWarnings("unused")
\r
2083 private void alteredChanged() {
\r
2084 QDateTime dt = new QDateTime();
\r
2085 dt.setDate(alteredDate.date());
\r
2086 dt.setTime(alteredTime.time());
\r
2087 noteSignal.alteredDateChanged.emit(currentNote.getGuid(), dt);
\r
2090 @SuppressWarnings("unused")
\r
2091 private void subjectDateTimeChanged() {
\r
2092 QDateTime dt = new QDateTime();
\r
2093 dt.setDate(subjectDate.date());
\r
2094 dt.setTime(subjectTime.time());
\r
2095 noteSignal.subjectDateChanged.emit(currentNote.getGuid(), dt);
\r
2099 @SuppressWarnings("unused")
\r
2100 private void sourceUrlChanged() {
\r
2101 noteSignal.sourceUrlChanged.emit(currentNote.getGuid(), urlText.text());
\r
2104 @SuppressWarnings("unused")
\r
2105 private void authorChanged() {
\r
2106 noteSignal.authorChanged.emit(currentNote.getGuid(), authorText.text());
\r
2109 @SuppressWarnings("unused")
\r
2110 private void geoBoxChanged() {
\r
2111 int index = geoBox.currentIndex();
\r
2112 geoBox.setCurrentIndex(0);
\r
2114 GeoDialog box = new GeoDialog();
\r
2115 box.setLongitude(currentNote.getAttributes().getLongitude());
\r
2116 box.setLatitude(currentNote.getAttributes().getLatitude());
\r
2117 box.setAltitude(currentNote.getAttributes().getAltitude());
\r
2119 if (!box.okPressed())
\r
2121 double alt = box.getAltitude();
\r
2122 double lat = box.getLatitude();
\r
2123 double lon = box.getLongitude();
\r
2124 if (alt != currentNote.getAttributes().getAltitude() ||
\r
2125 lon != currentNote.getAttributes().getLongitude() ||
\r
2126 lat != currentNote.getAttributes().getLatitude()) {
\r
2127 noteSignal.geoChanged.emit(currentNote.getGuid(), lon, lat, alt);
\r
2128 currentNote.getAttributes().setAltitude(alt);
\r
2129 currentNote.getAttributes().setLongitude(lon);
\r
2130 currentNote.getAttributes().setLatitude(lat);
\r
2135 noteSignal.geoChanged.emit(currentNote.getGuid(), 0.0, 0.0, 0.0);
\r
2136 currentNote.getAttributes().setAltitude(0.0);
\r
2137 currentNote.getAttributes().setLongitude(0.0);
\r
2138 currentNote.getAttributes().setLatitude(0.0);
\r
2141 if (index == 3 || index == 0) {
\r
2142 QDesktopServices.openUrl(new QUrl("http://maps.google.com/maps?z=6&q="+currentNote.getAttributes().getLatitude() +"," +currentNote.getAttributes().getLongitude()));
\r
2146 // ************************************************************
\r
2147 // * User chose to save an attachment. Pares out the request *
\r
2148 // * into a guid & file. Save the result. *
\r
2149 // ************************************************************
\r
2150 public void downloadAttachment(QNetworkRequest request) {
\r
2152 QFileDialog fd = new QFileDialog(this);
\r
2153 fd.setFileMode(FileMode.AnyFile);
\r
2154 fd.setConfirmOverwrite(true);
\r
2155 fd.setWindowTitle(tr("Save File"));
\r
2156 fd.setAcceptMode(AcceptMode.AcceptSave);
\r
2157 fd.setDirectory(System.getProperty("user.home"));
\r
2158 String name = request.url().toString();
\r
2160 int pos = name.lastIndexOf(Global.attachmentNameDelimeter);
\r
2162 guid = name.substring(0, pos).replace("nnres://", "");
\r
2163 name = name.substring(pos +Global.attachmentNameDelimeter.length());
\r
2164 fd.selectFile(name);
\r
2165 pos = name.lastIndexOf('.');
\r
2167 String mimeType = "(*." + name.substring(pos + 1)
\r
2168 + ");; All Files (*)";
\r
2169 fd.setFilter(tr(mimeType));
\r
2175 // Strip URL prefix and base dir
\r
2176 guid = guid.replace("nnres://", "")
\r
2177 .replace(FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath()), "");
\r
2178 guid = guid.replace("file://", "").replace("/", "")
\r
2179 .replace(FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath()), "");
\r
2181 pos = guid.lastIndexOf('.');
\r
2183 guid = guid.substring(0,pos);
\r
2184 if (fd.exec() != 0 && fd.selectedFiles().size() > 0) {
\r
2185 name = name.replace('\\', '/');
\r
2186 Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);
\r
2187 QFile saveFile = new QFile(fd.selectedFiles().get(0));
\r
2188 QFile.OpenMode mode = new QFile.OpenMode();
\r
2189 mode.set(QFile.OpenModeFlag.WriteOnly);
\r
2190 saveFile.open(mode);
\r
2191 QDataStream saveOut = new QDataStream(saveFile);
\r
2192 QByteArray binData = new QByteArray(resBinary.getData().getBody());
\r
2193 saveOut.writeBytes(binData.toByteArray());
\r
2200 // ************************************************************
\r
2201 // * User chose to save an attachment. Pares out the request *
\r
2202 // * into a guid & file. Save the result. --- DONE FROM downloadAttachment now!!!!!
\r
2203 // ************************************************************
\r
2204 public void downloadImage(QNetworkRequest request) {
\r
2205 QFileDialog fd = new QFileDialog(this);
\r
2206 fd.setFileMode(FileMode.AnyFile);
\r
2207 fd.setConfirmOverwrite(true);
\r
2208 fd.setWindowTitle(tr("Save File"));
\r
2209 fd.setAcceptMode(AcceptMode.AcceptSave);
\r
2210 fd.setDirectory(System.getProperty("user.home"));
\r
2211 String name = request.url().toString();
\r
2212 name = name.replace("nnres://", "");
\r
2213 String dPath = FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath());
\r
2214 name = name.replace(dPath, "");
\r
2215 int pos = name.lastIndexOf('.');
\r
2216 String guid = name;
\r
2218 String mimeType = "(*." + name.substring(pos + 1)
\r
2219 + ");; All Files (*)";
\r
2220 fd.setFilter(tr(mimeType));
\r
2221 guid = guid.substring(0,pos);
\r
2223 pos = name.lastIndexOf(Global.attachmentNameDelimeter);
\r
2225 guid = name.substring(0, pos);
\r
2226 fd.selectFile(name.substring(pos+Global.attachmentNameDelimeter.length()));
\r
2228 if (fd.exec() != 0 && fd.selectedFiles().size() > 0) {
\r
2229 Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);
\r
2230 String fileName = fd.selectedFiles().get(0);
\r
2231 QFile saveFile = new QFile(fileName);
\r
2232 QFile.OpenMode mode = new QFile.OpenMode();
\r
2233 mode.set(QFile.OpenModeFlag.WriteOnly);
\r
2234 saveFile.open(mode);
\r
2235 QDataStream saveOut = new QDataStream(saveFile);
\r
2236 QByteArray binData = new QByteArray(resBinary.getData().getBody());
\r
2237 saveOut.writeBytes(binData.toByteArray());
\r
2243 // *************************************************************
\r
2244 // * decrypt any hidden text. We could do an XML parse, but
\r
2245 // * it is quicker here just to scan for an <img tag & do the fix
\r
2246 // * the manual way
\r
2247 // *************************************************************
\r
2248 private void removeEncryption(String id, String plainText, boolean permanent, String slot) {
\r
2250 plainText = " <table class=\"en-crypt-temp\" slot=\""
\r
2253 +"border=1 width=100%><tbody><tr><td>"
\r
2254 +plainText+"</td></tr></tbody></table>";
\r
2257 String html = browser.page().mainFrame().toHtml();
\r
2258 String text = html;
\r
2259 int imagePos = html.indexOf("<img");
\r
2261 for ( ;imagePos>0; ) {
\r
2262 // Find the end tag
\r
2263 endPos = text.indexOf(">", imagePos);
\r
2264 String tag = text.substring(imagePos-1,endPos);
\r
2265 if (tag.indexOf("id=\""+id+"\"") > -1) {
\r
2266 text = text.substring(0,imagePos) +plainText+text.substring(endPos+1);
\r
2267 QTextCodec codec = QTextCodec.codecForName("UTF-8");
\r
2268 QByteArray unicode = codec.fromUnicode(text);
\r
2269 browser.setContent(unicode);
\r
2273 imagePos = text.indexOf("<img", imagePos+1);
\r
2278 //****************************************************************
\r
2279 //* Focus shortcuts
\r
2280 //****************************************************************
\r
2281 @SuppressWarnings("unused")
\r
2282 private void focusTitle() {
\r
2283 titleLabel.setFocus();
\r
2285 @SuppressWarnings("unused")
\r
2286 private void focusTag() {
\r
2287 tagEdit.setFocus();
\r
2289 @SuppressWarnings("unused")
\r
2290 private void focusNote() {
\r
2291 browser.setFocus();
\r
2293 @SuppressWarnings("unused")
\r
2294 private void focusAuthor() {
\r
2295 authorLabel.setFocus();
\r
2297 @SuppressWarnings("unused")
\r
2298 private void focusUrl() {
\r
2299 urlLabel.setFocus();
\r
2303 //*****************************************************************
\r
2304 //* Set the document background color
\r
2305 //*****************************************************************
\r
2306 public void setBackgroundColor(String color) {
\r
2307 String js = "function changeBackground(color) {"
\r
2308 +"document.body.style.background = color;"
\r
2310 +"changeBackground('" +color+"');";
\r
2311 browser.page().mainFrame().evaluateJavaScript(js);
\r
2316 //****************************************************************
\r
2317 //* MicroFocus changed
\r
2318 //****************************************************************
\r
2319 private void microFocusChanged() {
\r
2320 boldButton.setDown(false);
\r
2321 italicButton.setDown(false);
\r
2322 underlineButton.setDown(false);
\r
2323 browser.openAction.setEnabled(false);
\r
2324 browser.downloadAttachment.setEnabled(false);
\r
2325 browser.downloadImage.setEnabled(false);
\r
2326 browser.rotateImageLeft.setEnabled(false);
\r
2327 browser.rotateImageRight.setEnabled(false);
\r
2328 browser.insertTableAction.setEnabled(true);
\r
2329 browser.insertTableRowAction.setEnabled(false);
\r
2330 browser.deleteTableRowAction.setEnabled(false);
\r
2331 browser.insertLinkAction.setText(tr("Insert Hyperlink"));
\r
2332 currentHyperlink ="";
\r
2333 insideList = false;
\r
2334 forceTextPaste = false;
\r
2336 String js = new String( "function getCursorPos() {"
\r
2338 +"if (window.getSelection) {"
\r
2339 +" var selObj = window.getSelection();"
\r
2340 +" var selRange = selObj.getRangeAt(0);"
\r
2341 +" var workingNode = window.getSelection().anchorNode.parentNode;"
\r
2342 +" while(workingNode != null) { "
\r
2343 // +" window.jambi.printNode(workingNode.nodeName);"
\r
2344 +" if (workingNode.nodeName=='TABLE') { if (workingNode.getAttribute('class').toLowerCase() == 'en-crypt-temp') window.jambi.forceTextPaste(); }"
\r
2345 +" if (workingNode.nodeName=='B') window.jambi.boldActive();"
\r
2346 +" if (workingNode.nodeName=='I') window.jambi.italicActive();"
\r
2347 +" if (workingNode.nodeName=='U') window.jambi.underlineActive();"
\r
2348 +" if (workingNode.nodeName=='UL') window.jambi.setInsideList();"
\r
2349 +" if (workingNode.nodeName=='OL') window.jambi.setInsideList();"
\r
2350 +" if (workingNode.nodeName=='LI') window.jambi.setInsideList();"
\r
2351 +" if (workingNode.nodeName=='TBODY') window.jambi.setInsideTable();"
\r
2352 +" 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
2353 +" if (workingNode.nodeName=='SPAN') {"
\r
2354 +" if (workingNode.getAttribute('style') == 'text-decoration: underline;') window.jambi.underlineActive();"
\r
2356 +" workingNode = workingNode.parentNode;"
\r
2359 +"} getCursorPos();");
\r
2360 browser.page().mainFrame().evaluateJavaScript(js);
\r
2363 public void printNode(String n) {
\r
2364 System.out.println("Node Vaule: " +n);
\r
2368 //****************************************************************
\r
2369 //* Insert a table row
\r
2370 //****************************************************************
\r
2371 public void insertTableRow() {
\r
2373 String js = new String( "function insertTableRow() {"
\r
2374 +" var selObj = window.getSelection();"
\r
2375 +" var selRange = selObj.getRangeAt(0);"
\r
2376 +" var workingNode = window.getSelection().anchorNode.parentNode;"
\r
2377 +" var cellCount = 0;"
\r
2378 +" while(workingNode != null) { "
\r
2379 +" if (workingNode.nodeName.toLowerCase()=='tr') {"
\r
2380 +" row = document.createElement('TR');"
\r
2381 +" var nodes = workingNode.getElementsByTagName('td');"
\r
2382 +" for (j=0; j<nodes.length; j=j+1) {"
\r
2383 +" cell = document.createElement('TD');"
\r
2384 +" cell.innerHTML=' ';"
\r
2385 +" row.appendChild(cell);"
\r
2387 +" workingNode.parentNode.insertBefore(row,workingNode.nextSibling);"
\r
2390 +" workingNode = workingNode.parentNode;"
\r
2392 +"} insertTableRow();");
\r
2393 browser.page().mainFrame().evaluateJavaScript(js);
\r
2396 //****************************************************************
\r
2397 //* Insert a table row
\r
2398 //****************************************************************
\r
2399 public void deleteTableRow() {
\r
2401 String js = new String( "function deleteTableRow() {"
\r
2402 +" var selObj = window.getSelection();"
\r
2403 +" var selRange = selObj.getRangeAt(0);"
\r
2404 +" var workingNode = window.getSelection().anchorNode.parentNode;"
\r
2405 +" var cellCount = 0;"
\r
2406 +" while(workingNode != null) { "
\r
2407 +" if (workingNode.nodeName.toLowerCase()=='tr') {"
\r
2408 +" workingNode.parentNode.removeChild(workingNode);"
\r
2411 +" workingNode = workingNode.parentNode;"
\r
2413 +"} deleteTableRow();");
\r
2414 browser.page().mainFrame().evaluateJavaScript(js);
\r
2417 public void setInsideTable() {
\r
2418 browser.insertTableRowAction.setEnabled(true);
\r
2419 browser.deleteTableRowAction.setEnabled(true);
\r
2420 browser.insertTableAction.setEnabled(false);
\r
2421 browser.encryptAction.setEnabled(false);
\r
2424 public void setInsideLink(String link) {
\r
2425 browser.insertLinkAction.setText(tr("Edit Hyperlink"));
\r
2426 currentHyperlink = link;
\r
2429 public void italicActive() {
\r
2430 italicButton.setDown(true);
\r
2432 public void boldActive() {
\r
2433 boldButton.setDown(true);
\r
2435 public void underlineActive() {
\r
2436 underlineButton.setDown(true);
\r
2438 public void forceTextPaste() {
\r
2439 forceTextPaste = true;
\r
2441 public void imageContextMenu(String f) {
\r
2442 browser.downloadImage.setEnabled(true);
\r
2443 browser.rotateImageRight.setEnabled(true);
\r
2444 browser.rotateImageLeft.setEnabled(true);
\r
2445 browser.openAction.setEnabled(true);
\r
2448 public void rotateImageRight() {
\r
2449 QWebSettings.setMaximumPagesInCache(0);
\r
2450 QWebSettings.setObjectCacheCapacities(0, 0, 0);
\r
2451 QImage image = new QImage(selectedFile);
\r
2452 QMatrix matrix = new QMatrix();
\r
2453 matrix.rotate( 90.0 );
\r
2454 image = image.transformed(matrix);
\r
2455 image.save(selectedFile);
\r
2456 QWebSettings.setMaximumPagesInCache(0);
\r
2457 QWebSettings.setObjectCacheCapacities(0, 0, 0);
\r
2458 browser.setHtml(browser.page().mainFrame().toHtml());
\r
2461 // resourceSignal.contentChanged.emit(selectedFile);
\r
2464 public void rotateImageLeft() {
\r
2465 QImage image = new QImage(selectedFile);
\r
2466 QMatrix matrix = new QMatrix();
\r
2467 matrix.rotate( -90.0 );
\r
2468 image = image.transformed(matrix);
\r
2469 image.save(selectedFile);
\r
2470 browser.setHtml(browser.page().mainFrame().toHtml());
\r
2473 // resourceSignal.contentChanged.emit(selectedFile);
\r
2475 public void resourceContextMenu(String f) {
\r
2476 browser.downloadAttachment.setEnabled(true);
\r
2477 browser.openAction.setEnabled(true);
\r
2482 //****************************************************************
\r
2483 //* Apply CSS style to specified word
\r
2484 //****************************************************************
\r
2485 /* public void applyStyleToWords(String word, String style) {
\r
2486 QFile script = new QFile("D:\\NeverNote\\js\\hilight1.js");
\r
2487 script.open(OpenModeFlag.ReadOnly);
\r
2488 String s = script.readAll().toString();
\r
2489 String js = new String(s +" findit('"+word+"', '"+style+"');");
\r
2490 browser.page().mainFrame().evaluateJavaScript(js);
\r
2491 System.out.println(getContent());
\r
2494 //****************************************************************
\r
2495 //* Someone tried to paste a resource between notes, so we need *
\r
2496 //* to do some special handling. *
\r
2497 //****************************************************************
\r
2498 private String fixInternotePaste(String text) {
\r
2499 logger.log(logger.EXTREME, "Fixing internote paste");
\r
2500 String returnValue = fixInternotePasteSearch(text, "<img", "src=\"");
\r
2501 return fixInternotePasteSearch(returnValue, "<a", "href=\"nnres://");
\r
2503 private String fixInternotePasteSearch(String text, String type, String locTag) {
\r
2505 // First, let's fix the images.
\r
2506 int startPos = text.indexOf(type);
\r
2508 for (; startPos>=0;) {
\r
2509 endPos = text.indexOf(">", startPos+1);
\r
2510 String segment = text.substring(startPos, endPos);
\r
2511 if (segment.indexOf("en-tag") > -1) {
\r
2512 String newSegment = segment;
\r
2514 int guidStartPos = segment.indexOf("guid=\"");
\r
2515 int guidEndPos = segment.indexOf("\"", guidStartPos+7);
\r
2516 String guid = segment.substring(guidStartPos+6,guidEndPos);
\r
2518 int mimeStartPos = segment.indexOf("type");
\r
2519 int mimeEndPos = segment.indexOf("\"", mimeStartPos+7);
\r
2520 String mime = segment.substring(mimeStartPos+6,mimeEndPos);
\r
2522 int srcStartPos = segment.indexOf("src");
\r
2523 int srcEndPos = segment.indexOf("\"", srcStartPos+6);
\r
2524 String src = segment.substring(srcStartPos+5,srcEndPos);
\r
2526 Calendar currentTime = new GregorianCalendar();
\r
2527 Long l = new Long(currentTime.getTimeInMillis());
\r
2528 long prevTime = l;
\r
2529 while (l==prevTime) {
\r
2530 currentTime = new GregorianCalendar();
\r
2531 l= new Long(currentTime.getTimeInMillis());
\r
2534 Resource r = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);
\r
2535 // if r==null, then the image doesn't exist (it was probably cut out of another note, so
\r
2536 // we need to recereate it
\r
2538 r = createResource(src, 1, mime, false);
\r
2542 String randint = new String(Long.toString(l));
\r
2543 String extension = null;
\r
2544 if (r.getMime()!= null) {
\r
2545 extension = r.getMime().toLowerCase();
\r
2546 if (extension.indexOf("/")>-1)
\r
2547 extension = extension.substring(extension.indexOf("/")+1);
\r
2549 String newFile = randint;
\r
2550 if (r.getAttributes().getFileName() != null && r.getAttributes().getFileName() != "")
\r
2551 if (!locTag.startsWith("src"))
\r
2552 newFile = newFile+Global.attachmentNameDelimeter+r.getAttributes().getFileName();
\r
2553 r.setNoteGuid(currentNote.getGuid());
\r
2555 r.setGuid(randint);
\r
2556 conn.getNoteTable().noteResourceTable.saveNoteResource(r, true);
\r
2557 QFile f = new QFile(Global.getFileManager().getResDirPath(newFile));
\r
2558 QByteArray bin = new QByteArray(r.getData().getBody());
\r
2559 f.open(QFile.OpenModeFlag.WriteOnly);
\r
2562 newSegment = newSegment.replace("guid=\""+guid, "guid=\""+randint);
\r
2563 currentNote.getResources().add(r);
\r
2565 int startSrcPos = newSegment.indexOf(locTag);
\r
2566 int endSrcPos = newSegment.indexOf("\"",startSrcPos+locTag.length()+1);
\r
2568 if (locTag.startsWith("src")) {
\r
2569 source = newSegment.substring(startSrcPos+locTag.length(),endSrcPos);
\r
2570 newSegment = newSegment.replace(source,
\r
2571 FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath(newFile)));
\r
2573 source = newSegment.substring(startSrcPos+locTag.length(),endSrcPos);
\r
2574 newSegment = newSegment.replace(source, newFile);
\r
2577 text = text.substring(0,startPos) + newSegment + text.substring(endPos);
\r
2579 startPos = text.indexOf(type, startPos+1);
\r
2585 public void nextPage(String file) {
\r
2586 logger.log(logger.EXTREME, "Starting nextPage()");
\r
2588 Integer pageNumber;
\r
2589 if (previewPageList.containsKey(file))
\r
2590 pageNumber = previewPageList.get(file)+1;
\r
2593 previewPageList.remove(file);
\r
2594 previewPageList.put(file, pageNumber);
\r
2595 PDFPreview pdfPreview = new PDFPreview();
\r
2596 boolean goodPreview = pdfPreview.setupPreview(file, "pdf", pageNumber);
\r
2597 if (goodPreview) {
\r
2599 // String html = getContent();
\r
2600 QWebSettings.setMaximumPagesInCache(0);
\r
2601 QWebSettings.setObjectCacheCapacities(0, 0, 0);
\r
2602 // browser.setContent(new QByteArray());
\r
2603 browser.setHtml(browser.page().mainFrame().toHtml());
\r
2605 // browser.setContent(new QByteArray(html));
\r
2606 // browser.triggerPageAction(WebAction.Reload);
\r
2607 // pdfMouseOver(selectedFile);
\r
2611 public void previousPage(String file) {
\r
2612 logger.log(logger.EXTREME, "Starting previousPage()");
\r
2614 Integer pageNumber;
\r
2615 if (previewPageList.containsKey(file))
\r
2616 pageNumber = previewPageList.get(file)-1;
\r
2619 previewPageList.remove(file);
\r
2620 previewPageList.put(file, pageNumber);
\r
2621 PDFPreview pdfPreview = new PDFPreview();
\r
2622 boolean goodPreview = pdfPreview.setupPreview(file, "pdf", pageNumber);
\r
2623 if (goodPreview) {
\r
2625 // String html = getContent();
\r
2626 QWebSettings.setMaximumPagesInCache(0);
\r
2627 QWebSettings.setObjectCacheCapacities(0, 0, 0);
\r
2628 browser.setHtml(browser.page().mainFrame().toHtml());
\r
2630 // browser.setContent(new QByteArray(html));
\r
2631 // browser.triggerPageAction(WebAction.Reload);
\r
2635 /* public void pdfMouseOver(String name) {
\r
2637 if (previewPageList.containsKey(selectedFile))
\r
2638 pageNumber = previewPageList.get(selectedFile)+1;
\r
2642 if (pageNumber <= 1)
\r
2643 browser.previousPageAction.setEnabled(false);
\r
2645 browser.previousPageAction.setEnabled(true);
\r
2647 PDFPreview pdf = new PDFPreview();
\r
2648 int totalPages = pdf.getPageCount(name);
\r
2649 if (previewPageList.containsKey(selectedFile))
\r
2650 pageNumber = previewPageList.get(selectedFile)+1;
\r
2653 if (totalPages > pageNumber)
\r
2654 browser.nextPageAction.setEnabled(true);
\r
2656 browser.nextPageAction.setEnabled(false);
\r
2660 public void pdfMouseOut() {
\r
2661 // browser.nextPageAction.setVisible(false);
\r
2662 // browser.previousPageAction.setVisible(false);
\r
2666 @SuppressWarnings("unused")
\r
2667 private void toggleUndoVisible(Boolean toggle) {
\r
2668 undoAction.setVisible(toggle);
\r
2669 Global.saveEditorButtonsVisible("undo", toggle);
\r
2671 @SuppressWarnings("unused")
\r
2672 private void toggleRedoVisible(Boolean toggle) {
\r
2673 redoAction.setVisible(toggle);
\r
2674 Global.saveEditorButtonsVisible("redo", toggle);
\r
2676 @SuppressWarnings("unused")
\r
2677 private void toggleCutVisible(Boolean toggle) {
\r
2678 cutAction.setVisible(toggle);
\r
2679 Global.saveEditorButtonsVisible("cut", toggle);
\r
2681 @SuppressWarnings("unused")
\r
2682 private void toggleCopyVisible(Boolean toggle) {
\r
2683 copyAction.setVisible(toggle);
\r
2684 Global.saveEditorButtonsVisible("copy", toggle);
\r
2686 @SuppressWarnings("unused")
\r
2687 private void togglePasteVisible(Boolean toggle) {
\r
2688 pasteAction.setVisible(toggle);
\r
2689 Global.saveEditorButtonsVisible("paste", toggle);
\r
2691 @SuppressWarnings("unused")
\r
2692 private void toggleBoldVisible(Boolean toggle) {
\r
2693 boldAction.setVisible(toggle);
\r
2694 Global.saveEditorButtonsVisible("bold", toggle);
\r
2696 @SuppressWarnings("unused")
\r
2697 private void toggleItalicVisible(Boolean toggle) {
\r
2698 italicAction.setVisible(toggle);
\r
2699 Global.saveEditorButtonsVisible("italic", toggle);
\r
2701 @SuppressWarnings("unused")
\r
2702 private void toggleUnderlineVisible(Boolean toggle) {
\r
2703 underlineAction.setVisible(toggle);
\r
2704 Global.saveEditorButtonsVisible("underline", toggle);
\r
2706 @SuppressWarnings("unused")
\r
2707 private void toggleStrikethroughVisible(Boolean toggle) {
\r
2708 strikethroughAction.setVisible(toggle);
\r
2709 Global.saveEditorButtonsVisible("strikethrough", toggle);
\r
2711 @SuppressWarnings("unused")
\r
2712 private void toggleLeftAlignVisible(Boolean toggle) {
\r
2713 leftAlignAction.setVisible(toggle);
\r
2714 Global.saveEditorButtonsVisible("alignLeft", toggle);
\r
2716 @SuppressWarnings("unused")
\r
2717 private void toggleRightAlignVisible(Boolean toggle) {
\r
2718 rightAlignAction.setVisible(toggle);
\r
2719 Global.saveEditorButtonsVisible("alignRight", toggle);
\r
2721 @SuppressWarnings("unused")
\r
2722 private void toggleCenterAlignVisible(Boolean toggle) {
\r
2723 centerAlignAction.setVisible(toggle);
\r
2724 Global.saveEditorButtonsVisible("alignCenter", toggle);
\r
2726 @SuppressWarnings("unused")
\r
2727 private void toggleHLineVisible(Boolean toggle) {
\r
2728 hlineAction.setVisible(toggle);
\r
2729 Global.saveEditorButtonsVisible("hline", toggle);
\r
2731 @SuppressWarnings("unused")
\r
2732 private void toggleIndentVisible(Boolean toggle) {
\r
2733 indentAction.setVisible(toggle);
\r
2734 Global.saveEditorButtonsVisible("indent", toggle);
\r
2736 @SuppressWarnings("unused")
\r
2737 private void toggleTodoVisible(Boolean toggle) {
\r
2738 todoAction.setVisible(toggle);
\r
2739 Global.saveEditorButtonsVisible("todo", toggle);
\r
2741 @SuppressWarnings("unused")
\r
2742 private void toggleOutdentVisible(Boolean toggle) {
\r
2743 outdentAction.setVisible(toggle);
\r
2744 Global.saveEditorButtonsVisible("outdent", toggle);
\r
2746 @SuppressWarnings("unused")
\r
2747 private void toggleBulletListVisible(Boolean toggle) {
\r
2748 bulletListAction.setVisible(toggle);
\r
2749 Global.saveEditorButtonsVisible("bulletList", toggle);
\r
2751 @SuppressWarnings("unused")
\r
2752 private void toggleNumberListVisible(Boolean toggle) {
\r
2753 numberListAction.setVisible(toggle);
\r
2754 Global.saveEditorButtonsVisible("numberList", toggle);
\r
2756 @SuppressWarnings("unused")
\r
2757 private void toggleFontListVisible(Boolean toggle) {
\r
2758 fontListAction.setVisible(toggle);
\r
2759 Global.saveEditorButtonsVisible("font", toggle);
\r
2761 @SuppressWarnings("unused")
\r
2762 private void toggleFontColorVisible(Boolean toggle) {
\r
2763 fontColorAction.setVisible(toggle);
\r
2764 Global.saveEditorButtonsVisible("fontColor", toggle);
\r
2766 @SuppressWarnings("unused")
\r
2767 private void toggleFontSizeVisible(Boolean toggle) {
\r
2768 fontSizeAction.setVisible(toggle);
\r
2769 Global.saveEditorButtonsVisible("fontSize", toggle);
\r
2771 @SuppressWarnings("unused")
\r
2772 private void toggleFontHilightVisible(Boolean toggle) {
\r
2773 fontHilightAction.setVisible(toggle);
\r
2774 Global.saveEditorButtonsVisible("fontHilight", toggle);
\r
2776 @SuppressWarnings("unused")
\r
2777 private void toggleSpellCheckVisible(Boolean toggle) {
\r
2778 spellCheckAction.setVisible(toggle);
\r
2779 Global.saveEditorButtonsVisible("spellCheck", toggle);
\r
2783 private void setupDictionary() {
\r
2784 File wordList = new File(Global.getFileManager().getSpellDirPath()+Locale.getDefault()+".dic");
\r
2786 dictionary = new SpellDictionaryHashMap(wordList);
\r
2787 spellChecker = new SpellChecker(dictionary);
\r
2789 File userWordList;
\r
2790 userWordList = new File(Global.getFileManager().getSpellDirPathUser()+"user.dic");
\r
2792 // Get the local user spell dictionary
\r
2794 userDictionary = new SpellDictionaryHashMap(userWordList);
\r
2795 } catch (FileNotFoundException e) {
\r
2796 userWordList.createNewFile();
\r
2797 userDictionary = new SpellDictionaryHashMap(userWordList);
\r
2798 } catch (IOException e) {
\r
2799 userWordList.createNewFile();
\r
2800 userDictionary = new SpellDictionaryHashMap(userWordList);
\r
2803 spellListener = new SuggestionListener(this, spellChecker);
\r
2805 // Add the user dictionary
\r
2806 spellChecker.addSpellCheckListener(spellListener);
\r
2807 spellChecker.setUserDictionary(userDictionary);
\r
2809 } catch (FileNotFoundException e) {
\r
2810 QMessageBox.critical(this, tr("Spell Check Error"),
\r
2811 tr("Dictionary "+ Global.getFileManager().getSpellDirPath()+Locale.getDefault()+
\r
2812 ".dic was not found."));
\r
2813 } catch (IOException e) {
\r
2814 QMessageBox.critical(this, tr("Spell Check Error"),
\r
2815 tr("Dictionary "+ Global.getFileManager().getSpellDirPath()+Locale.getDefault()+
\r
2816 ".dic is invalid."));
\r
2821 // Invoke spell checker dialog
\r
2822 @SuppressWarnings("unused")
\r
2823 private void spellCheckClicked() {
\r
2825 if (spellChecker == null) {
\r
2826 setupDictionary();
\r
2829 // Read user settings
\r
2830 spellChecker.getConfiguration().setBoolean(Configuration.SPELL_IGNOREDIGITWORDS,
\r
2831 Global.getSpellSetting(Configuration.SPELL_IGNOREDIGITWORDS));
\r
2832 spellChecker.getConfiguration().setBoolean(Configuration.SPELL_IGNOREINTERNETADDRESSES,
\r
2833 Global.getSpellSetting(Configuration.SPELL_IGNOREINTERNETADDRESSES));
\r
2834 spellChecker.getConfiguration().setBoolean(Configuration.SPELL_IGNOREMIXEDCASE,
\r
2835 Global.getSpellSetting(Configuration.SPELL_IGNOREMIXEDCASE));
\r
2836 spellChecker.getConfiguration().setBoolean(Configuration.SPELL_IGNOREUPPERCASE,
\r
2837 Global.getSpellSetting(Configuration.SPELL_IGNOREUPPERCASE));
\r
2838 spellChecker.getConfiguration().setBoolean(Configuration.SPELL_IGNORESENTENCECAPITALIZATION,
\r
2839 Global.getSpellSetting(Configuration.SPELL_IGNORESENTENCECAPITALIZATION));
\r
2841 spellListener.abortSpellCheck = false;
\r
2842 spellListener.errorsFound = false;
\r
2843 String content = getBrowser().page().mainFrame().toPlainText();
\r
2844 StringWordTokenizer tokenizer = new StringWordTokenizer(content);
\r
2845 if (!tokenizer.hasMoreWords())
\r
2847 getBrowser().page().action(WebAction.MoveToStartOfDocument);
\r
2849 getBrowser().setFocus();
\r
2852 // Move to the start of page
\r
2853 KeyboardModifiers ctrl = new KeyboardModifiers(KeyboardModifier.ControlModifier.value());
\r
2854 QKeyEvent home = new QKeyEvent(Type.KeyPress, Key.Key_Home.value(), ctrl);
\r
2855 browser.keyPressEvent(home);
\r
2856 getBrowser().setFocus();
\r
2858 tokenizer = new StringWordTokenizer(content);
\r
2861 while(tokenizer.hasMoreWords()) {
\r
2862 word = tokenizer.nextWord();
\r
2863 found = getBrowser().page().findText(word);
\r
2864 if (found && !spellListener.abortSpellCheck) {
\r
2865 spellChecker.checkSpelling(new StringWordTokenizer(word));
\r
2866 getBrowser().setFocus();
\r
2870 // Go to the end of the document & finish up.
\r
2871 home = new QKeyEvent(Type.KeyPress, Key.Key_End.value(), ctrl);
\r
2872 browser.keyPressEvent(home);
\r
2873 if (!spellListener.errorsFound)
\r
2874 QMessageBox.information(this, tr("Spell Check Complete"),
\r
2875 tr("No Errors Found"));
\r