Removed a bunch of slots/functions that are now available through the new actions...
[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 "FrameLoadRequest.h"
46 #include "KURL.h"
47 #include "Image.h"
48 #include "IconDatabase.h"
49 #include "InspectorClientQt.h"
50 #include "FocusController.h"
51 #include "Editor.h"
52 #include "PlatformScrollBar.h"
53 #include "PlatformKeyboardEvent.h"
54 #include "PlatformWheelEvent.h"
55 #include "ProgressTracker.h"
56 #include "RefPtr.h"
57 #include "HashMap.h"
58 #include "HitTestResult.h"
59 #include "LocalizedStrings.h"
60
61 #include <QDebug>
62 #include <QDragEnterEvent>
63 #include <QDragLeaveEvent>
64 #include <QDragMoveEvent>
65 #include <QDropEvent>
66 #include <QFileDialog>
67 #include <QHttpRequestHeader>
68 #include <QInputDialog>
69 #include <QMessageBox>
70 #include <QNetworkProxy>
71 #include <QUndoStack>
72 #include <QUrl>
73 #include <QPainter>
74
75 using namespace WebCore;
76
77 QWebPagePrivate::QWebPagePrivate(QWebPage *qq)
78     : q(qq)
79     , modified(false)
80 {
81     q->setMouseTracking(true);
82     q->setFocusPolicy(Qt::ClickFocus);
83     chromeClient = new ChromeClientQt(q);
84     contextMenuClient = new ContextMenuClientQt();
85     editorClient = new EditorClientQt(q);
86     page = new Page(chromeClient, contextMenuClient, editorClient,
87                     new DragClientQt(q), new InspectorClientQt());
88
89     // ### should be configurable
90     page->settings()->setDefaultTextEncodingName("iso-8859-1");
91     page->settings()->setDOMPasteAllowed(true);
92
93     settings = new QWebSettings(page->settings());
94
95     undoStack = 0;
96     mainFrame = 0;
97     networkInterface = 0;
98     insideOpenCall = false;
99
100     history.d = new QWebPageHistoryPrivate(page->backForwardList());
101     memset(actions, 0, sizeof(actions));
102 }
103
104 QWebPagePrivate::~QWebPagePrivate()
105 {
106     delete undoStack;
107     delete settings;
108     delete page;
109 }
110
111 QWebPage::NavigationRequestResponse QWebPagePrivate::navigationRequested(QWebFrame *frame, const QWebNetworkRequest &request, QWebPage::NavigationType type)
112 {
113     if (insideOpenCall
114         && frame == mainFrame)
115         return QWebPage::AcceptNavigationRequest;
116     return q->navigationRequested(frame, request, type);
117 }
118
119 void QWebPagePrivate::createMainFrame()
120 {
121     if (!mainFrame) {
122         QWebFrameData frameData;
123         frameData.ownerElement = 0;
124         frameData.allowsScrolling = true;
125         frameData.marginWidth = 0;
126         frameData.marginHeight = 0;
127         mainFrame = new QWebFrame(q, &frameData);
128         QObject::connect(mainFrame, SIGNAL(titleChanged(const QString&)),
129                 q, SIGNAL(titleChanged(const QString&)));
130         QObject::connect(mainFrame, SIGNAL(hoveringOverLink(const QString&, const QString&)),
131                 q, SIGNAL(hoveringOverLink(const QString&, const QString&)));
132         
133         mainFrame->d->frameView->setFrameGeometry(q->geometry());
134
135         emit q->frameCreated(mainFrame);
136     }
137 }
138
139 static QWebPage::WebAction webActionForContextMenuAction(WebCore::ContextMenuAction action)
140 {
141     switch (action) {
142         case WebCore::ContextMenuItemTagOpenLink: return QWebPage::OpenLink;
143         case WebCore::ContextMenuItemTagOpenLinkInNewWindow: return QWebPage::OpenLinkInNewWindow;
144         case WebCore::ContextMenuItemTagDownloadLinkToDisk: return QWebPage::DownloadLinkToDisk;
145         case WebCore::ContextMenuItemTagCopyLinkToClipboard: return QWebPage::CopyLinkToClipboard;
146         case WebCore::ContextMenuItemTagOpenImageInNewWindow: return QWebPage::OpenImageInNewWindow;
147         case WebCore::ContextMenuItemTagDownloadImageToDisk: return QWebPage::DownloadImageToDisk;
148         case WebCore::ContextMenuItemTagCopyImageToClipboard: return QWebPage::CopyImageToClipboard;
149         case WebCore::ContextMenuItemTagOpenFrameInNewWindow: return QWebPage::OpenFrameInNewWindow;
150         case WebCore::ContextMenuItemTagCopy: return QWebPage::Copy;
151         case WebCore::ContextMenuItemTagGoBack: return QWebPage::GoBack;
152         case WebCore::ContextMenuItemTagGoForward: return QWebPage::GoForward;
153         case WebCore::ContextMenuItemTagStop: return QWebPage::Stop;
154         case WebCore::ContextMenuItemTagReload: return QWebPage::Reload;
155         case WebCore::ContextMenuItemTagCut: return QWebPage::Cut;
156         case WebCore::ContextMenuItemTagPaste: return QWebPage::Paste;
157         default: break;
158     }
159     return QWebPage::NoWebAction;
160 }
161
162 QMenu *QWebPagePrivate::createContextMenu(QList<WebCore::ContextMenuItem> *items)
163 {
164     QMenu *menu = new QMenu;
165     for (int i = 0; i < items->count(); ++i) {
166         const ContextMenuItem &item = items->at(i);
167         switch (item.type()) {
168             case WebCore::ActionType: {
169                 QWebPage::WebAction action = webActionForContextMenuAction(item.action());
170                 QAction *a = q->webAction(action);
171                 if (a)
172                     menu->addAction(a);
173                 break;
174             }
175             case WebCore::SeparatorType:
176                 menu->addSeparator();
177                 break;
178             case WebCore::SubmenuType: {
179                 QMenu *subMenu = createContextMenu(item.platformSubMenu());
180                 subMenu->setTitle(item.title());
181                 menu->addAction(subMenu->menuAction());
182                 break;
183             }
184         }
185     }
186     return menu;
187 }
188
189 QWebFrame *QWebPagePrivate::frameAt(const QPoint &pos) const
190 {
191     QWebFrame *frame = mainFrame;
192
193 redo:
194     QList<QWebFrame*> children = frame->childFrames();
195     for (int i = 0; i < children.size(); ++i) {
196         if (children.at(i)->geometry().contains(pos)) {
197             frame = children.at(i);
198             goto redo;
199         }
200     }
201     if (frame->geometry().contains(pos))
202         return frame;
203     return 0;
204 }
205
206 void QWebPagePrivate::_q_webActionTriggered(bool checked)
207 {
208     QAction *a = qobject_cast<QAction *>(q->sender());
209     if (!a)
210         return;
211     QWebPage::WebAction action = static_cast<QWebPage::WebAction>(a->data().toInt());
212     q->webActionTriggered(action, checked);
213 }
214
215 void QWebPagePrivate::updateAction(QWebPage::WebAction action)
216 {
217     QAction *a = actions[action];
218     if (!a || !mainFrame)
219         return;
220
221     WebCore::FrameLoader *loader = mainFrame->d->frame->loader();
222     WebCore::Editor *editor = page->focusController()->focusedOrMainFrame()->editor();
223
224     bool enabled = a->isEnabled();
225
226     switch (action) {
227         case QWebPage::GoBack:
228             enabled = loader->canGoBackOrForward(-1);
229             break;
230         case QWebPage::GoForward:
231             enabled = loader->canGoBackOrForward(1);
232             break;
233         case QWebPage::Stop:
234             enabled = loader->isLoading();
235             break;
236         case QWebPage::Reload:
237             enabled = !loader->isLoading();
238             break;
239         case QWebPage::Cut:
240             enabled = editor->canCut();
241             break;
242         case QWebPage::Copy:
243             enabled = editor->canCopy();
244             break;
245         case QWebPage::Paste:
246             enabled = editor->canPaste();
247             break;
248         case QWebPage::Undo:
249         case QWebPage::Redo:
250             // those two are handled by QUndoStack
251             break;
252         default: break;
253     }
254
255     a->setEnabled(enabled);
256 }
257
258 void QWebPagePrivate::updateNavigationActions()
259 {
260     updateAction(QWebPage::GoBack);
261     updateAction(QWebPage::GoForward);
262     updateAction(QWebPage::Stop);
263     updateAction(QWebPage::Reload);
264 }
265
266 void QWebPagePrivate::updateEditorActions()
267 {
268     updateAction(QWebPage::Cut);
269     updateAction(QWebPage::Copy);
270     updateAction(QWebPage::Paste);
271 }
272
273 QWebPage::QWebPage(QWidget *parent)
274     : QWidget(parent)
275     , d(new QWebPagePrivate(this))
276 {
277
278     QPalette pal = palette();
279     pal.setBrush(QPalette::Background, Qt::white);
280
281     setAttribute(Qt::WA_OpaquePaintEvent);
282
283     setPalette(pal);
284     setAcceptDrops(true);
285     connect(this, SIGNAL(loadProgressChanged(int)), this, SLOT(_q_onLoadProgressChanged(int)));
286 }
287
288 QWebPage::~QWebPage()
289 {
290     FrameLoader *loader = d->mainFrame->d->frame->loader();
291     if (loader)
292         loader->detachFromParent();
293     delete d;
294 }
295
296 void QWebPage::open(const QUrl &url)
297 {
298     open(QWebNetworkRequest(url));
299 }
300
301 void QWebPage::open(const QWebNetworkRequest &req)
302 {
303     d->insideOpenCall = true;
304
305     QUrl url = req.url();
306     QHttpRequestHeader httpHeader = req.httpHeader();
307     QByteArray postData = req.postData();
308
309     WebCore::ResourceRequest request(KURL(url.toString()));
310
311     QString method = httpHeader.method();
312     if (!method.isEmpty())
313         request.setHTTPMethod(method);
314
315     QList<QPair<QString, QString> > values = httpHeader.values();
316     for (int i = 0; i < values.size(); ++i) {
317         const QPair<QString, QString> &val = values.at(i);
318         request.addHTTPHeaderField(val.first, val.second);
319     }
320
321     if (!postData.isEmpty()) {
322         WTF::RefPtr<WebCore::FormData> formData = new WebCore::FormData(postData.constData(), postData.size());
323         request.setHTTPBody(formData);
324     }
325
326     mainFrame()->d->frame->loader()->load(request);
327     d->insideOpenCall = false;
328 }
329
330 QUrl QWebPage::url() const
331 {
332     return QUrl((QString)mainFrame()->d->frame->loader()->url().url());
333 }
334
335 QString QWebPage::title() const
336 {
337     return mainFrame()->title();
338 }
339
340 QWebFrame *QWebPage::mainFrame() const
341 {
342     d->createMainFrame();
343     return d->mainFrame;
344 }
345
346 QSize QWebPage::sizeHint() const
347 {
348     return QSize(800, 600);
349 }
350
351 void QWebPage::stop()
352 {
353     webActionTriggered(Stop);
354 }
355
356 QWebPageHistory *QWebPage::history() const
357 {
358     return &d->history;
359 }
360
361 void QWebPage::javaScriptConsoleMessage(const QString& message, unsigned int lineNumber, const QString& sourceID)
362 {
363 }
364
365 void QWebPage::javaScriptAlert(QWebFrame *frame, const QString& msg)
366 {
367     //FIXME frame pos...
368     QMessageBox::information(this, title(), msg, QMessageBox::Ok);
369 }
370
371 bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg)
372 {
373     //FIXME frame pos...
374     return 0 == QMessageBox::information(this, title(), msg, QMessageBox::Yes, QMessageBox::No);
375 }
376
377 bool QWebPage::javaScriptPrompt(QWebFrame *frame, const QString& msg, const QString& defaultValue, QString* result)
378 {
379     //FIXME frame pos...
380     bool ok = false;
381 #ifndef QT_NO_INPUTDIALOG
382     QString x = QInputDialog::getText(this, title(), msg, QLineEdit::Normal, defaultValue, &ok);
383     if (ok && result) {
384         *result = x;
385     }
386 #endif
387     return ok;
388 }
389
390 QWebPage *QWebPage::createWindow()
391 {
392     return 0;
393 }
394
395 QWebPage *QWebPage::createModalDialog()
396 {
397     return 0;
398 }
399
400 QObject *QWebPage::createPlugin(const QString &classid, const QUrl &url, const QStringList &paramNames, const QStringList &paramValues)
401 {
402     Q_UNUSED(classid)
403     Q_UNUSED(url)
404     Q_UNUSED(paramNames)
405     Q_UNUSED(paramValues)
406     return 0;
407 }
408
409 static WebCore::FrameLoadRequest frameLoadRequest(const QUrl &url, WebCore::Frame *frame)
410 {
411     WebCore::ResourceRequest rr(WebCore::KURL(url.toString()),
412                                 frame->loader()->outgoingReferrer());
413     return WebCore::FrameLoadRequest(rr);
414 }
415
416 static void openNewWindow(const QUrl& url, WebCore::Frame* frame)
417 {
418     if (Page* oldPage = frame->page())
419         if (Page* newPage = oldPage->chrome()->createWindow(frame,
420                 frameLoadRequest(url, frame)))
421             newPage->chrome()->show();
422 }
423
424 void QWebPage::webActionTriggered(WebAction action, bool checked)
425 {
426     WebCore::Frame *frame = d->page->focusController()->focusedOrMainFrame();
427     WebCore::Editor *editor = frame->editor();
428     const char *command = 0;
429
430     switch (action) {
431         case OpenLink:
432             if (QWebFrame *targetFrame = d->currentContext.targetFrame()) {
433                 WTF::RefPtr<WebCore::Frame> wcFrame = targetFrame->d->frame;
434                 targetFrame->d->frame->loader()->load(frameLoadRequest(d->currentContext.linkUrl(), wcFrame.get()),
435                                                       /*lockHistory*/ false,
436                                                       /*userGesture*/ true,
437                                                       /*event*/ 0,
438                                                       /*HTMLFormElement*/ 0,
439                                                       /*formValues*/
440                                                       WTF::HashMap<String, String>());
441                 break;
442             } else {
443             }
444             // fall through
445         case OpenLinkInNewWindow:
446             openNewWindow(d->currentContext.linkUrl(), frame);
447             break;
448         case OpenFrameInNewWindow:
449             break;
450         case DownloadLinkToDisk:
451         case CopyLinkToClipboard:
452             editor->copyURL(WebCore::KURL(d->currentContext.linkUrl().toString()), d->currentContext.text());
453             break;
454         case OpenImageInNewWindow:
455             openNewWindow(d->currentContext.imageUrl(), frame);
456             break;
457         case DownloadImageToDisk:
458         case CopyImageToClipboard:
459             break;
460         case GoBack:
461             d->page->goBack();
462             break;
463         case GoForward:
464             d->page->goForward();
465             break;
466         case Stop:
467             mainFrame()->d->frame->loader()->stopForUserCancel();
468             break;
469         case Reload:
470             mainFrame()->d->frame->loader()->reload();
471             break;
472         case Cut:
473             editor->cut();
474             break;
475         case Copy:
476             editor->copy();
477             break;
478         case Paste:
479             editor->paste();
480             break;
481
482         case Undo:
483             editor->undo();
484             break;
485         case Redo:
486             editor->redo();
487             break;
488
489         case MoveToNextChar:
490             command = "MoveForward";
491             break;
492         case MoveToPreviousChar:
493             command = "MoveBackward";
494             break;
495         case MoveToNextWord:
496             command = "MoveWordForward";
497             break;
498         case MoveToPreviousWord:
499             command = "MoveWordBackward";
500             break;
501         case MoveToNextLine:
502             command = "MoveDown";
503             break;
504         case MoveToPreviousLine:
505             command = "MoveUp";
506             break;
507         case MoveToStartOfLine:
508             command = "MoveToBeginningOfLine";
509             break;
510         case MoveToEndOfLine:
511             command = "MoveToEndOfLine";
512             break;
513         case MoveToStartOfBlock:
514             command = "MoveToBeginningOfParagraph";
515             break;
516         case MoveToEndOfBlock:
517             command = "MoveToEndOfParagraph";
518             break;
519         case MoveToStartOfDocument:
520             command = "MoveToBeginningOfDocument";
521             break;
522         case MoveToEndOfDocument:
523             command = "MoveToEndOfDocument";
524             break;
525         case SelectNextChar:
526             command = "MoveForwardAndModifySelection";
527             break;
528         case SelectPreviousChar:
529             command = "MoveBackwardAndModifySelection";
530             break;
531         case SelectNextWord:
532             command = "MoveWordForwardAndModifySelection";
533             break;
534         case SelectPreviousWord:
535             command = "MoveWordBackwardAndModifySelection";
536             break;
537         case SelectNextLine:
538             command = "MoveDownAndModifySelection";
539             break;
540         case SelectPreviousLine:
541             command = "MoveUpAndModifySelection";
542             break;
543         case SelectStartOfLine:
544             command = "MoveToBeginningOfLineAndModifySelection";
545             break;
546         case SelectEndOfLine:
547             command = "MoveToEndOfLineAndModifySelection";
548             break;
549         case SelectStartOfBlock:
550             command = "MoveToBeginningOfParagraphAndModifySelection";
551             break;
552         case SelectEndOfBlock:
553             command = "MoveToEndOfParagraphAndModifySelection";
554             break;
555         case SelectStartOfDocument:
556             command = "MoveToBeginningOfDocumentAndModifySelection";
557             break;
558         case SelectEndOfDocument:
559             command = "MoveToEndOfDocumentAndModifySelection";
560             break;
561         case DeleteStartOfWord:
562             command = "DeleteWordBackward";
563             break;
564         case DeleteEndOfWord:
565             command = "DeleteWordForward";
566             break;
567
568         default: break;
569     }
570
571     if (command)
572         editor->execCommand(command);
573 }
574
575 QWebPage::NavigationRequestResponse QWebPage::navigationRequested(QWebFrame *frame, const QWebNetworkRequest &request, QWebPage::NavigationType type)
576 {
577     Q_UNUSED(request)
578     return AcceptNavigationRequest;
579 }
580
581 void QWebPage::setWindowGeometry(const QRect& geom)
582 {
583     Q_UNUSED(geom)
584 }
585
586 QString QWebPage::selectedText() const
587 {
588     return d->page->focusController()->focusedOrMainFrame()->selectedText();
589 }
590
591 QAction *QWebPage::webAction(WebAction action) const
592 {
593     if (action == QWebPage::NoWebAction) return 0;
594     if (d->actions[action])
595         return d->actions[action];
596
597     QString text;
598
599     switch (action) {
600         case OpenLink:
601             text = contextMenuItemTagOpenLink();
602             break;
603         case OpenLinkInNewWindow:
604             text = contextMenuItemTagOpenLinkInNewWindow();
605             break;
606         case OpenFrameInNewWindow:
607             text = contextMenuItemTagOpenFrameInNewWindow();
608             break;
609
610         case DownloadLinkToDisk:
611             text = contextMenuItemTagDownloadLinkToDisk();
612             break;
613         case CopyLinkToClipboard:
614             text = contextMenuItemTagCopyLinkToClipboard();
615             break;
616
617         case OpenImageInNewWindow:
618             text = contextMenuItemTagOpenImageInNewWindow();
619             break;
620         case DownloadImageToDisk:
621             text = contextMenuItemTagDownloadImageToDisk();
622             break;
623         case CopyImageToClipboard:
624             text = contextMenuItemTagCopyImageToClipboard();
625             break;
626
627         case GoBack:
628             text = contextMenuItemTagGoBack();
629             break;
630         case GoForward:
631             text = contextMenuItemTagGoForward();
632             break;
633         case Stop:
634             text = contextMenuItemTagStop();
635             break;
636         case Reload:
637             text = contextMenuItemTagReload();
638             break;
639
640         case Cut:
641             text = contextMenuItemTagCut();
642             break;
643         case Copy:
644             text = contextMenuItemTagCopy();
645             break;
646         case Paste:
647             text = contextMenuItemTagPaste();
648             break;
649
650         case Undo: {
651             QAction *a = undoStack()->createUndoAction(d->q);
652             d->actions[action] = a;
653             return a;
654         }
655         case Redo: {
656             QAction *a = undoStack()->createRedoAction(d->q);
657             d->actions[action] = a;
658             return a;
659         }
660         case MoveToNextChar:
661         case MoveToPreviousChar:
662         case MoveToNextWord:
663         case MoveToPreviousWord:
664         case MoveToNextLine:
665         case MoveToPreviousLine:
666         case MoveToStartOfLine:
667         case MoveToEndOfLine:
668         case MoveToStartOfBlock:
669         case MoveToEndOfBlock:
670         case MoveToStartOfDocument:
671         case MoveToEndOfDocument:
672         case SelectNextChar:
673         case SelectPreviousChar:
674         case SelectNextWord:
675         case SelectPreviousWord:
676         case SelectNextLine:
677         case SelectPreviousLine:
678         case SelectStartOfLine:
679         case SelectEndOfLine:
680         case SelectStartOfBlock:
681         case SelectEndOfBlock:
682         case SelectStartOfDocument:
683         case SelectEndOfDocument:
684         case DeleteStartOfWord:
685         case DeleteEndOfWord:
686             break; // ####
687
688         case NoWebAction:
689             return 0;
690     }
691
692     if (text.isEmpty())
693         return 0;
694
695     QAction *a = new QAction(d->q);
696     a->setText(text);
697     a->setData(action);
698
699     connect(a, SIGNAL(triggered(bool)),
700             this, SLOT(_q_webActionTriggered(bool)));
701
702     d->actions[action] = a;
703     d->updateAction(action);
704     return a;
705 }
706
707 /*!
708   Returns true if the page contains unsubmitted form data.
709 */
710 bool QWebPage::isModified() const
711 {
712     return d->modified;
713 }
714
715
716 QUndoStack *QWebPage::undoStack() const
717 {
718     if (!d->undoStack)
719         d->undoStack = new QUndoStack(const_cast<QWebPage *>(this));
720
721     return d->undoStack;
722 }
723
724 static inline DragOperation dropActionToDragOp(Qt::DropActions actions)
725 {
726     unsigned result = 0;
727     if (actions & Qt::CopyAction)
728         result |= DragOperationCopy;
729     if (actions & Qt::MoveAction)
730         result |= DragOperationMove;
731     if (actions & Qt::LinkAction)
732         result |= DragOperationLink;
733     return (DragOperation)result;    
734 }
735
736 static inline Qt::DropAction dragOpToDropAction(unsigned actions)
737 {
738     Qt::DropAction result = Qt::IgnoreAction;
739     if (actions & DragOperationCopy)
740         result = Qt::CopyAction;
741     else if (actions & DragOperationMove)
742         result = Qt::MoveAction;
743     else if (actions & DragOperationLink)
744         result = Qt::LinkAction;
745     return result;    
746 }
747
748 void QWebPage::resizeEvent(QResizeEvent *e)
749 {
750     QWidget::resizeEvent(e);
751     if (mainFrame()->d->frame && mainFrame()->d->frameView) {
752         mainFrame()->d->frameView->setFrameGeometry(rect());
753         mainFrame()->d->frame->forceLayout();
754         mainFrame()->d->frame->view()->adjustViewSize();
755     }
756 }
757
758 void QWebPage::paintEvent(QPaintEvent *ev)
759 {
760 #ifdef QWEBKIT_TIME_RENDERING
761     QTime time;
762     time.start();
763 #endif
764
765     QPainter p(this);
766
767     QVector<QRect> vector = ev->region().rects();
768     if (!vector.isEmpty()) {
769         for (int i = 0; i < vector.size(); ++i) {
770             mainFrame()->render(&p, vector.at(i));
771         }
772     } else {
773         mainFrame()->render(&p, ev->rect());
774     }
775
776 #ifdef    QWEBKIT_TIME_RENDERING
777     int elapsed = time.elapsed();
778     qDebug()<<"paint event on "<<ev->region()<<", took to render =  "<<elapsed;
779 #endif
780 }
781
782 void QWebPage::mouseMoveEvent(QMouseEvent *ev)
783 {
784     QWebFramePrivate *frame = d->currentFrame(ev->pos())->d;
785     if (!frame->frameView)
786         return;
787
788     frame->eventHandler->handleMouseMoveEvent(PlatformMouseEvent(ev, 0));
789     const int xOffset =
790         frame->horizontalScrollBar() ? frame->horizontalScrollBar()->value() : 0;
791     const int yOffset =
792         frame->verticalScrollBar() ? frame->verticalScrollBar()->value() : 0;
793     IntPoint pt(ev->x() + xOffset, ev->y() + yOffset);
794     WebCore::HitTestResult result = frame->eventHandler->hitTestResultAtPoint(pt, false);
795     WebCore::Element *link = result.URLElement();
796     if (link != frame->lastHoverElement) {
797         frame->lastHoverElement = link;
798         emit hoveringOverLink(result.absoluteLinkURL().prettyURL(), result.title());
799     }
800 }
801
802 void QWebPage::mousePressEvent(QMouseEvent *ev)
803 {
804     d->frameUnderMouse = d->frameAt(ev->pos());
805     QWebFramePrivate *frame = d->frameUnderMouse->d;
806     if (!frame->eventHandler)
807         return;
808
809     frame->eventHandler->handleMousePressEvent(PlatformMouseEvent(ev, 1));
810
811     //FIXME need to keep track of subframe focus for key events!
812     frame->page->setFocus();
813 }
814
815 void QWebPage::mouseDoubleClickEvent(QMouseEvent *ev)
816 {
817     QWebFramePrivate *frame = d->currentFrame(ev->pos())->d;
818     if (!frame->eventHandler)
819         return;
820
821     frame->eventHandler->handleMousePressEvent(PlatformMouseEvent(ev, 2));
822
823     //FIXME need to keep track of subframe focus for key events!
824     frame->page->setFocus();
825 }
826
827 void QWebPage::mouseReleaseEvent(QMouseEvent *ev)
828 {
829     QWebFramePrivate *frame = d->currentFrame(ev->pos())->d;
830     if (frame->frameView) {
831         frame->eventHandler->handleMouseReleaseEvent(PlatformMouseEvent(ev, 0));
832
833         //FIXME need to keep track of subframe focus for key events!
834         frame->page->setFocus();
835     }
836     d->frameUnderMouse = 0;
837 }
838
839 void QWebPage::contextMenuEvent(QContextMenuEvent *ev)
840 {
841     QWebFramePrivate *frame = d->currentFrame(ev->pos())->d;
842     if (!frame->eventHandler)
843         return;
844     d->page->contextMenuController()->clearContextMenu();
845     frame->eventHandler->sendContextMenuEvent(PlatformMouseEvent(ev, 1));
846     ContextMenu *menu = d->page->contextMenuController()->contextMenu();
847
848     QWebPageContext oldContext = d->currentContext;
849     d->currentContext = QWebPageContext(menu->hitTestResult());
850
851     QList<ContextMenuItem> *items = menu->platformDescription();
852     QMenu *qmenu = d->createContextMenu(items);
853     if (qmenu) {
854         qmenu->exec(ev->globalPos());
855         delete qmenu;
856     }
857     d->currentContext = oldContext;
858 }
859
860 void QWebPage::wheelEvent(QWheelEvent *ev)
861 {
862     QWebFramePrivate *frame = d->currentFrame(ev->pos())->d;
863
864     bool accepted = false;
865     if (frame->eventHandler) {
866         WebCore::PlatformWheelEvent pev(ev);
867         accepted = frame->eventHandler->handleWheelEvent(pev);
868     }
869
870     ev->setAccepted(accepted);
871
872     //FIXME need to keep track of subframe focus for key events!
873     frame->page->setFocus();
874
875     if (!ev->isAccepted())
876         QWidget::wheelEvent(ev);
877 }
878
879 void QWebPage::keyPressEvent(QKeyEvent *ev)
880 {
881     if (!mainFrame()->d->eventHandler)
882         return;
883
884     bool handled = false;
885     QWebFrame *frame = mainFrame();
886     WebCore::Editor *editor = frame->d->frame->editor();
887     if (editor->canEdit()) {
888         if (ev == QKeySequence::Cut) {
889             webActionTriggered(Cut);
890             handled = true;
891         } else if (ev == QKeySequence::Copy) {
892             webActionTriggered(Copy);
893             handled = true;
894         } else if (ev == QKeySequence::Paste) {
895             webActionTriggered(Paste);
896             handled = true;
897         } else if (ev == QKeySequence::Undo) {
898             webActionTriggered(Undo);
899             handled = true;
900         } else if (ev == QKeySequence::Redo) {
901             webActionTriggered(Redo);
902             handled = true;
903         } else if(ev == QKeySequence::MoveToNextChar) {
904             webActionTriggered(MoveToNextChar);
905             handled = true;
906         } else if(ev == QKeySequence::MoveToPreviousChar) {
907             webActionTriggered(MoveToPreviousChar);
908             handled = true;
909         } else if(ev == QKeySequence::MoveToNextWord) {
910             webActionTriggered(MoveToNextWord);
911             handled = true;
912         } else if(ev == QKeySequence::MoveToPreviousWord) {
913             webActionTriggered(MoveToPreviousWord);
914             handled = true;
915         } else if(ev == QKeySequence::MoveToNextLine) {
916             webActionTriggered(MoveToNextLine);
917             handled = true;
918         } else if(ev == QKeySequence::MoveToPreviousLine) {
919             webActionTriggered(MoveToPreviousLine);
920             handled = true;
921 //             } else if(ev == QKeySequence::MoveToNextPage) {
922 //             } else if(ev == QKeySequence::MoveToPreviousPage) {
923         } else if(ev == QKeySequence::MoveToStartOfLine) {
924             webActionTriggered(MoveToStartOfLine);
925             handled = true;
926         } else if(ev == QKeySequence::MoveToEndOfLine) {
927             webActionTriggered(MoveToEndOfLine);
928             handled = true;
929         } else if(ev == QKeySequence::MoveToStartOfBlock) {
930             webActionTriggered(MoveToStartOfBlock);
931             handled = true;
932         } else if(ev == QKeySequence::MoveToEndOfBlock) {
933             webActionTriggered(MoveToEndOfBlock);
934             handled = true;
935         } else if(ev == QKeySequence::MoveToStartOfDocument) {
936             webActionTriggered(MoveToStartOfDocument);
937             handled = true;
938         } else if(ev == QKeySequence::MoveToEndOfDocument) {
939             webActionTriggered(MoveToEndOfDocument);
940             handled = true;
941         } else if(ev == QKeySequence::SelectNextChar) {
942             webActionTriggered(SelectNextChar);
943             handled = true;
944         } else if(ev == QKeySequence::SelectPreviousChar) {
945             webActionTriggered(SelectPreviousChar);
946             handled = true;
947         } else if(ev == QKeySequence::SelectNextWord) {
948             webActionTriggered(SelectNextWord);
949             handled = true;
950         } else if(ev == QKeySequence::SelectPreviousWord) {
951             webActionTriggered(SelectPreviousWord);
952             handled = true;
953         } else if(ev == QKeySequence::SelectNextLine) {
954             webActionTriggered(SelectNextLine);
955             handled = true;
956         } else if(ev == QKeySequence::SelectPreviousLine) {
957             webActionTriggered(SelectPreviousLine);
958             handled = true;
959 //             } else if(ev == QKeySequence::SelectNextPage) {
960 //             } else if(ev == QKeySequence::SelectPreviousPage) {
961         } else if(ev == QKeySequence::SelectStartOfLine) {
962             webActionTriggered(SelectStartOfLine);
963             handled = true;
964         } else if(ev == QKeySequence::SelectEndOfLine) {
965             webActionTriggered(SelectEndOfLine);
966             handled = true;
967         } else if(ev == QKeySequence::SelectStartOfBlock) {
968             webActionTriggered(SelectStartOfBlock);
969             handled = true;
970         } else if(ev == QKeySequence::SelectEndOfBlock) {
971             webActionTriggered(SelectEndOfBlock);
972             handled = true;
973         } else if(ev == QKeySequence::SelectStartOfDocument) {
974             webActionTriggered(SelectStartOfDocument);
975             handled = true;
976         } else if(ev == QKeySequence::SelectEndOfDocument) {
977             webActionTriggered(SelectEndOfDocument);
978             handled = true;
979         } else if(ev == QKeySequence::DeleteStartOfWord) {
980             webActionTriggered(DeleteStartOfWord);
981             handled = true;
982         } else if(ev == QKeySequence::DeleteEndOfWord) {
983             webActionTriggered(DeleteEndOfWord);
984             handled = true;
985 //             } else if(ev == QKeySequence::DeleteEndOfLine) {
986         }
987     }
988     if (!handled) 
989         handled = frame->d->eventHandler->keyEvent(ev);
990     if (!handled) {
991         handled = true;
992         PlatformScrollbar *h, *v;
993         h = mainFrame()->d->horizontalScrollBar();
994         v = mainFrame()->d->verticalScrollBar();
995
996         if (ev == QKeySequence::MoveToNextPage) {
997             if (v)
998                 v->setValue(v->value() + height());
999         } else if (ev == QKeySequence::MoveToPreviousPage) {
1000             if (v)
1001                 v->setValue(v->value() - height());
1002         } else {
1003             switch (ev->key()) {
1004             case Qt::Key_Up:
1005                 if (v)
1006                     v->setValue(v->value() - 10);
1007                 break;
1008             case Qt::Key_Down:
1009                 if (v)
1010                     v->setValue(v->value() + 10);
1011                 break;
1012             case Qt::Key_Left:
1013                 if (h)
1014                     h->setValue(h->value() - 10);
1015                 break;
1016             case Qt::Key_Right:
1017                 if (h)
1018                     h->setValue(h->value() + 10);
1019                 break;
1020             default:
1021                 handled = false;
1022                 break;
1023             }
1024         }
1025     }
1026
1027     ev->setAccepted(handled);
1028 }
1029
1030 void QWebPage::keyReleaseEvent(QKeyEvent *ev)
1031 {
1032     if (ev->isAutoRepeat()) {
1033         ev->setAccepted(true);
1034         return;
1035     }
1036
1037     if (!mainFrame()->d->eventHandler)
1038         return;
1039
1040     bool handled = mainFrame()->d->eventHandler->keyEvent(ev);
1041     ev->setAccepted(handled);
1042 }
1043
1044 void QWebPage::focusInEvent(QFocusEvent *ev)
1045 {
1046     if (ev->reason() != Qt::PopupFocusReason) 
1047         mainFrame()->d->frame->page()->focusController()->setFocusedFrame(mainFrame()->d->frame);
1048     QWidget::focusInEvent(ev);
1049 }
1050
1051 void QWebPage::focusOutEvent(QFocusEvent *ev)
1052 {
1053     QWidget::focusOutEvent(ev);
1054     if (ev->reason() != Qt::PopupFocusReason) {
1055         mainFrame()->d->frame->selectionController()->clear();
1056         mainFrame()->d->frame->setIsActive(false);
1057     }
1058 }
1059
1060 bool QWebPage::focusNextPrevChild(bool next)
1061 {
1062     Q_UNUSED(next)
1063     return false;
1064 }
1065
1066 void QWebPage::dragEnterEvent(QDragEnterEvent *ev)
1067 {
1068 #ifndef QT_NO_DRAGANDDROP
1069     DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), 
1070                       dropActionToDragOp(ev->possibleActions()));
1071     Qt::DropAction action = dragOpToDropAction(d->page->dragController()->dragEntered(&dragData));
1072     ev->setDropAction(action);
1073     ev->accept();
1074 #endif
1075 }
1076
1077 void QWebPage::dragLeaveEvent(QDragLeaveEvent *ev)
1078 {
1079 #ifndef QT_NO_DRAGANDDROP
1080     DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone);
1081     d->page->dragController()->dragExited(&dragData);
1082     ev->accept();
1083 #endif
1084 }
1085
1086 void QWebPage::dragMoveEvent(QDragMoveEvent *ev)
1087 {
1088 #ifndef QT_NO_DRAGANDDROP
1089     DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), 
1090                       dropActionToDragOp(ev->possibleActions()));
1091     Qt::DropAction action = dragOpToDropAction(d->page->dragController()->dragUpdated(&dragData));
1092     ev->setDropAction(action);
1093     ev->accept();
1094 #endif
1095 }
1096
1097 void QWebPage::dropEvent(QDropEvent *ev)
1098 {
1099 #ifndef QT_NO_DRAGANDDROP
1100     DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), 
1101                       dropActionToDragOp(ev->possibleActions()));
1102     Qt::DropAction action = dragOpToDropAction(d->page->dragController()->performDrag(&dragData));
1103     ev->accept();
1104 #endif
1105 }
1106
1107 void QWebPage::setNetworkInterface(QWebNetworkInterface *interface)
1108 {
1109     d->networkInterface = interface;
1110 }
1111
1112 QWebNetworkInterface *QWebPage::networkInterface() const
1113 {
1114     if (d->networkInterface)
1115         return d->networkInterface;
1116     else
1117         return QWebNetworkInterface::defaultInterface();
1118 }
1119
1120 QPixmap QWebPage::icon() const
1121 {
1122     Image* image = iconDatabase()->iconForPageURL(url().toString(), IntSize(16, 16));
1123     if (!image || image->isNull()) {
1124         image = iconDatabase()->defaultIcon(IntSize(16, 16));
1125     }
1126
1127     if (!image) {
1128         return QPixmap();
1129     }
1130
1131     QPixmap *icon = image->getPixmap();
1132     if (!icon) {
1133         return QPixmap();
1134     }
1135     return *icon;
1136 }
1137
1138 QWebSettings *QWebPage::settings()
1139 {
1140     return d->settings;
1141 }
1142
1143 QString QWebPage::chooseFile(QWebFrame *parentFrame, const QString& oldFile)
1144 {
1145     //FIXME frame pos...
1146 #ifndef QT_NO_FILEDIALOG
1147     return QFileDialog::getOpenFileName(this, QString::null, oldFile);
1148 #else
1149     return QString::null;
1150 #endif
1151 }
1152
1153 #ifndef QT_NO_NETWORKPROXY
1154 void QWebPage::setNetworkProxy(const QNetworkProxy& proxy)
1155 {
1156     d->networkProxy = proxy;
1157 }
1158
1159 QNetworkProxy QWebPage::networkProxy() const
1160 {
1161     return d->networkProxy;
1162 }
1163 #endif
1164
1165 QString QWebPage::userAgentStringForUrl(const QUrl& forUrl) const {
1166     Q_UNUSED(forUrl)
1167     return QLatin1String("Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en) AppleWebKit/418.9.1 (KHTML, like Gecko) Safari/419.3 Qt");
1168 }
1169
1170
1171 void QWebPagePrivate::_q_onLoadProgressChanged(int) {
1172     m_totalBytes = page->progress()->totalPageAndResourceBytesToLoad();
1173     m_bytesReceived = page->progress()->totalBytesReceived();
1174 }
1175
1176
1177 quint64 QWebPage::totalBytes() const {
1178     return d->m_bytesReceived;
1179 }
1180
1181
1182 quint64 QWebPage::bytesReceived() const {
1183     return d->m_totalBytes;
1184 }
1185
1186 QWebPageContext::QWebPageContext(const WebCore::HitTestResult &hitTest)
1187     : d(new QWebPageContextPrivate)
1188 {
1189     d->pos = hitTest.point();
1190     d->text = hitTest.textContent();
1191     d->linkUrl = hitTest.absoluteLinkURL().url();
1192     d->imageUrl = hitTest.absoluteImageURL().url();
1193     WebCore::Image *img = hitTest.image();
1194     if (img) {
1195         QPixmap *pix = img->getPixmap();
1196         if (pix)
1197             d->image = *pix;
1198     }
1199     WebCore::Frame *frame = hitTest.targetFrame();
1200     if (frame)
1201         d->targetFrame = frame->view()->qwebframe();
1202 }
1203
1204 QWebPageContext::QWebPageContext()
1205     : d(0)
1206 {
1207 }
1208
1209 QWebPageContext::QWebPageContext(const QWebPageContext &other)
1210     : d(0)
1211 {
1212     if (other.d)
1213         d = new QWebPageContextPrivate(*other.d);
1214 }
1215
1216 QWebPageContext &QWebPageContext::operator=(const QWebPageContext &other)
1217 {
1218     if (this != &other) {
1219         if (other.d) {
1220             if (!d)
1221                 d = new QWebPageContextPrivate;
1222             *d = *other.d;
1223         } else {
1224             delete d;
1225             d = 0;
1226         }
1227     }
1228     return *this;
1229 }
1230
1231 QWebPageContext::~QWebPageContext()
1232 {
1233     delete d;
1234 }
1235
1236 QPoint QWebPageContext::pos() const
1237 {
1238     if (!d)
1239         return QPoint();
1240     return d->pos;
1241 }
1242
1243 QString QWebPageContext::text() const
1244 {
1245     if (!d)
1246         return QString();
1247     return d->text;
1248 }
1249
1250 QUrl QWebPageContext::linkUrl() const
1251 {
1252     if (!d)
1253         return QUrl();
1254     return d->linkUrl;
1255 }
1256
1257 QUrl QWebPageContext::imageUrl() const
1258 {
1259     if (!d)
1260         return QUrl();
1261     return d->linkUrl;
1262 }
1263
1264 QPixmap QWebPageContext::image() const
1265 {
1266     if (!d)
1267         return QPixmap();
1268     return d->image;
1269 }
1270
1271 QWebFrame *QWebPageContext::targetFrame() const
1272 {
1273     if (!d)
1274         return 0;
1275     return d->targetFrame;
1276 }
1277
1278 #include "moc_qwebpage.cpp"