2006-10-15 Nikolas Zimmermann <zimmermann@kde.org>
[WebKit-https.git] / WebCore / platform / qt / FrameQt.cpp
1 /*
2  * Copyright (C) 2006 Dirk Mueller <mueller@kde.org>
3  * Copyright (C) 2006 Zack Rusin <zack@kde.org>
4  * Copyright (C) 2006 George Staikos <staikos@kde.org>
5  * Copyright (C) 2006 Simon Hausmann <hausmann@kde.org>
6  * Copyright (C) 2006 Rob Buis <buis@kde.org>
7  * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
8  *
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
21  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
28  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #include "config.h"
34 #include "FrameQt.h"
35 #include "Element.h"
36 #include "RenderObject.h"
37 #include "RenderWidget.h"
38 #include "RenderLayer.h"
39 #include "Page.h"
40 #include "Document.h"
41 #include "HTMLElement.h"
42 #include "DOMWindow.h"
43 #include "FrameLoadRequest.h"
44 #include "DOMImplementation.h"
45 #include "BrowserExtensionQt.h"
46 #include "ResourceLoaderInternal.h"
47 #include "Document.h"
48 #include "Settings.h"
49 #include "Plugin.h"
50 #include "FramePrivate.h"
51 #include "GraphicsContext.h"
52 #include "HTMLDocument.h"
53 #include "ResourceLoader.h"
54 #include "PlatformMouseEvent.h"
55 #include "PlatformKeyboardEvent.h"
56 #include "PlatformWheelEvent.h"
57 #include "MouseEventWithHitTestResults.h"
58 #include "SelectionController.h"
59 #include "TypingCommand.h"
60 #include "JSLock.h"
61 #include "kjs_window.h"
62 #include "runtime_root.h"
63
64 #include <QScrollArea>
65
66 #define notImplemented() do { fprintf(stderr, "FIXME: UNIMPLEMENTED: %s:%d\n", __FILE__, __LINE__); } while(0)
67
68 namespace WebCore {
69
70 static void doScroll(const RenderObject* r, bool isHorizontal, int multiplier)
71 {
72     // FIXME: The scrolling done here should be done in the default handlers
73     // of the elements rather than here in the part.
74     if (!r)
75         return;
76
77     //broken since it calls scroll on scrollbars
78     //and we have none now
79     //r->scroll(direction, KWQScrollWheel, multiplier);
80     if (!r->layer())
81         return;
82
83     int x = r->layer()->scrollXOffset();
84     int y = r->layer()->scrollYOffset();
85     if (isHorizontal)
86         x += multiplier;
87     else
88         y += multiplier;
89
90     r->layer()->scrollToOffset(x, y, true, true);
91 }
92
93 FrameQt::FrameQt(Page* page, Element* ownerElement, FrameQtClient* client)
94     : Frame(page, ownerElement)
95     , m_bindingRoot(0)
96 {
97     d->m_extension = new BrowserExtensionQt(this);
98     Settings* settings = new Settings;
99     settings->setAutoLoadImages(true);
100     settings->setMinFontSize(5);
101     settings->setMinLogicalFontSize(5);
102     settings->setShouldPrintBackgrounds(true);
103     settings->setIsJavaScriptEnabled(true);
104  
105     settings->setMediumFixedFontSize(14);
106     settings->setMediumFontSize(14);
107     settings->setSerifFontName("Times New Roman");
108     settings->setSansSerifFontName("Arial");
109     settings->setFixedFontName("Courier");
110     settings->setStdFontName("Arial");
111
112     setSettings(settings);
113
114     m_client = client;
115     m_client->setFrame(this);
116 }
117
118 FrameQt::~FrameQt()
119 {
120     setView(0);
121     clearRecordedFormValues();
122
123     cancelAndClear();
124 }
125
126 bool FrameQt::openURL(const KURL& url)
127 {
128     if (!m_client)
129         return false;
130
131     m_client->openURL(url);
132     return true;
133 }
134
135 void FrameQt::submitForm(const FrameLoadRequest& frameLoadRequest)
136 {
137     ResourceRequest request = frameLoadRequest.m_request;
138
139     // FIXME: this is a hack inherited from FrameMac, and should be pushed into Frame
140     if (d->m_submittedFormURL == request.url())
141         return;
142
143     d->m_submittedFormURL = request.url();
144
145     if (m_client)
146         m_client->submitForm(request.doPost() ? "POST" : "GET", request.url(), &request.postData);
147
148     clearRecordedFormValues();
149 }
150
151 void FrameQt::urlSelected(const FrameLoadRequest& frameLoadRequest)
152 {
153     ResourceRequest request = frameLoadRequest.m_request;
154
155     if (!m_client)
156         return;
157
158     m_client->openURL(request.url());
159 }
160
161 String FrameQt::userAgent() const
162 {
163     return "Mozilla/5.0 (PC; U; Intel; Linux; en) AppleWebKit/420+ (KHTML, like Gecko)";
164 }
165
166 void FrameQt::runJavaScriptAlert(String const& message)
167 {
168     m_client->runJavaScriptAlert(message);
169 }
170
171 bool FrameQt::runJavaScriptConfirm(String const& message)
172 {
173     return m_client->runJavaScriptConfirm(message);
174 }
175
176 bool FrameQt::locationbarVisible()
177 {
178     return m_client->locationbarVisible();
179 }
180
181 void FrameQt::setTitle(const String& title)
182 {
183     if (view() && view()->parentWidget())
184         view()->parentWidget()->setWindowTitle(title);
185 }
186
187 Frame* FrameQt::createFrame(const KURL& url, const String& name, Element* ownerElement, const String& referrer)
188 {
189     notImplemented();
190     return 0;
191 }
192
193 bool FrameQt::passWheelEventToChildWidget(Node*)
194 {
195     notImplemented();
196     return false;
197 }
198
199 bool FrameQt::passSubframeEventToSubframe(MouseEventWithHitTestResults& mev, Frame*)
200 {
201     notImplemented(); 
202     return false;
203 }
204
205 ObjectContentType FrameQt::objectContentType(const KURL&, const String& mimeType)
206 {
207     notImplemented();
208     return ObjectContentType();
209 }
210
211 Plugin* FrameQt::createPlugin(Element*, const KURL&, const Vector<String>&, const Vector<String>&, const String&)
212 {
213     notImplemented();
214     return 0;
215 }
216
217 bool FrameQt::passMouseDownEventToWidget(Widget*)
218 {
219     notImplemented();
220     return false;
221 }
222
223 bool FrameQt::isLoadTypeReload()
224 {
225     notImplemented();
226     return false;
227 }
228
229 bool FrameQt::menubarVisible()
230 {
231     return m_client->menubarVisible();
232 }
233
234 bool FrameQt::personalbarVisible()
235 {
236     return m_client->personalbarVisible();
237 }
238
239 bool FrameQt::statusbarVisible()
240 {
241     return m_client->statusbarVisible();
242 }
243
244 bool FrameQt::toolbarVisible()
245 {
246     return m_client->toolbarVisible();
247 }
248
249 void FrameQt::createEmptyDocument()
250 {
251     // Although it's not completely clear from the name of this function,
252     // it does nothing if we already have a document, and just creates an
253     // empty one if we have no document at all.
254
255     // Force creation.
256     if (!d->m_doc) {
257         begin();
258         end();
259     }
260 }
261
262 Range* FrameQt::markedTextRange() const
263 {
264     // FIXME: Handle selections.
265     return 0;
266 }
267
268 String FrameQt::incomingReferrer() const
269 {
270     notImplemented();
271     return String();
272 }
273
274 String FrameQt::mimeTypeForFileName(const String&) const
275 {
276     notImplemented();
277     return String();
278 }
279
280 void FrameQt::markMisspellingsInAdjacentWords(const VisiblePosition&)
281 {
282     notImplemented();
283 }
284
285 void FrameQt::markMisspellings(const Selection&)
286 {
287     notImplemented();
288 }
289
290 bool FrameQt::lastEventIsMouseUp() const
291 {
292     // no-op
293     return false;
294 }
295
296 void FrameQt::saveDocumentState()
297 {
298     // FIXME: Implement this as soon a KPart is created...
299 }
300
301 void FrameQt::restoreDocumentState()
302 {
303     // FIXME: Implement this as soon a KPart is created...
304 }
305
306 void FrameQt::openURLRequest(const FrameLoadRequest& request)
307 {
308     urlSelected(request);
309 }
310
311 void FrameQt::scheduleClose()
312 {
313     // no-op
314 }
315
316 void FrameQt::unfocusWindow()
317 {
318     if (!view())
319         return;
320
321     if (!tree()->parent())
322         view()->qwidget()->clearFocus();
323 }
324
325 void FrameQt::focusWindow()
326 {
327     if (!view())
328         return;
329
330     if (!tree()->parent())
331         view()->qwidget()->setFocus();
332 }
333
334 String FrameQt::overrideMediaType() const
335 {
336     // no-op
337     return String();
338 }
339
340 void FrameQt::addMessageToConsole(const String& message, unsigned lineNumber, const String& sourceID)
341 {
342     qDebug("[FrameQt::addMessageToConsole] message=%s lineNumber=%d sourceID=%s",
343            qPrintable(QString(message)), lineNumber, qPrintable(QString(sourceID)));
344 }
345
346 bool FrameQt::runJavaScriptPrompt(const String& message, const String& defaultValue, String& result)
347 {
348     return m_client->runJavaScriptPrompt(message, defaultValue, result);
349 }
350
351 KJS::Bindings::Instance* FrameQt::getEmbedInstanceForWidget(Widget*)
352 {
353     notImplemented();
354     return 0;
355 }
356
357 KJS::Bindings::Instance* FrameQt::getObjectInstanceForWidget(Widget*)
358 {
359     notImplemented();
360     return 0;
361 }
362
363 KJS::Bindings::Instance* FrameQt::getAppletInstanceForWidget(Widget*)
364 {
365     notImplemented();
366     return 0;
367 }
368
369 KJS::Bindings::RootObject* FrameQt::bindingRootObject()
370 {
371     ASSERT(jScriptEnabled());
372
373     if (!m_bindingRoot) {
374         KJS::JSLock lock;
375         m_bindingRoot = new KJS::Bindings::RootObject(0); // The root gets deleted by JavaScriptCore.
376
377         KJS::JSObject* win = KJS::Window::retrieveWindow(this);
378         m_bindingRoot->setRootObjectImp(win);
379         m_bindingRoot->setInterpreter(jScript()->interpreter());
380         addPluginRootObject(m_bindingRoot);
381     }
382
383     return m_bindingRoot;
384 }
385
386 void FrameQt::addPluginRootObject(KJS::Bindings::RootObject* root)
387 {
388     m_rootObjects.append(root);
389 }
390
391 Widget* FrameQt::createJavaAppletWidget(const IntSize&, Element*, const HashMap<String, String>&)
392 {
393     notImplemented();
394     return 0; 
395 }
396
397 void FrameQt::registerCommandForUndo(PassRefPtr<EditCommand>)
398 {
399     // FIXME: Implement this in the FrameQtClient, to be used within WebKitPart.
400 }
401
402 void FrameQt::registerCommandForRedo(PassRefPtr<EditCommand>)
403 {
404     // FIXME: Implement this in the FrameQtClient, to be used within WebKitPart.
405 }
406
407 void FrameQt::clearUndoRedoOperations()
408 {
409     // FIXME: Implement this in the FrameQtClient, to be used within WebKitPart.
410 }
411
412 void FrameQt::issueUndoCommand()
413 {
414     notImplemented();
415 }
416
417 void FrameQt::issueRedoCommand()
418 {
419     notImplemented();
420 }
421
422 void FrameQt::issueCutCommand()
423 {
424     notImplemented();
425 }
426
427 void FrameQt::issueCopyCommand()
428 {
429     notImplemented();
430 }
431
432 void FrameQt::issuePasteCommand()
433 {
434     notImplemented();
435 }
436
437 void FrameQt::issuePasteAndMatchStyleCommand()
438 {
439     notImplemented();
440 }
441
442 void FrameQt::issueTransposeCommand()
443 {
444     notImplemented();
445 }
446
447 void FrameQt::respondToChangedSelection(const Selection& oldSelection, bool closeTyping)
448 {
449     // TODO: If we want continous spell checking, we need to implement this.
450 }
451
452 void FrameQt::respondToChangedContents(const Selection& endingSelection)
453 {
454     // TODO: If we want accessibility, we need to implement this.
455 }
456
457 bool FrameQt::shouldChangeSelection(const Selection& oldSelection, const Selection& newSelection, EAffinity affinity, bool stillSelecting) const
458 {
459     // no-op
460     return true;
461 }
462
463 void FrameQt::partClearedInBegin()
464 {
465     // FIXME: This is only related to the js debugger.
466     // See WebCoreSupport/WebFrameBridge.m "windowObjectCleared",
467     // which is called by FrameMac::partClearedInBegin() ...
468 }
469
470 bool FrameQt::canGoBackOrForward(int distance) const
471 {
472     // FIXME: Implement this in the FrameQtClient, to be used within WebKitPart.
473     notImplemented();
474     return false;
475 }
476
477 void FrameQt::handledOnloadEvents()
478 {
479     // TODO: FrameMac doesn't need that - it seems.
480     // It must be handled differently, can't figure it out.
481     // If we won't call this here doc->parsing() remains 'true'
482     // all the time. Calling document.open(); document.write(...)
483     // from JavaScript leaves the parsing state 'true', and DRT will
484     // hang on these tests (fast/dom/Document/document-reopen.html for instance)
485     endIfNotLoading();
486 }
487
488 bool FrameQt::canPaste() const
489 {
490     // FIXME: Implement this in the FrameQtClient, to be used within WebKitPart. 
491     notImplemented();
492     return false;
493 }
494
495 bool FrameQt::canRedo() const
496 {
497     // FIXME: Implement this in the FrameQtClient, to be used within WebKitPart. 
498     notImplemented();
499     return false;
500 }
501
502 bool FrameQt::canUndo() const
503 {
504     // FIXME: Implement this in the FrameQtClient, to be used within WebKitPart. 
505     notImplemented();
506     return false;
507 }
508
509 void FrameQt::print()
510 {
511     notImplemented();
512 }
513
514 bool FrameQt::shouldInterruptJavaScript()
515 {
516     notImplemented();
517     return false;
518 }
519
520 KURL FrameQt::originalRequestURL() const
521 {
522     notImplemented();
523     return KURL();
524 }
525
526 bool FrameQt::keyEvent(const PlatformKeyboardEvent& keyEvent)
527 {
528     bool result;
529
530     // Check for cases where we are too early for events -- possible unmatched key up
531     // from pressing return in the location bar.
532     Document* doc = document();
533     if (!doc)
534         return false;
535
536     Node* node = doc->focusNode();
537     if (!node) {
538         if (doc->isHTMLDocument())
539             node = doc->body();
540         else
541             node = doc->documentElement();
542
543         if (!node)
544             return false;
545     }
546
547     if (!keyEvent.isKeyUp())
548         prepareForUserAction();
549
550     result = !EventTargetNodeCast(node)->dispatchKeyEvent(keyEvent);
551
552     // FIXME: FrameMac has a keyDown/keyPress hack here which we are not copying.
553     return result;
554 }
555
556 void FrameQt::setFrameGeometry(const IntRect& r)
557 {
558     setFrameGeometry(QRect(r));
559 }
560
561 void FrameQt::tokenizerProcessedData()
562 {
563     if (d->m_doc)
564         checkCompleted();
565 }
566
567 }
568
569 // vim: ts=4 sw=4 et