Moved all the event handlers from QWebFrame into QWebPage.
[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 "ContextMenuClientQt.h"
37 #include "DragClientQt.h"
38 #include "DragController.h"
39 #include "DragData.h"
40 #include "EditorClientQt.h"
41 #include "Settings.h"
42 #include "Page.h"
43 #include "FrameLoader.h"
44 #include "KURL.h"
45 #include "Image.h"
46 #include "IconDatabase.h"
47 #include "InspectorClientQt.h"
48 #include "FocusController.h"
49 #include "Editor.h"
50 #include "PlatformScrollBar.h"
51 #include "PlatformKeyboardEvent.h"
52 #include "PlatformWheelEvent.h"
53 #include "ProgressTracker.h"
54 #include "HitTestResult.h"
55
56 #include <QDebug>
57 #include <QDragEnterEvent>
58 #include <QDragLeaveEvent>
59 #include <QDragMoveEvent>
60 #include <QDropEvent>
61 #include <QFileDialog>
62 #include <QHttpRequestHeader>
63 #include <QInputDialog>
64 #include <QMessageBox>
65 #include <QNetworkProxy>
66 #include <QUndoStack>
67 #include <QUrl>
68 #include <QPainter>
69
70 using namespace WebCore;
71
72 QWebPagePrivate::QWebPagePrivate(QWebPage *qq)
73     : q(qq)
74     , modified(false)
75 {
76     q->setMouseTracking(true);
77     q->setFocusPolicy(Qt::ClickFocus);
78     chromeClient = new ChromeClientQt(q);
79     contextMenuClient = new ContextMenuClientQt();
80     editorClient = new EditorClientQt(q);
81     page = new Page(chromeClient, contextMenuClient, editorClient,
82                     new DragClientQt(q), new InspectorClientQt());
83
84     undoStack = 0;
85     mainFrame = 0;
86     networkInterface = 0;
87     insideOpenCall = false;
88 }
89
90 QWebPagePrivate::~QWebPagePrivate()
91 {
92     delete undoStack;
93     delete page;
94 }
95
96 QWebPage::NavigationRequestResponse QWebPagePrivate::navigationRequested(QWebFrame *frame, const QWebNetworkRequest &request, QWebPage::NavigationType type)
97 {
98     if (insideOpenCall
99         && frame == mainFrame)
100         return QWebPage::AcceptNavigationRequest;
101     return q->navigationRequested(frame, request, type);
102 }
103
104 void QWebPagePrivate::createMainFrame()
105 {
106     if (!mainFrame) {
107         QWebFrameData frameData;
108         frameData.ownerElement = 0;
109         frameData.allowsScrolling = true;
110         frameData.marginWidth = 0;
111         frameData.marginHeight = 0;
112         mainFrame = q->createFrame(0, &frameData);
113         QObject::connect(mainFrame, SIGNAL(titleChanged(const QString&)),
114                 q, SIGNAL(titleChanged(const QString&)));
115         QObject::connect(mainFrame, SIGNAL(hoveringOverLink(const QString&, const QString&)),
116                 q, SIGNAL(hoveringOverLink(const QString&, const QString&)));
117         
118         mainFrame->d->frameView->setFrameGeometry(q->geometry());
119     }
120 }
121
122 QWebFrame *QWebPagePrivate::frameAt(const QPoint &pos) const
123 {
124     QWebFrame *frame = mainFrame;
125
126 redo:
127     QList<QWebFrame*> children = frame->childFrames();
128     for (int i = 0; i < children.size(); ++i) {
129         if (children.at(i)->geometry().contains(pos)) {
130             frame = children.at(i);
131             goto redo;
132         }
133     }
134     if (frame->geometry().contains(pos))
135         return frame;
136     return 0;
137 }
138
139 QWebPage::QWebPage(QWidget *parent)
140     : QWidget(parent)
141     , d(new QWebPagePrivate(this))
142 {
143     setSettings(QWebSettings::global());
144     QPalette pal = palette();
145     pal.setBrush(QPalette::Background, Qt::white);
146
147     setAttribute(Qt::WA_OpaquePaintEvent);
148
149     setPalette(pal);
150     setAcceptDrops(true);
151     connect(this, SIGNAL(loadProgressChanged(int)), this, SLOT(onLoadProgressChanged(int)));
152 }
153
154 QWebPage::~QWebPage()
155 {
156     FrameLoader *loader = d->mainFrame->d->frame->loader();
157     if (loader)
158         loader->detachFromParent();
159     delete d;
160 }
161
162 QWebFrame *QWebPage::createFrame(QWebFrame *parentFrame, QWebFrameData *frameData)
163 {
164     if (parentFrame)
165         return new QWebFrame(parentFrame, frameData);
166     QWebFrame *f = new QWebFrame(this, frameData);
167     return f;
168 }
169
170 void QWebPage::open(const QUrl &url)
171 {
172     open(QWebNetworkRequest(url));
173 }
174
175 void QWebPage::open(const QWebNetworkRequest &req)
176 {
177     d->insideOpenCall = true;
178
179     QUrl url = req.url();
180     QHttpRequestHeader httpHeader = req.httpHeader();
181     QByteArray postData = req.postData();
182
183     WebCore::ResourceRequest request(KURL(url.toString()));
184
185     QString method = httpHeader.method();
186     if (!method.isEmpty())
187         request.setHTTPMethod(method);
188
189     QList<QPair<QString, QString> > values = httpHeader.values();
190     for (int i = 0; i < values.size(); ++i) {
191         const QPair<QString, QString> &val = values.at(i);
192         request.addHTTPHeaderField(val.first, val.second);
193     }
194
195     if (!postData.isEmpty()) {
196         WTF::RefPtr<WebCore::FormData> formData = new WebCore::FormData(postData.constData(), postData.size());
197         request.setHTTPBody(formData);
198     }
199
200     mainFrame()->d->frame->loader()->load(request);
201     d->insideOpenCall = false;
202 }
203
204 QUrl QWebPage::url() const
205 {
206     return QUrl((QString)mainFrame()->d->frame->loader()->url().url());
207 }
208
209 QString QWebPage::title() const
210 {
211     return mainFrame()->title();
212 }
213
214 QWebFrame *QWebPage::mainFrame() const
215 {
216     d->createMainFrame();
217     return d->mainFrame;
218 }
219
220 QSize QWebPage::sizeHint() const
221 {
222     return QSize(800, 600);
223 }
224
225 void QWebPage::stop()
226 {
227     FrameLoader *f = mainFrame()->d->frame->loader();
228     f->stopForUserCancel();
229 }
230
231 QWebPageHistory QWebPage::history() const
232 {
233     WebCore::BackForwardList *lst = d->page->backForwardList();
234     QWebPageHistoryPrivate *priv = new QWebPageHistoryPrivate(lst);
235     return QWebPageHistory(priv);
236 }
237
238 void QWebPage::goBack()
239 {
240     d->page->goBack();
241 }
242
243 void QWebPage::goForward()
244 {
245     d->page->goForward();
246 }
247
248 void QWebPage::goToHistoryItem(const QWebHistoryItem &item)
249 {
250     d->page->goToItem(item.d->item, FrameLoadTypeIndexedBackForward);
251 }
252
253 void QWebPage::javaScriptConsoleMessage(const QString& message, unsigned int lineNumber, const QString& sourceID)
254 {
255 }
256
257 void QWebPage::javaScriptAlert(QWebFrame *frame, const QString& msg)
258 {
259     //FIXME frame pos...
260     QMessageBox::information(this, title(), msg, QMessageBox::Ok);
261 }
262
263 bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg)
264 {
265     //FIXME frame pos...
266     return 0 == QMessageBox::information(this, title(), msg, QMessageBox::Yes, QMessageBox::No);
267 }
268
269 bool QWebPage::javaScriptPrompt(QWebFrame *frame, const QString& msg, const QString& defaultValue, QString* result)
270 {
271     //FIXME frame pos...
272     bool ok = false;
273 #ifndef QT_NO_INPUTDIALOG
274     QString x = QInputDialog::getText(this, title(), msg, QLineEdit::Normal, defaultValue, &ok);
275     if (ok && result) {
276         *result = x;
277     }
278 #endif
279     return ok;
280 }
281
282 QWebPage *QWebPage::createWindow()
283 {
284     return 0;
285 }
286
287 QWebPage *QWebPage::createModalDialog()
288 {
289     return 0;
290 }
291
292 QObject *QWebPage::createPlugin(const QString &classid, const QUrl &url, const QStringList &paramNames, const QStringList &paramValues)
293 {
294     Q_UNUSED(classid)
295     Q_UNUSED(url)
296     Q_UNUSED(paramNames)
297     Q_UNUSED(paramValues)
298     return 0;
299 }
300
301 QWebPage::NavigationRequestResponse QWebPage::navigationRequested(QWebFrame *frame, const QWebNetworkRequest &request, QWebPage::NavigationType type)
302 {
303     Q_UNUSED(request)
304     return AcceptNavigationRequest;
305 }
306
307 void QWebPage::setWindowGeometry(const QRect& geom)
308 {
309     Q_UNUSED(geom)
310 }
311
312 bool QWebPage::canCut() const
313 {
314     return d->page->focusController()->focusedOrMainFrame()->editor()->canCut();
315 }
316
317 bool QWebPage::canCopy() const
318 {
319     return d->page->focusController()->focusedOrMainFrame()->editor()->canCopy();
320 }
321
322 bool QWebPage::canPaste() const
323 {
324     return d->page->focusController()->focusedOrMainFrame()->editor()->canPaste();
325 }
326
327 void QWebPage::cut()
328 {
329     d->page->focusController()->focusedOrMainFrame()->editor()->cut();
330 }
331
332 void QWebPage::copy()
333 {
334     d->page->focusController()->focusedOrMainFrame()->editor()->copy();
335 }
336
337 void QWebPage::paste()
338 {
339     d->page->focusController()->focusedOrMainFrame()->editor()->paste();
340 }
341
342 /*!
343   Returns true if the page contains unsubmitted form data.
344 */
345 bool QWebPage::isModified() const
346 {
347     return d->modified;
348 }
349
350
351 QUndoStack *QWebPage::undoStack()
352 {
353     if (!d->undoStack)
354         d->undoStack = new QUndoStack(this);
355
356     return d->undoStack;
357 }
358
359 static inline DragOperation dropActionToDragOp(Qt::DropActions actions)
360 {
361     unsigned result = 0;
362     if (actions & Qt::CopyAction)
363         result |= DragOperationCopy;
364     if (actions & Qt::MoveAction)
365         result |= DragOperationMove;
366     if (actions & Qt::LinkAction)
367         result |= DragOperationLink;
368     return (DragOperation)result;    
369 }
370
371 static inline Qt::DropAction dragOpToDropAction(unsigned actions)
372 {
373     Qt::DropAction result = Qt::IgnoreAction;
374     if (actions & DragOperationCopy)
375         result = Qt::CopyAction;
376     else if (actions & DragOperationMove)
377         result = Qt::MoveAction;
378     else if (actions & DragOperationLink)
379         result = Qt::LinkAction;
380     return result;    
381 }
382
383 void QWebPage::resizeEvent(QResizeEvent *e)
384 {
385     QWidget::resizeEvent(e);
386     if (mainFrame()->d->frame && mainFrame()->d->frameView) {
387         mainFrame()->d->frameView->setFrameGeometry(rect());
388         mainFrame()->d->frame->forceLayout();
389         mainFrame()->d->frame->view()->adjustViewSize();
390     }
391 }
392
393 void QWebPage::paintEvent(QPaintEvent *ev)
394 {
395 #ifdef QWEBKIT_TIME_RENDERING
396     QTime time;
397     time.start();
398 #endif
399
400     QPainter p(this);
401
402     QVector<QRect> vector = ev->region().rects();
403     if (!vector.isEmpty()) {
404         for (int i = 0; i < vector.size(); ++i) {
405             mainFrame()->render(&p, vector.at(i));
406         }
407     } else {
408         mainFrame()->render(&p, ev->rect());
409     }
410
411 #ifdef    QWEBKIT_TIME_RENDERING
412     int elapsed = time.elapsed();
413     qDebug()<<"paint event on "<<ev->region()<<", took to render =  "<<elapsed;
414 #endif
415 }
416
417 void QWebPage::mouseMoveEvent(QMouseEvent *ev)
418 {
419     QWebFramePrivate *frame = d->currentFrame(ev->pos())->d;
420     if (!frame->frameView)
421         return;
422
423     frame->eventHandler->handleMouseMoveEvent(PlatformMouseEvent(ev, 0));
424     const int xOffset =
425         frame->horizontalScrollBar() ? frame->horizontalScrollBar()->value() : 0;
426     const int yOffset =
427         frame->verticalScrollBar() ? frame->verticalScrollBar()->value() : 0;
428     IntPoint pt(ev->x() + xOffset, ev->y() + yOffset);
429     WebCore::HitTestResult result = frame->eventHandler->hitTestResultAtPoint(pt, false);
430     WebCore::Element *link = result.URLElement();
431     if (link != frame->lastHoverElement) {
432         frame->lastHoverElement = link;
433         emit hoveringOverLink(result.absoluteLinkURL().prettyURL(), result.title());
434     }
435 }
436
437 void QWebPage::mousePressEvent(QMouseEvent *ev)
438 {
439     d->frameUnderMouse = d->frameAt(ev->pos());
440     QWebFramePrivate *frame = d->frameUnderMouse->d;
441     if (!frame->eventHandler)
442         return;
443
444     if (ev->button() == Qt::RightButton)
445         frame->eventHandler->sendContextMenuEvent(PlatformMouseEvent(ev, 1));
446     else
447         frame->eventHandler->handleMousePressEvent(PlatformMouseEvent(ev, 1));
448
449     //FIXME need to keep track of subframe focus for key events!
450     frame->page->setFocus();
451 }
452
453 void QWebPage::mouseDoubleClickEvent(QMouseEvent *ev)
454 {
455     QWebFramePrivate *frame = d->currentFrame(ev->pos())->d;
456     if (!frame->eventHandler)
457         return;
458
459     frame->eventHandler->handleMousePressEvent(PlatformMouseEvent(ev, 2));
460
461     //FIXME need to keep track of subframe focus for key events!
462     frame->page->setFocus();
463 }
464
465 void QWebPage::mouseReleaseEvent(QMouseEvent *ev)
466 {
467     QWebFramePrivate *frame = d->currentFrame(ev->pos())->d;
468     if (frame->frameView) {
469         frame->eventHandler->handleMouseReleaseEvent(PlatformMouseEvent(ev, 0));
470
471         //FIXME need to keep track of subframe focus for key events!
472         frame->page->setFocus();
473     }
474     d->frameUnderMouse = 0;
475 }
476
477 void QWebPage::wheelEvent(QWheelEvent *ev)
478 {
479     QWebFramePrivate *frame = d->currentFrame(ev->pos())->d;
480
481     bool accepted = false;
482     if (frame->eventHandler) {
483         WebCore::PlatformWheelEvent pev(ev);
484         accepted = frame->eventHandler->handleWheelEvent(pev);
485     }
486
487     ev->setAccepted(accepted);
488
489     //FIXME need to keep track of subframe focus for key events!
490     frame->page->setFocus();
491
492     if (!ev->isAccepted())
493         QWidget::wheelEvent(ev);
494 }
495
496 void QWebPage::keyPressEvent(QKeyEvent *ev)
497 {
498     if (!mainFrame()->d->eventHandler)
499         return;
500
501     bool handled = false;
502     QWebFrame *frame = mainFrame();
503     WebCore::Editor *editor = frame->d->frame->editor();
504     if (editor->canEdit()) {
505         const char *command = 0;
506         if (ev == QKeySequence::Cut) {
507             editor->cut();
508             handled = true;
509         } else if (ev == QKeySequence::Copy) {
510             editor->copy();
511             handled = true;
512         } else if (ev == QKeySequence::Paste) {
513             editor->paste();
514             handled = true;
515         } else if (ev == QKeySequence::Undo) {
516             editor->undo();
517             handled = true;
518         } else if (ev == QKeySequence::Redo) {
519             editor->redo();
520             handled = true;
521         } else if(ev == QKeySequence::MoveToNextChar) {
522             command = "MoveForward";
523         } else if(ev == QKeySequence::MoveToPreviousChar) {
524             command = "MoveBackward";
525         } else if(ev == QKeySequence::MoveToNextWord) {
526             command = "MoveWordForward";
527         } else if(ev == QKeySequence::MoveToPreviousWord) {
528             command = "MoveWordBackward";
529         } else if(ev == QKeySequence::MoveToNextLine) {
530             command = "MoveDown";
531         } else if(ev == QKeySequence::MoveToPreviousLine) {
532             command = "MoveUp";
533 //             } else if(ev == QKeySequence::MoveToNextPage) {
534 //             } else if(ev == QKeySequence::MoveToPreviousPage) {
535         } else if(ev == QKeySequence::MoveToStartOfLine) {
536             command = "MoveToBeginningOfLine";
537         } else if(ev == QKeySequence::MoveToEndOfLine) {
538             command = "MoveToEndOfLine";
539         } else if(ev == QKeySequence::MoveToStartOfBlock) {
540             command = "MoveToBeginningOfParagraph";
541         } else if(ev == QKeySequence::MoveToEndOfBlock) {
542             command = "MoveToEndOfParagraph";
543         } else if(ev == QKeySequence::MoveToStartOfDocument) {
544             command = "MoveToBeginningOfDocument";
545         } else if(ev == QKeySequence::MoveToEndOfDocument) {
546             command = "MoveToEndOfDocument";
547         } else if(ev == QKeySequence::SelectNextChar) {
548             command = "MoveForwardAndModifySelection";
549         } else if(ev == QKeySequence::SelectPreviousChar) {
550             command = "MoveBackwardAndModifySelection";
551         } else if(ev == QKeySequence::SelectNextWord) {
552             command = "MoveWordForwardAndModifySelection";
553         } else if(ev == QKeySequence::SelectPreviousWord) {
554             command = "MoveWordBackwardAndModifySelection";
555         } else if(ev == QKeySequence::SelectNextLine) {
556             command = "MoveDownAndModifySelection";
557         } else if(ev == QKeySequence::SelectPreviousLine) {
558             command = "MoveUpAndModifySelection";
559 //             } else if(ev == QKeySequence::SelectNextPage) {
560 //             } else if(ev == QKeySequence::SelectPreviousPage) {
561         } else if(ev == QKeySequence::SelectStartOfLine) {
562             command = "MoveToBeginningOfLineAndModifySelection";
563         } else if(ev == QKeySequence::SelectEndOfLine) {
564             command = "MoveToEndOfLineAndModifySelection";
565         } else if(ev == QKeySequence::SelectStartOfBlock) {
566             command = "MoveToBeginningOfParagraphAndModifySelection";
567         } else if(ev == QKeySequence::SelectEndOfBlock) {
568             command = "MoveToEndOfParagraphAndModifySelection";
569         } else if(ev == QKeySequence::SelectStartOfDocument) {
570             command = "MoveToBeginningOfDocumentAndModifySelection";
571         } else if(ev == QKeySequence::SelectEndOfDocument) {
572             command = "MoveToEndOfDocumentAndModifySelection";
573         } else if(ev == QKeySequence::DeleteStartOfWord) {
574             command = "DeleteWordBackward";
575         } else if(ev == QKeySequence::DeleteEndOfWord) {
576             command = "DeleteWordForward";
577 //             } else if(ev == QKeySequence::DeleteEndOfLine) {
578         }
579         if (command) {
580             editor->execCommand(command);
581             handled = true;
582         }
583     }
584     if (!handled) 
585         handled = frame->d->eventHandler->keyEvent(ev);
586     if (!handled) {
587         handled = true;
588         PlatformScrollbar *h, *v;
589         h = mainFrame()->d->horizontalScrollBar();
590         v = mainFrame()->d->verticalScrollBar();
591
592         if (ev == QKeySequence::MoveToNextPage) {
593             if (v)
594                 v->setValue(v->value() + height());
595         } else if (ev == QKeySequence::MoveToPreviousPage) {
596             if (v)
597                 v->setValue(v->value() - height());
598         } else {
599             switch (ev->key()) {
600             case Qt::Key_Up:
601                 if (v)
602                     v->setValue(v->value() - 10);
603                 break;
604             case Qt::Key_Down:
605                 if (v)
606                     v->setValue(v->value() + 10);
607                 break;
608             case Qt::Key_Left:
609                 if (h)
610                     h->setValue(h->value() - 10);
611                 break;
612             case Qt::Key_Right:
613                 if (h)
614                     h->setValue(h->value() + 10);
615                 break;
616             default:
617                 handled = false;
618                 break;
619             }
620         }
621     }
622
623     ev->setAccepted(handled);
624 }
625
626 void QWebPage::keyReleaseEvent(QKeyEvent *ev)
627 {
628     if (ev->isAutoRepeat()) {
629         ev->setAccepted(true);
630         return;
631     }
632
633     if (!mainFrame()->d->eventHandler)
634         return;
635
636     bool handled = mainFrame()->d->eventHandler->keyEvent(ev);
637     ev->setAccepted(handled);
638 }
639
640 void QWebPage::focusInEvent(QFocusEvent *ev)
641 {
642     if (ev->reason() != Qt::PopupFocusReason) 
643         mainFrame()->d->frame->page()->focusController()->setFocusedFrame(mainFrame()->d->frame);
644     QWidget::focusInEvent(ev);
645 }
646
647 void QWebPage::focusOutEvent(QFocusEvent *ev)
648 {
649     QWidget::focusOutEvent(ev);
650     if (ev->reason() != Qt::PopupFocusReason) {
651         mainFrame()->d->frame->selectionController()->clear();
652         mainFrame()->d->frame->setIsActive(false);
653     }
654 }
655
656 bool QWebPage::focusNextPrevChild(bool next)
657 {
658     Q_UNUSED(next)
659     return false;
660 }
661
662 void QWebPage::dragEnterEvent(QDragEnterEvent *ev)
663 {
664 #ifndef QT_NO_DRAGANDDROP
665     DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), 
666                       dropActionToDragOp(ev->possibleActions()));
667     Qt::DropAction action = dragOpToDropAction(d->page->dragController()->dragEntered(&dragData));
668     ev->setDropAction(action);
669     ev->accept();
670 #endif
671 }
672
673 void QWebPage::dragLeaveEvent(QDragLeaveEvent *ev)
674 {
675 #ifndef QT_NO_DRAGANDDROP
676     DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone);
677     d->page->dragController()->dragExited(&dragData);
678     ev->accept();
679 #endif
680 }
681
682 void QWebPage::dragMoveEvent(QDragMoveEvent *ev)
683 {
684 #ifndef QT_NO_DRAGANDDROP
685     DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), 
686                       dropActionToDragOp(ev->possibleActions()));
687     Qt::DropAction action = dragOpToDropAction(d->page->dragController()->dragUpdated(&dragData));
688     ev->setDropAction(action);
689     ev->accept();
690 #endif
691 }
692
693 void QWebPage::dropEvent(QDropEvent *ev)
694 {
695 #ifndef QT_NO_DRAGANDDROP
696     DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), 
697                       dropActionToDragOp(ev->possibleActions()));
698     Qt::DropAction action = dragOpToDropAction(d->page->dragController()->performDrag(&dragData));
699     ev->accept();
700 #endif
701 }
702
703 void QWebPage::setNetworkInterface(QWebNetworkInterface *interface)
704 {
705     d->networkInterface = interface;
706 }
707
708 QWebNetworkInterface *QWebPage::networkInterface() const
709 {
710     if (d->networkInterface)
711         return d->networkInterface;
712     else
713         return QWebNetworkInterface::defaultInterface();
714 }
715
716 QPixmap QWebPage::icon() const
717 {
718     Image* image = iconDatabase()->iconForPageURL(url().toString(), IntSize(16, 16));
719     if (!image || image->isNull()) {
720         image = iconDatabase()->defaultIcon(IntSize(16, 16));
721     }
722
723     if (!image) {
724         return QPixmap();
725     }
726
727     QPixmap *icon = image->getPixmap();
728     if (!icon) {
729         return QPixmap();
730     }
731     return *icon;
732 }
733
734 void QWebPage::setSettings(const QWebSettings &settings)
735 {
736     WebCore::Settings *wSettings = d->page->settings();
737
738     wSettings->setStandardFontFamily(
739         settings.fontFamily(QWebSettings::StandardFont));
740     wSettings->setFixedFontFamily(
741         settings.fontFamily(QWebSettings::FixedFont));
742     wSettings->setSerifFontFamily(
743         settings.fontFamily(QWebSettings::SerifFont));
744     wSettings->setSansSerifFontFamily(
745         settings.fontFamily(QWebSettings::SansSerifFont));
746     wSettings->setCursiveFontFamily(
747         settings.fontFamily(QWebSettings::CursiveFont));
748     wSettings->setFantasyFontFamily(
749         settings.fontFamily(QWebSettings::FantasyFont));
750
751     wSettings->setMinimumFontSize(settings.minimumFontSize());
752     wSettings->setMinimumLogicalFontSize(settings.minimumLogicalFontSize());
753     wSettings->setDefaultFontSize(settings.defaultFontSize());
754     wSettings->setDefaultFixedFontSize(settings.defaultFixedFontSize());
755
756     wSettings->setLoadsImagesAutomatically(
757         settings.testAttribute(QWebSettings::AutoLoadImages));
758     wSettings->setJavaScriptEnabled(
759         settings.testAttribute(QWebSettings::JavascriptEnabled));
760     wSettings->setJavaScriptCanOpenWindowsAutomatically(
761         settings.testAttribute(QWebSettings::JavascriptCanOpenWindows));
762     wSettings->setJavaEnabled(
763         settings.testAttribute(QWebSettings::JavaEnabled));
764     wSettings->setPluginsEnabled(
765         settings.testAttribute(QWebSettings::PluginsEnabled));
766     wSettings->setPrivateBrowsingEnabled(
767         settings.testAttribute(QWebSettings::PrivateBrowsingEnabled));
768
769     wSettings->setUserStyleSheetLocation(KURL(settings.userStyleSheetLocation()));
770
771     // ### should be configurable
772     wSettings->setDefaultTextEncodingName("iso-8859-1");
773     wSettings->setDOMPasteAllowed(true);
774 }
775
776 QWebSettings QWebPage::settings() const
777 {
778     QWebSettings settings;
779     WebCore::Settings *wSettings = d->page->settings();
780
781     settings.setFontFamily(QWebSettings::StandardFont,
782                            wSettings->standardFontFamily());
783     settings.setFontFamily(QWebSettings::FixedFont,
784                            wSettings->fixedFontFamily());
785     settings.setFontFamily(QWebSettings::SerifFont,
786                            wSettings->serifFontFamily());
787     settings.setFontFamily(QWebSettings::SansSerifFont,
788                            wSettings->sansSerifFontFamily());
789     settings.setFontFamily(QWebSettings::CursiveFont,
790                            wSettings->cursiveFontFamily());
791     settings.setFontFamily(QWebSettings::FantasyFont,
792                            wSettings->fantasyFontFamily());
793
794     settings.setMinimumFontSize(wSettings->minimumFontSize());
795     settings.setMinimumLogicalFontSize(wSettings->minimumLogicalFontSize());
796     settings.setDefaultFontSize(wSettings->defaultFontSize());
797     settings.setDefaultFixedFontSize(wSettings->defaultFixedFontSize());
798
799     settings.setAttribute(QWebSettings::AutoLoadImages,
800                           wSettings->loadsImagesAutomatically());
801     settings.setAttribute(QWebSettings::JavascriptEnabled,
802                           wSettings->isJavaScriptEnabled());
803     settings.setAttribute(QWebSettings::JavascriptCanOpenWindows,
804                           wSettings->JavaScriptCanOpenWindowsAutomatically());
805     settings.setAttribute(QWebSettings::JavaEnabled,
806                           wSettings->isJavaEnabled());
807     settings.setAttribute(QWebSettings::PluginsEnabled,
808                           wSettings->arePluginsEnabled());
809     settings.setAttribute(QWebSettings::PrivateBrowsingEnabled,
810                           wSettings->privateBrowsingEnabled());
811
812     settings.setUserStyleSheetLocation(
813         wSettings->userStyleSheetLocation().url());
814
815     return settings;
816 }
817
818 QString QWebPage::chooseFile(QWebFrame *parentFrame, const QString& oldFile)
819 {
820     //FIXME frame pos...
821 #ifndef QT_NO_FILEDIALOG
822     return QFileDialog::getOpenFileName(this, QString::null, oldFile);
823 #else
824     return QString::null;
825 #endif
826 }
827
828 #ifndef QT_NO_NETWORKPROXY
829 void QWebPage::setNetworkProxy(const QNetworkProxy& proxy)
830 {
831     d->networkProxy = proxy;
832 }
833
834 QNetworkProxy QWebPage::networkProxy() const
835 {
836     return d->networkProxy;
837 }
838 #endif
839
840 QString QWebPage::userAgentStringForUrl(const QUrl& forUrl) const {
841     Q_UNUSED(forUrl)
842     return QLatin1String("Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en) AppleWebKit/418.9.1 (KHTML, like Gecko) Safari/419.3 Qt");
843 }
844
845
846 void QWebPage::onLoadProgressChanged(int) {
847     d->m_totalBytes = d->page->progress()->totalPageAndResourceBytesToLoad();
848     d->m_bytesReceived = d->page->progress()->totalBytesReceived();
849 }
850
851
852 quint64 QWebPage::totalBytes() const {
853     return d->m_bytesReceived;
854 }
855
856
857 quint64 QWebPage::bytesReceived() const {
858     return d->m_totalBytes;
859 }