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.net.FileNameMap;
\r
24 import java.net.URI;
\r
25 import java.net.URLConnection;
\r
26 import java.security.MessageDigest;
\r
27 import java.security.NoSuchAlgorithmException;
\r
28 import java.text.SimpleDateFormat;
\r
29 import java.util.ArrayList;
\r
30 import java.util.Calendar;
\r
31 import java.util.Collections;
\r
32 import java.util.Date;
\r
33 import java.util.GregorianCalendar;
\r
34 import java.util.HashMap;
\r
35 import java.util.List;
\r
37 import com.evernote.edam.limits.Constants;
\r
38 import com.evernote.edam.type.Data;
\r
39 import com.evernote.edam.type.Note;
\r
40 import com.evernote.edam.type.Notebook;
\r
41 import com.evernote.edam.type.Resource;
\r
42 import com.evernote.edam.type.ResourceAttributes;
\r
43 import com.evernote.edam.type.Tag;
\r
44 import com.trolltech.qt.core.QByteArray;
\r
45 import com.trolltech.qt.core.QDataStream;
\r
46 import com.trolltech.qt.core.QDateTime;
\r
47 import com.trolltech.qt.core.QEvent;
\r
48 import com.trolltech.qt.core.QFile;
\r
49 import com.trolltech.qt.core.QFileSystemWatcher;
\r
50 import com.trolltech.qt.core.QIODevice;
\r
51 import com.trolltech.qt.core.QMimeData;
\r
52 import com.trolltech.qt.core.QUrl;
\r
53 import com.trolltech.qt.gui.QAction;
\r
54 import com.trolltech.qt.gui.QApplication;
\r
55 import com.trolltech.qt.gui.QCalendarWidget;
\r
56 import com.trolltech.qt.gui.QClipboard;
\r
57 import com.trolltech.qt.gui.QColor;
\r
58 import com.trolltech.qt.gui.QComboBox;
\r
59 import com.trolltech.qt.gui.QDateEdit;
\r
60 import com.trolltech.qt.gui.QDesktopServices;
\r
61 import com.trolltech.qt.gui.QFileDialog;
\r
62 import com.trolltech.qt.gui.QFileDialog.AcceptMode;
\r
63 import com.trolltech.qt.gui.QFileDialog.FileMode;
\r
64 import com.trolltech.qt.gui.QFontDatabase;
\r
65 import com.trolltech.qt.gui.QFormLayout;
\r
66 import com.trolltech.qt.gui.QGridLayout;
\r
67 import com.trolltech.qt.gui.QHBoxLayout;
\r
68 import com.trolltech.qt.gui.QIcon;
\r
69 import com.trolltech.qt.gui.QImage;
\r
70 import com.trolltech.qt.gui.QKeySequence;
\r
71 import com.trolltech.qt.gui.QLabel;
\r
72 import com.trolltech.qt.gui.QLineEdit;
\r
73 import com.trolltech.qt.gui.QListWidgetItem;
\r
74 import com.trolltech.qt.gui.QMatrix;
\r
75 import com.trolltech.qt.gui.QMessageBox;
\r
76 import com.trolltech.qt.gui.QPushButton;
\r
77 import com.trolltech.qt.gui.QShortcut;
\r
78 import com.trolltech.qt.gui.QTimeEdit;
\r
79 import com.trolltech.qt.gui.QVBoxLayout;
\r
80 import com.trolltech.qt.gui.QWidget;
\r
81 import com.trolltech.qt.network.QNetworkRequest;
\r
82 import com.trolltech.qt.webkit.QWebPage;
\r
83 import com.trolltech.qt.webkit.QWebPage.WebAction;
\r
84 import com.trolltech.qt.webkit.QWebSettings;
\r
85 import com.trolltech.qt.webkit.QWebView;
\r
87 import cx.fbn.nevernote.Global;
\r
88 import cx.fbn.nevernote.dialog.EnCryptDialog;
\r
89 import cx.fbn.nevernote.dialog.EnDecryptDialog;
\r
90 import cx.fbn.nevernote.dialog.GeoDialog;
\r
91 import cx.fbn.nevernote.dialog.InsertLinkDialog;
\r
92 import cx.fbn.nevernote.dialog.TableDialog;
\r
93 import cx.fbn.nevernote.dialog.TagAssign;
\r
94 import cx.fbn.nevernote.evernote.EnCrypt;
\r
95 import cx.fbn.nevernote.signals.NoteResourceSignal;
\r
96 import cx.fbn.nevernote.signals.NoteSignal;
\r
97 import cx.fbn.nevernote.sql.DatabaseConnection;
\r
98 import cx.fbn.nevernote.utilities.ApplicationLogger;
\r
99 import cx.fbn.nevernote.utilities.FileUtils;
\r
101 public class BrowserWindow extends QWidget {
\r
103 public final QLineEdit titleLabel;
\r
104 private final QLineEdit urlText;
\r
105 private final QLabel authorLabel;
\r
106 private final QLineEdit authorText;
\r
107 private final QComboBox geoBox;
\r
108 public final TagLineEdit tagEdit;
\r
109 public final QLabel tagLabel;
\r
110 private final QPushButton urlLabel;
\r
111 private final QLabel alteredLabel;
\r
112 private final QDateEdit alteredDate;
\r
113 private final QTimeEdit alteredTime;
\r
114 private final QDateEdit createdDate;
\r
115 private final QTimeEdit createdTime;
\r
116 private final QLabel subjectLabel;
\r
117 private final QDateEdit subjectDate;
\r
118 private final QTimeEdit subjectTime;
\r
119 public final QComboBox notebookBox;
\r
120 private final QLabel notebookLabel;
\r
121 private final QLabel createdLabel;
\r
122 public final QComboBox fontSize;
\r
123 public final QAction fontSizeAction;
\r
124 private boolean extendedOn;
\r
125 public boolean buttonsVisible;
\r
126 private final String iconPath = new String("classpath:cx/fbn/nevernote/icons/");
\r
127 private final ContentView browser;
\r
128 private List<Tag> allTags;
\r
129 private List<String> currentTags;
\r
130 public NoteSignal noteSignal;
\r
131 private List<Notebook> notebookList;
\r
132 private Note currentNote;
\r
133 private String saveNoteTitle;
\r
134 private String saveTagList;
\r
135 private boolean insideList;
\r
136 // private String selectedText;
\r
137 private final DatabaseConnection conn;
\r
138 private final QCalendarWidget createdCalendarWidget;
\r
139 private final QCalendarWidget alteredCalendarWidget;
\r
140 private final QCalendarWidget subjectCalendarWidget;
\r
142 public final QPushButton undoButton;
\r
143 public final QAction undoAction;
\r
144 public final QPushButton redoButton;
\r
145 public final QAction redoAction;
\r
146 public final QPushButton cutButton;
\r
147 public final QAction cutAction;
\r
148 public final QPushButton copyButton;
\r
149 public final QAction copyAction;
\r
150 public final QPushButton pasteButton;
\r
151 public final QAction pasteAction;
\r
152 public final QPushButton boldButton;
\r
153 public final QAction boldAction;
\r
154 public final QPushButton underlineButton;
\r
155 public final QAction underlineAction;
\r
156 public final QPushButton italicButton;
\r
157 public final QAction italicAction;
\r
158 public final Signal0 focusLost;
\r
159 public final NoteResourceSignal resourceSignal;
\r
161 public QPushButton rightAlignButton;
\r
162 public final QAction rightAlignAction;
\r
163 public QPushButton leftAlignButton;
\r
164 public final QAction leftAlignAction;
\r
165 public QPushButton centerAlignButton;
\r
166 public final QAction centerAlignAction;
\r
168 public final QPushButton strikethroughButton;
\r
169 public final QAction strikethroughAction;
\r
170 public final QPushButton hlineButton;
\r
171 public final QAction hlineAction;
\r
172 public final QPushButton indentButton;
\r
173 public final QAction indentAction;
\r
174 public final QPushButton outdentButton;
\r
175 public final QAction outdentAction;
\r
176 public final QPushButton bulletListButton;
\r
177 public final QAction bulletListAction;
\r
178 public final QPushButton numberListButton;
\r
179 public final QAction numberListAction;
\r
181 public final QShortcut focusTitleShortcut;
\r
182 public final QShortcut focusTagShortcut;
\r
183 public final QShortcut focusNoteShortcut;
\r
184 public final QShortcut focusUrlShortcut;
\r
185 public final QShortcut focusAuthorShortcut;
\r
187 public EditorButtonBar buttonLayout;
\r
188 public final QComboBox fontList;
\r
189 public final QAction fontListAction;
\r
190 public final QPushButton fontColor;
\r
191 public final QAction fontColorAction;
\r
192 private final ColorMenu fontColorMenu;
\r
193 public final QPushButton fontHilight;
\r
194 public final QAction fontHilightAction;
\r
195 // public final ColorComboBox fontHilight;
\r
196 private final ColorMenu fontHilightColorMenu;
\r
197 public final QFileSystemWatcher fileWatcher;
\r
198 public int cursorPosition;
\r
199 private boolean forceTextPaste = false;
\r
200 private String selectedFile;
\r
201 private String currentHyperlink;
\r
202 public boolean keepPDFNavigationHidden;
\r
203 private final ApplicationLogger logger;
\r
205 private final HashMap<String,Integer> previewPageList;
\r
208 public BrowserWindow(DatabaseConnection c) {
\r
209 logger = new ApplicationLogger("browser.log");
\r
210 logger.log(logger.HIGH, "Setting up browser");
\r
212 fileWatcher = new QFileSystemWatcher();
\r
213 // fileWatcher.fileChanged.connect(this, "fileChanged(String)");
\r
214 noteSignal = new NoteSignal();
\r
215 titleLabel = new QLineEdit();
\r
216 titleLabel.setMaxLength(Constants.EDAM_NOTE_TITLE_LEN_MAX);
\r
217 urlText = new QLineEdit();
\r
218 authorText = new QLineEdit();
\r
219 geoBox = new QComboBox();
\r
220 urlLabel = new QPushButton();
\r
221 urlLabel.clicked.connect(this, "sourceUrlClicked()");
\r
222 authorLabel = new QLabel();
\r
225 focusLost = new Signal0();
\r
227 tagEdit = new TagLineEdit(allTags);
\r
228 tagLabel = new QLabel("Tags:");
\r
229 tagEdit.focusLost.connect(this, "modifyTagsTyping()");
\r
231 createdCalendarWidget = new QCalendarWidget();
\r
232 createdDate = new QDateEdit();
\r
233 createdDate.setDisplayFormat(Global.getDateFormat());
\r
234 createdDate.setCalendarPopup(true);
\r
235 createdDate.setCalendarWidget(createdCalendarWidget);
\r
236 createdTime = new QTimeEdit();
\r
237 createdDate.dateChanged.connect(this, "createdChanged()");
\r
238 createdTime.timeChanged.connect(this, "createdChanged()");
\r
240 alteredCalendarWidget = new QCalendarWidget();
\r
241 alteredDate = new QDateEdit();
\r
242 alteredDate.setDisplayFormat(Global.getDateFormat());
\r
243 alteredDate.setCalendarPopup(true);
\r
244 alteredDate.setCalendarWidget(alteredCalendarWidget);
\r
245 alteredTime = new QTimeEdit();
\r
246 alteredLabel = new QLabel("Altered:");
\r
247 alteredDate.dateChanged.connect(this, "alteredChanged()");
\r
248 alteredTime.timeChanged.connect(this, "alteredChanged()");
\r
250 subjectCalendarWidget = new QCalendarWidget();
\r
251 subjectDate = new QDateEdit();
\r
252 subjectDate.setDisplayFormat(Global.getDateFormat());
\r
253 subjectDate.setCalendarPopup(true);
\r
254 subjectDate.setCalendarWidget(subjectCalendarWidget);
\r
255 subjectTime = new QTimeEdit();
\r
256 subjectLabel = new QLabel(tr("Subject Date:"));
\r
257 subjectDate.dateChanged.connect(this, "subjectDateTimeChanged()");
\r
258 subjectTime.timeChanged.connect(this, "subjectDateTimeChanged()");
\r
259 authorText.textChanged.connect(this, "authorChanged()");
\r
260 urlText.textChanged.connect(this, "sourceUrlChanged()");
\r
262 notebookBox = new QComboBox();
\r
263 notebookLabel = new QLabel(tr("Notebook"));
\r
264 createdLabel = new QLabel(tr("Created:"));
\r
265 // selectedText = new String();
\r
267 urlLabel.setVisible(false);
\r
268 urlText.setVisible(false);
\r
269 authorLabel.setVisible(false);
\r
271 geoBox.setVisible(false);
\r
272 geoBox.addItem(new QIcon(iconPath+"globe.png"), "");
\r
273 geoBox.addItem(new String(tr("Set")));
\r
274 geoBox.addItem(new String(tr("Clear")));
\r
275 geoBox.addItem(new String(tr("View On Map")));
\r
276 geoBox.activated.connect(this, "geoBoxChanged()");
\r
278 authorText.setVisible(false);
\r
279 createdDate.setVisible(false);
\r
280 alteredLabel.setVisible(false);
\r
281 //notebookBox.setVisible(false);
\r
282 notebookLabel.setVisible(false);
\r
283 createdLabel.setVisible(false);
\r
284 createdTime.setVisible(false);
\r
285 alteredDate.setVisible(false);
\r
286 alteredTime.setVisible(false);
\r
287 subjectLabel.setVisible(false);
\r
288 subjectDate.setVisible(false);
\r
289 subjectTime.setVisible(false);
\r
290 extendedOn = false;
\r
291 buttonsVisible = true;
\r
292 setAcceptDrops(true);
\r
294 browser = new ContentView(this);
\r
295 browser.page().setLinkDelegationPolicy(
\r
296 QWebPage.LinkDelegationPolicy.DelegateAllLinks);
\r
297 browser.linkClicked.connect(this, "linkClicked(QUrl)");
\r
298 currentHyperlink = "";
\r
300 QVBoxLayout v = new QVBoxLayout();
\r
301 QFormLayout notebookLayout = new QFormLayout();
\r
302 QGridLayout dateLayout = new QGridLayout();
\r
303 titleLabel.setReadOnly(false);
\r
304 titleLabel.editingFinished.connect(this, "titleEdited()");
\r
305 browser.page().contentsChanged.connect(this, "contentChanged()");
\r
306 browser.page().selectionChanged.connect(this, "selectionChanged()");
\r
307 browser.page().mainFrame().javaScriptWindowObjectCleared.connect(this,
\r
308 "exposeToJavascript()");
\r
310 notebookBox.activated.connect(this, "notebookChanged()");
\r
311 resourceSignal = new NoteResourceSignal();
\r
313 QHBoxLayout tagLayout = new QHBoxLayout();
\r
314 v.addWidget(titleLabel, 0);
\r
315 notebookLayout.addRow(notebookLabel, notebookBox);
\r
316 tagLayout.addLayout(notebookLayout, 0);
\r
317 tagLayout.stretch(4);
\r
318 tagLayout.addWidget(tagLabel, 0);
\r
319 tagLayout.addWidget(tagEdit, 1);
\r
320 v.addLayout(tagLayout);
\r
322 QHBoxLayout urlLayout = new QHBoxLayout();
\r
323 urlLayout.addWidget(urlLabel, 0);
\r
324 urlLayout.addWidget(urlText, 0);
\r
325 v.addLayout(urlLayout);
\r
327 QHBoxLayout authorLayout = new QHBoxLayout();
\r
328 authorLayout.addWidget(authorLabel, 0);
\r
329 authorLayout.addWidget(authorText, 0);
\r
330 authorLayout.addWidget(geoBox);
\r
331 v.addLayout(authorLayout);
\r
333 dateLayout.addWidget(createdLabel, 0, 0);
\r
334 dateLayout.addWidget(createdDate, 0, 1);
\r
335 dateLayout.addWidget(createdTime, 0, 2);
\r
336 dateLayout.setColumnStretch(9, 100);
\r
337 dateLayout.addWidget(alteredLabel, 0, 3);
\r
338 dateLayout.addWidget(alteredDate, 0, 4);
\r
339 dateLayout.addWidget(alteredTime, 0, 5);
\r
340 dateLayout.addWidget(subjectLabel, 0, 6);
\r
341 dateLayout.addWidget(subjectDate, 0, 7);
\r
342 dateLayout.addWidget(subjectTime, 0, 8);
\r
343 v.addLayout(dateLayout, 0);
\r
345 undoButton = newEditorButton("undo", tr("Undo Change"));
\r
346 redoButton = newEditorButton("redo", tr("Redo Change"));
\r
347 cutButton = newEditorButton("cut", tr("Cut"));
\r
348 copyButton = newEditorButton("copy", tr("Copy"));
\r
349 pasteButton = newEditorButton("paste", tr("Paste"));
\r
350 boldButton = newEditorButton("bold", tr("Bold"));
\r
351 underlineButton = newEditorButton("underline", tr("Underline"));
\r
352 italicButton = newEditorButton("italic", tr("Italic"));
\r
354 rightAlignButton = newEditorButton("justifyRight", tr("Right Align"));
\r
355 leftAlignButton = newEditorButton("justifyLeft", tr("Left Align"));
\r
356 centerAlignButton = newEditorButton("justifyCenter", tr("Center Align"));
\r
358 strikethroughButton = newEditorButton("strikethrough", tr("Strikethrough"));
\r
359 hlineButton = newEditorButton("hline", tr("Insert Horizontal Line"));
\r
360 indentButton = newEditorButton("indent", tr("Shift Right"));
\r
361 outdentButton = newEditorButton("outdent", tr("Shift Left"));
\r
362 bulletListButton = newEditorButton("bulletList", tr("Bullet List"));
\r
363 numberListButton = newEditorButton("numberList", tr("Number List"));
\r
366 buttonLayout = new EditorButtonBar();
\r
367 // buttonLayout.setSpacing(0);
\r
368 v.addWidget(buttonLayout);
\r
370 undoAction = buttonLayout.addWidget(undoButton);
\r
371 buttonLayout.toggleUndoVisible.triggered.connect(this, "toggleUndoVisible(Boolean)");
\r
372 redoAction = buttonLayout.addWidget(redoButton);
\r
373 buttonLayout.toggleRedoVisible.triggered.connect(this, "toggleRedoVisible(Boolean)");
\r
375 buttonLayout.addWidget(newSeparator());
\r
376 cutAction = buttonLayout.addWidget(cutButton);
\r
377 buttonLayout.toggleCutVisible.triggered.connect(this, "toggleCutVisible(Boolean)");
\r
378 copyAction = buttonLayout.addWidget(copyButton);
\r
379 buttonLayout.toggleCopyVisible.triggered.connect(this, "toggleCopyVisible(Boolean)");
\r
380 pasteAction = buttonLayout.addWidget(pasteButton);
\r
381 buttonLayout.togglePasteVisible.triggered.connect(this, "togglePasteVisible(Boolean)");
\r
383 buttonLayout.addWidget(newSeparator());
\r
384 boldAction = buttonLayout.addWidget(boldButton);
\r
385 buttonLayout.toggleBoldVisible.triggered.connect(this, "toggleBoldVisible(Boolean)");
\r
386 italicAction = buttonLayout.addWidget(italicButton);
\r
387 buttonLayout.toggleItalicVisible.triggered.connect(this, "toggleItalicVisible(Boolean)");
\r
388 underlineAction = buttonLayout.addWidget(underlineButton);
\r
389 buttonLayout.toggleUnderlineVisible.triggered.connect(this, "toggleUnderlineVisible(Boolean)");
\r
390 strikethroughAction = buttonLayout.addWidget(strikethroughButton);
\r
391 buttonLayout.toggleStrikethroughVisible.triggered.connect(this, "toggleStrikethroughVisible(Boolean)");
\r
394 buttonLayout.addWidget(newSeparator());
\r
395 leftAlignAction = buttonLayout.addWidget(leftAlignButton);
\r
396 buttonLayout.toggleLeftAlignVisible.triggered.connect(this, "toggleLeftAlignVisible(Boolean)");
\r
397 centerAlignAction = buttonLayout.addWidget(centerAlignButton);
\r
398 buttonLayout.toggleCenterAlignVisible.triggered.connect(this, "toggleCenterAlignVisible(Boolean)");
\r
399 rightAlignAction = buttonLayout.addWidget(rightAlignButton);
\r
400 buttonLayout.toggleRightAlignVisible.triggered.connect(this, "toggleRightAlignVisible(Boolean)");
\r
402 buttonLayout.addWidget(newSeparator());
\r
403 hlineAction = buttonLayout.addWidget(hlineButton);
\r
404 buttonLayout.toggleHLineVisible.triggered.connect(this, "toggleHLineVisible(Boolean)");
\r
406 indentAction = buttonLayout.addWidget(indentButton);
\r
407 buttonLayout.toggleIndentVisible.triggered.connect(this, "toggleIndentVisible(Boolean)");
\r
408 outdentAction = buttonLayout.addWidget(outdentButton);
\r
409 buttonLayout.toggleOutdentVisible.triggered.connect(this, "toggleOutdentVisible(Boolean)");
\r
410 bulletListAction = buttonLayout.addWidget(bulletListButton);
\r
411 buttonLayout.toggleBulletListVisible.triggered.connect(this, "toggleBulletListVisible(Boolean)");
\r
412 numberListAction = buttonLayout.addWidget(numberListButton);
\r
413 buttonLayout.toggleNumberListVisible.triggered.connect(this, "toggleNumberListVisible(Boolean)");
\r
415 // Setup the font & font size combo boxes
\r
416 buttonLayout.addWidget(newSeparator());
\r
417 fontList = new QComboBox();
\r
418 fontSize = new QComboBox();
\r
419 fontList.setToolTip("Font");
\r
420 fontSize.setToolTip("Font Size");
\r
421 fontList.activated.connect(this, "fontChanged(String)");
\r
422 fontSize.activated.connect(this, "fontSizeChanged(String)");
\r
423 fontListAction = buttonLayout.addWidget(fontList);
\r
424 buttonLayout.toggleFontVisible.triggered.connect(this, "toggleFontListVisible(Boolean)");
\r
425 fontSizeAction = buttonLayout.addWidget(fontSize);
\r
426 buttonLayout.toggleFontSizeVisible.triggered.connect(this, "toggleFontSizeVisible(Boolean)");
\r
427 QFontDatabase fonts = new QFontDatabase();
\r
428 List<String> fontFamilies = fonts.families();
\r
429 for (int i = 0; i < fontFamilies.size(); i++) {
\r
430 fontList.addItem(fontFamilies.get(i));
\r
432 loadFontSize(fontFamilies.get(i));
\r
436 // buttonLayout.addWidget(newSeparator(), 0);
\r
437 fontColor = newEditorButton("fontColor", tr("Font Color"));
\r
438 fontColorMenu = new ColorMenu(this);
\r
439 fontColor.setMenu(fontColorMenu.getMenu());
\r
440 fontColorMenu.getMenu().triggered.connect(this, "fontColorClicked()");
\r
441 fontColorAction = buttonLayout.addWidget(fontColor);
\r
442 buttonLayout.toggleFontColorVisible.triggered.connect(this, "toggleFontColorVisible(Boolean)");
\r
443 fontHilight = newEditorButton("fontHilight", tr("Font Hilight Color"));
\r
444 fontHilightColorMenu = new ColorMenu(this);
\r
445 fontHilight.setMenu(fontHilightColorMenu.getMenu());
\r
446 fontHilightColorMenu.getMenu().triggered.connect(this, "fontHilightClicked()");
\r
447 fontHilightAction = buttonLayout.addWidget(fontHilight);
\r
448 buttonLayout.toggleFontHilight.triggered.connect(this, "toggleFontHilightVisible(Boolean)");
\r
450 // buttonLayout.addWidget(new QLabel(), 1);
\r
451 v.addWidget(browser, 1);
\r
454 browser.downloadAttachmentRequested.connect(this,
\r
455 "downloadAttachment(QNetworkRequest)");
\r
456 browser.downloadImageRequested.connect(this,
\r
457 "downloadImage(QNetworkRequest)");
\r
458 setTabOrder(notebookBox, tagEdit);
\r
459 setTabOrder(tagEdit, browser);
\r
461 focusNoteShortcut = new QShortcut(this);
\r
462 setupShortcut(focusNoteShortcut, "Focus_Note");
\r
463 focusNoteShortcut.activated.connect(this, "focusNote()");
\r
464 focusTitleShortcut = new QShortcut(this);
\r
465 setupShortcut(focusTitleShortcut, "Focus_Title");
\r
466 focusTitleShortcut.activated.connect(this, "focusTitle()");
\r
467 focusTagShortcut = new QShortcut(this);
\r
468 setupShortcut(focusTagShortcut, "Focus_Tag");
\r
469 focusTagShortcut.activated.connect(this, "focusTag()");
\r
470 focusAuthorShortcut = new QShortcut(this);
\r
471 setupShortcut(focusAuthorShortcut, "Focus_Author");
\r
472 focusAuthorShortcut.activated.connect(this, "focusAuthor()");
\r
473 focusUrlShortcut = new QShortcut(this);
\r
474 setupShortcut(focusUrlShortcut, "Focus_Url");
\r
475 focusUrlShortcut.activated.connect(this, "focusUrl()");
\r
477 browser.page().mainFrame().setTextSizeMultiplier(Global.getTextSizeMultiplier());
\r
478 browser.page().mainFrame().setZoomFactor(Global.getZoomFactor());
\r
480 previewPageList = new HashMap<String,Integer>();
\r
482 browser.page().microFocusChanged.connect(this, "microFocusChanged()");
\r
483 logger.log(logger.HIGH, "Browser setup complete");
\r
487 private void setupShortcut(QShortcut action, String text) {
\r
488 if (!Global.shortcutKeys.containsAction(text))
\r
490 action.setKey(new QKeySequence(Global.shortcutKeys.getShortcut(text)));
\r
496 // Getter for the QWebView
\r
497 public QWebView getBrowser() {
\r
501 // Block signals while loading data or things are flagged as dirty by
\r
503 public void loadingData(boolean val) {
\r
504 logger.log(logger.EXTREME, "Entering BrowserWindow.loadingData() " +val);
\r
505 notebookBox.blockSignals(val);
\r
506 browser.page().blockSignals(val);
\r
507 browser.page().mainFrame().blockSignals(val);
\r
508 titleLabel.blockSignals(val);
\r
509 alteredDate.blockSignals(val);
\r
510 alteredTime.blockSignals(val);
\r
511 createdTime.blockSignals(val);
\r
512 createdDate.blockSignals(val);
\r
513 subjectDate.blockSignals(val);
\r
514 subjectTime.blockSignals(val);
\r
515 urlText.blockSignals(val);
\r
516 authorText.blockSignals(val);
\r
518 exposeToJavascript();
\r
519 logger.log(logger.EXTREME, "Exiting BrowserWindow.loadingData() " +val);
\r
523 public void setReadOnly(boolean v) {
\r
525 titleLabel.setEnabled(!v);
\r
526 notebookBox.setEnabled(!v);
\r
527 tagEdit.setEnabled(!v);
\r
528 authorLabel.setEnabled(!v);
\r
529 geoBox.setEnabled(!v);
\r
530 urlText.setEnabled(!v);
\r
531 createdDate.setEnabled(!v);
\r
532 subjectDate.setEnabled(!v);
\r
533 alteredDate.setEnabled(!v);
\r
534 getBrowser().setEnabled(true);
\r
537 // expose this class to Javascript on the web page
\r
538 private void exposeToJavascript() {
\r
539 browser.page().mainFrame().addToJavaScriptWindowObject("jambi", this);
\r
542 // Custom event queue
\r
544 public boolean event(QEvent e) {
\r
545 if (e.type().equals(QEvent.Type.FocusOut)) {
\r
546 logger.log(logger.EXTREME, "Focus lost");
\r
549 return super.event(e);
\r
552 // clear out browser
\r
553 public void clear() {
\r
554 logger.log(logger.EXTREME, "Entering BrowserWindow.clear()");
\r
556 browser.setContent(new QByteArray());
\r
557 tagEdit.setText("");
\r
558 tagEdit.tagCompleter.reset();
\r
559 urlLabel.setText(tr("Source URL:"));
\r
560 titleLabel.setText("");
\r
561 logger.log(logger.EXTREME, "Exiting BrowserWindow.clear()");
\r
564 // get/set current note
\r
565 public void setNote(Note n) {
\r
569 saveNoteTitle = n.getTitle();
\r
573 public Note getNote() {
\r
574 return currentNote;
\r
577 // New Editor Button
\r
578 private QPushButton newEditorButton(String name, String toolTip) {
\r
579 QPushButton button = new QPushButton();
\r
580 QIcon icon = new QIcon(iconPath + name + ".gif");
\r
581 button.setIcon(icon);
\r
582 button.setToolTip(toolTip);
\r
583 button.clicked.connect(this, name + "Clicked()");
\r
588 private QLabel newSeparator() {
\r
589 return new QLabel(" ");
\r
592 // Set the title in the window
\r
593 public void setTitle(String t) {
\r
594 titleLabel.setText(t);
\r
599 // Return the current text title
\r
600 public String getTitle() {
\r
601 return titleLabel.text();
\r
604 // Set the tag name string
\r
605 public void setTag(String t) {
\r
607 tagEdit.setText(t);
\r
608 tagEdit.tagCompleter.reset();
\r
611 // Set the source URL
\r
612 public void setUrl(String t) {
\r
613 urlLabel.setText(tr("Source URL:\t"));
\r
614 urlText.setText(t);
\r
617 // The user want's to launch a web browser on the source of the URL
\r
618 public void sourceUrlClicked() {
\r
619 // Make sure we have a valid URL
\r
620 if (urlText.text().trim().equals(""))
\r
623 String url = urlText.text();
\r
624 if (!url.toLowerCase().startsWith(tr("http://")))
\r
625 url = tr("http://") +url;
\r
627 if (!QDesktopServices.openUrl(new QUrl(url))) {
\r
628 logger.log(logger.LOW, "Error opening file :" +url);
\r
632 public void setAuthor(String t) {
\r
633 authorLabel.setText(tr("Author:\t"));
\r
634 authorText.setText(t);
\r
637 // Set the creation date
\r
638 public void setCreation(long date) {
\r
639 QDateTime dt = new QDateTime();
\r
640 dt.setTime_t((int) (date / 1000));
\r
641 createdDate.setDateTime(dt);
\r
642 createdTime.setDateTime(dt);
\r
643 createdDate.setDisplayFormat(Global.getDateFormat());
\r
644 createdTime.setDisplayFormat(Global.getTimeFormat());
\r
647 // Set the creation date
\r
648 public void setAltered(long date) {
\r
649 QDateTime dt = new QDateTime();
\r
650 dt.setTime_t((int) (date / 1000));
\r
651 alteredDate.setDateTime(dt);
\r
652 alteredTime.setDateTime(dt);
\r
653 alteredDate.setDisplayFormat(Global.getDateFormat());
\r
654 alteredTime.setDisplayFormat(Global.getTimeFormat());
\r
657 // Set the subject date
\r
658 public void setSubjectDate(long date) {
\r
659 QDateTime dt = new QDateTime();
\r
660 dt.setTime_t((int) (date / 1000));
\r
661 subjectDate.setDateTime(dt);
\r
662 subjectTime.setDateTime(dt);
\r
663 subjectDate.setDisplayFormat(Global.getDateFormat());
\r
664 subjectTime.setDisplayFormat(Global.getTimeFormat());
\r
667 // Toggle the extended attribute information
\r
668 public void toggleInformation() {
\r
670 extendedOn = false;
\r
674 urlLabel.setVisible(extendedOn);
\r
675 urlText.setVisible(extendedOn);
\r
676 authorText.setVisible(extendedOn);
\r
677 geoBox.setVisible(extendedOn);
\r
678 authorLabel.setVisible(extendedOn);
\r
679 createdDate.setVisible(extendedOn);
\r
680 createdTime.setVisible(extendedOn);
\r
681 createdLabel.setVisible(extendedOn);
\r
682 alteredLabel.setVisible(extendedOn);
\r
683 alteredDate.setVisible(extendedOn);
\r
684 alteredTime.setVisible(extendedOn);
\r
685 //notebookBox.setVisible(extendedOn);
\r
686 notebookLabel.setVisible(extendedOn);
\r
687 subjectLabel.setVisible(extendedOn);
\r
688 subjectDate.setVisible(extendedOn);
\r
689 subjectTime.setVisible(extendedOn);
\r
692 public void hideButtons() {
\r
694 undoButton.parentWidget().setVisible(false);
\r
695 buttonsVisible = false;
\r
699 // Is the extended view on?
\r
700 public boolean isExtended() {
\r
704 // Listener for when a link is clicked
\r
705 @SuppressWarnings("unused")
\r
706 private void openFile() {
\r
707 logger.log(logger.EXTREME, "Starting openFile()");
\r
708 File fileHandle = new File(selectedFile);
\r
709 URI fileURL = fileHandle.toURI();
\r
710 String localURL = fileURL.toString();
\r
711 QUrl url = new QUrl(localURL);
\r
712 QFile file = new QFile(selectedFile);
\r
714 logger.log(logger.EXTREME, "Adding to fileWatcher:"+file.fileName());
\r
715 fileWatcher.addPath(file.fileName());
\r
717 if (!QDesktopServices.openUrl(url)) {
\r
718 logger.log(logger.LOW, "Error opening file :" +url);
\r
723 // Listener for when a link is clicked
\r
724 @SuppressWarnings("unused")
\r
725 private void linkClicked(QUrl url) {
\r
726 logger.log(logger.EXTREME, "URL Clicked: " +url.toString());
\r
727 if (url.toString().substring(0,8).equals("nnres://")) {
\r
728 logger.log(logger.EXTREME, "URL is NN resource");
\r
729 if (url.toString().endsWith("/vnd.evernote.ink")) {
\r
730 logger.log(logger.EXTREME, "Unable to open ink note");
\r
731 QMessageBox.information(this, tr("Unable Open"), tr("This is an ink note.\n"+
\r
732 "Ink notes are not supported since Evernote has not\n published any specifications on them\n" +
\r
733 "and I'm too lazy to figure them out by myself."));
\r
736 String fullName = url.toString().substring(8);
\r
737 int index = fullName.indexOf(".");
\r
741 type = fullName.substring(index+1);
\r
742 guid = fullName.substring(0,index);
\r
744 index = guid.indexOf(Global.attachmentNameDelimeter);
\r
746 guid = guid.substring(0,index);
\r
748 List<Resource> resList = currentNote.getResources();
\r
749 Resource res = null;
\r
750 for (int i=0; i<resList.size(); i++) {
\r
751 if (resList.get(i).getGuid().equals(guid)) {
\r
752 res = resList.get(i);
\r
757 String resGuid = Global.resourceMap.get(guid);
\r
758 if (resGuid != null)
\r
759 res = conn.getNoteTable().noteResourceTable.getNoteResource(resGuid, true);
\r
763 if (res.getAttributes() != null &&
\r
764 res.getAttributes().getFileName() != null &&
\r
765 !res.getAttributes().getFileName().trim().equals(""))
\r
766 fileName = res.getGuid()+Global.attachmentNameDelimeter+res.getAttributes().getFileName();
\r
768 fileName = res.getGuid()+"."+type;
\r
769 QFile file = new QFile(Global.getFileManager().getResDirPath(fileName));
\r
770 QFile.OpenMode mode = new QFile.OpenMode();
\r
771 mode.set(QFile.OpenModeFlag.WriteOnly);
\r
772 boolean openResult = file.open(mode);
\r
773 logger.log(logger.EXTREME, "File opened:" +openResult);
\r
774 QDataStream out = new QDataStream(file);
\r
775 Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(res.getGuid(), true);
\r
776 QByteArray binData = new QByteArray(resBinary.getData().getBody());
\r
778 logger.log(logger.EXTREME, "Writing resource");
\r
779 out.writeBytes(binData.toByteArray());
\r
782 String whichOS = System.getProperty("os.name");
\r
783 if (whichOS.contains("Windows"))
\r
784 url.setUrl("file:///"+file.fileName());
\r
786 url.setUrl("file://"+file.fileName());
\r
787 // fileWatcher.removePath(file.fileName());
\r
788 logger.log(logger.EXTREME, "Adding file watcher " +file.fileName());
\r
789 fileWatcher.addPath(file.fileName());
\r
791 // If we can't open it, then prompt the user to save it.
\r
792 if (!QDesktopServices.openUrl(url)) {
\r
793 logger.log(logger.EXTREME, "We can't handle this. Where do we put it?");
\r
794 QFileDialog dialog = new QFileDialog();
\r
796 if (dialog.exec()!=0) {
\r
797 List<String> fileNames = dialog.selectedFiles(); //gets all selected filenames
\r
798 if (fileNames.size() == 0)
\r
800 String sf = fileNames.get(0);
\r
801 QFile saveFile = new QFile(sf);
\r
802 mode.set(QFile.OpenModeFlag.WriteOnly);
\r
803 saveFile.open(mode);
\r
804 QDataStream saveOut = new QDataStream(saveFile);
\r
805 saveOut.writeBytes(binData.toByteArray());
\r
813 logger.log(logger.EXTREME, "Launching URL");
\r
814 QDesktopServices.openUrl(url);
\r
817 // Listener for when BOLD is clicked
\r
818 @SuppressWarnings("unused")
\r
819 private void undoClicked() {
\r
820 browser.page().triggerAction(WebAction.Undo);
\r
821 browser.setFocus();
\r
824 // Listener for when BOLD is clicked
\r
825 @SuppressWarnings("unused")
\r
826 private void redoClicked() {
\r
827 browser.page().triggerAction(WebAction.Redo);
\r
828 browser.setFocus();
\r
831 // Listener for when BOLD is clicked
\r
832 @SuppressWarnings("unused")
\r
833 private void boldClicked() {
\r
834 browser.page().triggerAction(WebAction.ToggleBold);
\r
835 microFocusChanged();
\r
836 browser.setFocus();
\r
839 // Listener for when Italics is clicked
\r
840 @SuppressWarnings("unused")
\r
841 private void italicClicked() {
\r
842 browser.page().triggerAction(WebAction.ToggleItalic);
\r
843 microFocusChanged();
\r
844 browser.setFocus();
\r
847 // Listener for when UNDERLINE is clicked
\r
848 @SuppressWarnings("unused")
\r
849 private void underlineClicked() {
\r
850 browser.page().triggerAction(WebAction.ToggleUnderline);
\r
851 microFocusChanged();
\r
852 browser.setFocus();
\r
855 // Listener for when Strikethrough is clicked
\r
856 @SuppressWarnings("unused")
\r
857 private void strikethroughClicked() {
\r
858 browser.page().mainFrame().evaluateJavaScript(
\r
859 "document.execCommand('strikeThrough', false, '');");
\r
860 browser.setFocus();
\r
863 // Listener for when cut is clicked
\r
864 @SuppressWarnings("unused")
\r
865 private void cutClicked() {
\r
866 browser.page().triggerAction(WebAction.Cut);
\r
867 browser.setFocus();
\r
870 // Listener when COPY is clicked
\r
871 @SuppressWarnings("unused")
\r
872 private void copyClicked() {
\r
873 browser.page().triggerAction(WebAction.Copy);
\r
874 browser.setFocus();
\r
877 // Listener when PASTE is clicked
\r
878 void pasteClicked() {
\r
879 logger.log(logger.EXTREME, "Paste Clicked");
\r
880 if (forceTextPaste) {
\r
881 pasteWithoutFormattingClicked();
\r
884 QClipboard clipboard = QApplication.clipboard();
\r
885 QMimeData mime = clipboard.mimeData();
\r
887 // String x = mime.html();
\r
889 if (mime.hasImage()) {
\r
890 logger.log(logger.EXTREME, "Image paste found");
\r
892 browser.setFocus();
\r
896 if (mime.hasUrls()) {
\r
897 logger.log(logger.EXTREME, "URL paste found");
\r
899 browser.setFocus();
\r
903 String text = mime.html();
\r
904 if (text.contains("en-tag") && mime.hasHtml()) {
\r
905 logger.log(logger.EXTREME, "Intra-note paste found");
\r
906 text = fixInternotePaste(text);
\r
907 mime.setHtml(text);
\r
908 clipboard.setMimeData(mime);
\r
911 logger.log(logger.EXTREME, "Final paste choice encountered");
\r
912 browser.page().triggerAction(WebAction.Paste);
\r
913 browser.setFocus();
\r
917 // Paste text without formatting
\r
918 private void pasteWithoutFormattingClicked() {
\r
919 logger.log(logger.EXTREME, "Paste without format clipped");
\r
920 QClipboard clipboard = QApplication.clipboard();
\r
921 QMimeData mime = clipboard.mimeData();
\r
922 if (!mime.hasText())
\r
924 String text = mime.text();
\r
925 clipboard.setText(text);
\r
926 browser.page().triggerAction(WebAction.Paste);
\r
927 QApplication.clipboard().setMimeData(mime);
\r
928 browser.setFocus();
\r
932 // insert date/time
\r
933 @SuppressWarnings("unused")
\r
934 private void insertDateTime() {
\r
935 String fmt = Global.getDateFormat() + " " + Global.getTimeFormat();
\r
936 String dateTimeFormat = new String(fmt);
\r
937 SimpleDateFormat simple = new SimpleDateFormat(dateTimeFormat);
\r
938 Calendar cal = Calendar.getInstance();
\r
940 browser.page().mainFrame().evaluateJavaScript(
\r
941 "document.execCommand('insertHtml', false, '"+simple.format(cal.getTime())+"');");
\r
943 browser.setFocus();
\r
947 // Listener when Left is clicked
\r
948 @SuppressWarnings("unused")
\r
949 private void justifyLeftClicked() {
\r
950 browser.page().mainFrame().evaluateJavaScript(
\r
951 "document.execCommand('JustifyLeft', false, '');");
\r
952 browser.setFocus();
\r
955 // Listener when Center is clicked
\r
956 @SuppressWarnings("unused")
\r
957 private void justifyCenterClicked() {
\r
958 browser.page().mainFrame().evaluateJavaScript(
\r
959 "document.execCommand('JustifyCenter', false, '');");
\r
960 browser.setFocus();
\r
963 // Listener when Left is clicked
\r
964 @SuppressWarnings("unused")
\r
965 private void justifyRightClicked() {
\r
966 browser.page().mainFrame().evaluateJavaScript(
\r
967 "document.execCommand('JustifyRight', false, '');");
\r
968 browser.setFocus();
\r
971 // Listener when HLINE is clicked
\r
972 @SuppressWarnings("unused")
\r
973 private void hlineClicked() {
\r
974 browser.page().mainFrame().evaluateJavaScript(
\r
975 "document.execCommand('insertHorizontalRule', false, '');");
\r
976 browser.setFocus();
\r
979 // Listener when outdent is clicked
\r
980 private void outdentClicked() {
\r
981 browser.page().mainFrame().evaluateJavaScript(
\r
982 "document.execCommand('outdent', false, '');");
\r
983 browser.setFocus();
\r
986 // Listener when a bullet list is clicked
\r
987 @SuppressWarnings("unused")
\r
988 private void bulletListClicked() {
\r
989 browser.page().mainFrame().evaluateJavaScript(
\r
990 "document.execCommand('InsertUnorderedList', false, '');");
\r
991 browser.setFocus();
\r
994 // Listener when a bullet list is clicked
\r
995 @SuppressWarnings("unused")
\r
996 private void numberListClicked() {
\r
997 browser.page().mainFrame().evaluateJavaScript(
\r
998 "document.execCommand('InsertOrderedList', false, '');");
\r
999 browser.setFocus();
\r
1002 // Listener when indent is clicked
\r
1003 private void indentClicked() {
\r
1004 browser.page().mainFrame().evaluateJavaScript(
\r
1005 "document.execCommand('indent', false, '');");
\r
1006 browser.setFocus();
\r
1009 // Listener when the font name is changed
\r
1010 @SuppressWarnings("unused")
\r
1011 private void fontChanged(String font) {
\r
1012 browser.page().mainFrame().evaluateJavaScript(
\r
1013 "document.execCommand('fontName',false,'" + font + "');");
\r
1014 browser.setFocus();
\r
1017 // Listener when a font size is changed
\r
1018 @SuppressWarnings("unused")
\r
1019 private void fontSizeChanged(String font) {
\r
1020 String text = browser.selectedText();
\r
1021 if (text.trim().equalsIgnoreCase(""))
\r
1024 String selectedText = browser.selectedText();
\r
1025 String url = "<span style=\"font-size:" +font +"pt; \">"+selectedText +"</a>";
\r
1026 String script = "document.execCommand('insertHtml', false, '"+url+"');";
\r
1027 browser.page().mainFrame().evaluateJavaScript(script);
\r
1028 /* browser.page().mainFrame().evaluateJavaScript(
\r
1029 "document.execCommand('fontSize',false,'"
\r
1032 browser.setFocus();
\r
1035 // Load the font combo box based upon the font selected
\r
1036 private void loadFontSize(String name) {
\r
1037 QFontDatabase db = new QFontDatabase();
\r
1039 List<Integer> points = db.pointSizes(name);
\r
1040 for (int i=0; i<points.size(); i++) {
\r
1041 fontSize.addItem(points.get(i).toString());
\r
1044 fontSize.addItem("x-small");
\r
1045 fontSize.addItem("small");
\r
1046 fontSize.addItem("medium");
\r
1047 fontSize.addItem("large");
\r
1048 fontSize.addItem("x-large");
\r
1049 fontSize.addItem("xx-large");
\r
1050 fontSize.addItem("xxx-large");
\r
1054 // Listener when a font size is changed
\r
1055 @SuppressWarnings("unused")
\r
1056 private void fontColorClicked() {
\r
1057 // QColorDialog dialog = new QColorDialog();
\r
1058 // QColor color = QColorDialog.getColor();
\r
1059 QColor color = fontColorMenu.getColor();
\r
1060 if (color.isValid())
\r
1061 browser.page().mainFrame().evaluateJavaScript(
\r
1062 "document.execCommand('foreColor',false,'" + color.name()
\r
1064 browser.setFocus();
\r
1067 // Listener for when a background color change is requested
\r
1068 @SuppressWarnings("unused")
\r
1069 private void fontHilightClicked() {
\r
1070 // QColorDialog dialog = new QColorDialog();
\r
1071 // QColor color = QColorDialog.getColor();
\r
1072 QColor color = fontHilightColorMenu.getColor();
\r
1073 if (color.isValid())
\r
1074 browser.page().mainFrame().evaluateJavaScript(
\r
1075 "document.execCommand('backColor',false,'" + color.name()
\r
1077 browser.setFocus();
\r
1080 // Listener for when a background color change is requested
\r
1081 @SuppressWarnings("unused")
\r
1082 private void superscriptClicked() {
\r
1083 browser.page().mainFrame().evaluateJavaScript(
\r
1084 "document.execCommand('superscript');");
\r
1085 browser.setFocus();
\r
1088 // Listener for when a background color change is requested
\r
1089 @SuppressWarnings("unused")
\r
1090 private void subscriptClicked() {
\r
1091 browser.page().mainFrame().evaluateJavaScript(
\r
1092 "document.execCommand('subscript');");
\r
1093 browser.setFocus();
\r
1095 // Insert a to-do checkbox
\r
1096 @SuppressWarnings("unused")
\r
1097 private void todoClicked() {
\r
1098 FileNameMap fileNameMap = URLConnection.getFileNameMap();
\r
1099 String script_start = new String(
\r
1100 "document.execCommand('insertHtml', false, '");
\r
1101 String script_end = new String("');");
\r
1102 String todo = new String(
\r
1103 "<input TYPE=\"CHECKBOX\" value=\"false\" onClick=\"value=checked; window.jambi.contentChanged(); \" />");
\r
1104 browser.page().mainFrame().evaluateJavaScript(
\r
1105 script_start + todo + script_end);
\r
1106 browser.setFocus();
\r
1109 // Encrypt the selected text
\r
1110 @SuppressWarnings("unused")
\r
1111 private void encryptText() {
\r
1112 String text = browser.selectedText();
\r
1113 if (text.trim().equalsIgnoreCase(""))
\r
1116 EnCryptDialog dialog = new EnCryptDialog();
\r
1118 if (!dialog.okPressed()) {
\r
1122 EnCrypt crypt = new EnCrypt();
\r
1123 String encrypted = crypt.encrypt(text, dialog.getPassword().trim(), 64);
\r
1125 if (encrypted.trim().equals("")) {
\r
1126 QMessageBox.information(this, tr("Error"), tr("Error Encrypting String"));
\r
1129 StringBuffer buffer = new StringBuffer(encrypted.length() + 100);
\r
1130 buffer.append("<img en-tag=\"en-crypt\" cipher=\"RC2\" hint=\""
\r
1131 + dialog.getHint().replace("'","\\'") + "\" length=\"64\" ");
\r
1132 buffer.append("contentEditable=\"false\" alt=\"");
\r
1133 buffer.append(encrypted);
\r
1134 // NFC FIXME: should this be a file URL like in handleLocalAttachment and importAttachment?
\r
1135 buffer.append("\" src=\"").append(FileUtils.toForwardSlashedPath(Global.getFileManager().getImageDirPath("encrypt.png") +"\""));
\r
1136 Global.cryptCounter++;
\r
1137 buffer.append(" id=\"crypt"+Global.cryptCounter.toString() +"\"");
\r
1138 buffer.append(" onMouseOver=\"style.cursor=\\'hand\\'\"");
\r
1139 buffer.append(" onClick=\"window.jambi.decryptText(\\'crypt"+Global.cryptCounter.toString()
\r
1140 +"\\', \\'"+encrypted+"\\', \\'"+dialog.getHint().replace("'", "\\&apos;")+"\\');\"");
\r
1141 buffer.append("style=\"display:block\" />");
\r
1143 String script_start = new String(
\r
1144 "document.execCommand('insertHtml', false, '");
\r
1145 String script_end = new String("');");
\r
1146 browser.page().mainFrame().evaluateJavaScript(
\r
1147 script_start + buffer.toString() + script_end);
\r
1151 // Insert a hyperlink
\r
1152 public void insertLink() {
\r
1153 logger.log(logger.EXTREME, "Inserting link");
\r
1154 String text = browser.selectedText();
\r
1155 if (text.trim().equalsIgnoreCase(""))
\r
1158 InsertLinkDialog dialog = new InsertLinkDialog();
\r
1159 if (currentHyperlink != null && currentHyperlink != "") {
\r
1160 dialog.setUrl(currentHyperlink);
\r
1163 if (!dialog.okPressed()) {
\r
1164 logger.log(logger.EXTREME, "Insert link canceled");
\r
1167 if (browser.insertLinkAction.text().equalsIgnoreCase("Insert Hyperlink")) {
\r
1168 String selectedText = browser.selectedText();
\r
1169 logger.log(logger.EXTREME, "Inserting link on text "+selectedText);
\r
1170 logger.log(logger.EXTREME, "URL Link " +dialog.getUrl().trim());
\r
1171 String url = "<a href=\"" +dialog.getUrl().trim()
\r
1172 +"\" title=" +dialog.getUrl().trim()
\r
1173 +" >"+selectedText +"</a>";
\r
1174 String script = "document.execCommand('insertHtml', false, '"+url+"');";
\r
1175 browser.page().mainFrame().evaluateJavaScript(script);
\r
1178 String js = new String( "function getCursorPos() {"
\r
1180 +"if (window.getSelection) {"
\r
1181 +" var selObj = window.getSelection();"
\r
1182 +" var selRange = selObj.getRangeAt(0);"
\r
1183 +" var workingNode = window.getSelection().anchorNode.parentNode;"
\r
1184 +" while(workingNode != null) { "
\r
1185 +" if (workingNode.nodeName.toLowerCase()=='a') workingNode.setAttribute('href','" +dialog.getUrl() +"');"
\r
1186 +" workingNode = workingNode.parentNode;"
\r
1189 +"} getCursorPos();");
\r
1190 browser.page().mainFrame().evaluateJavaScript(js);
\r
1197 public void insertTable() {
\r
1198 TableDialog dialog = new TableDialog();
\r
1200 if (!dialog.okPressed()) {
\r
1204 int cols = dialog.getCols();
\r
1205 int rows = dialog.getRows();
\r
1206 int width = dialog.getWidth();
\r
1207 boolean percent = dialog.isPercent();
\r
1209 String newHTML = "<table border=\"1\" width=\"" +new Integer(width).toString();
\r
1211 newHTML = newHTML +"%";
\r
1212 newHTML = newHTML + "\"><tbody>";
\r
1214 for (int i=0; i<rows; i++) {
\r
1215 newHTML = newHTML +"<tr>";
\r
1216 for (int j=0; j<cols; j++) {
\r
1217 newHTML = newHTML +"<td> </td>";
\r
1219 newHTML = newHTML +"</tr>";
\r
1221 newHTML = newHTML+"</tbody></table>";
\r
1223 String script = "document.execCommand('insertHtml', false, '"+newHTML+"');";
\r
1224 browser.page().mainFrame().evaluateJavaScript(script);
\r
1228 // Text content changed
\r
1229 @SuppressWarnings("unused")
\r
1230 private void selectionChanged() {
\r
1231 browser.encryptAction.setEnabled(true);
\r
1232 browser.insertLinkAction.setEnabled(true);
\r
1233 String scriptStart = "var selection_text = (window.getSelection()).toString();"
\r
1234 + "var range = (window.getSelection()).getRangeAt(0);"
\r
1235 + "var parent_html = range.commonAncestorContainer.innerHTML;"
\r
1236 + "if (parent_html == undefined) {window.jambi.saveSelectedText(selection_text); return;}"
\r
1237 + "var first_text = range.startContainer.nodeValue.substr(range.startOffset);"
\r
1238 + "var last_text = (range.endContainer.nodeValue).substring(0,range.endOffset);"
\r
1239 + "var start = parent_html.indexOf(first_text);"
\r
1240 + "var end = parent_html.indexOf(last_text,start+1)+last_text.length;"
\r
1241 + "var value = parent_html.substring(start,end);"
\r
1242 + "window.jambi.saveSelectedText(value);" ;
\r
1243 browser.page().mainFrame().evaluateJavaScript(scriptStart);
\r
1247 public void saveSelectedText(String text) {
\r
1248 boolean enabled = true;
\r
1249 if (text.trim().length() == 0)
\r
1251 if (text.indexOf("en-tag=\"en-crypt\"") >= 0)
\r
1253 if (text.indexOf("<img en-tag=\"en-media\"") >= 0)
\r
1255 if (text.indexOf("<a en-tag=\"en-media\"") >= 0)
\r
1257 if (text.indexOf("<input ") >= 0)
\r
1260 browser.encryptAction.setEnabled(enabled);
\r
1261 browser.insertLinkAction.setEnabled(enabled);
\r
1262 // selectedText = text;
\r
1265 // Decrypt clicked text
\r
1266 public void decryptText(String id, String text, String hint) {
\r
1267 EnCrypt crypt = new EnCrypt();
\r
1268 String plainText = null;
\r
1269 Calendar currentTime = new GregorianCalendar();
\r
1270 Long l = new Long(currentTime.getTimeInMillis());
\r
1271 String slot = new String(Long.toString(l));
\r
1273 // First, try to decrypt with any keys we already have
\r
1274 for (int i=0; i<Global.passwordRemember.size(); i++) {
\r
1275 plainText = crypt.decrypt(text, Global.passwordRemember.get(i), 64);
\r
1276 if (plainText != null) {
\r
1277 slot = new String(Long.toString(l));
\r
1278 Global.passwordSafe.put(slot, Global.passwordRemember.get(i));
\r
1279 removeEncryption(id, plainText, false, slot);
\r
1285 EnDecryptDialog dialog = new EnDecryptDialog();
\r
1286 dialog.setHint(hint);
\r
1287 while (plainText == null || !dialog.okPressed()) {
\r
1289 if (!dialog.okPressed()) {
\r
1292 plainText = crypt.decrypt(text, dialog.getPassword().trim(), 64);
\r
1293 if (plainText == null) {
\r
1294 QMessageBox.warning(this, "Incorrect Password", "The password entered is not correct");
\r
1297 Global.passwordSafe.put(slot, dialog.getPassword());
\r
1298 removeEncryption(id, plainText, dialog.permanentlyDecrypt(), slot);
\r
1299 if (dialog.rememberPassword())
\r
1300 Global.passwordRemember.add(dialog.getPassword());
\r
1304 // Get the editor tag line
\r
1305 public TagLineEdit getTagLine() {
\r
1309 // Modify a note's tags
\r
1310 @SuppressWarnings("unused")
\r
1311 private void modifyTags() {
\r
1312 TagAssign tagWindow = new TagAssign(allTags, currentTags);
\r
1314 if (tagWindow.okClicked()) {
\r
1315 currentTags.clear();
\r
1316 StringBuffer tagDisplay = new StringBuffer();
\r
1318 List<QListWidgetItem> newTags = tagWindow.getTagList()
\r
1320 for (int i = 0; i < newTags.size(); i++) {
\r
1321 currentTags.add(newTags.get(i).text());
\r
1322 tagDisplay.append(newTags.get(i).text());
\r
1323 if (i < newTags.size() - 1) {
\r
1324 tagDisplay.append(Global.tagDelimeter + " ");
\r
1327 tagEdit.setText(tagDisplay.toString());
\r
1328 noteSignal.tagsChanged.emit(currentNote.getGuid(), currentTags);
\r
1332 // Tag line has been modified by typing text
\r
1333 @SuppressWarnings("unused")
\r
1334 private void modifyTagsTyping() {
\r
1335 String completionText = "";
\r
1336 if (tagEdit.currentCompleterSelection != null && !tagEdit.currentCompleterSelection.equals("")) {
\r
1337 completionText = tagEdit.currentCompleterSelection;
\r
1338 tagEdit.currentCompleterSelection = "";
\r
1341 if (tagEdit.text().equalsIgnoreCase(saveTagList))
\r
1344 // We know something has changed...
\r
1345 String oldTagArray[] = saveTagList.split(Global.tagDelimeter);
\r
1346 String newTagArray[] = tagEdit.text().split(Global.tagDelimeter);
\r
1348 if (!completionText.equals("") && newTagArray.length > 0) {
\r
1349 newTagArray[newTagArray.length-1] = completionText;
\r
1351 // Remove any potential duplicates from the new list
\r
1352 for (int i=0; i<newTagArray.length; i++) {
\r
1353 boolean foundOnce = false;
\r
1354 for (int j=0; j<newTagArray.length; j++) {
\r
1355 if (newTagArray[j].equalsIgnoreCase(newTagArray[i])) {
\r
1359 newTagArray[j] = "";
\r
1364 List<String> newTagList = new ArrayList<String>();
\r
1365 List<String> oldTagList = new ArrayList<String>();
\r
1367 for (int i = 0; i < oldTagArray.length; i++)
\r
1368 if (!oldTagArray[i].trim().equals(""))
\r
1369 oldTagList.add(oldTagArray[i]);
\r
1370 for (int i = 0; i < newTagArray.length; i++)
\r
1371 if (!newTagArray[i].trim().equals(""))
\r
1372 newTagList.add(newTagArray[i]);
\r
1374 // Let's cleanup the appearance of the tag list
\r
1375 Collections.sort(newTagList);
\r
1376 String newDisplay = "";
\r
1377 for (int i=0; i<newTagList.size(); i++) {
\r
1378 newDisplay = newDisplay+newTagList.get(i);
\r
1379 if (i<newTagList.size()-1)
\r
1380 newDisplay = newDisplay+", ";
\r
1382 tagEdit.blockSignals(true);
\r
1383 tagEdit.setText(newDisplay);
\r
1384 tagEdit.blockSignals(false);
\r
1386 // We now have lists of the new & old. Remove duplicates. If all
\r
1387 // are removed from both then nothing has really changed
\r
1388 for (int i = newTagList.size() - 1; i >= 0; i--) {
\r
1389 String nTag = newTagList.get(i);
\r
1390 for (int j = oldTagList.size() - 1; j >= 0; j--) {
\r
1391 String oTag = oldTagList.get(j);
\r
1392 if (oTag.equalsIgnoreCase(nTag)) {
\r
1393 oldTagList.remove(j);
\r
1394 newTagList.remove(i);
\r
1400 if (oldTagList.size() != 0 || newTagList.size() != 0) {
\r
1401 currentTags.clear();
\r
1402 newTagArray = tagEdit.text().split(Global.tagDelimeter);
\r
1403 for (int i = 0; i < newTagArray.length; i++)
\r
1404 if (!newTagArray[i].trim().equals(""))
\r
1405 currentTags.add(newTagArray[i].trim());
\r
1407 noteSignal.tagsChanged.emit(currentNote.getGuid(), currentTags);
\r
1412 // Tab button was pressed
\r
1413 public void tabPressed() {
\r
1414 if (!insideList) {
\r
1415 String script_start = new String(
\r
1416 "document.execCommand('insertHtml', false, ' ');");
\r
1417 browser.page().mainFrame().evaluateJavaScript(script_start);
\r
1422 public void backtabPressed() {
\r
1427 public void setInsideList() {
\r
1428 insideList = true;
\r
1431 // The title has been edited
\r
1432 @SuppressWarnings("unused")
\r
1433 private void titleEdited() {
\r
1434 // If we don't have a good note, or if the current title
\r
1435 // matches the old title then we don't need to do anything
\r
1436 if (currentNote == null)
\r
1438 if (currentNote.getTitle().trim().equals(titleLabel.text().trim()))
\r
1441 // If we have a real change, we need to save it.
\r
1442 noteSignal.titleChanged.emit(currentNote.getGuid(), titleLabel.text());
\r
1443 currentNote.setTitle(titleLabel.text());
\r
1444 saveNoteTitle = titleLabel.text();
\r
1448 // Set the list of note tags
\r
1449 public void setAllTags(List<Tag> l) {
\r
1451 tagEdit.setTagList(l);
\r
1454 // Setter for the current tags
\r
1455 public void setCurrentTags(List<String> s) {
\r
1459 // Save the list of notebooks
\r
1460 public void setNotebookList(List<Notebook> n) {
\r
1462 loadNotebookList();
\r
1465 // Load the notebook list and select the current notebook
\r
1466 private void loadNotebookList() {
\r
1467 if (notebookBox.count() != 0)
\r
1468 notebookBox.clear();
\r
1469 if (notebookList == null)
\r
1472 for (int i = 0; i < notebookList.size(); i++) {
\r
1473 notebookBox.addItem(notebookList.get(i).getName());
\r
1474 if (currentNote != null) {
\r
1475 if (currentNote.getNotebookGuid().equals(
\r
1476 notebookList.get(i).getGuid())) {
\r
1477 notebookBox.setCurrentIndex(i);
\r
1483 // Get the contents of the editor
\r
1484 public String getContent() {
\r
1485 return browser.page().currentFrame().toHtml();
\r
1488 // The note contents have changed
\r
1489 public void contentChanged() {
\r
1490 String content = getContent();
\r
1492 noteSignal.noteChanged.emit(currentNote.getGuid(), content);
\r
1495 // The notebook selection has changed
\r
1496 @SuppressWarnings("unused")
\r
1497 private void notebookChanged() {
\r
1498 boolean changed = false;
\r
1499 String n = notebookBox.currentText();
\r
1500 for (int i = 0; i < notebookList.size(); i++) {
\r
1501 if (n.equals(notebookList.get(i).getName())) {
\r
1502 if (!notebookList.get(i).getGuid().equals(currentNote.getNotebookGuid())) {
\r
1503 currentNote.setNotebookGuid(notebookList.get(i).getGuid());
\r
1506 i = notebookList.size();
\r
1510 // If the notebook changed, signal the update
\r
1512 noteSignal.notebookChanged.emit(currentNote.getGuid(), currentNote
\r
1513 .getNotebookGuid());
\r
1516 // Check the note title
\r
1517 private void checkNoteTitle() {
\r
1518 String text = browser.page().currentFrame().toPlainText();
\r
1519 if (saveNoteTitle.trim().equals("")) {
\r
1520 int newLine = text.indexOf("\n");
\r
1521 if (newLine > 0) {
\r
1522 text = text.substring(0, newLine);
\r
1523 if (text.trim().equals(""))
\r
1524 text = tr("Untitled Note");
\r
1525 titleLabel.setText(text);
\r
1527 if (text.length() > 20)
\r
1528 titleLabel.setText(text.substring(0, 20));
\r
1530 if (text.trim().equals(""))
\r
1531 titleLabel.setText(tr("Untitled Note"));
\r
1533 titleLabel.setText(text);
\r
1536 noteSignal.titleChanged.emit(currentNote.getGuid(), titleLabel
\r
1541 // Return the note contents so we can email them
\r
1542 public String getContentsToEmail() {
\r
1543 return browser.page().currentFrame().toPlainText().trim();
\r
1545 * int body = browser.page().currentFrame().toHtml().indexOf("<body>");
\r
1546 * String temp = browser.page().currentFrame().toHtml(); if (body == -1)
\r
1547 * temp = "<html><body><b>Test</b></body></html>"; else temp =
\r
1548 * "<html>"+temp.substring(body); return temp; // return
\r
1549 * urlEncode(browser.page().currentFrame().toHtml());
\r
1553 // Insert an image into the editor
\r
1554 private void insertImage(QMimeData mime) {
\r
1555 logger.log(logger.EXTREME, "Entering insertImage");
\r
1556 QImage img = (QImage) mime.imageData();
\r
1557 String script_start = new String(
\r
1558 "document.execCommand('insertHTML', false, '");
\r
1559 String script_end = new String("');");
\r
1561 long now = new Date().getTime();
\r
1562 String path = Global.getFileManager().getResDirPath(
\r
1563 (new Long(now).toString()) + ".jpg");
\r
1565 // This block is just a hack to make sure we wait at least 1ms so we
\r
1567 // have collisions on image names
\r
1568 long i = new Date().getTime();
\r
1570 i = new Date().getTime();
\r
1572 // Open the file & write the data
\r
1573 QFile tfile = new QFile(path);
\r
1574 tfile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.WriteOnly));
\r
1578 Resource newRes = createResource(QUrl.fromLocalFile(path).toString(), 0, "image/jpeg", false);
\r
1579 if (newRes == null)
\r
1581 currentNote.getResources().add(newRes);
\r
1583 // do the actual insert into the note
\r
1584 StringBuffer buffer = new StringBuffer(100);
\r
1585 buffer.append("<img src=\"");
\r
1586 buffer.append(tfile.fileName());
\r
1587 buffer.append("\" en-tag=en-media type=\"image/jpeg\""
\r
1588 +" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\""
\r
1589 +" guid=\"" +newRes.getGuid() +"\""
\r
1590 // +" onContextMenu=\"window.jambi.imageContextMenu('" +tfile.fileName() +"');\""
\r
1591 +" onContextMenu=\"window.jambi.imageContextMenu(&." +tfile.fileName() +"&.);\""
\r
1594 browser.page().mainFrame().evaluateJavaScript(
\r
1595 script_start + buffer + script_end);
\r
1600 // Handle URLs that are trying to be pasted
\r
1601 public void handleUrls(QMimeData mime) {
\r
1602 logger.log(logger.EXTREME, "Starting handleUrls");
\r
1603 FileNameMap fileNameMap = URLConnection.getFileNameMap();
\r
1605 List<QUrl> urlList = mime.urls();
\r
1606 String url = new String();
\r
1607 String script_start = new String(
\r
1608 "document.execCommand('createLink', false, '");
\r
1609 String script_end = new String("');");
\r
1611 for (int i = 0; i < urlList.size(); i++) {
\r
1612 url = urlList.get(i).toString();
\r
1613 // Find out what type of file we have
\r
1614 String mimeType = fileNameMap.getContentTypeFor(url);
\r
1616 // If null returned, we need to guess at the file type
\r
1617 if (mimeType == null)
\r
1618 mimeType = "application/"
\r
1619 + url.substring(url.lastIndexOf(".") + 1);
\r
1621 // Check if we have an image or some other type of file
\r
1622 if (url.substring(0, 5).equalsIgnoreCase("file:")
\r
1623 && mimeType.substring(0, 5).equalsIgnoreCase("image")) {
\r
1624 handleLocalImageURLPaste(mime, mimeType);
\r
1627 String[] type = mimeType.split("/");
\r
1628 boolean valid = validAttachment(type[1]);
\r
1629 boolean smallEnough = checkFileAttachmentSize(url);
\r
1630 if (smallEnough && valid
\r
1631 && url.substring(0, 5).equalsIgnoreCase("file:")
\r
1632 && !mimeType.substring(0, 5).equalsIgnoreCase("image")) {
\r
1633 handleLocalAttachment(mime, mimeType);
\r
1636 browser.page().mainFrame().evaluateJavaScript(
\r
1637 script_start + url + script_end);
\r
1642 // If a URL being pasted is an image URL, then attach the image
\r
1643 private void handleLocalImageURLPaste(QMimeData mime, String mimeType) {
\r
1644 List<QUrl> urlList = mime.urls();
\r
1645 String url = new String();
\r
1646 String script_start_image = new String(
\r
1647 "document.execCommand('insertHtml', false, '");
\r
1648 String script_end = new String("');");
\r
1649 StringBuffer buffer;
\r
1651 // Copy the image over into the resource directory and create a new resource
\r
1652 // record for each url pasted
\r
1653 for (int i = 0; i < urlList.size(); i++) {
\r
1654 url = urlList.get(i).toString();
\r
1656 Resource newRes = createResource(url, i, mimeType, false);
\r
1657 if (newRes == null)
\r
1659 currentNote.getResources().add(newRes);
\r
1660 buffer = new StringBuffer(100);
\r
1662 // Open the file & write the data
\r
1663 String fileName = Global.getFileManager().getResDirPath(newRes.getGuid());
\r
1664 QFile tfile = new QFile(fileName);
\r
1665 tfile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.WriteOnly));
\r
1666 tfile.write(newRes.getData().getBody());
\r
1668 buffer.append(script_start_image);
\r
1669 buffer.append("<img src=\"" + FileUtils.toForwardSlashedPath(fileName));
\r
1670 // if (mimeType.equalsIgnoreCase("image/jpg"))
\r
1671 // mimeType = "image/jpeg";
\r
1672 buffer.append("\" en-tag=\"en-media\" type=\"" + mimeType +"\""
\r
1673 +" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\""
\r
1674 +" guid=\"" +newRes.getGuid() +"\""
\r
1675 +" onContextMenu=\"window.jambi.imageContextMenu('" +tfile.fileName() +"');\""
\r
1677 buffer.append(script_end);
\r
1678 browser.page().mainFrame().evaluateJavaScript(buffer.toString());
\r
1684 // If a URL being pasted is a local file URL, then attach the file
\r
1685 private void handleLocalAttachment(QMimeData mime, String mimeType) {
\r
1686 logger.log(logger.EXTREME, "Attaching local file");
\r
1687 List<QUrl> urlList = mime.urls();
\r
1688 String script_start = new String(
\r
1689 "document.execCommand('insertHtml', false, '");
\r
1690 String script_end = new String("');");
\r
1691 StringBuffer buffer;
\r
1693 String[] type = mimeType.split("/");
\r
1694 String icon = findIcon(type[1]);
\r
1695 if (icon.equals("attachment.png"))
\r
1696 icon = findIcon(type[0]);
\r
1697 buffer = new StringBuffer(100);
\r
1699 for (int i = 0; i < urlList.size(); i++) {
\r
1700 String url = urlList.get(i).toString();
\r
1702 // Start building the HTML
\r
1703 if (icon.equals("attachment.png"))
\r
1704 icon = findIcon(url.substring(url.lastIndexOf(".")+1));
\r
1705 String imageURL = FileUtils.toFileURLString(Global.getFileManager().getImageDirFile(icon));
\r
1707 logger.log(logger.EXTREME, "Creating resource ");
\r
1708 Resource newRes = createResource(url, i, mimeType, true);
\r
1709 if (newRes == null)
\r
1711 logger.log(logger.EXTREME, "New resource size: " +newRes.getData().getSize());
\r
1712 currentNote.getResources().add(newRes);
\r
1714 String fileName = newRes.getGuid() + Global.attachmentNameDelimeter+newRes.getAttributes().getFileName();
\r
1715 // If we have a PDF, we need to setup the preview.
\r
1716 if (icon.equalsIgnoreCase("pdf.png") && Global.pdfPreview()) {
\r
1717 logger.log(logger.EXTREME, "Setting up PDF preview");
\r
1718 if (newRes.getAttributes() != null &&
\r
1719 newRes.getAttributes().getFileName() != null &&
\r
1720 !newRes.getAttributes().getFileName().trim().equals(""))
\r
1721 fileName = newRes.getGuid()+Global.attachmentNameDelimeter+
\r
1722 newRes.getAttributes().getFileName();
\r
1724 fileName = newRes.getGuid()+".pdf";
\r
1725 QFile file = new QFile(Global.getFileManager().getResDirPath(fileName));
\r
1726 QFile.OpenMode mode = new QFile.OpenMode();
\r
1727 mode.set(QFile.OpenModeFlag.WriteOnly);
\r
1729 QDataStream out = new QDataStream(file);
\r
1730 // Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(newRes.getGuid(), true);
\r
1731 QByteArray binData = new QByteArray(newRes.getData().getBody());
\r
1732 // resBinary = null;
\r
1733 out.writeBytes(binData.toByteArray());
\r
1736 PDFPreview pdfPreview = new PDFPreview();
\r
1737 if (pdfPreview.setupPreview(Global.getFileManager().getResDirPath(fileName), "pdf",0)) {
\r
1738 // NFC TODO: should this be a 'file://' url like the ones above?
\r
1739 imageURL = file.fileName() + ".png";
\r
1743 logger.log(logger.EXTREME, "Generating link tags");
\r
1744 buffer.delete(0, buffer.length());
\r
1745 buffer.append("<a en-tag=\"en-media\" guid=\"" +newRes.getGuid()+"\" ");
\r
1746 buffer.append(" onContextMenu=\"window.jambi.imageContextMenu('")
\r
1747 .append(Global.getFileManager().getResDirPath(fileName))
\r
1748 .append("');\" "); buffer.append("type=\"" + mimeType + "\" href=\"nnres://" + fileName +"\" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\" >");
\r
1749 buffer.append("<img src=\"" + imageURL + "\" title=\"" +newRes.getAttributes().getFileName());
\r
1750 buffer.append("\"></img>");
\r
1751 buffer.append("</a>");
\r
1752 browser.page().mainFrame().evaluateJavaScript(
\r
1753 script_start + buffer.toString() + script_end);
\r
1758 private Resource createResource(String url, int sequence, String mime, boolean attachment) {
\r
1759 logger.log(logger.EXTREME, "Inside create resource");
\r
1760 QFile resourceFile;
\r
1761 String urlTest = new QUrl(url).toLocalFile();
\r
1762 if (!urlTest.equals(""))
\r
1764 url = url.replace("/", File.separator);
\r
1765 resourceFile = new QFile(url);
\r
1766 resourceFile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly));
\r
1767 byte[] fileData = resourceFile.readAll().toByteArray();
\r
1768 resourceFile.close();
\r
1769 if (fileData.length == 0)
\r
1773 md = MessageDigest.getInstance("MD5");
\r
1774 md.update(fileData);
\r
1775 byte[] hash = md.digest();
\r
1777 Resource r = new Resource();
\r
1778 Calendar time = new GregorianCalendar();
\r
1779 long prevTime = time.getTimeInMillis();
\r
1780 while (prevTime == time.getTimeInMillis()) {
\r
1781 time = new GregorianCalendar();
\r
1783 r.setGuid(time.getTimeInMillis()+new Integer(sequence).toString());
\r
1784 r.setNoteGuid(currentNote.getGuid());
\r
1786 r.setActive(true);
\r
1787 r.setUpdateSequenceNum(0);
\r
1788 r.setWidth((short) 0);
\r
1789 r.setHeight((short) 0);
\r
1790 r.setDuration((short) 0);
\r
1792 Data d = new Data();
\r
1793 d.setBody(fileData);
\r
1794 d.setBodyIsSet(true);
\r
1795 d.setBodyHash(hash);
\r
1796 d.setBodyHashIsSet(true);
\r
1798 d.setSize(fileData.length);
\r
1800 int fileNamePos = url.lastIndexOf(File.separator);
\r
1801 if (fileNamePos == -1)
\r
1802 fileNamePos = url.lastIndexOf("/");
\r
1803 String fileName = url.substring(fileNamePos+1);
\r
1804 ResourceAttributes a = new ResourceAttributes();
\r
1806 a.setAltitudeIsSet(false);
\r
1807 a.setLongitude(0);
\r
1808 a.setLongitudeIsSet(false);
\r
1810 a.setLatitudeIsSet(false);
\r
1811 a.setCameraMake("");
\r
1812 a.setCameraMakeIsSet(false);
\r
1813 a.setCameraModel("");
\r
1814 a.setCameraModelIsSet(false);
\r
1815 a.setAttachment(attachment);
\r
1816 a.setAttachmentIsSet(true);
\r
1817 a.setClientWillIndex(false);
\r
1818 a.setClientWillIndexIsSet(true);
\r
1819 a.setRecoType("");
\r
1820 a.setRecoTypeIsSet(false);
\r
1821 a.setSourceURL(url);
\r
1822 a.setSourceURLIsSet(true);
\r
1823 a.setTimestamp(0);
\r
1824 a.setTimestampIsSet(false);
\r
1825 a.setFileName(fileName);
\r
1826 a.setFileNameIsSet(true);
\r
1827 r.setAttributes(a);
\r
1829 conn.getNoteTable().noteResourceTable.saveNoteResource(r, true);
\r
1831 } catch (NoSuchAlgorithmException e1) {
\r
1832 e1.printStackTrace();
\r
1838 // find the appropriate icon for an attachment
\r
1839 private String findIcon(String appl) {
\r
1840 appl = appl.toLowerCase();
\r
1841 File f = Global.getFileManager().getImageDirFile(appl + ".png");
\r
1843 return appl+".png";
\r
1844 return "attachment.png";
\r
1847 // Check if the account supports this type of attachment
\r
1848 private boolean validAttachment(String type) {
\r
1849 if (Global.isPremium())
\r
1851 if (type.equalsIgnoreCase("JPG"))
\r
1853 if (type.equalsIgnoreCase("PNG"))
\r
1855 if (type.equalsIgnoreCase("GIF"))
\r
1857 if (type.equalsIgnoreCase("MP3"))
\r
1859 if (type.equalsIgnoreCase("WAV"))
\r
1861 if (type.equalsIgnoreCase("AMR"))
\r
1863 if (type.equalsIgnoreCase("PDF"))
\r
1865 String error = tr("Non-premium accounts can only attach JPG, PNG, GIF, MP3, WAV, AMR, or PDF files.");
\r
1866 QMessageBox.information(this, tr("Non-Premium Account"), error);
\r
1871 // Check the file attachment to be sure it isn't over 25 mb
\r
1872 private boolean checkFileAttachmentSize(String url) {
\r
1873 String fileName = url.substring(8);
\r
1874 QFile resourceFile = new QFile(fileName);
\r
1875 resourceFile.open(new QIODevice.OpenMode(
\r
1876 QIODevice.OpenModeFlag.ReadOnly));
\r
1877 long size = resourceFile.size();
\r
1878 resourceFile.close();
\r
1879 size = size / 1024 / 1024;
\r
1880 if (size < 50 && Global.isPremium())
\r
1885 String error = tr("A file attachment may not exceed 25MB.");
\r
1886 QMessageBox.information(this, tr("Attachment Size"), error);
\r
1891 @SuppressWarnings("unused")
\r
1892 private void createdChanged() {
\r
1893 QDateTime dt = new QDateTime();
\r
1894 dt.setDate(createdDate.date());
\r
1895 dt.setTime(createdTime.time());
\r
1896 noteSignal.createdDateChanged.emit(currentNote.getGuid(), dt);
\r
1900 @SuppressWarnings("unused")
\r
1901 private void alteredChanged() {
\r
1902 QDateTime dt = new QDateTime();
\r
1903 dt.setDate(alteredDate.date());
\r
1904 dt.setTime(alteredTime.time());
\r
1905 noteSignal.alteredDateChanged.emit(currentNote.getGuid(), dt);
\r
1908 @SuppressWarnings("unused")
\r
1909 private void subjectDateTimeChanged() {
\r
1910 QDateTime dt = new QDateTime();
\r
1911 dt.setDate(subjectDate.date());
\r
1912 dt.setTime(subjectTime.time());
\r
1913 noteSignal.subjectDateChanged.emit(currentNote.getGuid(), dt);
\r
1917 @SuppressWarnings("unused")
\r
1918 private void sourceUrlChanged() {
\r
1919 noteSignal.sourceUrlChanged.emit(currentNote.getGuid(), urlText.text());
\r
1922 @SuppressWarnings("unused")
\r
1923 private void authorChanged() {
\r
1924 noteSignal.authorChanged.emit(currentNote.getGuid(), authorText.text());
\r
1927 @SuppressWarnings("unused")
\r
1928 private void geoBoxChanged() {
\r
1929 int index = geoBox.currentIndex();
\r
1930 geoBox.setCurrentIndex(0);
\r
1932 GeoDialog box = new GeoDialog();
\r
1933 box.setLongitude(currentNote.getAttributes().getLongitude());
\r
1934 box.setLatitude(currentNote.getAttributes().getLatitude());
\r
1935 box.setAltitude(currentNote.getAttributes().getAltitude());
\r
1937 if (!box.okPressed())
\r
1939 double alt = box.getAltitude();
\r
1940 double lat = box.getLatitude();
\r
1941 double lon = box.getLongitude();
\r
1942 if (alt != currentNote.getAttributes().getAltitude() ||
\r
1943 lon != currentNote.getAttributes().getLongitude() ||
\r
1944 lat != currentNote.getAttributes().getLatitude()) {
\r
1945 noteSignal.geoChanged.emit(currentNote.getGuid(), lon, lat, alt);
\r
1946 currentNote.getAttributes().setAltitude(alt);
\r
1947 currentNote.getAttributes().setLongitude(lon);
\r
1948 currentNote.getAttributes().setLatitude(lat);
\r
1953 noteSignal.geoChanged.emit(currentNote.getGuid(), 0.0, 0.0, 0.0);
\r
1954 currentNote.getAttributes().setAltitude(0.0);
\r
1955 currentNote.getAttributes().setLongitude(0.0);
\r
1956 currentNote.getAttributes().setLatitude(0.0);
\r
1959 if (index == 3 || index == 0) {
\r
1960 QDesktopServices.openUrl(new QUrl("http://maps.google.com/maps?z=6&q="+currentNote.getAttributes().getLatitude() +"," +currentNote.getAttributes().getLongitude()));
\r
1964 // ************************************************************
\r
1965 // * User chose to save an attachment. Pares out the request *
\r
1966 // * into a guid & file. Save the result. *
\r
1967 // ************************************************************
\r
1968 public void downloadAttachment(QNetworkRequest request) {
\r
1970 QFileDialog fd = new QFileDialog(this);
\r
1971 fd.setFileMode(FileMode.AnyFile);
\r
1972 fd.setConfirmOverwrite(true);
\r
1973 fd.setWindowTitle(tr("Save File"));
\r
1974 fd.setAcceptMode(AcceptMode.AcceptSave);
\r
1975 fd.setDirectory(System.getProperty("user.home"));
\r
1976 String name = request.url().toString();
\r
1978 int pos = name.lastIndexOf(Global.attachmentNameDelimeter);
\r
1980 guid = name.substring(0, pos).replace("nnres://", "");
\r
1981 name = name.substring(pos +Global.attachmentNameDelimeter.length());
\r
1982 fd.selectFile(name);
\r
1983 pos = name.lastIndexOf('.');
\r
1985 String mimeType = "(*." + name.substring(pos + 1)
\r
1986 + ");; All Files (*)";
\r
1987 fd.setFilter(tr(mimeType));
\r
1993 // Strip URL prefix and base dir
\r
1994 guid = guid.replace("nnres://", "")
\r
1995 .replace(FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath()), "");
\r
1997 pos = guid.lastIndexOf('.');
\r
1999 guid = guid.substring(0,pos);
\r
2000 if (fd.exec() != 0 && fd.selectedFiles().size() > 0) {
\r
2001 name = name.replace('\\', '/');
\r
2002 Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);
\r
2003 QFile saveFile = new QFile(fd.selectedFiles().get(0));
\r
2004 QFile.OpenMode mode = new QFile.OpenMode();
\r
2005 mode.set(QFile.OpenModeFlag.WriteOnly);
\r
2006 saveFile.open(mode);
\r
2007 QDataStream saveOut = new QDataStream(saveFile);
\r
2008 QByteArray binData = new QByteArray(resBinary.getData().getBody());
\r
2009 saveOut.writeBytes(binData.toByteArray());
\r
2016 // ************************************************************
\r
2017 // * User chose to save an attachment. Pares out the request *
\r
2018 // * into a guid & file. Save the result. --- DONE FROM downloadAttachment now!!!!!
\r
2019 // ************************************************************
\r
2020 // NFC TODO: unused? remove
\r
2021 public void downloadImage(QNetworkRequest request) {
\r
2022 QFileDialog fd = new QFileDialog(this);
\r
2023 fd.setFileMode(FileMode.AnyFile);
\r
2024 fd.setConfirmOverwrite(true);
\r
2025 fd.setWindowTitle(tr("Save File"));
\r
2026 fd.setAcceptMode(AcceptMode.AcceptSave);
\r
2027 fd.setDirectory(System.getProperty("user.home"));
\r
2028 String name = request.url().toString();
\r
2029 name = name.replace("nnres://", "");
\r
2030 String dPath = FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath());
\r
2031 name = name.replace(dPath, "");
\r
2032 int pos = name.lastIndexOf('.');
\r
2033 String guid = name;
\r
2035 String mimeType = "(*." + name.substring(pos + 1)
\r
2036 + ");; All Files (*)";
\r
2037 fd.setFilter(tr(mimeType));
\r
2038 guid = guid.substring(0,pos);
\r
2040 pos = name.lastIndexOf(Global.attachmentNameDelimeter);
\r
2042 guid = name.substring(0, pos);
\r
2043 fd.selectFile(name.substring(pos+Global.attachmentNameDelimeter.length()));
\r
2045 if (fd.exec() != 0 && fd.selectedFiles().size() > 0) {
\r
2046 Resource resBinary = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);
\r
2047 String fileName = fd.selectedFiles().get(0);
\r
2048 QFile saveFile = new QFile(fileName);
\r
2049 QFile.OpenMode mode = new QFile.OpenMode();
\r
2050 mode.set(QFile.OpenModeFlag.WriteOnly);
\r
2051 saveFile.open(mode);
\r
2052 QDataStream saveOut = new QDataStream(saveFile);
\r
2053 QByteArray binData = new QByteArray(resBinary.getData().getBody());
\r
2054 saveOut.writeBytes(binData.toByteArray());
\r
2060 // *************************************************************
\r
2061 // * decrypt any hidden text. We could do an XML parse, but
\r
2062 // * it is quicker here just to scan for an <img tag & do the fix
\r
2063 // * the manual way
\r
2064 // *************************************************************
\r
2065 private void removeEncryption(String id, String plainText, boolean permanent, String slot) {
\r
2067 plainText = " <en-crypt-temp slot=\""+slot +"\">" +plainText+"</en-crypt-temp> ";
\r
2070 String html = browser.page().mainFrame().toHtml();
\r
2071 String text = html;
\r
2072 int imagePos = html.indexOf("<img");
\r
2074 for ( ;imagePos>0; ) {
\r
2075 // Find the end tag
\r
2076 endPos = text.indexOf(">", imagePos);
\r
2077 String tag = text.substring(imagePos-1,endPos);
\r
2078 if (tag.indexOf("id=\""+id+"\"") > -1) {
\r
2079 text = text.substring(0,imagePos) +plainText+text.substring(endPos+1);
\r
2081 browser.setContent(new QByteArray(text));
\r
2084 imagePos = text.indexOf("<img", imagePos+1);
\r
2089 //****************************************************************
\r
2090 //* Focus shortcuts
\r
2091 //****************************************************************
\r
2092 @SuppressWarnings("unused")
\r
2093 private void focusTitle() {
\r
2094 titleLabel.setFocus();
\r
2096 @SuppressWarnings("unused")
\r
2097 private void focusTag() {
\r
2098 tagEdit.setFocus();
\r
2100 @SuppressWarnings("unused")
\r
2101 private void focusNote() {
\r
2102 browser.setFocus();
\r
2104 @SuppressWarnings("unused")
\r
2105 private void focusAuthor() {
\r
2106 authorLabel.setFocus();
\r
2108 @SuppressWarnings("unused")
\r
2109 private void focusUrl() {
\r
2110 urlLabel.setFocus();
\r
2114 //*****************************************************************
\r
2115 //* Set the document background color
\r
2116 //*****************************************************************
\r
2117 public void setBackgroundColor(String color) {
\r
2118 String js = "function changeBackground(color) {"
\r
2119 +"document.body.style.background = color;"
\r
2121 +"changeBackground('" +color+"');";
\r
2122 browser.page().mainFrame().evaluateJavaScript(js);
\r
2127 //****************************************************************
\r
2128 //* MicroFocus changed
\r
2129 //****************************************************************
\r
2130 private void microFocusChanged() {
\r
2131 boldButton.setDown(false);
\r
2132 italicButton.setDown(false);
\r
2133 underlineButton.setDown(false);
\r
2134 browser.openAction.setEnabled(false);
\r
2135 browser.downloadAttachment.setEnabled(false);
\r
2136 browser.downloadImage.setEnabled(false);
\r
2137 browser.rotateImageLeft.setEnabled(false);
\r
2138 browser.rotateImageRight.setEnabled(false);
\r
2139 browser.insertTableAction.setEnabled(true);
\r
2140 browser.insertTableRowAction.setEnabled(false);
\r
2141 browser.deleteTableRowAction.setEnabled(false);
\r
2142 browser.insertLinkAction.setText(tr("Insert Hyperlink"));
\r
2143 currentHyperlink ="";
\r
2144 insideList = false;
\r
2145 forceTextPaste = false;
\r
2147 String js = new String( "function getCursorPos() {"
\r
2149 +"if (window.getSelection) {"
\r
2150 +" var selObj = window.getSelection();"
\r
2151 +" var selRange = selObj.getRangeAt(0);"
\r
2152 +" var workingNode = window.getSelection().anchorNode.parentNode;"
\r
2153 +" while(workingNode != null) { "
\r
2154 // +" window.jambi.printNode(workingNode.nodeName);"
\r
2155 +" if (workingNode.nodeName=='EN-CRYPT-TEMP') window.jambi.forceTextPaste();"
\r
2156 +" if (workingNode.nodeName=='B') window.jambi.boldActive();"
\r
2157 +" if (workingNode.nodeName=='I') window.jambi.italicActive();"
\r
2158 +" if (workingNode.nodeName=='U') window.jambi.underlineActive();"
\r
2159 +" if (workingNode.nodeName=='UL') window.jambi.setInsideList();"
\r
2160 +" if (workingNode.nodeName=='OL') window.jambi.setInsideList();"
\r
2161 +" if (workingNode.nodeName=='LI') window.jambi.setInsideList();"
\r
2162 +" if (workingNode.nodeName=='TBODY') window.jambi.setInsideTable();"
\r
2163 +" 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
2164 +" if (workingNode.nodeName=='SPAN') {"
\r
2165 +" if (workingNode.getAttribute('style') == 'text-decoration: underline;') window.jambi.underlineActive();"
\r
2167 +" workingNode = workingNode.parentNode;"
\r
2170 +"} getCursorPos();");
\r
2171 browser.page().mainFrame().evaluateJavaScript(js);
\r
2174 public void printNode(String n) {
\r
2175 System.out.println("Node Vaule: " +n);
\r
2179 //****************************************************************
\r
2180 //* Insert a table row
\r
2181 //****************************************************************
\r
2182 public void insertTableRow() {
\r
2184 String js = new String( "function insertTableRow() {"
\r
2185 +" var selObj = window.getSelection();"
\r
2186 +" var selRange = selObj.getRangeAt(0);"
\r
2187 +" var workingNode = window.getSelection().anchorNode.parentNode;"
\r
2188 +" var cellCount = 0;"
\r
2189 +" while(workingNode != null) { "
\r
2190 +" if (workingNode.nodeName.toLowerCase()=='tr') {"
\r
2191 +" row = document.createElement('TR');"
\r
2192 +" var nodes = workingNode.getElementsByTagName('td');"
\r
2193 +" for (j=0; j<nodes.length; j=j+1) {"
\r
2194 +" cell = document.createElement('TD');"
\r
2195 +" cell.innerHTML=' ';"
\r
2196 +" row.appendChild(cell);"
\r
2198 +" workingNode.parentNode.insertBefore(row,workingNode.nextSibling);"
\r
2201 +" workingNode = workingNode.parentNode;"
\r
2203 +"} insertTableRow();");
\r
2204 browser.page().mainFrame().evaluateJavaScript(js);
\r
2207 //****************************************************************
\r
2208 //* Insert a table row
\r
2209 //****************************************************************
\r
2210 public void deleteTableRow() {
\r
2212 String js = new String( "function deleteTableRow() {"
\r
2213 +" var selObj = window.getSelection();"
\r
2214 +" var selRange = selObj.getRangeAt(0);"
\r
2215 +" var workingNode = window.getSelection().anchorNode.parentNode;"
\r
2216 +" var cellCount = 0;"
\r
2217 +" while(workingNode != null) { "
\r
2218 +" if (workingNode.nodeName.toLowerCase()=='tr') {"
\r
2219 +" workingNode.parentNode.removeChild(workingNode);"
\r
2222 +" workingNode = workingNode.parentNode;"
\r
2224 +"} deleteTableRow();");
\r
2225 browser.page().mainFrame().evaluateJavaScript(js);
\r
2228 public void setInsideTable() {
\r
2229 browser.insertTableRowAction.setEnabled(true);
\r
2230 browser.deleteTableRowAction.setEnabled(true);
\r
2231 browser.insertTableAction.setEnabled(false);
\r
2232 browser.encryptAction.setEnabled(false);
\r
2235 public void setInsideLink(String link) {
\r
2236 browser.insertLinkAction.setText(tr("Edit Hyperlink"));
\r
2237 currentHyperlink = link;
\r
2240 public void italicActive() {
\r
2241 italicButton.setDown(true);
\r
2243 public void boldActive() {
\r
2244 boldButton.setDown(true);
\r
2246 public void underlineActive() {
\r
2247 underlineButton.setDown(true);
\r
2249 public void forceTextPaste() {
\r
2250 forceTextPaste = true;
\r
2252 public void imageContextMenu(String f) {
\r
2253 browser.downloadImage.setEnabled(true);
\r
2254 browser.rotateImageRight.setEnabled(true);
\r
2255 browser.rotateImageLeft.setEnabled(true);
\r
2256 browser.openAction.setEnabled(true);
\r
2259 public void rotateImageRight() {
\r
2260 QWebSettings.setMaximumPagesInCache(0);
\r
2261 QWebSettings.setObjectCacheCapacities(0, 0, 0);
\r
2262 QImage image = new QImage(selectedFile);
\r
2263 QMatrix matrix = new QMatrix();
\r
2264 matrix.rotate( 90.0 );
\r
2265 image = image.transformed(matrix);
\r
2266 image.save(selectedFile);
\r
2267 QWebSettings.setMaximumPagesInCache(0);
\r
2268 QWebSettings.setObjectCacheCapacities(0, 0, 0);
\r
2269 browser.setHtml(browser.page().mainFrame().toHtml());
\r
2272 // resourceSignal.contentChanged.emit(selectedFile);
\r
2275 public void rotateImageLeft() {
\r
2276 QImage image = new QImage(selectedFile);
\r
2277 QMatrix matrix = new QMatrix();
\r
2278 matrix.rotate( -90.0 );
\r
2279 image = image.transformed(matrix);
\r
2280 image.save(selectedFile);
\r
2281 browser.setHtml(browser.page().mainFrame().toHtml());
\r
2284 // resourceSignal.contentChanged.emit(selectedFile);
\r
2286 public void resourceContextMenu(String f) {
\r
2287 browser.downloadAttachment.setEnabled(true);
\r
2288 browser.openAction.setEnabled(true);
\r
2293 //****************************************************************
\r
2294 //* Apply CSS style to specified word
\r
2295 //****************************************************************
\r
2296 /* public void applyStyleToWords(String word, String style) {
\r
2297 QFile script = new QFile("D:\\NeverNote\\js\\hilight1.js");
\r
2298 script.open(OpenModeFlag.ReadOnly);
\r
2299 String s = script.readAll().toString();
\r
2300 String js = new String(s +" findit('"+word+"', '"+style+"');");
\r
2301 browser.page().mainFrame().evaluateJavaScript(js);
\r
2302 System.out.println(getContent());
\r
2305 //****************************************************************
\r
2306 //* Someone tried to paste a resource between notes, so we need *
\r
2307 //* to do some special handling. *
\r
2308 //****************************************************************
\r
2309 private String fixInternotePaste(String text) {
\r
2310 logger.log(logger.EXTREME, "Fixing internote paste");
\r
2311 String returnValue = fixInternotePasteSearch(text, "<img", "src=\"");
\r
2312 return fixInternotePasteSearch(returnValue, "<a", "href=\"nnres://");
\r
2314 private String fixInternotePasteSearch(String text, String type, String locTag) {
\r
2316 // First, let's fix the images.
\r
2317 int startPos = text.indexOf(type);
\r
2319 for (; startPos>=0;) {
\r
2320 endPos = text.indexOf(">", startPos+1);
\r
2321 String segment = text.substring(startPos, endPos);
\r
2322 if (segment.indexOf("en-tag") > -1) {
\r
2323 String newSegment = segment;
\r
2325 int guidStartPos = segment.indexOf("guid=\"");
\r
2326 int guidEndPos = segment.indexOf("\"", guidStartPos+7);
\r
2327 String guid = segment.substring(guidStartPos+6,guidEndPos);
\r
2329 int mimeStartPos = segment.indexOf("type");
\r
2330 int mimeEndPos = segment.indexOf("\"", mimeStartPos+7);
\r
2331 String mime = segment.substring(mimeStartPos+6,mimeEndPos);
\r
2333 int srcStartPos = segment.indexOf("src");
\r
2334 int srcEndPos = segment.indexOf("\"", srcStartPos+6);
\r
2335 String src = segment.substring(srcStartPos+5,srcEndPos);
\r
2337 Calendar currentTime = new GregorianCalendar();
\r
2338 Long l = new Long(currentTime.getTimeInMillis());
\r
2339 long prevTime = l;
\r
2340 while (l==prevTime) {
\r
2341 currentTime = new GregorianCalendar();
\r
2342 l= new Long(currentTime.getTimeInMillis());
\r
2345 Resource r = conn.getNoteTable().noteResourceTable.getNoteResource(guid, true);
\r
2346 // if r==null, then the image doesn't exist (it was probably cut out of another note, so
\r
2347 // we need to recereate it
\r
2349 r = createResource(src, 1, mime, false);
\r
2353 String randint = new String(Long.toString(l));
\r
2354 String extension = null;
\r
2355 if (r.getMime()!= null) {
\r
2356 extension = r.getMime().toLowerCase();
\r
2357 if (extension.indexOf("/")>-1)
\r
2358 extension = extension.substring(extension.indexOf("/")+1);
\r
2360 String newFile = randint;
\r
2361 if (r.getAttributes().getFileName() != null && r.getAttributes().getFileName() != "")
\r
2362 if (!locTag.startsWith("src"))
\r
2363 newFile = newFile+Global.attachmentNameDelimeter+r.getAttributes().getFileName();
\r
2364 r.setNoteGuid(currentNote.getGuid());
\r
2366 r.setGuid(randint);
\r
2367 conn.getNoteTable().noteResourceTable.saveNoteResource(r, true);
\r
2368 QFile f = new QFile(Global.getFileManager().getResDirPath(newFile));
\r
2369 QByteArray bin = new QByteArray(r.getData().getBody());
\r
2370 f.open(QFile.OpenModeFlag.WriteOnly);
\r
2373 newSegment = newSegment.replace("guid=\""+guid, "guid=\""+randint);
\r
2374 currentNote.getResources().add(r);
\r
2376 int startSrcPos = newSegment.indexOf(locTag);
\r
2377 int endSrcPos = newSegment.indexOf("\"",startSrcPos+locTag.length()+1);
\r
2379 if (locTag.startsWith("src")) {
\r
2380 source = newSegment.substring(startSrcPos+locTag.length(),endSrcPos);
\r
2381 newSegment = newSegment.replace(source,
\r
2382 FileUtils.toForwardSlashedPath(Global.getFileManager().getResDirPath(newFile)));
\r
2384 source = newSegment.substring(startSrcPos+locTag.length(),endSrcPos);
\r
2385 newSegment = newSegment.replace(source, newFile);
\r
2388 text = text.substring(0,startPos) + newSegment + text.substring(endPos);
\r
2390 startPos = text.indexOf(type, startPos+1);
\r
2396 public void nextPage(String file) {
\r
2397 logger.log(logger.EXTREME, "Starting nextPage()");
\r
2399 Integer pageNumber;
\r
2400 if (previewPageList.containsKey(file))
\r
2401 pageNumber = previewPageList.get(file)+1;
\r
2404 previewPageList.remove(file);
\r
2405 previewPageList.put(file, pageNumber);
\r
2406 PDFPreview pdfPreview = new PDFPreview();
\r
2407 boolean goodPreview = pdfPreview.setupPreview(file, "pdf", pageNumber);
\r
2408 if (goodPreview) {
\r
2410 // String html = getContent();
\r
2411 QWebSettings.setMaximumPagesInCache(0);
\r
2412 QWebSettings.setObjectCacheCapacities(0, 0, 0);
\r
2413 // browser.setContent(new QByteArray());
\r
2414 browser.setHtml(browser.page().mainFrame().toHtml());
\r
2416 // browser.setContent(new QByteArray(html));
\r
2417 // browser.triggerPageAction(WebAction.Reload);
\r
2418 // pdfMouseOver(selectedFile);
\r
2422 public void previousPage(String file) {
\r
2423 logger.log(logger.EXTREME, "Starting previousPage()");
\r
2425 Integer pageNumber;
\r
2426 if (previewPageList.containsKey(file))
\r
2427 pageNumber = previewPageList.get(file)-1;
\r
2430 previewPageList.remove(file);
\r
2431 previewPageList.put(file, pageNumber);
\r
2432 PDFPreview pdfPreview = new PDFPreview();
\r
2433 boolean goodPreview = pdfPreview.setupPreview(file, "pdf", pageNumber);
\r
2434 if (goodPreview) {
\r
2436 // String html = getContent();
\r
2437 QWebSettings.setMaximumPagesInCache(0);
\r
2438 QWebSettings.setObjectCacheCapacities(0, 0, 0);
\r
2439 browser.setHtml(browser.page().mainFrame().toHtml());
\r
2441 // browser.setContent(new QByteArray(html));
\r
2442 // browser.triggerPageAction(WebAction.Reload);
\r
2446 /* public void pdfMouseOver(String name) {
\r
2448 if (previewPageList.containsKey(selectedFile))
\r
2449 pageNumber = previewPageList.get(selectedFile)+1;
\r
2453 if (pageNumber <= 1)
\r
2454 browser.previousPageAction.setEnabled(false);
\r
2456 browser.previousPageAction.setEnabled(true);
\r
2458 PDFPreview pdf = new PDFPreview();
\r
2459 int totalPages = pdf.getPageCount(name);
\r
2460 if (previewPageList.containsKey(selectedFile))
\r
2461 pageNumber = previewPageList.get(selectedFile)+1;
\r
2464 if (totalPages > pageNumber)
\r
2465 browser.nextPageAction.setEnabled(true);
\r
2467 browser.nextPageAction.setEnabled(false);
\r
2471 public void pdfMouseOut() {
\r
2472 // browser.nextPageAction.setVisible(false);
\r
2473 // browser.previousPageAction.setVisible(false);
\r