Added a QWebNetworkRequest convenience constructor.
[WebKit-https.git] / WebKitQt / 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., 59 Temple Place - Suite 330,
19     Boston, MA 02111-1307, 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
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
46 #include <QDebug>
47 #include <QDragEnterEvent>
48 #include <QDragLeaveEvent>
49 #include <QDragMoveEvent>
50 #include <QDropEvent>
51 #include <QUndoStack>
52 #include <QUrl>
53 #include <QVBoxLayout>
54 #include <QHttpRequestHeader>
55
56 using namespace WebCore;
57
58 QWebPagePrivate::QWebPagePrivate(QWebPage *qq)
59     : q(qq), modified(false)
60 {
61     chromeClient = new ChromeClientQt(q);
62     contextMenuClient = new ContextMenuClientQt();
63     editorClient = new EditorClientQt(q);
64     page = new Page(chromeClient, contextMenuClient, editorClient,
65                     new DragClientQt(q));
66
67     undoStack = 0;
68     mainFrame = 0;
69     networkInterface = 0;
70     insideOpenCall = false;
71 }
72
73 QWebPagePrivate::~QWebPagePrivate()
74 {
75     delete undoStack;
76     delete page;
77 }
78
79 QWebPage::NavigationRequestResponse QWebPagePrivate::navigationRequested(QWebFrame *frame, const QWebNetworkRequest &request)
80 {
81     if (insideOpenCall
82         && frame == mainFrame)
83         return QWebPage::AcceptNavigationRequest;
84     return q->navigationRequested(frame, request);
85 }
86
87 void QWebPagePrivate::createMainFrame()
88 {
89     if (!mainFrame) {
90         QWebFrameData frameData;
91         frameData.ownerElement = 0;
92         frameData.allowsScrolling = true;
93         frameData.marginWidth = 0;
94         frameData.marginHeight = 0;
95         mainFrame = q->createFrame(0, &frameData);
96         layout->addWidget(mainFrame);
97     }
98 }
99
100
101 QWebPage::QWebPage(QWidget *parent)
102     : QWidget(parent)
103     , d(new QWebPagePrivate(this))
104 {
105     setSettings(QWebSettings::global());
106     d->layout = new QVBoxLayout(this);
107     d->layout->setMargin(0);
108     d->layout->setSpacing(0);
109     setAcceptDrops(true);
110 }
111
112 QWebPage::~QWebPage()
113 {
114     FrameLoader *loader = d->mainFrame->d->frame->loader();
115     if (loader)
116         loader->detachFromParent();
117     delete d;
118 }
119
120 QWebFrame *QWebPage::createFrame(QWebFrame *parentFrame, QWebFrameData *frameData)
121 {
122     if (parentFrame)
123         return new QWebFrame(parentFrame, frameData);
124     QWebFrame *f = new QWebFrame(this, frameData);
125     connect(f, SIGNAL(titleChanged(const QString&)),
126             SIGNAL(titleChanged(const QString&)));
127     connect(f, SIGNAL(hoveringOverLink(const QString&, const QString&)),
128             SIGNAL(hoveringOverLink(const QString&, const QString&)));
129     return f;
130 }
131
132 void QWebPage::open(const QUrl &url)
133 {
134     open(QWebNetworkRequest(url));
135 }
136
137 void QWebPage::open(const QWebNetworkRequest &req)
138 {
139     d->insideOpenCall = true;
140
141     QUrl url = req.url();
142     QHttpRequestHeader httpHeader = req.httpHeader();
143     QByteArray postData = req.postData();
144
145     WebCore::ResourceRequest request(KURL(url.toString()));
146
147     QString method = httpHeader.method();
148     if (!method.isEmpty())
149         request.setHTTPMethod(method);
150
151     foreach (QString key, httpHeader.keys())
152         request.addHTTPHeaderField(key, httpHeader.value(key));
153
154     if (!postData.isEmpty()) {
155         WTF::RefPtr<WebCore::FormData> formData = new WebCore::FormData(postData.constData(), postData.size());
156         request.setHTTPBody(formData);
157     }
158
159     mainFrame()->d->frame->loader()->load(request);
160     d->insideOpenCall = false;
161 }
162
163 QUrl QWebPage::url() const
164 {
165     return QUrl((QString)mainFrame()->d->frame->loader()->url().url());
166 }
167
168 QString QWebPage::title() const
169 {
170     return mainFrame()->title();
171 }
172
173 QWebFrame *QWebPage::mainFrame() const
174 {
175     d->createMainFrame();
176     return d->mainFrame;
177 }
178
179 QSize QWebPage::sizeHint() const
180 {
181     return QSize(800, 600);
182 }
183
184 void QWebPage::stop()
185 {
186     FrameLoader *f = mainFrame()->d->frame->loader();
187     f->stopForUserCancel();
188 }
189
190 QWebPageHistory QWebPage::history() const
191 {
192     WebCore::BackForwardList *lst = d->page->backForwardList();
193     QWebPageHistoryPrivate *priv = new QWebPageHistoryPrivate(lst);
194     return QWebPageHistory(priv);
195 }
196
197 void QWebPage::goBack()
198 {
199     d->page->goBack();
200 }
201
202 void QWebPage::goForward()
203 {
204     d->page->goForward();
205 }
206
207 void QWebPage::goToHistoryItem(const QWebHistoryItem &item)
208 {
209     d->page->goToItem(item.d->item, FrameLoadTypeIndexedBackForward);
210 }
211
212 void QWebPage::javaScriptConsoleMessage(const QString& message, unsigned int lineNumber, const QString& sourceID)
213 {
214 }
215
216 void QWebPage::statusTextChanged(const QString& text)
217 {
218 }
219
220 void QWebPage::runJavaScriptAlert(QWebFrame *frame, const QString& msg)
221 {
222 }
223
224 QWebPage *QWebPage::createWindow()
225 {
226     return 0;
227 }
228
229 QWebPage::NavigationRequestResponse QWebPage::navigationRequested(QWebFrame *frame, const QWebNetworkRequest &request)
230 {
231     Q_UNUSED(request)
232     return AcceptNavigationRequest;
233 }
234
235 void QWebPage::setWindowGeometry(const QRect& geom)
236 {
237     Q_UNUSED(geom)
238 }
239
240 /*!
241   Returns true if the page contains unsubmitted form data.
242 */
243 bool QWebPage::isModified() const
244 {
245     return d->modified;
246 }
247
248
249 QUndoStack *QWebPage::undoStack()
250 {
251     if (!d->undoStack)
252         d->undoStack = new QUndoStack(this);
253
254     return d->undoStack;
255 }
256
257 static inline DragOperation dropActionToDragOp(Qt::DropActions actions)
258 {
259     unsigned result = 0;
260     if (actions & Qt::CopyAction)
261         result |= DragOperationCopy;
262     if (actions & Qt::MoveAction)
263         result |= DragOperationMove;
264     if (actions & Qt::LinkAction)
265         result |= DragOperationLink;
266     return (DragOperation)result;    
267 }
268
269 static inline Qt::DropAction dragOpToDropAction(unsigned actions)
270 {
271     Qt::DropAction result = Qt::IgnoreAction;
272     if (actions & DragOperationCopy)
273         result = Qt::CopyAction;
274     else if (actions & DragOperationMove)
275         result = Qt::MoveAction;
276     else if (actions & DragOperationLink)
277         result = Qt::LinkAction;
278     return result;    
279 }
280
281 void QWebPage::dragEnterEvent(QDragEnterEvent *ev)
282 {
283     DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), 
284                       dropActionToDragOp(ev->possibleActions()));
285     Qt::DropAction action = dragOpToDropAction(d->page->dragController()->dragEntered(&dragData));
286     ev->setDropAction(action);
287     ev->accept();
288 }
289
290 void QWebPage::dragLeaveEvent(QDragLeaveEvent *ev)
291 {
292     DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone);
293     d->page->dragController()->dragExited(&dragData);
294     ev->accept();
295 }
296
297 void QWebPage::dragMoveEvent(QDragMoveEvent *ev)
298 {
299     DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), 
300                       dropActionToDragOp(ev->possibleActions()));
301     Qt::DropAction action = dragOpToDropAction(d->page->dragController()->dragUpdated(&dragData));
302     ev->setDropAction(action);
303     ev->accept();
304 }
305
306 void QWebPage::dropEvent(QDropEvent *ev)
307 {
308     DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), 
309                       dropActionToDragOp(ev->possibleActions()));
310     Qt::DropAction action = dragOpToDropAction(d->page->dragController()->performDrag(&dragData));
311     ev->accept();
312 }
313
314 void QWebPage::setNetworkInterface(QWebNetworkInterface *interface)
315 {
316     d->networkInterface = interface;
317 }
318
319 QWebNetworkInterface *QWebPage::networkInterface() const
320 {
321     if (d->networkInterface)
322         return d->networkInterface;
323     else
324         return QWebNetworkInterface::defaultInterface();
325 }
326
327 void QWebPage::setSettings(const QWebSettings &settings)
328 {
329     WebCore::Settings *wSettings = d->page->settings();
330
331     wSettings->setStandardFontFamily(
332         settings.fontFamily(QWebSettings::StandardFont));
333     wSettings->setFixedFontFamily(
334         settings.fontFamily(QWebSettings::FixedFont));
335     wSettings->setSerifFontFamily(
336         settings.fontFamily(QWebSettings::SerifFont));
337     wSettings->setSansSerifFontFamily(
338         settings.fontFamily(QWebSettings::SansSerifFont));
339     wSettings->setCursiveFontFamily(
340         settings.fontFamily(QWebSettings::CursiveFont));
341     wSettings->setFantasyFontFamily(
342         settings.fontFamily(QWebSettings::FantasyFont));
343
344     wSettings->setMinimumFontSize(settings.minimumFontSize());
345     wSettings->setMinimumLogicalFontSize(settings.minimumLogicalFontSize());
346     wSettings->setDefaultFontSize(settings.defaultFontSize());
347     wSettings->setDefaultFixedFontSize(settings.defaultFixedFontSize());
348
349     wSettings->setLoadsImagesAutomatically(
350         settings.testAttribute(QWebSettings::AutoLoadImages));
351     wSettings->setJavaScriptEnabled(
352         settings.testAttribute(QWebSettings::JavascriptEnabled));
353     wSettings->setJavaScriptCanOpenWindowsAutomatically(
354         settings.testAttribute(QWebSettings::JavascriptCanOpenWindows));
355     wSettings->setJavaEnabled(
356         settings.testAttribute(QWebSettings::JavaEnabled));
357     wSettings->setPluginsEnabled(
358         settings.testAttribute(QWebSettings::PluginsEnabled));
359     wSettings->setPrivateBrowsingEnabled(
360         settings.testAttribute(QWebSettings::PrivateBrowsingEnabled));
361
362     wSettings->setUserStyleSheetLocation(KURL(settings.userStyleSheetLocation()));
363 }
364
365 QWebSettings QWebPage::settings() const
366 {
367     QWebSettings settings;
368     WebCore::Settings *wSettings = d->page->settings();
369
370     settings.setFontFamily(QWebSettings::StandardFont,
371                            wSettings->standardFontFamily());
372     settings.setFontFamily(QWebSettings::FixedFont,
373                            wSettings->fixedFontFamily());
374     settings.setFontFamily(QWebSettings::SerifFont,
375                            wSettings->serifFontFamily());
376     settings.setFontFamily(QWebSettings::SansSerifFont,
377                            wSettings->sansSerifFontFamily());
378     settings.setFontFamily(QWebSettings::CursiveFont,
379                            wSettings->cursiveFontFamily());
380     settings.setFontFamily(QWebSettings::FantasyFont,
381                            wSettings->fantasyFontFamily());
382
383     settings.setMinimumFontSize(wSettings->minimumFontSize());
384     settings.setMinimumLogicalFontSize(wSettings->minimumLogicalFontSize());
385     settings.setDefaultFontSize(wSettings->defaultFontSize());
386     settings.setDefaultFixedFontSize(wSettings->defaultFixedFontSize());
387
388     settings.setAttribute(QWebSettings::AutoLoadImages,
389                           wSettings->loadsImagesAutomatically());
390     settings.setAttribute(QWebSettings::JavascriptEnabled,
391                           wSettings->isJavaScriptEnabled());
392     settings.setAttribute(QWebSettings::JavascriptCanOpenWindows,
393                           wSettings->JavaScriptCanOpenWindowsAutomatically());
394     settings.setAttribute(QWebSettings::JavaEnabled,
395                           wSettings->isJavaEnabled());
396     settings.setAttribute(QWebSettings::PluginsEnabled,
397                           wSettings->arePluginsEnabled());
398     settings.setAttribute(QWebSettings::PrivateBrowsingEnabled,
399                           wSettings->privateBrowsingEnabled());
400
401     settings.setUserStyleSheetLocation(
402         wSettings->userStyleSheetLocation().url());
403
404     return settings;
405 }