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
19 package cx.fbn.nevernote.gui;
\r
21 import com.trolltech.qt.core.QEvent;
\r
22 import com.trolltech.qt.core.QMimeData;
\r
23 import com.trolltech.qt.core.Qt;
\r
24 import com.trolltech.qt.gui.QAction;
\r
25 import com.trolltech.qt.gui.QContextMenuEvent;
\r
26 import com.trolltech.qt.gui.QDropEvent;
\r
27 import com.trolltech.qt.gui.QKeyEvent;
\r
28 import com.trolltech.qt.gui.QKeySequence;
\r
29 import com.trolltech.qt.gui.QKeySequence.StandardKey;
\r
30 import com.trolltech.qt.gui.QMenu;
\r
31 import com.trolltech.qt.gui.QShortcut;
\r
32 import com.trolltech.qt.network.QNetworkRequest;
\r
33 import com.trolltech.qt.webkit.QWebPage;
\r
34 import com.trolltech.qt.webkit.QWebView;
\r
36 import cx.fbn.nevernote.Global;
\r
38 public class ContentView extends QWebView {
\r
40 BrowserWindow parent;
\r
41 QMenu contextMenu = new QMenu(this);
\r
42 QMenu tableMenu = new QMenu(this);
\r
44 QShortcut cutShortcut;
\r
46 QShortcut copyShortcut;
\r
47 QAction pasteAction;
\r
48 QShortcut pasteShortcut;
\r
49 QAction pasteWithoutFormatAction;
\r
50 QShortcut pasteWithoutFormatShortcut;
\r
52 QShortcut todoShortcut;
\r
53 QAction encryptAction;
\r
54 QShortcut encryptShortcut;
\r
55 QAction downloadAttachment;
\r
56 QShortcut downloadAttachmentShortcut;
\r
57 QAction downloadImage;
\r
58 QShortcut downloadImageShortcut;
\r
59 QAction rotateImageRight;
\r
60 QShortcut rotateImageRightShortcut;
\r
61 QAction rotateImageLeft;
\r
62 QShortcut rotateImageLeftShortcut;
\r
63 QAction insertLinkAction;
\r
64 QShortcut insertLinkShortcut;
\r
65 QAction insertLatexAction;
\r
66 QShortcut insertLatexShortcut;
\r
67 QAction insertTableAction;
\r
68 QShortcut insertTableShortcut;
\r
69 QAction insertTableRowAction;
\r
70 QShortcut insertTableRowShortcut;
\r
71 QAction insertTableColumnAction;
\r
72 QShortcut insertTableColumnShortcut;
\r
73 QAction deleteTableRowAction;
\r
74 QShortcut deleteTableRowShortcut;
\r
75 QAction deleteTableColumnAction;
\r
76 QShortcut deleteTableColumnShortcut;
\r
79 QAction redBackgroundColor;
\r
81 QShortcut insertDateTimeShortcut;
\r
83 Signal1<QNetworkRequest> downloadAttachmentRequested;
\r
84 Signal1<QNetworkRequest> downloadImageRequested;
\r
86 public ContentView(BrowserWindow p) {
\r
88 contextMenu = new QMenu(this);
\r
90 openAction = new QAction(tr("Open"), this);
\r
91 openAction.setText(tr("Open"));
\r
92 contextMenu.addAction(openAction);
\r
93 openAction.triggered.connect(parent, "openFile()");
\r
95 cutAction = new QAction(tr("Cut"), this);
\r
96 cutAction.triggered.connect(parent, "cutClicked()");
\r
97 contextMenu.addAction(cutAction);
\r
98 contextMenu.insertSeparator(cutAction);
\r
99 setupShortcut(cutAction, "Edit_Cut");
\r
100 cutShortcut = new QShortcut(this);
\r
101 cutShortcut.activated.connect(parent, "cutClicked()");
\r
102 setupShortcut(cutShortcut, "Edit_Cut");
\r
104 copyAction = new QAction(tr("Copy"), this);
\r
105 copyAction.triggered.connect(parent, "copyClicked()");
\r
106 contextMenu.addAction(copyAction);
\r
107 setupShortcut(copyAction, "Edit_Copy");
\r
108 copyShortcut = new QShortcut(this);
\r
109 copyShortcut.activated.connect(parent, "copyClicked()");
\r
110 setupShortcut(copyShortcut, "Edit_Copy");
\r
112 pasteAction = pageAction(QWebPage.WebAction.Paste);
\r
113 pasteAction.disconnect();
\r
114 pasteAction.triggered.connect(parent, "pasteClicked()");
\r
116 contextMenu.addAction(pasteAction);
\r
117 setupShortcut(pasteAction, "Edit_Paste");
\r
118 pasteShortcut = new QShortcut(this);
\r
119 pasteShortcut.activated.connect(parent, "pasteClicked()");
\r
120 setupShortcut(pasteShortcut, "Edit_Paste");
\r
122 pasteWithoutFormatAction = new QAction(tr("Paste Without Formatting"), this);
\r
123 pasteWithoutFormatAction.triggered.connect(parent, "pasteWithoutFormattingClicked()");
\r
124 contextMenu.addAction(pasteWithoutFormatAction);
\r
125 setupShortcut(pasteWithoutFormatAction, "Edit_Paste_Without_Formatting");
\r
126 // pasteWithoutFormatShortcut = new QShortcut(this);
\r
127 // pasteWithoutFormatShortcut.activated.connect(parent, "pasteWithoutFormattingClicked()");
\r
128 // setupShortcut(pasteWithoutFormatShortcut, "Edit_Paste_Without_Formatting");
\r
130 contextMenu.addSeparator();
\r
131 QMenu colorMenu = new QMenu(tr("Background Color"));
\r
132 contextMenu.addMenu(colorMenu);
\r
134 colorMenu.addAction(setupColorMenuOption("White"));
\r
135 colorMenu.addAction(setupColorMenuOption("Red"));
\r
136 colorMenu.addAction(setupColorMenuOption("Blue"));
\r
137 colorMenu.addAction(setupColorMenuOption("Green"));
\r
138 colorMenu.addAction(setupColorMenuOption("Yellow"));
\r
139 colorMenu.addAction(setupColorMenuOption("Black"));
\r
140 colorMenu.addAction(setupColorMenuOption("Grey"));
\r
141 colorMenu.addAction(setupColorMenuOption("Purple"));
\r
142 colorMenu.addAction(setupColorMenuOption("Brown"));
\r
143 colorMenu.addAction(setupColorMenuOption("Orange"));
\r
144 colorMenu.addAction(setupColorMenuOption("Powder Blue"));
\r
147 contextMenu.addSeparator();
\r
148 todoAction = new QAction(tr("To-do"), this);
\r
149 todoAction.triggered.connect(parent, "todoClicked()");
\r
150 contextMenu.addAction(todoAction);
\r
151 setupShortcut(todoAction, "Edit_Insert_Todo");
\r
152 contextMenu.insertSeparator(todoAction);
\r
153 todoShortcut = new QShortcut(this);
\r
154 todoShortcut.activated.connect(parent, "todoClicked()");
\r
155 setupShortcut(todoShortcut, "Edit_Insert_Todo");
\r
157 encryptAction = new QAction(tr("Encrypt Selected Text"), this);
\r
158 encryptAction.triggered.connect(parent, "encryptText()");
\r
159 contextMenu.addAction(encryptAction);
\r
160 contextMenu.insertSeparator(encryptAction);
\r
161 setupShortcut(encryptAction, "Edit_Encrypt_Text");
\r
162 encryptAction.setEnabled(false);
\r
163 encryptShortcut = new QShortcut(this);
\r
164 encryptShortcut.activated.connect(parent, "encryptText()");
\r
165 setupShortcut(encryptShortcut, "Edit_Encrypt_Text");
\r
167 insertLinkAction = new QAction(tr("Insert Hyperlink"), this);
\r
168 insertLinkAction.triggered.connect(parent, "insertLink()");
\r
169 setupShortcut(insertLinkAction, "Edit_Insert_Hyperlink");
\r
170 contextMenu.addAction(insertLinkAction);
\r
171 insertLinkAction.setEnabled(false);
\r
172 insertLinkShortcut = new QShortcut(this);
\r
173 setupShortcut(insertLinkShortcut, "Edit_Insert_Hyperlink");
\r
174 insertLinkShortcut.activated.connect(parent, "insertLink()");
\r
176 insertLatexAction = new QAction(tr("Insert LaTeX Formula"), this);
\r
177 insertLatexAction.triggered.connect(parent, "insertLatex()");
\r
178 setupShortcut(insertLatexAction, "Insert_Latex");
\r
179 contextMenu.addAction(insertLatexAction);
\r
180 insertLatexShortcut = new QShortcut(this);
\r
181 setupShortcut(insertLatexShortcut, "Latex_Insert");
\r
182 insertLatexShortcut.activated.connect(parent, "insertLatex()");
\r
184 contextMenu.addMenu(tableMenu);
\r
185 tableMenu.setTitle("Table");
\r
186 insertTableAction = new QAction(tr("Insert Table"), this);
\r
187 insertTableAction.triggered.connect(parent, "insertTable()");
\r
188 setupShortcut(insertTableAction, "Edit_Insert_Table");
\r
189 tableMenu.addAction(insertTableAction);
\r
190 insertTableShortcut = new QShortcut(this);
\r
191 setupShortcut(insertTableShortcut, "Edit_Insert_Table");
\r
192 insertTableShortcut.activated.connect(parent, "insertTable()");
\r
194 insertTableRowAction = new QAction(tr("Insert Row"), this);
\r
195 insertTableRowAction.triggered.connect(parent, "insertTableRow()");
\r
196 setupShortcut(insertTableRowAction, "Edit_Insert_Table_Row");
\r
197 tableMenu.addAction(insertTableRowAction);
\r
198 insertTableRowShortcut = new QShortcut(this);
\r
199 setupShortcut(insertTableRowShortcut, "Edit_Insert_Table_Row");
\r
200 insertTableRowShortcut.activated.connect(parent, "insertTableRow()");
\r
202 insertTableColumnAction = new QAction(tr("Insert Column"), this);
\r
203 insertTableColumnAction.triggered.connect(parent, "insertTableColumn()");
\r
204 setupShortcut(insertTableColumnAction, "Edit_Insert_Table_Column");
\r
205 tableMenu.addAction(insertTableColumnAction);
\r
206 insertTableColumnShortcut = new QShortcut(this);
\r
207 setupShortcut(insertTableColumnShortcut, "Edit_Insert_Table_Column");
\r
208 insertTableColumnShortcut.activated.connect(parent, "insertTableColumn()");
\r
210 deleteTableRowAction = new QAction(tr("Delete Row"), this);
\r
211 deleteTableRowAction.triggered.connect(parent, "deleteTableRow()");
\r
212 setupShortcut(deleteTableRowAction, "Edit_Delete_Table_Row");
\r
213 tableMenu.addAction(deleteTableRowAction);
\r
214 deleteTableRowShortcut = new QShortcut(this);
\r
215 setupShortcut(deleteTableRowShortcut, "Edit_Delete_Table_Row");
\r
216 deleteTableRowShortcut.activated.connect(parent, "deleteTableRow()");
\r
218 deleteTableColumnAction = new QAction(tr("Delete Column"), this);
\r
219 deleteTableColumnAction.triggered.connect(parent, "deleteTableColumn()");
\r
220 setupShortcut(deleteTableColumnAction, "Edit_Delete_Table_Column");
\r
221 tableMenu.addAction(deleteTableColumnAction);
\r
222 deleteTableColumnShortcut = new QShortcut(this);
\r
223 setupShortcut(deleteTableColumnShortcut, "Edit_Delete_Table_Column");
\r
224 deleteTableColumnShortcut.activated.connect(parent, "deleteTableColumn()");
\r
227 insertDateTimeShortcut = new QShortcut(this);
\r
228 insertDateTimeShortcut.activated.connect(parent, "insertDateTime()");
\r
229 setupShortcut(insertDateTimeShortcut, "Insert_DateTime");
\r
231 QMenu imageMenu = new QMenu();
\r
232 imageMenu.setTitle(tr("Image"));
\r
233 contextMenu.addMenu(imageMenu);
\r
234 downloadImage = pageAction(QWebPage.WebAction.DownloadImageToDisk);
\r
235 downloadImage.setText(tr("Save Image"));
\r
236 imageMenu.addAction(downloadImage);
\r
237 // contextMenu.insertSeparator(downloadImage);
\r
238 // page().downloadRequested.connect(this, "downloadImage(QNetworkRequest)");
\r
239 downloadImageRequested = new Signal1<QNetworkRequest>();
\r
241 rotateImageRight = new QAction(tr("Rotate Right"), this);
\r
242 imageMenu.addAction(rotateImageRight);
\r
243 rotateImageRight.triggered.connect(parent, "rotateImageRight()");
\r
244 rotateImageRightShortcut = new QShortcut(this);
\r
245 setupShortcut(rotateImageRightShortcut, "Edit_Image_Rotate_Right");
\r
246 rotateImageRightShortcut.activated.connect(parent, "rotateImageRight()");
\r
248 rotateImageLeft = new QAction(tr("Rotate Left"), this);
\r
249 imageMenu.addAction(rotateImageLeft);
\r
250 rotateImageLeft.triggered.connect(parent, "rotateImageLeft()");
\r
251 rotateImageLeftShortcut = new QShortcut(this);
\r
252 setupShortcut(rotateImageLeftShortcut, "Edit_Image_Rotate_Left");
\r
253 rotateImageLeftShortcut.activated.connect(parent, "rotateImageLeft()");
\r
255 downloadAttachment = pageAction(QWebPage.WebAction.DownloadLinkToDisk);
\r
256 downloadAttachment.setText(tr("Save Attachment"));
\r
257 contextMenu.addAction(downloadAttachment);
\r
258 page().downloadRequested.connect(this, "downloadAttachment(QNetworkRequest)");
\r
259 downloadAttachmentRequested = new Signal1<QNetworkRequest>();
\r
263 private void setupShortcut(QAction action, String text) {
\r
264 if (!Global.shortcutKeys.containsAction(text))
\r
266 action.setShortcut(Global.shortcutKeys.getShortcut(text));
\r
269 private void setupShortcut(QShortcut action, String text) {
\r
270 if (!Global.shortcutKeys.containsAction(text))
\r
272 action.setKey(new QKeySequence(Global.shortcutKeys.getShortcut(text)));
\r
275 private QAction setupColorMenuOption(String color) {
\r
276 QAction backgroundColor = new QAction(tr(color), this);
\r
277 color = color.replace(" ", "");
\r
278 backgroundColor.triggered.connect(this, "setBackground"+color+"()");
\r
279 return backgroundColor;
\r
283 public boolean event(QEvent event)
\r
285 if (event.type().equals(QEvent.Type.KeyPress)) {
\r
286 QKeyEvent ke = (QKeyEvent) event;
\r
287 if (ke.key() == Qt.Key.Key_Tab.value()) {
\r
288 parent.tabPressed();
\r
292 if (ke.key() == Qt.Key.Key_Backtab.value()) {
\r
293 parent.backtabPressed();
\r
297 return super.event(event);
\r
302 public void keyPressEvent(QKeyEvent e) {
\r
304 // This is done because if we set the content editable, the scroll keys are
\r
305 // ignored by webkit.
\r
306 if (e.key() == Qt.Key.Key_PageUp.value() || e.key() == Qt.Key.Key_PageDown.value()) {
\r
307 int bottom = page().mainFrame().geometry().bottom();
\r
308 int top = page().mainFrame().geometry().top();
\r
309 int scrollValue = top-bottom;
\r
310 if (e.key() == Qt.Key.Key_PageDown.value())
\r
311 scrollValue = -1*scrollValue;
\r
312 page().mainFrame().scroll(0, scrollValue);
\r
315 // This is done to allow proper pasting of resources, otherwise it messes up multiple pastes
\r
316 if (e.matches(StandardKey.Paste)) {
\r
317 parent.pasteClicked();
\r
321 super.keyPressEvent(e);
\r
324 // public void downloadImage(QNetworkRequest req) {
\r
325 // System.out.println(req.url().toString());
\r
326 // downloadImageRequested.emit(req);
\r
328 public void downloadAttachment(QNetworkRequest req) {
\r
329 downloadAttachmentRequested.emit(req);
\r
334 public void dropEvent(QDropEvent e) {
\r
336 QMimeData mime = e.mimeData();
\r
337 parent.handleUrls(mime);
\r
338 parent.contentChanged();
\r
339 // triggerPageAction(WebAction.Reload);
\r
343 public void contextMenuEvent(QContextMenuEvent event) {
\r
345 contextMenu.exec(event.globalPos());
\r
350 @SuppressWarnings("unused")
\r
351 private void setBackgroundWhite() {parent.setBackgroundColor("white");}
\r
352 @SuppressWarnings("unused")
\r
353 private void setBackgroundRed() {parent.setBackgroundColor("red");}
\r
354 @SuppressWarnings("unused")
\r
355 private void setBackgroundBlue() {parent.setBackgroundColor("blue");}
\r
356 @SuppressWarnings("unused")
\r
357 private void setBackgroundGreen() {parent.setBackgroundColor("green");}
\r
358 @SuppressWarnings("unused")
\r
359 private void setBackgroundYellow() {parent.setBackgroundColor("yellow");}
\r
360 @SuppressWarnings("unused")
\r
361 private void setBackgroundBlack() {parent.setBackgroundColor("black");}
\r
362 @SuppressWarnings("unused")
\r
363 private void setBackgroundPurple() {parent.setBackgroundColor("purple");}
\r
364 @SuppressWarnings("unused")
\r
365 private void setBackgroundBrown() {parent.setBackgroundColor("brown");}
\r
366 @SuppressWarnings("unused")
\r
367 private void setBackgroundGrey() {parent.setBackgroundColor("grey");}
\r
368 @SuppressWarnings("unused")
\r
369 private void setBackgroundOrange() {parent.setBackgroundColor("orange");}
\r
370 @SuppressWarnings("unused")
\r
371 private void setBackgroundPowderBlue() {parent.setBackgroundColor("powderblue");}
\r