b100542ec6e49a90b4cc04bb2692c44eac135d1d
[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     QWebNetworkRequest request;
135     request.setUrl(url);
136     open(request);
137 }
138
139 void QWebPage::open(const QWebNetworkRequest &req)
140 {
141     d->insideOpenCall = true;
142
143     QUrl url = req.url();
144     QHttpRequestHeader httpHeader = req.httpHeader();
145     QByteArray postData = req.postData();
146
147     WebCore::ResourceRequest request(KURL(url.toString()));
148
149     QString method = httpHeader.method();
150     if (!method.isEmpty())
151         request.setHTTPMethod(method);
152
153     foreach (QString key, httpHeader.keys())
154         request.addHTTPHeaderField(key, httpHeader.value(key));
155
156     if (!postData.isEmpty()) {
157         WTF::RefPtr<WebCore::FormData> formData = new WebCore::FormData(postData.constData(), postData.size());
158         request.setHTTPBody(formData);
159     }
160
161     mainFrame()->d->frame->loader()->load(request);
162     d->insideOpenCall = false;
163 }
164
165 QUrl QWebPage::url() const
166 {
167     return QUrl((QString)mainFrame()->d->frame->loader()->url().url());
168 }
169
170 QString QWebPage::title() const
171 {
172     return mainFrame()->title();
173 }
174
175 QWebFrame *QWebPage::mainFrame() const
176 {
177     d->createMainFrame();
178     return d->mainFrame;
179 }
180
181 QSize QWebPage::sizeHint() const
182 {
183     return QSize(800, 600);
184 }
185
186 void QWebPage::stop()
187 {
188     FrameLoader *f = mainFrame()->d->frame->loader();
189     f->stopForUserCancel();
190 }
191
192 QWebPageHistory QWebPage::history() const
193 {
194     WebCore::BackForwardList *lst = d->page->backForwardList();
195     QWebPageHistoryPrivate *priv = new QWebPageHistoryPrivate(lst);
196     return QWebPageHistory(priv);
197 }
198
199 void QWebPage::goBack()
200 {
201     d->page->goBack();
202 }
203
204 void QWebPage::goForward()
205 {
206     d->page->goForward();
207 }
208
209 void QWebPage::goToHistoryItem(const QWebHistoryItem &item)
210 {
211     d->page->goToItem(item.d->item, FrameLoadTypeIndexedBackForward);
212 }
213
214 void QWebPage::javaScriptConsoleMessage(const QString& message, unsigned int lineNumber, const QString& sourceID)
215 {
216 }
217
218 void QWebPage::statusTextChanged(const QString& text)
219 {
220 }
221
222 void QWebPage::runJavaScriptAlert(QWebFrame *frame, const QString& msg)
223 {
224 }
225
226 QWebPage *QWebPage::createWindow()
227 {
228     return 0;
229 }
230
231 QWebPage::NavigationRequestResponse QWebPage::navigationRequested(QWebFrame *frame, const QWebNetworkRequest &request)
232 {
233     Q_UNUSED(request)
234     return AcceptNavigationRequest;
235 }
236
237 void QWebPage::setWindowGeometry(const QRect& geom)
238 {
239     Q_UNUSED(geom)
240 }
241
242 /*!
243   Returns true if the page contains unsubmitted form data.
244 */
245 bool QWebPage::isModified() const
246 {
247     return d->modified;
248 }
249
250
251 QUndoStack *QWebPage::undoStack()
252 {
253     if (!d->undoStack)
254         d->undoStack = new QUndoStack(this);
255
256     return d->undoStack;
257 }
258
259 static inline DragOperation dropActionToDragOp(Qt::DropActions actions)
260 {
261     unsigned result = 0;
262     if (actions & Qt::CopyAction)
263         result |= DragOperationCopy;
264     if (actions & Qt::MoveAction)
265         result |= DragOperationMove;
266     if (actions & Qt::LinkAction)
267         result |= DragOperationLink;
268     return (DragOperation)result;    
269 }
270
271 static inline Qt::DropAction dragOpToDropAction(unsigned actions)
272 {
273     Qt::DropAction result = Qt::IgnoreAction;
274     if (actions & DragOperationCopy)
275         result = Qt::CopyAction;
276     else if (actions & DragOperationMove)
277         result = Qt::MoveAction;
278     else if (actions & DragOperationLink)
279         result = Qt::LinkAction;
280     return result;    
281 }
282
283 void QWebPage::dragEnterEvent(QDragEnterEvent *ev)
284 {
285     DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), 
286                       dropActionToDragOp(ev->possibleActions()));
287     Qt::DropAction action = dragOpToDropAction(d->page->dragController()->dragEntered(&dragData));
288     ev->setDropAction(action);
289     ev->accept();
290 }
291
292 void QWebPage::dragLeaveEvent(QDragLeaveEvent *ev)
293 {
294     DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone);
295     d->page->dragController()->dragExited(&dragData);
296     ev->accept();
297 }
298
299 void QWebPage::dragMoveEvent(QDragMoveEvent *ev)
300 {
301     DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), 
302                       dropActionToDragOp(ev->possibleActions()));
303     Qt::DropAction action = dragOpToDropAction(d->page->dragController()->dragUpdated(&dragData));
304     ev->setDropAction(action);
305     ev->accept();
306 }
307
308 void QWebPage::dropEvent(QDropEvent *ev)
309 {
310     DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), 
311                       dropActionToDragOp(ev->possibleActions()));
312     Qt::DropAction action = dragOpToDropAction(d->page->dragController()->performDrag(&dragData));
313     ev->accept();
314 }
315
316 void QWebPage::setNetworkInterface(QWebNetworkInterface *interface)
317 {
318     d->networkInterface = interface;
319 }
320
321 QWebNetworkInterface *QWebPage::networkInterface() const
322 {
323     if (d->networkInterface)
324         return d->networkInterface;
325     else
326         return QWebNetworkInterface::defaultInterface();
327 }
328
329 void QWebPage::setSettings(const QWebSettings &settings)
330 {
331     WebCore::Settings *wSettings = d->page->settings();
332
333     wSettings->setStandardFontFamily(
334         settings.fontFamily(QWebSettings::StandardFont));
335     wSettings->setFixedFontFamily(
336         settings.fontFamily(QWebSettings::FixedFont));
337     wSettings->setSerifFontFamily(
338         settings.fontFamily(QWebSettings::SerifFont));
339     wSettings->setSansSerifFontFamily(
340         settings.fontFamily(QWebSettings::SansSerifFont));
341     wSettings->setCursiveFontFamily(
342         settings.fontFamily(QWebSettings::CursiveFont));
343     wSettings->setFantasyFontFamily(
344         settings.fontFamily(QWebSettings::FantasyFont));
345
346     wSettings->setMinimumFontSize(settings.minimumFontSize());
347     wSettings->setMinimumLogicalFontSize(settings.minimumLogicalFontSize());
348     wSettings->setDefaultFontSize(settings.defaultFontSize());
349     wSettings->setDefaultFixedFontSize(settings.defaultFixedFontSize());
350
351     wSettings->setLoadsImagesAutomatically(
352         settings.testAttribute(QWebSettings::AutoLoadImages));
353     wSettings->setJavaScriptEnabled(
354         settings.testAttribute(QWebSettings::JavascriptEnabled));
355     wSettings->setJavaScriptCanOpenWindowsAutomatically(
356         settings.testAttribute(QWebSettings::JavascriptCanOpenWindows));
357     wSettings->setJavaEnabled(
358         settings.testAttribute(QWebSettings::JavaEnabled));
359     wSettings->setPluginsEnabled(
360         settings.testAttribute(QWebSettings::PluginsEnabled));
361     wSettings->setPrivateBrowsingEnabled(
362         settings.testAttribute(QWebSettings::PrivateBrowsingEnabled));
363
364     wSettings->setUserStyleSheetLocation(KURL(settings.userStyleSheetLocation()));
365 }
366
367 QWebSettings QWebPage::settings() const
368 {
369     QWebSettings settings;
370     WebCore::Settings *wSettings = d->page->settings();
371
372     settings.setFontFamily(QWebSettings::StandardFont,
373                            wSettings->standardFontFamily());
374     settings.setFontFamily(QWebSettings::FixedFont,
375                            wSettings->fixedFontFamily());
376     settings.setFontFamily(QWebSettings::SerifFont,
377                            wSettings->serifFontFamily());
378     settings.setFontFamily(QWebSettings::SansSerifFont,
379                            wSettings->sansSerifFontFamily());
380     settings.setFontFamily(QWebSettings::CursiveFont,
381                            wSettings->cursiveFontFamily());
382     settings.setFontFamily(QWebSettings::FantasyFont,
383                            wSettings->fantasyFontFamily());
384
385     settings.setMinimumFontSize(wSettings->minimumFontSize());
386     settings.setMinimumLogicalFontSize(wSettings->minimumLogicalFontSize());
387     settings.setDefaultFontSize(wSettings->defaultFontSize());
388     settings.setDefaultFixedFontSize(wSettings->defaultFixedFontSize());
389
390     settings.setAttribute(QWebSettings::AutoLoadImages,
391                           wSettings->loadsImagesAutomatically());
392     settings.setAttribute(QWebSettings::JavascriptEnabled,
393                           wSettings->isJavaScriptEnabled());
394     settings.setAttribute(QWebSettings::JavascriptCanOpenWindows,
395                           wSettings->JavaScriptCanOpenWindowsAutomatically());
396     settings.setAttribute(QWebSettings::JavaEnabled,
397                           wSettings->isJavaEnabled());
398     settings.setAttribute(QWebSettings::PluginsEnabled,
399                           wSettings->arePluginsEnabled());
400     settings.setAttribute(QWebSettings::PrivateBrowsingEnabled,
401                           wSettings->privateBrowsingEnabled());
402
403     settings.setUserStyleSheetLocation(
404         wSettings->userStyleSheetLocation().url());
405
406     return settings;
407 }