Moved the editing actions implemented in keyPressEvent into webActionTriggered.
[WebKit-https.git] / WebKit / qt / Api / qwebpage.cpp
1 /*
2     Copyright (C) 2007 Trolltech ASA
3     Copyright (C) 2007 Staikos Computing Services Inc.
4     Copyright (C) 2007 Apple Inc.
5
6     This library is free software; you can redistribute it and/or
7     modify it under the terms of the GNU Library General Public
8     License as published by the Free Software Foundation; either
9     version 2 of the License, or (at your option) any later version.
10
11     This library is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14     Library General Public License for more details.
15
16     You should have received a copy of the GNU Library General Public License
17     along with this library; see the file COPYING.LIB.  If not, write to
18     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19     Boston, MA 02110-1301, USA.
20
21     This class provides all functionality needed for loading images, style sheets and html
22     pages from the web. It has a memory cache for these objects.
23 */
24 #include "config.h"
25 #include "qwebpage.h"
26 #include "qwebframe.h"
27 #include "qwebpage_p.h"
28 #include "qwebframe_p.h"
29 #include "qwebnetworkinterface.h"
30 #include "qwebpagehistory.h"
31 #include "qwebpagehistory_p.h"
32 #include "qwebsettings.h"
33
34 #include "Frame.h"
35 #include "ChromeClientQt.h"
36 #include "ContextMenu.h"
37 #include "ContextMenuClientQt.h"
38 #include "DragClientQt.h"
39 #include "DragController.h"
40 #include "DragData.h"
41 #include "EditorClientQt.h"
42 #include "Settings.h"
43 #include "Page.h"
44 #include "FrameLoader.h"
45 #include "KURL.h"
46 #include "Image.h"
47 #include "IconDatabase.h"
48 #include "InspectorClientQt.h"
49 #include "FocusController.h"
50 #include "Editor.h"
51 #include "PlatformScrollBar.h"
52 #include "PlatformKeyboardEvent.h"
53 #include "PlatformWheelEvent.h"
54 #include "ProgressTracker.h"
55 #include "HitTestResult.h"
56
57 #include <QDebug>
58 #include <QDragEnterEvent>
59 #include <QDragLeaveEvent>
60 #include <QDragMoveEvent>
61 #include <QDropEvent>
62 #include <QFileDialog>
63 #include <QHttpRequestHeader>
64 #include <QInputDialog>
65 #include <QMessageBox>
66 #include <QNetworkProxy>
67 #include <QUndoStack>
68 #include <QUrl>
69 #include <QPainter>
70
71 using namespace WebCore;
72
73 QWebPagePrivate::QWebPagePrivate(QWebPage *qq)
74     : q(qq)
75     , modified(false)
76 {
77     q->setMouseTracking(true);
78     q->setFocusPolicy(Qt::ClickFocus);
79     chromeClient = new ChromeClientQt(q);
80     contextMenuClient = new ContextMenuClientQt();
81     editorClient = new EditorClientQt(q);
82     page = new Page(chromeClient, contextMenuClient, editorClient,
83                     new DragClientQt(q), new InspectorClientQt());
84
85     undoStack = 0;
86     mainFrame = 0;
87     networkInterface = 0;
88     insideOpenCall = false;
89
90     history.d = new QWebPageHistoryPrivate(page->backForwardList());
91 }
92
93 QWebPagePrivate::~QWebPagePrivate()
94 {
95     delete undoStack;
96     delete page;
97 }
98
99 QWebPage::NavigationRequestResponse QWebPagePrivate::navigationRequested(QWebFrame *frame, const QWebNetworkRequest &request, QWebPage::NavigationType type)
100 {
101     if (insideOpenCall
102         && frame == mainFrame)
103         return QWebPage::AcceptNavigationRequest;
104     return q->navigationRequested(frame, request, type);
105 }
106
107 void QWebPagePrivate::createMainFrame()
108 {
109     if (!mainFrame) {
110         QWebFrameData frameData;
111         frameData.ownerElement = 0;
112         frameData.allowsScrolling = true;
113         frameData.marginWidth = 0;
114         frameData.marginHeight = 0;
115         mainFrame = new QWebFrame(q, &frameData);
116         QObject::connect(mainFrame, SIGNAL(titleChanged(const QString&)),
117                 q, SIGNAL(titleChanged(const QString&)));
118         QObject::connect(mainFrame, SIGNAL(hoveringOverLink(const QString&, const QString&)),
119                 q, SIGNAL(hoveringOverLink(const QString&, const QString&)));
120         
121         mainFrame->d->frameView->setFrameGeometry(q->geometry());
122
123         emit q->frameCreated(mainFrame);
124     }
125 }
126
127 QMenu *QWebPagePrivate::createContextMenu(QList<WebCore::ContextMenuItem> *items)
128 {
129     QMenu *menu = new QMenu;
130     for (int i = 0; i < items->count(); ++i) {
131         const ContextMenuItem &item = items->at(i);
132         switch (item.type()) {
133             case WebCore::ActionType:
134                 menu->addAction(item.title());
135                 break;
136             case WebCore::SeparatorType:
137                 menu->addSeparator();
138                 break;
139             case WebCore::SubmenuType: {
140                 QMenu *subMenu = createContextMenu(item.platformSubMenu());
141                 subMenu->setTitle(item.title());
142                 menu->addAction(subMenu->menuAction());
143                 break;
144             }
145         }
146     }
147     return menu;
148 }
149
150 QWebFrame *QWebPagePrivate::frameAt(const QPoint &pos) const
151 {
152     QWebFrame *frame = mainFrame;
153
154 redo:
155     QList<QWebFrame*> children = frame->childFrames();
156     for (int i = 0; i < children.size(); ++i) {
157         if (children.at(i)->geometry().contains(pos)) {
158             frame = children.at(i);
159             goto redo;
160         }
161     }
162     if (frame->geometry().contains(pos))
163         return frame;
164     return 0;
165 }
166
167 QWebPage::QWebPage(QWidget *parent)
168     : QWidget(parent)
169     , d(new QWebPagePrivate(this))
170 {
171     setSettings(QWebSettings::global());
172     QPalette pal = palette();
173     pal.setBrush(QPalette::Background, Qt::white);
174
175     setAttribute(Qt::WA_OpaquePaintEvent);
176
177     setPalette(pal);
178     setAcceptDrops(true);
179     connect(this, SIGNAL(loadProgressChanged(int)), this, SLOT(_q_onLoadProgressChanged(int)));
180 }
181
182 QWebPage::~QWebPage()
183 {
184     FrameLoader *loader = d->mainFrame->d->frame->loader();
185     if (loader)
186         loader->detachFromParent();
187     delete d;
188 }
189
190 void QWebPage::open(const QUrl &url)
191 {
192     open(QWebNetworkRequest(url));
193 }
194
195 void QWebPage::open(const QWebNetworkRequest &req)
196 {
197     d->insideOpenCall = true;
198
199     QUrl url = req.url();
200     QHttpRequestHeader httpHeader = req.httpHeader();
201     QByteArray postData = req.postData();
202
203     WebCore::ResourceRequest request(KURL(url.toString()));
204
205     QString method = httpHeader.method();
206     if (!method.isEmpty())
207         request.setHTTPMethod(method);
208
209     QList<QPair<QString, QString> > values = httpHeader.values();
210     for (int i = 0; i < values.size(); ++i) {
211         const QPair<QString, QString> &val = values.at(i);
212         request.addHTTPHeaderField(val.first, val.second);
213     }
214
215     if (!postData.isEmpty()) {
216         WTF::RefPtr<WebCore::FormData> formData = new WebCore::FormData(postData.constData(), postData.size());
217         request.setHTTPBody(formData);
218     }
219
220     mainFrame()->d->frame->loader()->load(request);
221     d->insideOpenCall = false;
222 }
223
224 QUrl QWebPage::url() const
225 {
226     return QUrl((QString)mainFrame()->d->frame->loader()->url().url());
227 }
228
229 QString QWebPage::title() const
230 {
231     return mainFrame()->title();
232 }
233
234 QWebFrame *QWebPage::mainFrame() const
235 {
236     d->createMainFrame();
237     return d->mainFrame;
238 }
239
240 QSize QWebPage::sizeHint() const
241 {
242     return QSize(800, 600);
243 }
244
245 void QWebPage::stop()
246 {
247     webActionTriggered(Stop);
248 }
249
250 QWebPageHistory *QWebPage::history() const
251 {
252     return &d->history;
253 }
254
255 void QWebPage::goBack()
256 {
257     webActionTriggered(GoBack);
258 }
259
260 void QWebPage::goForward()
261 {
262     webActionTriggered(GoForward);
263 }
264
265 void QWebPage::goToHistoryItem(const QWebHistoryItem &item)
266 {
267     d->page->goToItem(item.d->item, FrameLoadTypeIndexedBackForward);
268 }
269
270 void QWebPage::javaScriptConsoleMessage(const QString& message, unsigned int lineNumber, const QString& sourceID)
271 {
272 }
273
274 void QWebPage::javaScriptAlert(QWebFrame *frame, const QString& msg)
275 {
276     //FIXME frame pos...
277     QMessageBox::information(this, title(), msg, QMessageBox::Ok);
278 }
279
280 bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg)
281 {
282     //FIXME frame pos...
283     return 0 == QMessageBox::information(this, title(), msg, QMessageBox::Yes, QMessageBox::No);
284 }
285
286 bool QWebPage::javaScriptPrompt(QWebFrame *frame, const QString& msg, const QString& defaultValue, QString* result)
287 {
288     //FIXME frame pos...
289     bool ok = false;
290 #ifndef QT_NO_INPUTDIALOG
291     QString x = QInputDialog::getText(this, title(), msg, QLineEdit::Normal, defaultValue, &ok);
292     if (ok && result) {
293         *result = x;
294     }
295 #endif
296     return ok;
297 }
298
299 QWebPage *QWebPage::createWindow()
300 {
301     return 0;
302 }
303
304 QWebPage *QWebPage::createModalDialog()
305 {
306     return 0;
307 }
308
309 QObject *QWebPage::createPlugin(const QString &classid, const QUrl &url, const QStringList &paramNames, const QStringList &paramValues)
310 {
311     Q_UNUSED(classid)
312     Q_UNUSED(url)
313     Q_UNUSED(paramNames)
314     Q_UNUSED(paramValues)
315     return 0;
316 }
317
318 void QWebPage::webActionTriggered(WebAction action, bool checked)
319 {
320     WebCore::Editor *editor = d->page->focusController()->focusedOrMainFrame()->editor();
321     const char *command = 0;
322
323     switch (action) {
324         // ### these need a context...
325         case OpenLinkInNewWindow:
326         case OpenFrameInNewWindow:
327         case DownloadLinkToDisk:
328         case CopyLinkToClipboard:
329         case OpenImageInNewWindow:
330         case DownloadImageToDisk:
331         case CopyImageToClipboard:
332             break;
333         case GoBack:
334             d->page->goBack();
335             break;
336         case GoForward:
337             d->page->goForward();
338             break;
339         case Stop:
340             mainFrame()->d->frame->loader()->stopForUserCancel();
341             break;
342         case Reload:
343             mainFrame()->d->frame->loader()->reload();
344             break;
345         case Cut:
346             editor->cut();
347             break;
348         case Copy:
349             editor->copy();
350             break;
351         case Paste:
352             editor->paste();
353             break;
354
355         case Undo:
356             editor->undo();
357             break;
358         case Redo:
359             editor->redo();
360             break;
361
362         case MoveToNextChar:
363             command = "MoveForward";
364             break;
365         case MoveToPreviousChar:
366             command = "MoveBackward";
367             break;
368         case MoveToNextWord:
369             command = "MoveWordForward";
370             break;
371         case MoveToPreviousWord:
372             command = "MoveWordBackward";
373             break;
374         case MoveToNextLine:
375             command = "MoveDown";
376             break;
377         case MoveToPreviousLine:
378             command = "MoveUp";
379             break;
380         case MoveToStartOfLine:
381             command = "MoveToBeginningOfLine";
382             break;
383         case MoveToEndOfLine:
384             command = "MoveToEndOfLine";
385             break;
386         case MoveToStartOfBlock:
387             command = "MoveToBeginningOfParagraph";
388             break;
389         case MoveToEndOfBlock:
390             command = "MoveToEndOfParagraph";
391             break;
392         case MoveToStartOfDocument:
393             command = "MoveToBeginningOfDocument";
394             break;
395         case MoveToEndOfDocument:
396             command = "MoveToEndOfDocument";
397             break;
398         case SelectNextChar:
399             command = "MoveForwardAndModifySelection";
400             break;
401         case SelectPreviousChar:
402             command = "MoveBackwardAndModifySelection";
403             break;
404         case SelectNextWord:
405             command = "MoveWordForwardAndModifySelection";
406             break;
407         case SelectPreviousWord:
408             command = "MoveWordBackwardAndModifySelection";
409             break;
410         case SelectNextLine:
411             command = "MoveDownAndModifySelection";
412             break;
413         case SelectPreviousLine:
414             command = "MoveUpAndModifySelection";
415             break;
416         case SelectStartOfLine:
417             command = "MoveToBeginningOfLineAndModifySelection";
418             break;
419         case SelectEndOfLine:
420             command = "MoveToEndOfLineAndModifySelection";
421             break;
422         case SelectStartOfBlock:
423             command = "MoveToBeginningOfParagraphAndModifySelection";
424             break;
425         case SelectEndOfBlock:
426             command = "MoveToEndOfParagraphAndModifySelection";
427             break;
428         case SelectStartOfDocument:
429             command = "MoveToBeginningOfDocumentAndModifySelection";
430             break;
431         case SelectEndOfDocument:
432             command = "MoveToEndOfDocumentAndModifySelection";
433             break;
434         case DeleteStartOfWord:
435             command = "DeleteWordBackward";
436             break;
437         case DeleteEndOfWord:
438             command = "DeleteWordForward";
439             break;
440
441         default: break;
442     }
443
444     if (command)
445         editor->execCommand(command);
446 }
447
448 QWebPage::NavigationRequestResponse QWebPage::navigationRequested(QWebFrame *frame, const QWebNetworkRequest &request, QWebPage::NavigationType type)
449 {
450     Q_UNUSED(request)
451     return AcceptNavigationRequest;
452 }
453
454 void QWebPage::setWindowGeometry(const QRect& geom)
455 {
456     Q_UNUSED(geom)
457 }
458
459 bool QWebPage::canCut() const
460 {
461     return d->page->focusController()->focusedOrMainFrame()->editor()->canCut();
462 }
463
464 bool QWebPage::canCopy() const
465 {
466     return d->page->focusController()->focusedOrMainFrame()->editor()->canCopy();
467 }
468
469 bool QWebPage::canPaste() const
470 {
471     return d->page->focusController()->focusedOrMainFrame()->editor()->canPaste();
472 }
473
474 void QWebPage::cut()
475 {
476     webActionTriggered(Cut);
477 }
478
479 void QWebPage::copy()
480 {
481     webActionTriggered(Copy);
482 }
483
484 void QWebPage::paste()
485 {
486     webActionTriggered(Paste);
487 }
488
489 /*!
490   Returns true if the page contains unsubmitted form data.
491 */
492 bool QWebPage::isModified() const
493 {
494     return d->modified;
495 }
496
497
498 QUndoStack *QWebPage::undoStack()
499 {
500     if (!d->undoStack)
501         d->undoStack = new QUndoStack(this);
502
503     return d->undoStack;
504 }
505
506 static inline DragOperation dropActionToDragOp(Qt::DropActions actions)
507 {
508     unsigned result = 0;
509     if (actions & Qt::CopyAction)
510         result |= DragOperationCopy;
511     if (actions & Qt::MoveAction)
512         result |= DragOperationMove;
513     if (actions & Qt::LinkAction)
514         result |= DragOperationLink;
515     return (DragOperation)result;    
516 }
517
518 static inline Qt::DropAction dragOpToDropAction(unsigned actions)
519 {
520     Qt::DropAction result = Qt::IgnoreAction;
521     if (actions & DragOperationCopy)
522         result = Qt::CopyAction;
523     else if (actions & DragOperationMove)
524         result = Qt::MoveAction;
525     else if (actions & DragOperationLink)
526         result = Qt::LinkAction;
527     return result;    
528 }
529
530 void QWebPage::resizeEvent(QResizeEvent *e)
531 {
532     QWidget::resizeEvent(e);
533     if (mainFrame()->d->frame && mainFrame()->d->frameView) {
534         mainFrame()->d->frameView->setFrameGeometry(rect());
535         mainFrame()->d->frame->forceLayout();
536         mainFrame()->d->frame->view()->adjustViewSize();
537     }
538 }
539
540 void QWebPage::paintEvent(QPaintEvent *ev)
541 {
542 #ifdef QWEBKIT_TIME_RENDERING
543     QTime time;
544     time.start();
545 #endif
546
547     QPainter p(this);
548
549     QVector<QRect> vector = ev->region().rects();
550     if (!vector.isEmpty()) {
551         for (int i = 0; i < vector.size(); ++i) {
552             mainFrame()->render(&p, vector.at(i));
553         }
554     } else {
555         mainFrame()->render(&p, ev->rect());
556     }
557
558 #ifdef    QWEBKIT_TIME_RENDERING
559     int elapsed = time.elapsed();
560     qDebug()<<"paint event on "<<ev->region()<<", took to render =  "<<elapsed;
561 #endif
562 }
563
564 void QWebPage::mouseMoveEvent(QMouseEvent *ev)
565 {
566     QWebFramePrivate *frame = d->currentFrame(ev->pos())->d;
567     if (!frame->frameView)
568         return;
569
570     frame->eventHandler->handleMouseMoveEvent(PlatformMouseEvent(ev, 0));
571     const int xOffset =
572         frame->horizontalScrollBar() ? frame->horizontalScrollBar()->value() : 0;
573     const int yOffset =
574         frame->verticalScrollBar() ? frame->verticalScrollBar()->value() : 0;
575     IntPoint pt(ev->x() + xOffset, ev->y() + yOffset);
576     WebCore::HitTestResult result = frame->eventHandler->hitTestResultAtPoint(pt, false);
577     WebCore::Element *link = result.URLElement();
578     if (link != frame->lastHoverElement) {
579         frame->lastHoverElement = link;
580         emit hoveringOverLink(result.absoluteLinkURL().prettyURL(), result.title());
581     }
582 }
583
584 void QWebPage::mousePressEvent(QMouseEvent *ev)
585 {
586     d->frameUnderMouse = d->frameAt(ev->pos());
587     QWebFramePrivate *frame = d->frameUnderMouse->d;
588     if (!frame->eventHandler)
589         return;
590
591     frame->eventHandler->handleMousePressEvent(PlatformMouseEvent(ev, 1));
592
593     //FIXME need to keep track of subframe focus for key events!
594     frame->page->setFocus();
595 }
596
597 void QWebPage::mouseDoubleClickEvent(QMouseEvent *ev)
598 {
599     QWebFramePrivate *frame = d->currentFrame(ev->pos())->d;
600     if (!frame->eventHandler)
601         return;
602
603     frame->eventHandler->handleMousePressEvent(PlatformMouseEvent(ev, 2));
604
605     //FIXME need to keep track of subframe focus for key events!
606     frame->page->setFocus();
607 }
608
609 void QWebPage::mouseReleaseEvent(QMouseEvent *ev)
610 {
611     QWebFramePrivate *frame = d->currentFrame(ev->pos())->d;
612     if (frame->frameView) {
613         frame->eventHandler->handleMouseReleaseEvent(PlatformMouseEvent(ev, 0));
614
615         //FIXME need to keep track of subframe focus for key events!
616         frame->page->setFocus();
617     }
618     d->frameUnderMouse = 0;
619 }
620
621 void QWebPage::contextMenuEvent(QContextMenuEvent *ev)
622 {
623     QWebFramePrivate *frame = d->currentFrame(ev->pos())->d;
624     if (!frame->eventHandler)
625         return;
626     d->page->contextMenuController()->clearContextMenu();
627     frame->eventHandler->sendContextMenuEvent(PlatformMouseEvent(ev, 1));
628     ContextMenu *menu = d->page->contextMenuController()->contextMenu();
629
630     QList<ContextMenuItem> *items = menu->platformDescription();
631     QMenu *qmenu = d->createContextMenu(items);
632     if (qmenu) {
633         qmenu->exec(ev->globalPos());
634         delete qmenu;
635     }
636 }
637
638 void QWebPage::wheelEvent(QWheelEvent *ev)
639 {
640     QWebFramePrivate *frame = d->currentFrame(ev->pos())->d;
641
642     bool accepted = false;
643     if (frame->eventHandler) {
644         WebCore::PlatformWheelEvent pev(ev);
645         accepted = frame->eventHandler->handleWheelEvent(pev);
646     }
647
648     ev->setAccepted(accepted);
649
650     //FIXME need to keep track of subframe focus for key events!
651     frame->page->setFocus();
652
653     if (!ev->isAccepted())
654         QWidget::wheelEvent(ev);
655 }
656
657 void QWebPage::keyPressEvent(QKeyEvent *ev)
658 {
659     if (!mainFrame()->d->eventHandler)
660         return;
661
662     bool handled = false;
663     QWebFrame *frame = mainFrame();
664     WebCore::Editor *editor = frame->d->frame->editor();
665     if (editor->canEdit()) {
666         if (ev == QKeySequence::Cut) {
667             webActionTriggered(Cut);
668             handled = true;
669         } else if (ev == QKeySequence::Copy) {
670             webActionTriggered(Copy);
671             handled = true;
672         } else if (ev == QKeySequence::Paste) {
673             webActionTriggered(Paste);
674             handled = true;
675         } else if (ev == QKeySequence::Undo) {
676             webActionTriggered(Undo);
677             handled = true;
678         } else if (ev == QKeySequence::Redo) {
679             webActionTriggered(Redo);
680             handled = true;
681         } else if(ev == QKeySequence::MoveToNextChar) {
682             webActionTriggered(MoveToNextChar);
683             handled = true;
684         } else if(ev == QKeySequence::MoveToPreviousChar) {
685             webActionTriggered(MoveToPreviousChar);
686             handled = true;
687         } else if(ev == QKeySequence::MoveToNextWord) {
688             webActionTriggered(MoveToNextWord);
689             handled = true;
690         } else if(ev == QKeySequence::MoveToPreviousWord) {
691             webActionTriggered(MoveToPreviousWord);
692             handled = true;
693         } else if(ev == QKeySequence::MoveToNextLine) {
694             webActionTriggered(MoveToNextLine);
695             handled = true;
696         } else if(ev == QKeySequence::MoveToPreviousLine) {
697             webActionTriggered(MoveToPreviousLine);
698             handled = true;
699 //             } else if(ev == QKeySequence::MoveToNextPage) {
700 //             } else if(ev == QKeySequence::MoveToPreviousPage) {
701         } else if(ev == QKeySequence::MoveToStartOfLine) {
702             webActionTriggered(MoveToStartOfLine);
703             handled = true;
704         } else if(ev == QKeySequence::MoveToEndOfLine) {
705             webActionTriggered(MoveToEndOfLine);
706             handled = true;
707         } else if(ev == QKeySequence::MoveToStartOfBlock) {
708             webActionTriggered(MoveToStartOfBlock);
709             handled = true;
710         } else if(ev == QKeySequence::MoveToEndOfBlock) {
711             webActionTriggered(MoveToEndOfBlock);
712             handled = true;
713         } else if(ev == QKeySequence::MoveToStartOfDocument) {
714             webActionTriggered(MoveToStartOfDocument);
715             handled = true;
716         } else if(ev == QKeySequence::MoveToEndOfDocument) {
717             webActionTriggered(MoveToEndOfDocument);
718             handled = true;
719         } else if(ev == QKeySequence::SelectNextChar) {
720             webActionTriggered(SelectNextChar);
721             handled = true;
722         } else if(ev == QKeySequence::SelectPreviousChar) {
723             webActionTriggered(SelectPreviousChar);
724             handled = true;
725         } else if(ev == QKeySequence::SelectNextWord) {
726             webActionTriggered(SelectNextWord);
727             handled = true;
728         } else if(ev == QKeySequence::SelectPreviousWord) {
729             webActionTriggered(SelectPreviousWord);
730             handled = true;
731         } else if(ev == QKeySequence::SelectNextLine) {
732             webActionTriggered(SelectNextLine);
733             handled = true;
734         } else if(ev == QKeySequence::SelectPreviousLine) {
735             webActionTriggered(SelectPreviousLine);
736             handled = true;
737 //             } else if(ev == QKeySequence::SelectNextPage) {
738 //             } else if(ev == QKeySequence::SelectPreviousPage) {
739         } else if(ev == QKeySequence::SelectStartOfLine) {
740             webActionTriggered(SelectStartOfLine);
741             handled = true;
742         } else if(ev == QKeySequence::SelectEndOfLine) {
743             webActionTriggered(SelectEndOfLine);
744             handled = true;
745         } else if(ev == QKeySequence::SelectStartOfBlock) {
746             webActionTriggered(SelectStartOfBlock);
747             handled = true;
748         } else if(ev == QKeySequence::SelectEndOfBlock) {
749             webActionTriggered(SelectEndOfBlock);
750             handled = true;
751         } else if(ev == QKeySequence::SelectStartOfDocument) {
752             webActionTriggered(SelectStartOfDocument);
753             handled = true;
754         } else if(ev == QKeySequence::SelectEndOfDocument) {
755             webActionTriggered(SelectEndOfDocument);
756             handled = true;
757         } else if(ev == QKeySequence::DeleteStartOfWord) {
758             webActionTriggered(DeleteStartOfWord);
759             handled = true;
760         } else if(ev == QKeySequence::DeleteEndOfWord) {
761             webActionTriggered(DeleteEndOfWord);
762             handled = true;
763 //             } else if(ev == QKeySequence::DeleteEndOfLine) {
764         }
765     }
766     if (!handled) 
767         handled = frame->d->eventHandler->keyEvent(ev);
768     if (!handled) {
769         handled = true;
770         PlatformScrollbar *h, *v;
771         h = mainFrame()->d->horizontalScrollBar();
772         v = mainFrame()->d->verticalScrollBar();
773
774         if (ev == QKeySequence::MoveToNextPage) {
775             if (v)
776                 v->setValue(v->value() + height());
777         } else if (ev == QKeySequence::MoveToPreviousPage) {
778             if (v)
779                 v->setValue(v->value() - height());
780         } else {
781             switch (ev->key()) {
782             case Qt::Key_Up:
783                 if (v)
784                     v->setValue(v->value() - 10);
785                 break;
786             case Qt::Key_Down:
787                 if (v)
788                     v->setValue(v->value() + 10);
789                 break;
790             case Qt::Key_Left:
791                 if (h)
792                     h->setValue(h->value() - 10);
793                 break;
794             case Qt::Key_Right:
795                 if (h)
796                     h->setValue(h->value() + 10);
797                 break;
798             default:
799                 handled = false;
800                 break;
801             }
802         }
803     }
804
805     ev->setAccepted(handled);
806 }
807
808 void QWebPage::keyReleaseEvent(QKeyEvent *ev)
809 {
810     if (ev->isAutoRepeat()) {
811         ev->setAccepted(true);
812         return;
813     }
814
815     if (!mainFrame()->d->eventHandler)
816         return;
817
818     bool handled = mainFrame()->d->eventHandler->keyEvent(ev);
819     ev->setAccepted(handled);
820 }
821
822 void QWebPage::focusInEvent(QFocusEvent *ev)
823 {
824     if (ev->reason() != Qt::PopupFocusReason) 
825         mainFrame()->d->frame->page()->focusController()->setFocusedFrame(mainFrame()->d->frame);
826     QWidget::focusInEvent(ev);
827 }
828
829 void QWebPage::focusOutEvent(QFocusEvent *ev)
830 {
831     QWidget::focusOutEvent(ev);
832     if (ev->reason() != Qt::PopupFocusReason) {
833         mainFrame()->d->frame->selectionController()->clear();
834         mainFrame()->d->frame->setIsActive(false);
835     }
836 }
837
838 bool QWebPage::focusNextPrevChild(bool next)
839 {
840     Q_UNUSED(next)
841     return false;
842 }
843
844 void QWebPage::dragEnterEvent(QDragEnterEvent *ev)
845 {
846 #ifndef QT_NO_DRAGANDDROP
847     DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), 
848                       dropActionToDragOp(ev->possibleActions()));
849     Qt::DropAction action = dragOpToDropAction(d->page->dragController()->dragEntered(&dragData));
850     ev->setDropAction(action);
851     ev->accept();
852 #endif
853 }
854
855 void QWebPage::dragLeaveEvent(QDragLeaveEvent *ev)
856 {
857 #ifndef QT_NO_DRAGANDDROP
858     DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone);
859     d->page->dragController()->dragExited(&dragData);
860     ev->accept();
861 #endif
862 }
863
864 void QWebPage::dragMoveEvent(QDragMoveEvent *ev)
865 {
866 #ifndef QT_NO_DRAGANDDROP
867     DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), 
868                       dropActionToDragOp(ev->possibleActions()));
869     Qt::DropAction action = dragOpToDropAction(d->page->dragController()->dragUpdated(&dragData));
870     ev->setDropAction(action);
871     ev->accept();
872 #endif
873 }
874
875 void QWebPage::dropEvent(QDropEvent *ev)
876 {
877 #ifndef QT_NO_DRAGANDDROP
878     DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), 
879                       dropActionToDragOp(ev->possibleActions()));
880     Qt::DropAction action = dragOpToDropAction(d->page->dragController()->performDrag(&dragData));
881     ev->accept();
882 #endif
883 }
884
885 void QWebPage::setNetworkInterface(QWebNetworkInterface *interface)
886 {
887     d->networkInterface = interface;
888 }
889
890 QWebNetworkInterface *QWebPage::networkInterface() const
891 {
892     if (d->networkInterface)
893         return d->networkInterface;
894     else
895         return QWebNetworkInterface::defaultInterface();
896 }
897
898 QPixmap QWebPage::icon() const
899 {
900     Image* image = iconDatabase()->iconForPageURL(url().toString(), IntSize(16, 16));
901     if (!image || image->isNull()) {
902         image = iconDatabase()->defaultIcon(IntSize(16, 16));
903     }
904
905     if (!image) {
906         return QPixmap();
907     }
908
909     QPixmap *icon = image->getPixmap();
910     if (!icon) {
911         return QPixmap();
912     }
913     return *icon;
914 }
915
916 void QWebPage::setSettings(const QWebSettings &settings)
917 {
918     WebCore::Settings *wSettings = d->page->settings();
919
920     wSettings->setStandardFontFamily(
921         settings.fontFamily(QWebSettings::StandardFont));
922     wSettings->setFixedFontFamily(
923         settings.fontFamily(QWebSettings::FixedFont));
924     wSettings->setSerifFontFamily(
925         settings.fontFamily(QWebSettings::SerifFont));
926     wSettings->setSansSerifFontFamily(
927         settings.fontFamily(QWebSettings::SansSerifFont));
928     wSettings->setCursiveFontFamily(
929         settings.fontFamily(QWebSettings::CursiveFont));
930     wSettings->setFantasyFontFamily(
931         settings.fontFamily(QWebSettings::FantasyFont));
932
933     wSettings->setMinimumFontSize(settings.minimumFontSize());
934     wSettings->setMinimumLogicalFontSize(settings.minimumLogicalFontSize());
935     wSettings->setDefaultFontSize(settings.defaultFontSize());
936     wSettings->setDefaultFixedFontSize(settings.defaultFixedFontSize());
937
938     wSettings->setLoadsImagesAutomatically(
939         settings.testAttribute(QWebSettings::AutoLoadImages));
940     wSettings->setJavaScriptEnabled(
941         settings.testAttribute(QWebSettings::JavascriptEnabled));
942     wSettings->setJavaScriptCanOpenWindowsAutomatically(
943         settings.testAttribute(QWebSettings::JavascriptCanOpenWindows));
944     wSettings->setJavaEnabled(
945         settings.testAttribute(QWebSettings::JavaEnabled));
946     wSettings->setPluginsEnabled(
947         settings.testAttribute(QWebSettings::PluginsEnabled));
948     wSettings->setPrivateBrowsingEnabled(
949         settings.testAttribute(QWebSettings::PrivateBrowsingEnabled));
950
951     wSettings->setUserStyleSheetLocation(KURL(settings.userStyleSheetLocation()));
952
953     // ### should be configurable
954     wSettings->setDefaultTextEncodingName("iso-8859-1");
955     wSettings->setDOMPasteAllowed(true);
956 }
957
958 QWebSettings QWebPage::settings() const
959 {
960     QWebSettings settings;
961     WebCore::Settings *wSettings = d->page->settings();
962
963     settings.setFontFamily(QWebSettings::StandardFont,
964                            wSettings->standardFontFamily());
965     settings.setFontFamily(QWebSettings::FixedFont,
966                            wSettings->fixedFontFamily());
967     settings.setFontFamily(QWebSettings::SerifFont,
968                            wSettings->serifFontFamily());
969     settings.setFontFamily(QWebSettings::SansSerifFont,
970                            wSettings->sansSerifFontFamily());
971     settings.setFontFamily(QWebSettings::CursiveFont,
972                            wSettings->cursiveFontFamily());
973     settings.setFontFamily(QWebSettings::FantasyFont,
974                            wSettings->fantasyFontFamily());
975
976     settings.setMinimumFontSize(wSettings->minimumFontSize());
977     settings.setMinimumLogicalFontSize(wSettings->minimumLogicalFontSize());
978     settings.setDefaultFontSize(wSettings->defaultFontSize());
979     settings.setDefaultFixedFontSize(wSettings->defaultFixedFontSize());
980
981     settings.setAttribute(QWebSettings::AutoLoadImages,
982                           wSettings->loadsImagesAutomatically());
983     settings.setAttribute(QWebSettings::JavascriptEnabled,
984                           wSettings->isJavaScriptEnabled());
985     settings.setAttribute(QWebSettings::JavascriptCanOpenWindows,
986                           wSettings->JavaScriptCanOpenWindowsAutomatically());
987     settings.setAttribute(QWebSettings::JavaEnabled,
988                           wSettings->isJavaEnabled());
989     settings.setAttribute(QWebSettings::PluginsEnabled,
990                           wSettings->arePluginsEnabled());
991     settings.setAttribute(QWebSettings::PrivateBrowsingEnabled,
992                           wSettings->privateBrowsingEnabled());
993
994     settings.setUserStyleSheetLocation(
995         wSettings->userStyleSheetLocation().url());
996
997     return settings;
998 }
999
1000 QString QWebPage::chooseFile(QWebFrame *parentFrame, const QString& oldFile)
1001 {
1002     //FIXME frame pos...
1003 #ifndef QT_NO_FILEDIALOG
1004     return QFileDialog::getOpenFileName(this, QString::null, oldFile);
1005 #else
1006     return QString::null;
1007 #endif
1008 }
1009
1010 #ifndef QT_NO_NETWORKPROXY
1011 void QWebPage::setNetworkProxy(const QNetworkProxy& proxy)
1012 {
1013     d->networkProxy = proxy;
1014 }
1015
1016 QNetworkProxy QWebPage::networkProxy() const
1017 {
1018     return d->networkProxy;
1019 }
1020 #endif
1021
1022 QString QWebPage::userAgentStringForUrl(const QUrl& forUrl) const {
1023     Q_UNUSED(forUrl)
1024     return QLatin1String("Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en) AppleWebKit/418.9.1 (KHTML, like Gecko) Safari/419.3 Qt");
1025 }
1026
1027
1028 void QWebPagePrivate::_q_onLoadProgressChanged(int) {
1029     m_totalBytes = page->progress()->totalPageAndResourceBytesToLoad();
1030     m_bytesReceived = page->progress()->totalBytesReceived();
1031 }
1032
1033
1034 quint64 QWebPage::totalBytes() const {
1035     return d->m_bytesReceived;
1036 }
1037
1038
1039 quint64 QWebPage::bytesReceived() const {
1040     return d->m_totalBytes;
1041 }
1042
1043 #include "moc_qwebpage.cpp"