forked from qt-creator/qt-creator
Help: Provide native WebView backend on Mac
Run Qt Creator with environment variable QTC_HELPVIEWER_BACKEND to * 'native' to get the WebView based one on Mac * 'textbrowser' to get the QTextBrowser based one Defaults to use QWebView if QtWebKit is available, or QTextBrowser if not, like before. Change-Id: If0660782b18ff3d89301fa7bcaf4e2e2fb69627d Reviewed-by: Eike Ziller <eike.ziller@digia.com>
This commit is contained in:
@@ -82,7 +82,9 @@ QWidget *GeneralSettingsPage::widget()
|
||||
m_ui->sizeComboBox->setEditable(false);
|
||||
m_ui->styleComboBox->setEditable(false);
|
||||
|
||||
m_font = qvariant_cast<QFont>(HelpManager::customValue(QLatin1String("font"), m_font));
|
||||
QVariant fontSetting = LocalHelpManager::engineFontSettings();
|
||||
if (fontSetting.isValid())
|
||||
m_font = fontSetting.value<QFont>();
|
||||
|
||||
updateFontSize();
|
||||
updateFontStyle();
|
||||
@@ -155,7 +157,7 @@ void GeneralSettingsPage::apply()
|
||||
|
||||
if (newFont != m_font) {
|
||||
m_font = newFont;
|
||||
HelpManager::setCustomValue(QLatin1String("font"), newFont);
|
||||
HelpManager::setCustomValue(Constants::FontKey, newFont);
|
||||
emit fontChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -68,5 +68,14 @@ FORMS += docsettingspage.ui \
|
||||
generalsettingspage.ui \
|
||||
remotehelpfilter.ui
|
||||
|
||||
macx:minQtVersion(5, 2, 0) {
|
||||
DEFINES += QTC_MAC_NATIVE_HELPVIEWER
|
||||
QT += macextras
|
||||
HEADERS += macwebkithelpviewer.h
|
||||
OBJECTIVE_SOURCES += macwebkithelpviewer.mm
|
||||
|
||||
LIBS += -framework WebKit -framework AppKit
|
||||
}
|
||||
|
||||
RESOURCES += help.qrc
|
||||
include(../../shared/help/help.pri)
|
||||
|
||||
@@ -54,6 +54,7 @@ static const QLatin1String DefaultZoomFactor("0.0");
|
||||
static const QLatin1String AboutBlank("about:blank");
|
||||
static const QLatin1String WeAddedFilterKey("UnfilteredFilterInserted");
|
||||
static const QLatin1String PreviousFilterNameKey("UnfilteredFilterName");
|
||||
static const QLatin1String FontKey("font");
|
||||
|
||||
const int P_MODE_HELP = 70;
|
||||
const char ID_MODE_HELP [] = "Help";
|
||||
|
||||
@@ -48,6 +48,10 @@
|
||||
#include "searchtaskhandler.h"
|
||||
#include "textbrowserhelpviewer.h"
|
||||
|
||||
#ifdef QTC_MAC_NATIVE_HELPVIEWER
|
||||
#include "macwebkithelpviewer.h"
|
||||
#endif
|
||||
|
||||
#include <bookmarkmanager.h>
|
||||
#include <contentwindow.h>
|
||||
#include <indexwindow.h>
|
||||
@@ -638,14 +642,27 @@ void HelpPlugin::resetRightPaneScale()
|
||||
|
||||
HelpViewer *HelpPlugin::createHelpViewer(qreal zoom)
|
||||
{
|
||||
#ifndef QT_NO_WEBKIT
|
||||
if (qgetenv("QTC_FORCE_TEXTBROWSER").isEmpty())
|
||||
return new QtWebKitHelpViewer(zoom);
|
||||
else
|
||||
return new TextBrowserHelpViewer(zoom);
|
||||
#else
|
||||
return new TextBrowserHelpViewer(zoom);
|
||||
HelpViewer *viewer = 0;
|
||||
const QString backend = QLatin1String(qgetenv("QTC_HELPVIEWER_BACKEND"));
|
||||
if (backend.compare(QLatin1String("native"), Qt::CaseInsensitive) == 0) {
|
||||
#ifdef QTC_MAC_NATIVE_HELPVIEWER
|
||||
viewer = new MacWebKitHelpViewer(zoom);
|
||||
#endif
|
||||
} else if (backend.compare(QLatin1String("textbrowser"), Qt::CaseInsensitive) == 0) {
|
||||
viewer = new TextBrowserHelpViewer(zoom);
|
||||
} else {
|
||||
#ifndef QT_NO_WEBKIT
|
||||
viewer = new QtWebKitHelpViewer(zoom);
|
||||
#else
|
||||
viewer = new TextBrowserHelpViewer(zoom);
|
||||
#endif
|
||||
}
|
||||
|
||||
// initialize font
|
||||
QVariant fontSetting = LocalHelpManager::engineFontSettings();
|
||||
if (fontSetting.isValid())
|
||||
viewer->setViewerFont(fontSetting.value<QFont>());
|
||||
return viewer;
|
||||
}
|
||||
|
||||
void HelpPlugin::activateHelpMode()
|
||||
@@ -729,11 +746,11 @@ void HelpPlugin::fontChanged()
|
||||
if (!m_helpViewerForSideBar)
|
||||
createRightPaneContextViewer();
|
||||
|
||||
const QHelpEngine &engine = LocalHelpManager::helpEngine();
|
||||
QFont font = qvariant_cast<QFont>(engine.customValue(QLatin1String("font"),
|
||||
m_helpViewerForSideBar->viewerFont()));
|
||||
QVariant fontSetting = LocalHelpManager::engineFontSettings();
|
||||
QFont font = fontSetting.isValid() ? fontSetting.value<QFont>()
|
||||
: m_helpViewerForSideBar->viewerFont();
|
||||
|
||||
m_helpViewerForSideBar->setFont(font);
|
||||
m_helpViewerForSideBar->setViewerFont(font);
|
||||
const int count = OpenPagesManager::instance().pageCount();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (HelpViewer *viewer = CentralWidget::instance()->viewerAt(i))
|
||||
|
||||
@@ -60,7 +60,6 @@ public:
|
||||
virtual qreal scale() const = 0;
|
||||
|
||||
virtual QString title() const = 0;
|
||||
virtual void setTitle(const QString &title) = 0;
|
||||
|
||||
virtual QUrl source() const = 0;
|
||||
virtual void setSource(const QUrl &url) = 0;
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
|
||||
#include "localhelpmanager.h"
|
||||
|
||||
#include <bookmarkmanager.h>
|
||||
#include "bookmarkmanager.h"
|
||||
#include "helpconstants.h"
|
||||
|
||||
#include <app/app_version.h>
|
||||
#include <coreplugin/helpmanager.h>
|
||||
@@ -40,6 +41,8 @@
|
||||
|
||||
using namespace Help::Internal;
|
||||
|
||||
static LocalHelpManager *m_instance = 0;
|
||||
|
||||
QMutex LocalHelpManager::m_guiMutex;
|
||||
QHelpEngine* LocalHelpManager::m_guiEngine = 0;
|
||||
|
||||
@@ -51,6 +54,7 @@ LocalHelpManager::LocalHelpManager(QObject *parent)
|
||||
, m_guiNeedsSetup(true)
|
||||
, m_needsCollectionFile(true)
|
||||
{
|
||||
m_instance = this;
|
||||
}
|
||||
|
||||
LocalHelpManager::~LocalHelpManager()
|
||||
@@ -65,6 +69,11 @@ LocalHelpManager::~LocalHelpManager()
|
||||
m_guiEngine = 0;
|
||||
}
|
||||
|
||||
LocalHelpManager *LocalHelpManager::instance()
|
||||
{
|
||||
return m_instance;
|
||||
}
|
||||
|
||||
void LocalHelpManager::setupGuiHelpEngine()
|
||||
{
|
||||
if (m_needsCollectionFile) {
|
||||
@@ -110,3 +119,16 @@ BookmarkManager& LocalHelpManager::bookmarkManager()
|
||||
}
|
||||
return *m_bookmarkManager;
|
||||
}
|
||||
|
||||
QVariant LocalHelpManager::engineFontSettings()
|
||||
{
|
||||
return helpEngine().customValue(Constants::FontKey, QVariant());
|
||||
}
|
||||
|
||||
QByteArray LocalHelpManager::helpData(const QUrl &url)
|
||||
{
|
||||
const QHelpEngineCore &engine = helpEngine();
|
||||
|
||||
return engine.findFile(url).isValid() ? engine.fileData(url)
|
||||
: tr("Could not load \"%1\".").arg(url.toString()).toUtf8();
|
||||
}
|
||||
|
||||
@@ -48,12 +48,18 @@ public:
|
||||
LocalHelpManager(QObject *parent = 0);
|
||||
~LocalHelpManager();
|
||||
|
||||
static LocalHelpManager *instance();
|
||||
|
||||
void setupGuiHelpEngine();
|
||||
void setEngineNeedsUpdate();
|
||||
|
||||
static QHelpEngine& helpEngine();
|
||||
static BookmarkManager& bookmarkManager();
|
||||
|
||||
static QVariant engineFontSettings();
|
||||
|
||||
Q_INVOKABLE QByteArray helpData(const QUrl &url);
|
||||
|
||||
private:
|
||||
bool m_guiNeedsSetup;
|
||||
bool m_needsCollectionFile;
|
||||
|
||||
140
src/plugins/help/macwebkithelpviewer.h
Normal file
140
src/plugins/help/macwebkithelpviewer.h
Normal file
@@ -0,0 +1,140 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef MACWEBKITHELPVIEWER_H
|
||||
#define MACWEBKITHELPVIEWER_H
|
||||
|
||||
#include "helpviewer.h"
|
||||
|
||||
#include <QMacCocoaViewContainer>
|
||||
|
||||
Q_FORWARD_DECLARE_OBJC_CLASS(DOMNode);
|
||||
Q_FORWARD_DECLARE_OBJC_CLASS(DOMRange);
|
||||
Q_FORWARD_DECLARE_OBJC_CLASS(NSString);
|
||||
Q_FORWARD_DECLARE_OBJC_CLASS(WebView);
|
||||
|
||||
namespace Help {
|
||||
namespace Internal {
|
||||
|
||||
class MacWebKitHelpViewer;
|
||||
class MacWebKitHelpWidgetPrivate;
|
||||
|
||||
class MacResponderHack : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MacResponderHack(QObject *parent);
|
||||
|
||||
private slots:
|
||||
void responderHack(QWidget *old, QWidget *now);
|
||||
};
|
||||
|
||||
class MacWebKitHelpWidget : public QMacCocoaViewContainer
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MacWebKitHelpWidget(MacWebKitHelpViewer *parent);
|
||||
~MacWebKitHelpWidget();
|
||||
|
||||
void setOpenInNewWindowActionVisible(bool visible);
|
||||
|
||||
WebView *webView() const;
|
||||
|
||||
protected:
|
||||
void hideEvent(QHideEvent *);
|
||||
void showEvent(QShowEvent *);
|
||||
|
||||
private:
|
||||
MacWebKitHelpWidgetPrivate *d;
|
||||
};
|
||||
|
||||
class MacWebKitHelpViewer : public HelpViewer
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MacWebKitHelpViewer(qreal zoom, QWidget *parent = 0);
|
||||
~MacWebKitHelpViewer();
|
||||
|
||||
QFont viewerFont() const;
|
||||
void setViewerFont(const QFont &font);
|
||||
|
||||
void scaleUp();
|
||||
void scaleDown();
|
||||
void resetScale();
|
||||
|
||||
qreal scale() const;
|
||||
|
||||
QString title() const;
|
||||
|
||||
QUrl source() const;
|
||||
void setSource(const QUrl &url);
|
||||
void scrollToAnchor(const QString &anchor);
|
||||
void highlightId(const QString &id) { Q_UNUSED(id) }
|
||||
|
||||
void setHtml(const QString &html);
|
||||
|
||||
QString selectedText() const;
|
||||
bool isForwardAvailable() const;
|
||||
bool isBackwardAvailable() const;
|
||||
void addBackHistoryItems(QMenu *backMenu);
|
||||
void addForwardHistoryItems(QMenu *forwardMenu);
|
||||
void setOpenInNewWindowActionVisible(bool visible);
|
||||
|
||||
bool findText(const QString &text, Core::FindFlags flags,
|
||||
bool incremental, bool fromSearch, bool *wrapped = 0);
|
||||
|
||||
MacWebKitHelpWidget *widget() const { return m_widget; }
|
||||
|
||||
public slots:
|
||||
void copy();
|
||||
void stop();
|
||||
void forward();
|
||||
void backward();
|
||||
void print(QPrinter *printer);
|
||||
|
||||
public slots:
|
||||
void slotLoadStarted();
|
||||
void slotLoadFinished();
|
||||
|
||||
private slots:
|
||||
void goToHistoryItem();
|
||||
|
||||
private:
|
||||
DOMRange *findText(NSString *text, bool forward, bool caseSensitive, DOMNode *startNode,
|
||||
int startOffset);
|
||||
MacWebKitHelpWidget *m_widget;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Help
|
||||
|
||||
#endif // MACWEBKITHELPVIEWER_H
|
||||
812
src/plugins/help/macwebkithelpviewer.mm
Normal file
812
src/plugins/help/macwebkithelpviewer.mm
Normal file
@@ -0,0 +1,812 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "macwebkithelpviewer.h"
|
||||
|
||||
#include "localhelpmanager.h"
|
||||
#include "openpagesmanager.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QHelpEngine>
|
||||
#include <QtMac>
|
||||
#include <QUrl>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#import <AppKit/NSMenuItem.h>
|
||||
#import <Foundation/NSURLProtocol.h>
|
||||
#import <Foundation/NSURLResponse.h>
|
||||
#import <WebKit/DOMDocument.h>
|
||||
#import <WebKit/DOMElement.h>
|
||||
#import <WebKit/DOMHTMLElement.h>
|
||||
#import <WebKit/DOMNodeFilter.h>
|
||||
#import <WebKit/DOMNodeIterator.h>
|
||||
#import <WebKit/DOMRange.h>
|
||||
#import <WebKit/WebBackForwardList.h>
|
||||
#import <WebKit/WebDataSource.h>
|
||||
#import <WebKit/WebDocument.h>
|
||||
#import <WebKit/WebFrame.h>
|
||||
#import <WebKit/WebFrameLoadDelegate.h>
|
||||
#import <WebKit/WebFrameView.h>
|
||||
#import <WebKit/WebHistoryItem.h>
|
||||
#import <WebKit/WebPreferences.h>
|
||||
#import <WebKit/WebUIDelegate.h>
|
||||
#import <WebKit/WebView.h>
|
||||
|
||||
// #pragma mark -- AutoreleasePool
|
||||
|
||||
class AutoreleasePool
|
||||
{
|
||||
public:
|
||||
AutoreleasePool();
|
||||
~AutoreleasePool();
|
||||
private:
|
||||
NSAutoreleasePool *pool;
|
||||
};
|
||||
|
||||
AutoreleasePool::AutoreleasePool()
|
||||
{
|
||||
pool = [[NSAutoreleasePool alloc] init];
|
||||
}
|
||||
|
||||
AutoreleasePool::~AutoreleasePool()
|
||||
{
|
||||
[pool release];
|
||||
}
|
||||
|
||||
// #pragma mark -- DOMNodeIterator (PrivateExtensions)
|
||||
|
||||
@interface DOMNodeIterator (PrivateExtensions)
|
||||
|
||||
- (BOOL)findNode:(DOMNode *)node;
|
||||
- (DOMNode *)nextTextNode;
|
||||
- (DOMNode *)previousTextNode;
|
||||
- (DOMNode *)gotoEnd;
|
||||
|
||||
@end
|
||||
|
||||
@implementation DOMNodeIterator (PrivateExtensions)
|
||||
|
||||
- (BOOL)findNode:(DOMNode *)node
|
||||
{
|
||||
while (DOMNode *next = [self nextNode]) {
|
||||
if (next == node)
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (DOMNode *)nextTextNode
|
||||
{
|
||||
DOMNode *node = nil;
|
||||
do {
|
||||
node = [self nextNode];
|
||||
} while (node && node.nodeType != DOM_TEXT_NODE);
|
||||
return node;
|
||||
}
|
||||
|
||||
- (DOMNode *)previousTextNode
|
||||
{
|
||||
DOMNode *node = nil;
|
||||
do {
|
||||
node = [self previousNode];
|
||||
} while (node && node.nodeType != DOM_TEXT_NODE);
|
||||
return node;
|
||||
}
|
||||
|
||||
- (DOMNode *)gotoEnd
|
||||
{
|
||||
DOMNode *previous = nil;
|
||||
DOMNode *node = nil;
|
||||
do {
|
||||
previous = node;
|
||||
node = [self nextNode];
|
||||
} while (node);
|
||||
return previous;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// #pragma mark -- QtHelpURLProtocol
|
||||
|
||||
@interface QtHelpURLProtocol : NSURLProtocol
|
||||
{
|
||||
}
|
||||
|
||||
+ (BOOL)canInitWithRequest:(NSURLRequest *)request;
|
||||
|
||||
@end
|
||||
|
||||
@implementation QtHelpURLProtocol
|
||||
|
||||
+ (BOOL)canInitWithRequest:(NSURLRequest *)request
|
||||
{
|
||||
return [[[request URL] scheme] isEqualToString:@"qthelp"];
|
||||
}
|
||||
|
||||
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request
|
||||
{
|
||||
return request;
|
||||
}
|
||||
|
||||
- (void)startLoading
|
||||
{
|
||||
const QUrl &url = QUrl::fromNSURL(self.request.URL);
|
||||
QByteArray data;
|
||||
Help::Internal::LocalHelpManager *helpManager = Help::Internal::LocalHelpManager::instance();
|
||||
|
||||
QMetaObject::invokeMethod(helpManager, "helpData", Qt::BlockingQueuedConnection,
|
||||
Q_RETURN_ARG(QByteArray, data), Q_ARG(QUrl, url));
|
||||
|
||||
QString mtString = Help::Internal::HelpViewer::mimeFromUrl(url);
|
||||
if (mtString.isEmpty())
|
||||
mtString = QLatin1String("application/octet-stream");
|
||||
NSString *mimeType = mtString.toNSString();
|
||||
|
||||
NSData *nsdata = QtMac::toNSData(data); // Qt 5.3 has this in QByteArray
|
||||
|
||||
NSURLResponse *response = [[NSURLResponse alloc] initWithURL:self.request.URL
|
||||
MIMEType:mimeType
|
||||
expectedContentLength:data.length()
|
||||
textEncodingName:@"UTF8"];
|
||||
[self.client URLProtocol:self didReceiveResponse:response
|
||||
cacheStoragePolicy:NSURLCacheStorageNotAllowed];
|
||||
[self.client URLProtocol:self didLoadData:nsdata];
|
||||
[self.client URLProtocolDidFinishLoading:self];
|
||||
[response release];
|
||||
}
|
||||
|
||||
- (void)stopLoading
|
||||
{
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
static void ensureProtocolHandler()
|
||||
{
|
||||
static bool registered = false;
|
||||
if (!registered) {
|
||||
[NSURLProtocol registerClass:[QtHelpURLProtocol class]];
|
||||
registered = true;
|
||||
}
|
||||
}
|
||||
|
||||
// #pragma mark -- FrameLoadDelegate
|
||||
|
||||
@interface FrameLoadDelegate : NSObject
|
||||
{
|
||||
WebFrame *mainFrame;
|
||||
Help::Internal::MacWebKitHelpViewer *viewer;
|
||||
}
|
||||
|
||||
- (id)initWithMainFrame:(WebFrame *)frame viewer:(Help::Internal::MacWebKitHelpViewer *)viewer;
|
||||
- (void)webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame *)frame;
|
||||
- (void)webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame;
|
||||
- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame;
|
||||
|
||||
@end
|
||||
|
||||
@implementation FrameLoadDelegate
|
||||
|
||||
- (id)initWithMainFrame:(WebFrame *)frame viewer:(Help::Internal::MacWebKitHelpViewer *)helpViewer
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
mainFrame = frame;
|
||||
viewer = helpViewer;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame *)frame
|
||||
{
|
||||
Q_UNUSED(sender)
|
||||
if (frame == mainFrame)
|
||||
viewer->slotLoadStarted();
|
||||
}
|
||||
|
||||
- (void)webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame
|
||||
{
|
||||
Q_UNUSED(sender)
|
||||
Q_UNUSED(title)
|
||||
if (frame == mainFrame)
|
||||
viewer->titleChanged();
|
||||
}
|
||||
|
||||
- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
|
||||
{
|
||||
Q_UNUSED(sender)
|
||||
if (frame == mainFrame)
|
||||
viewer->slotLoadFinished();
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// #pragma mark -- UIDelegate
|
||||
|
||||
@interface UIDelegate : NSObject
|
||||
{
|
||||
QWidget *widget;
|
||||
}
|
||||
|
||||
@property (assign) BOOL openInNewWindowActionVisible;
|
||||
|
||||
- (id)initWithWidget:(QWidget *)theWidget;
|
||||
- (void)webView:(WebView *)sender makeFirstResponder:(NSResponder *)responder;
|
||||
- (NSArray *)webView:(WebView *)sender contextMenuItemsForElement:(NSDictionary *)element
|
||||
defaultMenuItems:(NSArray *)defaultMenuItems;
|
||||
- (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request;
|
||||
|
||||
@end
|
||||
|
||||
@implementation UIDelegate
|
||||
|
||||
- (id)initWithWidget:(QWidget *)theWidget
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
widget = theWidget;
|
||||
self.openInNewWindowActionVisible = YES;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)webView:(WebView *)sender makeFirstResponder:(NSResponder *)responder
|
||||
{
|
||||
// make the widget get focus
|
||||
if (responder) {
|
||||
widget->setFocus();
|
||||
[sender.window makeFirstResponder:responder];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray *)webView:(WebView *)sender contextMenuItemsForElement:(NSDictionary *)element
|
||||
defaultMenuItems:(NSArray *)defaultMenuItems
|
||||
{
|
||||
Q_UNUSED(sender)
|
||||
Q_UNUSED(element)
|
||||
NSMutableArray *ret = [[NSMutableArray alloc] init];
|
||||
for (NSMenuItem *item in defaultMenuItems) {
|
||||
switch (item.tag) {
|
||||
case WebMenuItemTagCopyLinkToClipboard:
|
||||
case WebMenuItemTagCopyImageToClipboard:
|
||||
case WebMenuItemTagCopy:
|
||||
case WebMenuItemTagGoBack:
|
||||
case WebMenuItemTagGoForward:
|
||||
case WebMenuItemTagStop:
|
||||
case WebMenuItemTagReload:
|
||||
case WebMenuItemTagOther:
|
||||
case WebMenuItemTagSearchInSpotlight:
|
||||
case WebMenuItemTagSearchWeb:
|
||||
case WebMenuItemTagLookUpInDictionary:
|
||||
case WebMenuItemTagOpenWithDefaultApplication:
|
||||
[ret addObject:item];
|
||||
break;
|
||||
case WebMenuItemTagOpenLinkInNewWindow:
|
||||
case WebMenuItemTagOpenImageInNewWindow:
|
||||
if (self.openInNewWindowActionVisible)
|
||||
[ret addObject:item];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return [ret autorelease];
|
||||
}
|
||||
|
||||
- (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request
|
||||
{
|
||||
Q_UNUSED(sender)
|
||||
Q_UNUSED(request)
|
||||
Help::Internal::MacWebKitHelpViewer* viewer
|
||||
= static_cast<Help::Internal::MacWebKitHelpViewer *>(
|
||||
Help::Internal::OpenPagesManager::instance().createPage(QUrl()));
|
||||
return viewer->widget()->webView();
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// #pragma mark -- MyWebView
|
||||
@interface MyWebView : WebView
|
||||
@end
|
||||
|
||||
// work around Qt + WebView issue QTBUG-26593, that Qt does not pass mouseMoved: events up the event chain,
|
||||
// but the Web(HTML)View is only handling mouse moved for hovering etc if the event was passed up
|
||||
// to the NSWindow (arguably a bug in Web(HTML)View)
|
||||
@implementation MyWebView
|
||||
|
||||
- (void)updateTrackingAreas
|
||||
{
|
||||
[super updateTrackingAreas];
|
||||
if (NSArray *trackingArray = [self trackingAreas]) {
|
||||
NSUInteger size = [trackingArray count];
|
||||
for (NSUInteger i = 0; i < size; ++i) {
|
||||
NSTrackingArea *t = [trackingArray objectAtIndex:i];
|
||||
[self removeTrackingArea:t];
|
||||
}
|
||||
}
|
||||
NSUInteger trackingOptions = NSTrackingActiveInActiveApp | NSTrackingInVisibleRect
|
||||
| NSTrackingMouseMoved;
|
||||
NSTrackingArea *ta = [[[NSTrackingArea alloc] initWithRect:[self frame]
|
||||
options:trackingOptions
|
||||
owner:self
|
||||
userInfo:nil]
|
||||
autorelease];
|
||||
[self addTrackingArea:ta];
|
||||
}
|
||||
|
||||
- (void)mouseMoved:(NSEvent *)theEvent
|
||||
{
|
||||
[self.window mouseMoved:theEvent];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
namespace Help {
|
||||
namespace Internal {
|
||||
|
||||
// #pragma mark -- MacWebKitHelpWidget
|
||||
|
||||
class MacWebKitHelpWidgetPrivate
|
||||
{
|
||||
public:
|
||||
MacWebKitHelpWidgetPrivate()
|
||||
: m_savedResponder(nil)
|
||||
{
|
||||
}
|
||||
|
||||
~MacWebKitHelpWidgetPrivate()
|
||||
{
|
||||
[m_webView release];
|
||||
[m_frameLoadDelegate release];
|
||||
[m_uiDelegate release];
|
||||
}
|
||||
|
||||
WebView *m_webView;
|
||||
FrameLoadDelegate *m_frameLoadDelegate;
|
||||
UIDelegate *m_uiDelegate;
|
||||
NSResponder *m_savedResponder;
|
||||
};
|
||||
|
||||
// #pragma mark -- MacWebKitHelpWidget
|
||||
|
||||
MacWebKitHelpWidget::MacWebKitHelpWidget(MacWebKitHelpViewer *parent)
|
||||
: QMacCocoaViewContainer(0, parent),
|
||||
d(new MacWebKitHelpWidgetPrivate)
|
||||
{
|
||||
AutoreleasePool pool; Q_UNUSED(pool)
|
||||
d->m_webView = [[MyWebView alloc] init];
|
||||
d->m_frameLoadDelegate = [[FrameLoadDelegate alloc] initWithMainFrame:d->m_webView.mainFrame
|
||||
viewer:parent];
|
||||
[d->m_webView setFrameLoadDelegate:d->m_frameLoadDelegate];
|
||||
d->m_uiDelegate = [[UIDelegate alloc] initWithWidget:this];
|
||||
[d->m_webView setUIDelegate:d->m_uiDelegate];
|
||||
|
||||
setCocoaView(d->m_webView);
|
||||
}
|
||||
|
||||
MacWebKitHelpWidget::~MacWebKitHelpWidget()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
void MacWebKitHelpWidget::setOpenInNewWindowActionVisible(bool visible)
|
||||
{
|
||||
d->m_uiDelegate.openInNewWindowActionVisible = visible;
|
||||
}
|
||||
|
||||
WebView *MacWebKitHelpWidget::webView() const
|
||||
{
|
||||
return d->m_webView;
|
||||
}
|
||||
|
||||
void MacWebKitHelpWidget::hideEvent(QHideEvent *)
|
||||
{
|
||||
[d->m_webView setHidden:YES];
|
||||
}
|
||||
|
||||
void MacWebKitHelpWidget::showEvent(QShowEvent *)
|
||||
{
|
||||
[d->m_webView setHidden:NO];
|
||||
}
|
||||
|
||||
// #pragma mark -- MacWebKitHelpViewer
|
||||
|
||||
MacWebKitHelpViewer::MacWebKitHelpViewer(qreal zoom, QWidget *parent)
|
||||
: HelpViewer(parent),
|
||||
m_widget(new MacWebKitHelpWidget(this))
|
||||
{
|
||||
static bool responderHackInstalled = false;
|
||||
if (!responderHackInstalled) {
|
||||
responderHackInstalled = true;
|
||||
new MacResponderHack(qApp);
|
||||
}
|
||||
|
||||
AutoreleasePool pool; Q_UNUSED(pool)
|
||||
QVBoxLayout *layout = new QVBoxLayout;
|
||||
setLayout(layout);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->addWidget(m_widget, 10);
|
||||
m_widget->webView().textSizeMultiplier = (zoom == 0.0 ? 1.0 : zoom);
|
||||
}
|
||||
|
||||
MacWebKitHelpViewer::~MacWebKitHelpViewer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QFont MacWebKitHelpViewer::viewerFont() const
|
||||
{
|
||||
AutoreleasePool pool; Q_UNUSED(pool)
|
||||
WebPreferences *preferences = m_widget->webView().preferences;
|
||||
QString family = QString::fromNSString([preferences standardFontFamily]);
|
||||
int size = [preferences defaultFontSize];
|
||||
return QFont(family, size);
|
||||
}
|
||||
|
||||
void MacWebKitHelpViewer::setViewerFont(const QFont &font)
|
||||
{
|
||||
AutoreleasePool pool; Q_UNUSED(pool)
|
||||
WebPreferences *preferences = m_widget->webView().preferences;
|
||||
[preferences setStandardFontFamily:font.family().toNSString()];
|
||||
[preferences setDefaultFontSize:font.pointSize()];
|
||||
}
|
||||
|
||||
void MacWebKitHelpViewer::scaleUp()
|
||||
{
|
||||
AutoreleasePool pool; Q_UNUSED(pool)
|
||||
m_widget->webView().textSizeMultiplier += 0.1;
|
||||
}
|
||||
|
||||
void MacWebKitHelpViewer::scaleDown()
|
||||
{
|
||||
AutoreleasePool pool; Q_UNUSED(pool)
|
||||
m_widget->webView().textSizeMultiplier = qMax(0.1, m_widget->webView().textSizeMultiplier - 0.1);
|
||||
}
|
||||
|
||||
void MacWebKitHelpViewer::resetScale()
|
||||
{
|
||||
AutoreleasePool pool; Q_UNUSED(pool)
|
||||
m_widget->webView().textSizeMultiplier = 1.0;
|
||||
}
|
||||
|
||||
qreal MacWebKitHelpViewer::scale() const
|
||||
{
|
||||
AutoreleasePool pool; Q_UNUSED(pool)
|
||||
return m_widget->webView().textSizeMultiplier;
|
||||
}
|
||||
|
||||
QString MacWebKitHelpViewer::title() const
|
||||
{
|
||||
AutoreleasePool pool; Q_UNUSED(pool)
|
||||
return QString::fromNSString(m_widget->webView().mainFrameTitle);
|
||||
}
|
||||
|
||||
QUrl MacWebKitHelpViewer::source() const
|
||||
{
|
||||
AutoreleasePool pool; Q_UNUSED(pool)
|
||||
WebDataSource *dataSource = m_widget->webView().mainFrame.dataSource;
|
||||
if (!dataSource)
|
||||
dataSource = m_widget->webView().mainFrame.provisionalDataSource;
|
||||
return QUrl::fromNSURL(dataSource.request.URL);
|
||||
}
|
||||
|
||||
void MacWebKitHelpViewer::setSource(const QUrl &url)
|
||||
{
|
||||
AutoreleasePool pool; Q_UNUSED(pool)
|
||||
ensureProtocolHandler();
|
||||
[m_widget->webView().mainFrame loadRequest:[NSURLRequest requestWithURL:url.toNSURL()]];
|
||||
}
|
||||
|
||||
void MacWebKitHelpViewer::scrollToAnchor(const QString &anchor)
|
||||
{
|
||||
QUrl url = source();
|
||||
url.setFragment(anchor);
|
||||
setSource(url);
|
||||
}
|
||||
|
||||
void MacWebKitHelpViewer::setHtml(const QString &html)
|
||||
{
|
||||
AutoreleasePool pool; Q_UNUSED(pool)
|
||||
[m_widget->webView().mainFrame
|
||||
loadHTMLString:html.toNSString()
|
||||
baseURL:[NSURL fileURLWithPath:Core::ICore::resourcePath().toNSString()]];
|
||||
}
|
||||
|
||||
QString MacWebKitHelpViewer::selectedText() const
|
||||
{
|
||||
AutoreleasePool pool; Q_UNUSED(pool)
|
||||
return QString::fromNSString(m_widget->webView().selectedDOMRange.text);
|
||||
}
|
||||
|
||||
bool MacWebKitHelpViewer::isForwardAvailable() const
|
||||
{
|
||||
AutoreleasePool pool; Q_UNUSED(pool)
|
||||
return m_widget->webView().canGoForward;
|
||||
}
|
||||
|
||||
bool MacWebKitHelpViewer::isBackwardAvailable() const
|
||||
{
|
||||
AutoreleasePool pool; Q_UNUSED(pool)
|
||||
return m_widget->webView().canGoBack;
|
||||
}
|
||||
|
||||
void MacWebKitHelpViewer::addBackHistoryItems(QMenu *backMenu)
|
||||
{
|
||||
AutoreleasePool pool; Q_UNUSED(pool)
|
||||
WebBackForwardList *list = m_widget->webView().backForwardList;
|
||||
int backListCount = list.backListCount;
|
||||
for (int i = 0; i < backListCount; ++i) {
|
||||
int historyIndex = -(i+1);
|
||||
QAction *action = new QAction(backMenu);
|
||||
action->setText(QString::fromNSString([list itemAtIndex:historyIndex].title));
|
||||
action->setData(historyIndex);
|
||||
connect(action, SIGNAL(triggered()), this, SLOT(goToHistoryItem()));
|
||||
backMenu->addAction(action);
|
||||
}
|
||||
}
|
||||
|
||||
void MacWebKitHelpViewer::addForwardHistoryItems(QMenu *forwardMenu)
|
||||
{
|
||||
AutoreleasePool pool; Q_UNUSED(pool)
|
||||
WebBackForwardList *list = m_widget->webView().backForwardList;
|
||||
int forwardListCount = list.forwardListCount;
|
||||
for (int i = 0; i < forwardListCount; ++i) {
|
||||
int historyIndex = i + 1;
|
||||
QAction *action = new QAction(forwardMenu);
|
||||
action->setText(QString::fromNSString([list itemAtIndex:historyIndex].title));
|
||||
action->setData(historyIndex);
|
||||
connect(action, SIGNAL(triggered()), this, SLOT(goToHistoryItem()));
|
||||
forwardMenu->addAction(action);
|
||||
}
|
||||
}
|
||||
|
||||
void MacWebKitHelpViewer::setOpenInNewWindowActionVisible(bool visible)
|
||||
{
|
||||
m_widget->setOpenInNewWindowActionVisible(visible);
|
||||
}
|
||||
|
||||
DOMRange *MacWebKitHelpViewer::findText(NSString *text, bool forward, bool caseSensitive, DOMNode *startNode, int startOffset)
|
||||
{
|
||||
QTC_ASSERT(text, return nil);
|
||||
if (text.length == 0)
|
||||
return nil;
|
||||
DOMDocument *document = m_widget->webView().mainFrame.DOMDocument;
|
||||
// search only the body
|
||||
DOMNodeIterator *iterator = [document createNodeIterator:document.body whatToShow:DOM_SHOW_ALL
|
||||
filter:nil expandEntityReferences:NO];
|
||||
|
||||
DOMNode *selectionStart = nil;
|
||||
int selectionStartOffset = 0;
|
||||
DOMNode *currentNode = startNode;
|
||||
int currentOffset = startOffset;
|
||||
NSString *searchTerm = caseSensitive ? text : [text lowercaseString];
|
||||
int searchTermLength = searchTerm.length;
|
||||
int indexInSearchTerm = forward ? 0 : searchTerm.length - 1;
|
||||
if (!currentNode) { // search whole body from end
|
||||
if (forward)
|
||||
currentNode = document.body;
|
||||
else
|
||||
currentNode = [iterator gotoEnd];
|
||||
} else { // otherwise find the start node
|
||||
QTC_ASSERT([iterator findNode:currentNode], return nil);
|
||||
}
|
||||
if (!forward) { // findNode leaves iterator behind currentNode, we need to go back
|
||||
QTC_ASSERT([iterator previousNode] == currentNode, return nil);
|
||||
}
|
||||
if (currentNode.nodeType != DOM_TEXT_NODE) { // we only want text nodes
|
||||
currentNode = forward ? [iterator nextTextNode] : [iterator previousTextNode];
|
||||
currentOffset = -1; // search whole node
|
||||
}
|
||||
while (currentNode) {
|
||||
NSString *currentText = caseSensitive ? currentNode.nodeValue : [currentNode.nodeValue lowercaseString];
|
||||
int currentTextLength = currentText.length;
|
||||
if (currentOffset < 0) // search whole node
|
||||
currentOffset = forward ? 0 : currentTextLength - 1;
|
||||
while (currentOffset < currentTextLength/*forward*/ && currentOffset >= 0/*backward*/) {
|
||||
if ([currentText characterAtIndex:currentOffset] == [searchTerm characterAtIndex:indexInSearchTerm]) {
|
||||
indexInSearchTerm += forward ? 1 : -1;
|
||||
if (!selectionStart) {
|
||||
selectionStart = currentNode;
|
||||
selectionStartOffset = currentOffset;
|
||||
}
|
||||
} else {
|
||||
indexInSearchTerm = forward ? 0 : searchTerm.length - 1;
|
||||
selectionStart = nil;
|
||||
}
|
||||
currentOffset += forward ? 1 : -1;
|
||||
if (indexInSearchTerm >= searchTermLength/*forward*/ || indexInSearchTerm < 0/*backward*/) {
|
||||
// we have found a match!
|
||||
DOMRange *range = [document createRange];
|
||||
if (forward) {
|
||||
[range setStart:selectionStart offset:selectionStartOffset];
|
||||
[range setEnd:currentNode offset:currentOffset];
|
||||
} else {
|
||||
[range setStart:currentNode offset:(currentOffset + 1)]; // was already decreased
|
||||
[range setEnd:selectionStart offset:(selectionStartOffset + 1)];
|
||||
}
|
||||
return range;
|
||||
}
|
||||
}
|
||||
currentNode = forward ? [iterator nextTextNode] : [iterator previousTextNode];
|
||||
currentOffset = -1; // search whole node
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
bool MacWebKitHelpViewer::findText(const QString &text, Core::FindFlags flags, bool incremental,
|
||||
bool fromSearch, bool *wrapped)
|
||||
{
|
||||
Q_UNUSED(incremental);
|
||||
Q_UNUSED(fromSearch);
|
||||
AutoreleasePool pool; Q_UNUSED(pool)
|
||||
if (wrapped)
|
||||
*wrapped = false;
|
||||
bool forward = !(flags & Core::FindBackward);
|
||||
bool caseSensitive = (flags & Core::FindCaseSensitively);
|
||||
WebView *webView = m_widget->webView();
|
||||
|
||||
// WebView searchFor:.... grabs first responder, and when losing first responder afterwards,
|
||||
// it removes the selection and forgets the search state, making it pretty useless for us
|
||||
|
||||
// define the start node and offset for the search
|
||||
DOMNode *start = nil; // default is search whole body
|
||||
int startOffset = -1;
|
||||
DOMRange *selection = webView.selectedDOMRange;
|
||||
if (selection) {
|
||||
if (QString::fromNSString(selection.text).compare(
|
||||
text, caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive) != 0) {
|
||||
// for incremental search we want to search from the beginning of the selection
|
||||
start = selection.startContainer;
|
||||
startOffset = selection.startOffset;
|
||||
} else {
|
||||
// search for next occurrence
|
||||
if (forward) {
|
||||
start = selection.endContainer;
|
||||
startOffset = selection.endOffset;
|
||||
} else {
|
||||
start = selection.startContainer;
|
||||
startOffset = selection.startOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
DOMRange *newSelection = findText(text.toNSString(), forward, caseSensitive,
|
||||
start, startOffset);
|
||||
if (!newSelection && start != nil) { // wrap
|
||||
start = nil;
|
||||
startOffset = -1;
|
||||
newSelection = findText(text.toNSString(), forward, caseSensitive,
|
||||
start, startOffset);
|
||||
if (newSelection && wrapped)
|
||||
*wrapped = true;
|
||||
}
|
||||
if (newSelection) {
|
||||
// found, select and scroll there
|
||||
[webView setSelectedDOMRange:newSelection affinity:NSSelectionAffinityDownstream];
|
||||
if (forward)
|
||||
[newSelection.endContainer.parentElement scrollIntoViewIfNeeded:YES];
|
||||
else
|
||||
[newSelection.startContainer.parentElement scrollIntoViewIfNeeded:YES];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MacWebKitHelpViewer::copy()
|
||||
{
|
||||
QApplication::clipboard()->setText(selectedText());
|
||||
}
|
||||
|
||||
void MacWebKitHelpViewer::stop()
|
||||
{
|
||||
[m_widget->webView() stopLoading:nil];
|
||||
}
|
||||
|
||||
void MacWebKitHelpViewer::forward()
|
||||
{
|
||||
AutoreleasePool pool; Q_UNUSED(pool)
|
||||
[m_widget->webView() goForward];
|
||||
emit forwardAvailable(isForwardAvailable());
|
||||
emit backwardAvailable(isBackwardAvailable());
|
||||
}
|
||||
|
||||
void MacWebKitHelpViewer::backward()
|
||||
{
|
||||
AutoreleasePool pool; Q_UNUSED(pool)
|
||||
[m_widget->webView() goBack];
|
||||
emit forwardAvailable(isForwardAvailable());
|
||||
emit backwardAvailable(isBackwardAvailable());
|
||||
}
|
||||
|
||||
void MacWebKitHelpViewer::print(QPrinter *printer)
|
||||
{
|
||||
Q_UNUSED(printer)
|
||||
}
|
||||
|
||||
void MacWebKitHelpViewer::slotLoadStarted()
|
||||
{
|
||||
HelpViewer::slotLoadStarted();
|
||||
}
|
||||
|
||||
void MacWebKitHelpViewer::slotLoadFinished()
|
||||
{
|
||||
HelpViewer::slotLoadFinished();
|
||||
emit forwardAvailable(isForwardAvailable());
|
||||
emit backwardAvailable(isBackwardAvailable());
|
||||
}
|
||||
|
||||
void MacWebKitHelpViewer::goToHistoryItem()
|
||||
{
|
||||
AutoreleasePool pool; Q_UNUSED(pool)
|
||||
QAction *action = qobject_cast<QAction *>(sender());
|
||||
QTC_ASSERT(action, return);
|
||||
bool ok = false;
|
||||
int index = action->data().toInt(&ok);
|
||||
QTC_ASSERT(ok, return);
|
||||
WebBackForwardList *list = m_widget->webView().backForwardList;
|
||||
WebHistoryItem *item = [list itemAtIndex:index];
|
||||
QTC_ASSERT(item, return);
|
||||
[m_widget->webView() goToBackForwardItem:item];
|
||||
emit forwardAvailable(isForwardAvailable());
|
||||
emit backwardAvailable(isBackwardAvailable());
|
||||
}
|
||||
|
||||
// #pragma mark -- MacResponderHack
|
||||
|
||||
MacResponderHack::MacResponderHack(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
connect(qApp, SIGNAL(focusChanged(QWidget*,QWidget*)),
|
||||
this, SLOT(responderHack(QWidget*,QWidget*)));
|
||||
}
|
||||
|
||||
void MacResponderHack::responderHack(QWidget *old, QWidget *now)
|
||||
{
|
||||
// On focus change, Qt does not make the corresponding QNSView firstResponder.
|
||||
// That breaks when embedding native NSView into a Qt hierarchy. When the focus is changed
|
||||
// by clicking with the mouse into a widget, everything is fine, because Cocoa automatically
|
||||
// adapts firstResponder in that case, but it breaks when setting the Qt focus from code.
|
||||
Q_UNUSED(old)
|
||||
if (!now)
|
||||
return;
|
||||
AutoreleasePool pool; Q_UNUSED(pool)
|
||||
NSView *view;
|
||||
if (QMacCocoaViewContainer *viewContainer = qobject_cast<QMacCocoaViewContainer *>(now))
|
||||
view = viewContainer->cocoaView();
|
||||
else
|
||||
view = (NSView *)now->effectiveWinId();
|
||||
[view.window makeFirstResponder:view];
|
||||
}
|
||||
|
||||
} // Internal
|
||||
} // Help
|
||||
@@ -196,7 +196,7 @@ HelpViewer *OpenPagesManager::createPageFromSearch(const QUrl &url)
|
||||
|
||||
HelpViewer *OpenPagesManager::createPage(const QUrl &url, bool fromSearch)
|
||||
{
|
||||
if (HelpViewer::launchWithExternalApp(url))
|
||||
if (url.isValid() && HelpViewer::launchWithExternalApp(url))
|
||||
return 0;
|
||||
|
||||
m_model->addPage(url);
|
||||
|
||||
@@ -77,7 +77,8 @@ void OpenPagesModel::addPage(const QUrl &url, qreal zoom)
|
||||
connect(page, SIGNAL(titleChanged()), this, SLOT(handleTitleChanged()));
|
||||
m_pages << page;
|
||||
endInsertRows();
|
||||
page->setSource(url);
|
||||
if (url.isValid())
|
||||
page->setSource(url);
|
||||
}
|
||||
|
||||
void OpenPagesModel::removePage(int index)
|
||||
|
||||
@@ -451,18 +451,13 @@ QtWebKitHelpViewer::QtWebKitHelpViewer(qreal zoom, QWidget *parent)
|
||||
connect(m_webView->page(), SIGNAL(printRequested(QWebFrame*)), this, SIGNAL(printRequested()));
|
||||
connect(m_webView, SIGNAL(backwardAvailable(bool)), this, SIGNAL(backwardAvailable(bool)));
|
||||
connect(m_webView, SIGNAL(forwardAvailable(bool)), this, SIGNAL(forwardAvailable(bool)));
|
||||
|
||||
setViewerFont(viewerFont());
|
||||
}
|
||||
|
||||
QFont QtWebKitHelpViewer::viewerFont() const
|
||||
{
|
||||
QWebSettings* webSettings = QWebSettings::globalSettings();
|
||||
QFont font(QApplication::font().family(),
|
||||
QWebSettings* webSettings = m_webView->settings();
|
||||
return QFont(webSettings->fontFamily(QWebSettings::StandardFont),
|
||||
webSettings->fontSize(QWebSettings::DefaultFontSize));
|
||||
const QHelpEngineCore &engine = LocalHelpManager::helpEngine();
|
||||
return qvariant_cast<QFont>(engine.customValue(QLatin1String("font"),
|
||||
font));
|
||||
}
|
||||
|
||||
void QtWebKitHelpViewer::setViewerFont(const QFont &font)
|
||||
@@ -497,11 +492,6 @@ QString QtWebKitHelpViewer::title() const
|
||||
return m_webView->title();
|
||||
}
|
||||
|
||||
void QtWebKitHelpViewer::setTitle(const QString &title)
|
||||
{
|
||||
Q_UNUSED(title)
|
||||
}
|
||||
|
||||
QUrl QtWebKitHelpViewer::source() const
|
||||
{
|
||||
return m_webView->url();
|
||||
|
||||
@@ -59,7 +59,6 @@ public:
|
||||
qreal scale() const;
|
||||
|
||||
QString title() const;
|
||||
void setTitle(const QString &title);
|
||||
|
||||
QUrl source() const;
|
||||
void setSource(const QUrl &url);
|
||||
|
||||
@@ -64,11 +64,6 @@ TextBrowserHelpViewer::TextBrowserHelpViewer(qreal zoom, QWidget *parent)
|
||||
p.color(QPalette::Active, QPalette::HighlightedText));
|
||||
setPalette(p);
|
||||
|
||||
// ???
|
||||
QFont font = viewerFont();
|
||||
font.setPointSize(int(font.pointSize() + zoom));
|
||||
setViewerFont(font);
|
||||
|
||||
connect(m_textBrowser, SIGNAL(sourceChanged(QUrl)), this, SIGNAL(titleChanged()));
|
||||
connect(m_textBrowser, SIGNAL(forwardAvailable(bool)), this, SIGNAL(forwardAvailable(bool)));
|
||||
connect(m_textBrowser, SIGNAL(backwardAvailable(bool)), this, SIGNAL(backwardAvailable(bool)));
|
||||
@@ -80,18 +75,14 @@ TextBrowserHelpViewer::~TextBrowserHelpViewer()
|
||||
|
||||
QFont TextBrowserHelpViewer::viewerFont() const
|
||||
{
|
||||
const QHelpEngineCore &engine = LocalHelpManager::helpEngine();
|
||||
return qvariant_cast<QFont>(engine.customValue(QLatin1String("font"),
|
||||
qApp->font()));
|
||||
return m_textBrowser->font();
|
||||
}
|
||||
|
||||
void TextBrowserHelpViewer::setViewerFont(const QFont &newFont)
|
||||
{
|
||||
if (font() != newFont) {
|
||||
m_textBrowser->forceFont = true;
|
||||
m_textBrowser->setFont(newFont);
|
||||
m_textBrowser->forceFont = false;
|
||||
}
|
||||
m_textBrowser->forceFont = true;
|
||||
m_textBrowser->setFont(newFont);
|
||||
m_textBrowser->forceFont = false;
|
||||
}
|
||||
|
||||
void TextBrowserHelpViewer::scaleUp()
|
||||
@@ -124,11 +115,6 @@ QString TextBrowserHelpViewer::title() const
|
||||
return m_textBrowser->documentTitle();
|
||||
}
|
||||
|
||||
void TextBrowserHelpViewer::setTitle(const QString &title)
|
||||
{
|
||||
m_textBrowser->setDocumentTitle(title);
|
||||
}
|
||||
|
||||
QUrl TextBrowserHelpViewer::source() const
|
||||
{
|
||||
return m_textBrowser->source();
|
||||
|
||||
@@ -59,7 +59,6 @@ public:
|
||||
qreal scale() const;
|
||||
|
||||
QString title() const;
|
||||
void setTitle(const QString &title);
|
||||
|
||||
QUrl source() const;
|
||||
void setSource(const QUrl &url);
|
||||
|
||||
Reference in New Issue
Block a user