~osomon/oxide/i18n

« back to all changes in this revision

Viewing changes to qt/quick/api/oxideqquickwebview.cc

  • Committer: Olivier Tilloy
  • Date: 2014-04-08 10:03:11 UTC
  • mfrom: (312.2.173 oxide)
  • Revision ID: olivier.tilloy@canonical.com-20140408100311-b3zb7q1jfrevbrf1
Merge the latest changes from trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
#include "oxideqquickwebview_p.h"
19
19
#include "oxideqquickwebview_p_p.h"
20
20
 
 
21
#include <QMetaMethod>
21
22
#include <QPointF>
22
23
#include <QQmlEngine>
23
24
#include <QQuickWindow>
30
31
#include "qt/quick/oxide_qquick_alert_dialog_delegate.h"
31
32
#include "qt/quick/oxide_qquick_before_unload_dialog_delegate.h"
32
33
#include "qt/quick/oxide_qquick_confirm_dialog_delegate.h"
 
34
#include "qt/quick/oxide_qquick_file_picker_delegate.h"
33
35
#include "qt/quick/oxide_qquick_prompt_dialog_delegate.h"
34
36
#include "qt/quick/oxide_qquick_render_view_item.h"
35
37
#include "qt/quick/oxide_qquick_web_popup_menu_delegate.h"
57
59
  view_ = view;
58
60
}
59
61
 
60
 
void OxideQQuickWebViewPrivate::contextInitialized() {
61
 
  completeConstruction();
62
 
}
63
 
 
64
 
void OxideQQuickWebViewPrivate::contextWillBeDestroyed() {
65
 
  Q_Q(OxideQQuickWebView);
66
 
 
67
 
  // XXX: Our underlying BrowserContext lives on, so we're left in a
68
 
  // bit of a weird state here (WebView.context will return no context,
69
 
  // which is a lie)
70
 
  context = NULL;
71
 
  emit q->contextChanged();
72
 
}
73
 
 
74
 
void OxideQQuickWebViewPrivate::detachContextSignals() {
75
 
  Q_Q(OxideQQuickWebView);
76
 
 
77
 
  if (context) {
78
 
    QObject::disconnect(OxideQQuickWebContextPrivate::get(context),
79
 
                        SIGNAL(initialized()),
80
 
                        q, SLOT(contextInitialized()));
81
 
    QObject::disconnect(OxideQQuickWebContextPrivate::get(context),
82
 
                        SIGNAL(willBeDestroyed()),
83
 
                        q, SLOT(contextWillBeDestroyed()));
84
 
  }
85
 
}
86
 
 
87
62
OxideQQuickWebViewPrivate::OxideQQuickWebViewPrivate(
88
63
    OxideQQuickWebView* view) :
89
64
    oxide::qt::WebViewAdapter(view),
90
 
    context(NULL),
91
 
    navigationHistory(view),
92
 
    popup_menu(NULL),
93
 
    alert_dialog(NULL),
94
 
    confirm_dialog(NULL),
95
 
    prompt_dialog(NULL),
96
 
    before_unload_dialog(NULL),
97
 
    init_props_(new InitData()),
98
 
    load_progress_(0) {}
99
 
 
100
 
OxideQQuickWebViewPrivate::~OxideQQuickWebViewPrivate() {
101
 
}
102
 
 
103
 
oxide::qt::RenderWidgetHostViewDelegate*
104
 
OxideQQuickWebViewPrivate::CreateRenderWidgetHostViewDelegate() {
105
 
  Q_Q(OxideQQuickWebView);
106
 
 
107
 
  return new oxide::qquick::RenderViewItem(q);
108
 
}
 
65
    load_progress_(0),
 
66
    constructed_(false),
 
67
    navigation_history_(view),
 
68
    popup_menu_(NULL),
 
69
    alert_dialog_(NULL),
 
70
    confirm_dialog_(NULL),
 
71
    prompt_dialog_(NULL),
 
72
    before_unload_dialog_(NULL),
 
73
    file_picker_(NULL) {}
109
74
 
110
75
oxide::qt::WebPopupMenuDelegate*
111
76
OxideQQuickWebViewPrivate::CreateWebPopupMenuDelegate() {
138
103
  return new oxide::qquick::BeforeUnloadDialogDelegate(q);
139
104
}
140
105
 
 
106
oxide::qt::FilePickerDelegate*
 
107
OxideQQuickWebViewPrivate::CreateFilePickerDelegate() {
 
108
  Q_Q(OxideQQuickWebView);
 
109
 
 
110
  return new oxide::qquick::FilePickerDelegate(q);
 
111
}
 
112
 
 
113
void OxideQQuickWebViewPrivate::OnInitialized(
 
114
    bool orig_incognito,
 
115
    oxide::qt::WebContextAdapter* orig_context) {
 
116
  Q_Q(OxideQQuickWebView);
 
117
 
 
118
  // Make the webview the QObject parent of the new root frame,
 
119
  // to stop Qml from collecting the frame tree
 
120
  q->rootFrame()->setParent(q);
 
121
 
 
122
  // Initialization created the root frame. This is the only time
 
123
  // this is emitted
 
124
  emit q->rootFrameChanged();
 
125
 
 
126
  if (orig_incognito != incognito()) {
 
127
    emit q->incognitoChanged();
 
128
  }
 
129
  if (orig_context != context()) {
 
130
    detachContextSignals(static_cast<OxideQQuickWebContextPrivate *>(orig_context));
 
131
    attachContextSignals(static_cast<OxideQQuickWebContextPrivate *>(context()));
 
132
 
 
133
    emit q->contextChanged();
 
134
  }
 
135
}
 
136
 
141
137
void OxideQQuickWebViewPrivate::URLChanged() {
142
138
  Q_Q(OxideQQuickWebView);
143
139
 
169
165
  emit q->loadingChanged(event);
170
166
}
171
167
 
 
168
void OxideQQuickWebViewPrivate::AddMessageToConsole(
 
169
    int level,
 
170
    const QString& message,
 
171
    int line_no,
 
172
    const QString& source_id) {
 
173
  Q_Q(OxideQQuickWebView);
 
174
 
 
175
  OxideQQuickWebView::LogMessageSeverityLevel oxideLevel =
 
176
    OxideQQuickWebView::LogSeverityInfo;
 
177
  if (level >= 0 && level <= OxideQQuickWebView::LogSeverityFatal) {
 
178
    oxideLevel = static_cast<OxideQQuickWebView::LogMessageSeverityLevel>(level);
 
179
  }
 
180
  emit q->javaScriptConsoleMessage(
 
181
      oxideLevel,
 
182
      message,
 
183
      line_no,
 
184
      source_id);
 
185
}
 
186
 
172
187
void OxideQQuickWebViewPrivate::NavigationEntryCommitted() {
173
 
  navigationHistory.onNavigationEntryCommitted();
 
188
  navigation_history_.onNavigationEntryCommitted();
174
189
}
175
190
 
176
191
void OxideQQuickWebViewPrivate::NavigationListPruned(bool from_front, int count) {
177
 
  navigationHistory.onNavigationListPruned(from_front, count);
 
192
  navigation_history_.onNavigationListPruned(from_front, count);
178
193
}
179
194
 
180
195
void OxideQQuickWebViewPrivate::NavigationEntryChanged(int index) {
181
 
  navigationHistory.onNavigationEntryChanged(index);
 
196
  navigation_history_.onNavigationEntryChanged(index);
182
197
}
183
198
 
184
199
oxide::qt::WebFrameAdapter* OxideQQuickWebViewPrivate::CreateWebFrame() {
200
215
                q->width(), q->height()).toRect();
201
216
}
202
217
 
 
218
bool OxideQQuickWebViewPrivate::IsVisible() const {
 
219
  Q_Q(const OxideQQuickWebView);
 
220
 
 
221
  return q->isVisible();
 
222
}
 
223
 
203
224
void OxideQQuickWebViewPrivate::OnWebPreferencesChanged() {
204
225
  Q_Q(OxideQQuickWebView);
205
226
 
220
241
  emit q->frameRemoved(adapterToQObject<OxideQQuickWebFrame>(frame));
221
242
}
222
243
 
 
244
bool OxideQQuickWebViewPrivate::CanCreateWindows() const {
 
245
  Q_Q(const OxideQQuickWebView);
 
246
 
 
247
  static const QMetaMethod signal =
 
248
      QMetaMethod::fromSignal(&OxideQQuickWebView::newViewRequested);
 
249
  return q->isSignalConnected(signal);
 
250
}
 
251
 
 
252
void OxideQQuickWebViewPrivate::NavigationRequested(
 
253
    OxideQNavigationRequest* request) {
 
254
  Q_Q(OxideQQuickWebView);
 
255
 
 
256
  emit q->navigationRequested(request);
 
257
}
 
258
 
 
259
void OxideQQuickWebViewPrivate::NewViewRequested(
 
260
    OxideQNewViewRequest* request) {
 
261
  Q_Q(OxideQQuickWebView);
 
262
 
 
263
  emit q->newViewRequested(request);
 
264
}
 
265
 
223
266
void OxideQQuickWebViewPrivate::completeConstruction() {
224
267
  Q_Q(OxideQQuickWebView);
225
268
 
226
 
  Q_ASSERT(init_props_);
227
 
 
228
 
  OxideQQuickWebContext* context_in_use = context;
229
 
  if (!context_in_use) {
230
 
    // The default context is reference counted and not exposed to the
231
 
    // embedder
232
 
    default_context_ = OxideQQuickWebContext::defaultContext();
233
 
    context_in_use = default_context_.data();
 
269
  if (!context()) {
 
270
    OxideQQuickWebContext* c = OxideQQuickWebContext::defaultContext(true);
 
271
    setContext(OxideQQuickWebContextPrivate::get(c));
234
272
  }
235
273
 
236
 
  init(OxideQQuickWebContextPrivate::get(context_in_use),
237
 
       QSizeF(q->width(), q->height()).toSize(),
238
 
       init_props_->incognito,
239
 
       init_props_->url,
240
 
       q->isVisible());
241
 
 
242
 
  init_props_.reset();
243
 
 
244
 
  // Make the webview the QObject parent of the new root frame,
245
 
  // to stop Qml from collecting the frame tree
246
 
  q->rootFrame()->setParent(q);
247
 
 
248
 
  // Initialization created the root frame. This is the only time
249
 
  // this is emitted
250
 
  emit q->rootFrameChanged();
 
274
  init();
251
275
}
252
276
 
253
277
// static
302
326
  }
303
327
}
304
328
 
 
329
void OxideQQuickWebViewPrivate::contextConstructed() {
 
330
  if (constructed_) {
 
331
    completeConstruction();
 
332
  }
 
333
}
 
334
 
 
335
void OxideQQuickWebViewPrivate::contextWillBeDestroyed() {
 
336
  Q_Q(OxideQQuickWebView);
 
337
 
 
338
  // XXX: Our underlying BrowserContext lives on, so we're left in a
 
339
  // bit of a weird state here (WebView.context will return no context,
 
340
  // which is a lie)
 
341
  emit q->contextChanged();
 
342
}
 
343
 
 
344
void OxideQQuickWebViewPrivate::attachContextSignals(
 
345
    OxideQQuickWebContextPrivate* context) {
 
346
  Q_Q(OxideQQuickWebView);
 
347
 
 
348
  if (!context) {
 
349
    return;
 
350
  }
 
351
 
 
352
  QObject::connect(context, SIGNAL(willBeDestroyed()),
 
353
                   q, SLOT(contextWillBeDestroyed()));
 
354
  QObject::connect(context, SIGNAL(constructed()),
 
355
                   q, SLOT(contextConstructed()));
 
356
}
 
357
 
 
358
void OxideQQuickWebViewPrivate::detachContextSignals(
 
359
    OxideQQuickWebContextPrivate* context) {
 
360
  Q_Q(OxideQQuickWebView);
 
361
 
 
362
  if (!context) {
 
363
    return;
 
364
  }
 
365
 
 
366
  QObject::disconnect(context, SIGNAL(constructed()),
 
367
                      q, SLOT(contextConstructed()));
 
368
  QObject::disconnect(context, SIGNAL(willBeDestroyed()),
 
369
                      q, SLOT(contextWillBeDestroyed()));
 
370
}
 
371
 
 
372
OxideQQuickWebViewPrivate::~OxideQQuickWebViewPrivate() {}
 
373
 
305
374
// static
306
375
OxideQQuickWebViewPrivate* OxideQQuickWebViewPrivate::get(
307
376
    OxideQQuickWebView* view) {
317
386
  attached->setView(q);
318
387
}
319
388
 
320
 
void OxideQQuickWebView::visibilityChangedListener() {
321
 
  Q_D(OxideQQuickWebView);
322
 
 
323
 
  if (!d->isInitialized()) {
324
 
    return;
325
 
  }
326
 
 
327
 
  d->updateVisibility(isVisible());
328
 
}
329
 
 
330
389
void OxideQQuickWebView::geometryChanged(const QRectF& newGeometry,
331
390
                                         const QRectF& oldGeometry) {
332
391
  Q_D(OxideQQuickWebView);
338
397
  }
339
398
}
340
399
 
 
400
void OxideQQuickWebView::itemChange(QQuickItem::ItemChange change,
 
401
                                    const QQuickItem::ItemChangeData& value) {
 
402
  Q_D(OxideQQuickWebView);
 
403
 
 
404
  QQuickItem::itemChange(change, value);
 
405
 
 
406
  if (!d->isInitialized()) {
 
407
    return;
 
408
  }
 
409
 
 
410
  if (change == QQuickItem::ItemVisibleHasChanged) {
 
411
    d->updateVisibility(value.boolValue);
 
412
  }
 
413
}
 
414
 
341
415
OxideQQuickWebView::OxideQQuickWebView(QQuickItem* parent) :
342
416
    QQuickItem(parent) {
343
417
  // WebView instantiates NotificationRegistrar, which starts
345
419
  // else we'll crash
346
420
  OxideQQuickWebContextPrivate::ensureChromiumStarted();
347
421
  d_ptr.reset(new OxideQQuickWebViewPrivate(this));
348
 
  QObject::connect(this, SIGNAL(visibleChanged()),
349
 
                   this, SLOT(visibilityChangedListener()));
350
422
}
351
423
 
352
424
OxideQQuickWebView::~OxideQQuickWebView() {
353
425
  Q_D(OxideQQuickWebView);
354
426
 
355
 
  disconnect(this, SIGNAL(visibleChanged()),
356
 
             this, SLOT(visibilityChangedListener()));
357
 
  d->detachContextSignals();
 
427
  d->detachContextSignals(
 
428
      static_cast<OxideQQuickWebContextPrivate *>(d->context()));
358
429
 
359
430
  // Do this before our d_ptr is cleared, as these call back in to us
360
431
  // when they are deleted
367
438
void OxideQQuickWebView::componentComplete() {
368
439
  Q_D(OxideQQuickWebView);
369
440
 
 
441
  Q_ASSERT(!d->constructed_);
 
442
  d->constructed_ = true;
 
443
 
370
444
  QQuickItem::componentComplete();
371
445
 
372
 
  if (d->context) {
373
 
    connect(OxideQQuickWebContextPrivate::get(d->context),
374
 
            SIGNAL(initialized()),
375
 
            this, SLOT(contextInitialized()));
376
 
  }
377
 
 
378
 
  if (!d->context ||
379
 
      OxideQQuickWebContextPrivate::get(d->context)->isInitialized()) {
 
446
  if (!d->context() ||
 
447
      static_cast<OxideQQuickWebContextPrivate *>(d->context())->isConstructed()) {
380
448
    d->completeConstruction();
381
449
  }
382
450
}
390
458
void OxideQQuickWebView::setUrl(const QUrl& url) {
391
459
  Q_D(OxideQQuickWebView);
392
460
 
393
 
  if (d->init_props()) {
394
 
    d->init_props()->url = url;
395
 
  } else {
396
 
    d->setUrl(url);
397
 
  }
 
461
  d->setUrl(url);
398
462
}
399
463
 
400
464
QString OxideQQuickWebView::title() const {
424
488
void OxideQQuickWebView::setIncognito(bool incognito) {
425
489
  Q_D(OxideQQuickWebView);
426
490
 
427
 
  if (d->isInitialized()) {
428
 
    qWarning() << "Cannot change incognito mode after initialization";
 
491
  if (incognito == d->incognito()) {
429
492
    return;
430
493
  }
431
494
 
432
 
  d->init_props()->incognito = incognito;
 
495
  d->setIncognito(incognito);
 
496
  emit incognitoChanged();
433
497
}
434
498
 
435
499
bool OxideQQuickWebView::loading() const {
512
576
QQmlComponent* OxideQQuickWebView::popupMenu() const {
513
577
  Q_D(const OxideQQuickWebView);
514
578
 
515
 
  return d->popup_menu;
 
579
  return d->popup_menu_;
516
580
}
517
581
 
518
582
void OxideQQuickWebView::setPopupMenu(QQmlComponent* popup_menu) {
519
583
  Q_D(OxideQQuickWebView);
520
584
 
521
 
  if (d->popup_menu == popup_menu) {
 
585
  if (d->popup_menu_ == popup_menu) {
522
586
    return;
523
587
  }
524
588
 
525
 
  d->popup_menu = popup_menu;
 
589
  d->popup_menu_ = popup_menu;
526
590
  emit popupMenuChanged();
527
591
}
528
592
 
529
593
QQmlComponent* OxideQQuickWebView::alertDialog() const {
530
594
  Q_D(const OxideQQuickWebView);
531
595
 
532
 
  return d->alert_dialog;
 
596
  return d->alert_dialog_;
533
597
}
534
598
 
535
599
void OxideQQuickWebView::setAlertDialog(QQmlComponent* alert_dialog) {
536
600
  Q_D(OxideQQuickWebView);
537
601
 
538
 
  if (d->alert_dialog == alert_dialog) {
 
602
  if (d->alert_dialog_ == alert_dialog) {
539
603
    return;
540
604
  }
541
605
 
542
 
  d->alert_dialog = alert_dialog;
 
606
  d->alert_dialog_ = alert_dialog;
543
607
  emit alertDialogChanged();
544
608
}
545
609
 
546
610
QQmlComponent* OxideQQuickWebView::confirmDialog() const {
547
611
  Q_D(const OxideQQuickWebView);
548
612
 
549
 
  return d->confirm_dialog;
 
613
  return d->confirm_dialog_;
550
614
}
551
615
 
552
616
void OxideQQuickWebView::setConfirmDialog(QQmlComponent* confirm_dialog) {
553
617
  Q_D(OxideQQuickWebView);
554
618
 
555
 
  if (d->confirm_dialog == confirm_dialog) {
 
619
  if (d->confirm_dialog_ == confirm_dialog) {
556
620
    return;
557
621
  }
558
622
 
559
 
  d->confirm_dialog = confirm_dialog;
 
623
  d->confirm_dialog_ = confirm_dialog;
560
624
  emit confirmDialogChanged();
561
625
}
562
626
 
563
627
QQmlComponent* OxideQQuickWebView::promptDialog() const {
564
628
  Q_D(const OxideQQuickWebView);
565
629
 
566
 
  return d->prompt_dialog;
 
630
  return d->prompt_dialog_;
567
631
}
568
632
 
569
633
void OxideQQuickWebView::setPromptDialog(QQmlComponent* prompt_dialog) {
570
634
  Q_D(OxideQQuickWebView);
571
635
 
572
 
  if (d->prompt_dialog == prompt_dialog) {
 
636
  if (d->prompt_dialog_ == prompt_dialog) {
573
637
    return;
574
638
  }
575
639
 
576
 
  d->prompt_dialog = prompt_dialog;
 
640
  d->prompt_dialog_ = prompt_dialog;
577
641
  emit promptDialogChanged();
578
642
}
579
643
 
580
644
QQmlComponent* OxideQQuickWebView::beforeUnloadDialog() const {
581
645
  Q_D(const OxideQQuickWebView);
582
646
 
583
 
  return d->before_unload_dialog;
 
647
  return d->before_unload_dialog_;
584
648
}
585
649
 
586
650
void OxideQQuickWebView::setBeforeUnloadDialog(
587
651
    QQmlComponent* before_unload_dialog) {
588
652
  Q_D(OxideQQuickWebView);
589
653
 
590
 
  if (d->before_unload_dialog == before_unload_dialog) {
 
654
  if (d->before_unload_dialog_ == before_unload_dialog) {
591
655
    return;
592
656
  }
593
657
 
594
 
  d->before_unload_dialog = before_unload_dialog;
 
658
  d->before_unload_dialog_ = before_unload_dialog;
595
659
  emit beforeUnloadDialogChanged();
596
660
}
597
661
 
 
662
QQmlComponent* OxideQQuickWebView::filePicker() const {
 
663
  Q_D(const OxideQQuickWebView);
 
664
 
 
665
  return d->file_picker_;
 
666
}
 
667
 
 
668
void OxideQQuickWebView::setFilePicker(QQmlComponent* file_picker) {
 
669
  Q_D(OxideQQuickWebView);
 
670
 
 
671
  if (d->file_picker_ == file_picker) {
 
672
    return;
 
673
  }
 
674
 
 
675
  d->file_picker_ = file_picker;
 
676
  emit filePickerChanged();
 
677
}
 
678
 
598
679
OxideQQuickWebContext* OxideQQuickWebView::context() const {
599
680
  Q_D(const OxideQQuickWebView);
600
681
 
601
 
  return d->context;
 
682
  OxideQQuickWebContext* c =
 
683
      adapterToQObject<OxideQQuickWebContext>(d->context());
 
684
  if (c == OxideQQuickWebContext::defaultContext(false)) {
 
685
    return NULL;
 
686
  }
 
687
 
 
688
  return c;
602
689
}
603
690
 
604
691
void OxideQQuickWebView::setContext(OxideQQuickWebContext* context) {
605
692
  Q_D(OxideQQuickWebView);
606
693
 
607
 
  if (!d->init_props()) {
608
 
    qWarning() << "The context can only be set at construction time";
609
 
    return;
610
 
  }
611
 
 
612
 
  if (context == d->context) {
613
 
    return;
614
 
  }
615
 
 
616
 
  d->detachContextSignals();
 
694
  if (d->isInitialized()) {
 
695
    qWarning() << "WebView context must be set during construction";
 
696
    return;
 
697
  }
 
698
 
 
699
  if (context == OxideQQuickWebContext::defaultContext(false)) {
 
700
    qWarning() <<
 
701
        "Setting WebView context to default context is unnecessary. WebView "
 
702
        "will automatically use the default context if it is created without "
 
703
        "one";
 
704
    return;
 
705
  }
 
706
 
 
707
  oxide::qt::WebContextAdapter* old = d->context();
 
708
  if (context == adapterToQObject<OxideQQuickWebContext>(old)) {
 
709
    return;
 
710
  }
 
711
  d->detachContextSignals(static_cast<OxideQQuickWebContextPrivate *>(old));
 
712
 
 
713
  OxideQQuickWebContextPrivate* cd = NULL;
617
714
  if (context) {
618
 
    connect(OxideQQuickWebContextPrivate::get(context), SIGNAL(willBeDestroyed()),
619
 
            this, SLOT(contextWillBeDestroyed()));
 
715
    cd = OxideQQuickWebContextPrivate::get(context);
620
716
  }
 
717
  d->attachContextSignals(cd);
 
718
  d->setContext(cd);
621
719
 
622
 
  d->context = context;
623
720
  emit contextChanged();
624
721
}
625
722
 
644
741
OxideQQuickNavigationHistory* OxideQQuickWebView::navigationHistory() {
645
742
  Q_D(OxideQQuickWebView);
646
743
 
647
 
  return &d->navigationHistory;
 
744
  return &d->navigation_history_;
 
745
}
 
746
 
 
747
// This exists purely to remove a moc warning. We don't store this request
 
748
// anywhere, it's only a transient object and I can't think of any possible
 
749
// reason why anybody would want to read it back
 
750
OxideQNewViewRequest* OxideQQuickWebView::request() const {
 
751
  return NULL;
 
752
}
 
753
 
 
754
void OxideQQuickWebView::setRequest(OxideQNewViewRequest* request) {
 
755
  Q_D(OxideQQuickWebView);
 
756
 
 
757
  d->setRequest(request);
648
758
}
649
759
 
650
760
// static