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