11#include <QWebEngineProfile> 
   12#include <QWebEngineHistory> 
   13#include <QWebEngineSettings> 
   14#include <QWebEngineFindTextResult> 
   15#include <QRegularExpression> 
   16#include <QWebEngineCookieStore> 
   17#include <QStandardPaths> 
   18#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0) 
   19    #include <QWebEngineProfileBuilder> 
   21#include <QLoggingCategory> 
   22#include "RabbitCommonDir.h" 
   23#include "RabbitCommonTools.h" 
   24#include "FrmWebBrowser.h" 
   27static Q_LOGGING_CATEGORY(log, 
"WebBrowser.Browser")
 
   38    , m_pFindNext(
nullptr)
 
   39    , m_pFindPrevious(
nullptr)
 
   40    , m_pZoomOriginal(
nullptr)
 
   43    , m_pFavAction(
nullptr)
 
   46    , m_pAddPageIncognito(
nullptr)
 
   47    , m_pAddWindow(
nullptr)
 
   49    , m_pPrintToPdf(
nullptr)
 
   50    , m_pAddWindowIncognito(
nullptr)
 
   51    , m_pDownload(
nullptr)
 
   52    , m_pInspector(
nullptr)
 
   54    , m_pUrlLineEdit(
nullptr)
 
   55    , m_pProgressBar(
nullptr)
 
   57    , m_DownloadManager(pPara)
 
   59    qDebug(log) << Q_FUNC_INFO;
 
   62    setWindowIcon(QIcon::fromTheme(
"web-browser"));
 
   64    QVBoxLayout* pLayout = 
new QVBoxLayout(
this);
 
   68    pLayout->setSpacing(0);
 
   69    pLayout->setContentsMargins(0, 0, 0, 0);
 
   72    m_pToolBar = 
new QToolBar(
this);
 
   74        pLayout->addWidget(m_pToolBar);
 
   77    m_pBack = m_pToolBar->addAction(
 
   78        QIcon::fromTheme(
"go-previous"), tr(
"Back"),
 
   81            if(pWeb && pWeb->page())
 
   82                pWeb->page()->action(QWebEnginePage::Back)->trigger();
 
   84    m_pBack->setEnabled(
false);
 
   85    m_pBack->setStatusTip(m_pBack->text());
 
   86    m_pForward = m_pToolBar->addAction(
 
   87        QIcon::fromTheme(
"go-next"), tr(
"Forward"),
 
   90            if(pWeb && pWeb->page())
 
   91                pWeb->page()->action(QWebEnginePage::Forward)->trigger();
 
   93    m_pForward->setEnabled(
false);
 
   94    m_pForward->setStatusTip(m_pForward->text());
 
   95    m_pRefresh = m_pToolBar->addAction(
 
   96        QIcon::fromTheme(
"view-refresh"), tr(
"Refresh"),
 
   99            if(pWeb && pWeb->page())
 
  100                pWeb->page()->action(QWebEnginePage::Reload)->trigger();
 
  102    m_pRefresh->setShortcut(QKeySequence(QKeySequence::Refresh));
 
  103    m_pRefresh->setStatusTip(m_pRefresh->text());
 
  105    m_pUrlLineEdit = 
new QLineEdit(
this);
 
  106    m_pFavAction = 
new QAction(m_pUrlLineEdit);
 
  107    m_pUrlLineEdit->addAction(m_pFavAction, QLineEdit::LeadingPosition);
 
  108    m_pUrlLineEdit->setClearButtonEnabled(
true);
 
  109    m_pUrl = m_pToolBar->addWidget(m_pUrlLineEdit);
 
  110    check = connect(m_pUrlLineEdit, &QLineEdit::returnPressed,
 
  111                         this, &CFrmWebBrowser::slotReturnPressed);
 
  113    check = connect(m_pUrlLineEdit, &QLineEdit::editingFinished,
 
  114                    this, &CFrmWebBrowser::slotReturnPressed);
 
  116    m_pGo = 
new QAction(QIcon::fromTheme(
"go-next"), tr(
"go"), m_pUrlLineEdit);
 
  117    m_pGo->setStatusTip(m_pGo->text());
 
  118    check = connect(m_pGo, &QAction::triggered, 
this, &CFrmWebBrowser::slotReturnPressed);
 
  120    m_pUrlLineEdit->addAction(m_pGo, QLineEdit::TrailingPosition);
 
  121    m_pGo->setVisible(
false);
 
  122    check = connect(m_pUrlLineEdit, &QLineEdit::textEdited,
 
  123                    this, [&](
const QString &text){
 
  124        QLineEdit* pLineEdit = qobject_cast<QLineEdit*>(sender());
 
  127                if(m_pGo->isVisible())
 
  128                    m_pGo->setVisible(
false);
 
  130                if(!m_pGo->isVisible())
 
  131                    m_pGo->setVisible(
true);
 
  137    m_pAddPage = m_pToolBar->addAction(QIcon::fromTheme(
"add"), tr(
"Add tab page"),
 
  139        CreateWindow(QWebEnginePage::WebBrowserTab);
 
  140        if(!m_pPara->GetTabUrl().isEmpty()) {
 
  141            m_pUrlLineEdit->setText(m_pPara->GetTabUrl());
 
  145    m_pAddPage->setStatusTip(m_pAddPage->text());
 
  147    m_pDownload = m_pToolBar->addAction(
 
  148        QIcon::fromTheme(
"emblem-downloads"), tr(
"Download Manager"));
 
  149    m_pDownload->setCheckable(
true);
 
  150    m_pDownload->setStatusTip(m_pDownload->text());
 
  151    check = connect(m_pDownload, &QAction::toggled,
 
  152                    this, [&](
bool checked){
 
  154                            m_DownloadManager.show();
 
  156                            m_DownloadManager.hide();
 
  159    check = connect(&m_DownloadManager, &CFrmDownloadManager::sigVisible, 
this,
 
  162                            m_pDownload->setChecked(visible);
 
  166    m_pProgressBar = 
new QProgressBar(
this);
 
  168        pLayout->addWidget(m_pProgressBar);
 
  169        m_pProgressBar->setMaximumHeight(1);
 
  170        m_pProgressBar->setTextVisible(
false);
 
  171        m_pProgressBar->show();
 
  172        m_pProgressBar->setStyleSheet(
"QProgressBar {border: 0px} QProgressBar::chunk {background-color: #da4453}");
 
  175    m_pTab = 
new QTabWidget(
this);
 
  177        m_pTab->setTabsClosable(
true);
 
  178        m_pTab->setUsesScrollButtons(
true);
 
  179        m_pTab->setMovable(
true);
 
  180        m_pTab->setElideMode(Qt::TextElideMode::ElideRight);
 
  181        pLayout->addWidget(m_pTab);
 
  183    check = connect(m_pTab, &QTabWidget::currentChanged,
 
  184                    this, &CFrmWebBrowser::slotTabCurrentChanged);
 
  186    check = connect(m_pTab, &QTabWidget::tabCloseRequested,
 
  187                    this, &CFrmWebBrowser::slotTabCloseRequested);
 
  190    m_DownloadManager.hide();
 
  191    QWebEngineProfile::defaultProfile()->setDownloadPath(m_pPara->GetDownloadFolder());
 
  192    check = connect(QWebEngineProfile::defaultProfile(), &QWebEngineProfile::downloadRequested,
 
  193                     &m_DownloadManager, &CFrmDownloadManager::slotDownloadRequested);
 
  195    check = connect(m_pPara, &CParameterWebBrowser::sigDownloadFolderChanged,
 
  197        QWebEngineProfile::defaultProfile()->setDownloadPath(m_pPara->GetDownloadFolder());
 
  199            m_profile->setDownloadPath(m_pPara->GetDownloadFolder());
 
  206        m_pMenuBar = 
new QMenuBar(
this);
 
  208            m_Menu.setTitle(tr(
"Operate"));
 
  209            m_pMenuBar->addMenu(&m_Menu);
 
  210            pLayout->setMenuBar(m_pMenuBar);
 
  215CFrmWebBrowser::~CFrmWebBrowser()
 
  217    qDebug(log) << Q_FUNC_INFO;
 
  219        m_pToolBar->deleteLater();
 
  220        m_pToolBar = 
nullptr;
 
  223        m_pTab->deleteLater();
 
  227    if(m_pPara->GetClearCookie() && m_profile)
 
  228        m_profile->cookieStore()->deleteAllCookies();
 
  229    if(m_pPara->GetClearHttpCache() && m_profile)
 
  230        m_profile->clearHttpCache();
 
  233QMenu* CFrmWebBrowser::GetMenu(QWidget *parent)
 
  235    if(m_Menu.actions().isEmpty())
 
  240QWebEngineView* CFrmWebBrowser::CreateWindow(
 
  241    QWebEnginePage::WebWindowType type, 
bool offTheRecord)
 
  243    qDebug(log) << 
"Create window:" << type;
 
  247    case QWebEnginePage::WebBrowserTab: {
 
  248        auto pTab = CreateTab(&pView, offTheRecord);
 
  249        int index = m_pTab->addTab(pTab, pView->favIcon(), tr(
"New page"));
 
  251            m_pTab->setCurrentIndex(index);
 
  254    case QWebEnginePage::WebBrowserBackgroundTab: {
 
  255        auto pTab = CreateTab(&pView, offTheRecord);
 
  256        int index = m_pTab->currentIndex();
 
  257        m_pTab->addTab(pTab, pView->favIcon(), tr(
"New page"));
 
  258        if(-1 < index && index != m_pTab->currentIndex())
 
  259            m_pTab->setCurrentIndex(index);
 
  262    case QWebEnginePage::WebBrowserWindow: {
 
  265            pView = qobject_cast<CFrmWebView*>(
 
  266                pWin->CreateWindow(QWebEnginePage::WebBrowserTab));
 
  267            pWin->setAttribute(Qt::WA_DeleteOnClose);
 
  268            auto pMainWin = RabbitCommon::CTools::GetMainWindow();
 
  270                pWin->resize(pMainWin->frameGeometry().width(),
 
  271                             pMainWin->frameGeometry().height());
 
  276    case QWebEnginePage::WebDialog: {
 
  278        auto popup = 
new CFrmPopup(GetProfile(offTheRecord), 
this);
 
  279        pView = popup->GetView();
 
  290    check = connect(pWeb, &CFrmWebView::sigDevToolsRequested,
 
  293                                 m_pInspector->setChecked(
true);
 
  296    check = connect(pWeb, &CFrmWebView::sigWebActionEnabledChanged,
 
  297                    this, [
this, pWeb](QWebEnginePage::WebAction webAction, 
bool enabled){
 
  298        if(!IsCurrentView(pWeb)) 
return;
 
  300        case QWebEnginePage::WebAction::Back:
 
  301            m_pBack->setEnabled(enabled);
 
  303        case QWebEnginePage::WebAction::Forward:
 
  304            m_pForward->setEnabled(enabled);
 
  306        case QWebEnginePage::WebAction::Reload: {
 
  307            m_pRefresh->setEnabled(enabled);
 
  308            if(m_pRefresh->isEnabled())
 
  309                m_pToolBar->insertAction(m_pUrl, m_pRefresh);
 
  311                m_pToolBar->removeAction(m_pRefresh);
 
  314        case QWebEnginePage::WebAction::Stop: {
 
  315            m_pStop->setEnabled(enabled);
 
  316            if(m_pStop->isEnabled())
 
  317                m_pToolBar->insertAction(m_pUrl, m_pStop);
 
  319                m_pToolBar->removeAction(m_pStop);
 
  326    check = connect(pWeb, &QWebEngineView::urlChanged,
 
  327                    this, [&](
const QUrl &url){
 
  328                        CFrmWebView* pWeb = qobject_cast<CFrmWebView*>(sender());
 
  329                        if(IsCurrentView(pWeb))
 
  330                            m_pUrlLineEdit->setText(url.toString());
 
  333    check = connect(pWeb, &CFrmWebView::titleChanged,
 
  334                    this, [&](
const QString &title) {
 
  335                        CFrmWebView* pWeb = qobject_cast<CFrmWebView*>(sender());
 
  336                        int index = IndexOfTab(pWeb);
 
  338                            m_pTab->setTabText(index, title);
 
  339                            setWindowTitle(title);
 
  344    check = connect(pWeb, &CFrmWebView::favIconChanged,
 
  345                    this, [&](
const QIcon &icon){
 
  346                        CFrmWebView* pWeb = qobject_cast<CFrmWebView*>(sender());
 
  347                        int index = IndexOfTab(pWeb);
 
  349                            m_pTab->setTabIcon(index, icon);
 
  355    check = connect(pWeb, &CFrmWebView::sigLinkHovered,
 
  356                    this, &CFrmWebBrowser::sigInformation);
 
  358    check = connect(pWeb, &CFrmWebView::sigCloseRequested,
 
  359                    this, &CFrmWebBrowser::slotViewCloseRequested);
 
  361    check = connect(pWeb, &CFrmWebView::loadProgress,
 
  362                    this, [&](
int progress){
 
  363                        CFrmWebView* pWeb = qobject_cast<CFrmWebView*>(sender());
 
  364                        if(IsCurrentView(pWeb))
 
  365                            m_pProgressBar->setValue(progress);
 
  368    m_pProgressBar->setValue(pWeb->progress());
 
  369#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0) 
  370    check = connect(pWeb, &CFrmWebView::printFinished,
 
  371                    this, &CFrmWebBrowser::slotPrintFinished);
 
  373    check = connect(pWeb, &CFrmWebView::pdfPrintingFinished,
 
  374                    this, &CFrmWebBrowser::slotPdfPrintingFinished);
 
  379QWebEngineProfile* CFrmWebBrowser::GetProfile(
bool offTheRecord)
 
  382        return QWebEngineProfile::defaultProfile();
 
  384        return m_profile.get();
 
  386#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0) 
  387    const QString name = 
"io.github.KangLin.RabbitRemoteControl." 
  388                         + QLatin1StringView(qWebEngineChromiumVersion());
 
  389    QWebEngineProfileBuilder profileBuilder;
 
  390    m_profile.reset(profileBuilder.createProfile(name));
 
  392    const QString name = 
"io.github.KangLin.RabbitRemoteControl";
 
  393    m_profile.reset(
new QWebEngineProfile(name));
 
  396        return QWebEngineProfile::defaultProfile();
 
  397    m_profile->settings()->setAttribute(QWebEngineSettings::PluginsEnabled, 
true);
 
  398    m_profile->settings()->setAttribute(QWebEngineSettings::DnsPrefetchEnabled, 
true);
 
  399    m_profile->settings()->setAttribute(QWebEngineSettings::LocalContentCanAccessRemoteUrls, 
true);
 
  400    m_profile->settings()->setAttribute(QWebEngineSettings::LocalContentCanAccessFileUrls, 
false);
 
  401    m_profile->settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, 
true);
 
  402    m_profile->settings()->setAttribute(QWebEngineSettings::FullScreenSupportEnabled, 
true);
 
  403#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0) 
  404    m_profile->settings()->setAttribute(QWebEngineSettings::PlaybackRequiresUserGesture, 
false);
 
  406    m_profile->setDownloadPath(m_pPara->GetDownloadFolder());
 
  407    bool check = connect(m_profile.get(), &QWebEngineProfile::downloadRequested,
 
  408                         &m_DownloadManager, &CFrmDownloadManager::slotDownloadRequested);
 
  410    qDebug(log) << 
"User agent:" << m_profile->httpUserAgent()
 
  411                << 
"Persistent path:" << m_profile->persistentStoragePath()
 
  412                << 
"Cache path:" << m_profile->cachePath()
 
  413                << 
"Storage name:" << m_profile->storageName()
 
  414                << 
"Cookie:" << m_profile->cookieStore()
 
  415                << 
"Is off the Record:" << m_profile->isOffTheRecord()
 
  416                << 
"Download:" << m_profile->downloadPath();
 
  417    return m_profile.get();
 
  420CFrmWebView *CFrmWebBrowser::CreateWebView(
bool offTheRecord)
 
  424        auto profile = GetProfile(offTheRecord);
 
  428        auto page = 
new QWebEnginePage(profile, pView);
 
  429        pView->setPage(page);
 
  434QWidget* CFrmWebBrowser::CreateTab(
CFrmWebView **view, 
bool offTheRecord)
 
  436    QSplitter *pSplitter = 
new QSplitter(Qt::Vertical, 
this);
 
  438        pSplitter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
 
  445                pWeb = CreateWebView(offTheRecord);
 
  449            pWeb = CreateWebView(offTheRecord);
 
  452            pSplitter->addWidget(pWeb);
 
  459CFrmWebView *CFrmWebBrowser::CurrentView(ViewType type)
 
  461    auto w = m_pTab->currentWidget();
 
  462    if(!w) 
return nullptr;
 
  463    QSplitter *pSplitter = qobject_cast<QSplitter*>(w);
 
  464    if(!pSplitter) 
return nullptr;
 
  465    int index = (int)type;
 
  466    if(0 > index && pSplitter->count() <= index) 
return nullptr;
 
  467    return qobject_cast<CFrmWebView*>(pSplitter->widget(index));
 
  470CFrmWebView* CFrmWebBrowser::GetView(
int index, ViewType type)
 
  472    if(0 > index || m_pTab->count() <= index) 
return nullptr;
 
  473    auto w = m_pTab->widget(index);
 
  474    if(!w) 
return nullptr;
 
  475    QSplitter *pSplitter = qobject_cast<QSplitter*>(w);
 
  476    if(!pSplitter) 
return nullptr;
 
  478    if(0 > idx && pSplitter->count() <= idx) 
return nullptr;
 
  479    return qobject_cast<CFrmWebView*>(pSplitter->widget(idx));
 
  482bool CFrmWebBrowser::IsCurrentView(
CFrmWebView *pView)
 
  484    auto w = m_pTab->currentWidget();
 
  486    QSplitter *pSplitter = qobject_cast<QSplitter*>(w);
 
  487    if(!pSplitter) 
return false;
 
  488    return -1 != pSplitter->indexOf(pView);
 
  494    if(!pView) 
return nRet;
 
  495    QWidget* p = qobject_cast<QWidget*>(pView->parent());
 
  497    nRet = m_pTab->indexOf(p);
 
  501int CFrmWebBrowser::InitMenu(QMenu *pMenu)
 
  505    pMenu->addAction(m_pBack);
 
  506    pMenu->addAction(m_pForward);
 
  507    pMenu->addAction(m_pRefresh);
 
  508    m_pStop = pMenu->addAction(QIcon::fromTheme(
"media-playback-stop"), tr(
"Stop"),
 
  511        if(pWeb && pWeb->page())
 
  512            pWeb->page()->action(QWebEnginePage::Stop)->trigger();
 
  514    m_pStop->setEnabled(
false);
 
  516    pMenu->addSeparator();
 
  517    pMenu->addAction(m_pAddPage);
 
  518    m_pAddPageIncognito = pMenu->addAction(
 
  519        QIcon::fromTheme(
"add"), tr(
"Add incognito tab"),
 
  521            CreateWindow(QWebEnginePage::WebBrowserTab, 
true);
 
  522            if(!m_pPara->GetTabUrl().isEmpty()) {
 
  523                m_pUrlLineEdit->setText(m_pPara->GetTabUrl());
 
  527    m_pAddPageIncognito->setStatusTip(m_pAddPageIncognito->text());
 
  528    m_pAddWindow = pMenu->addAction(
 
  529        QIcon::fromTheme(
"add"), tr(
"Add window"),
 
  531            CreateWindow(QWebEnginePage::WebBrowserWindow);
 
  533    m_pAddWindow->setVisible(
false);
 
  534    m_pAddWindow->setStatusTip(m_pAddWindow->text());
 
  535    m_pAddWindowIncognito = pMenu->addAction(
 
  536        QIcon::fromTheme(
"add"), tr(
"Add Incognito Window"),
 
  538            CreateWindow(QWebEnginePage::WebBrowserWindow, 
true);
 
  540    m_pAddWindowIncognito->setVisible(
false);
 
  541    m_pAddWindowIncognito->setStatusTip(m_pAddWindowIncognito->text());
 
  543    pMenu->addSeparator();
 
  544    m_pFind = pMenu->addAction(
 
  545        QIcon::fromTheme(
"edit-find"), tr(
"&Find"), 
this,
 
  550                 QString search = QInputDialog::getText(
this, tr(
"Find"),
 
  551                                   tr(
"Find:"), QLineEdit::Normal,
 
  553                if (ok && !search.isEmpty()) {
 
  554                    m_szFindText = search;
 
  555#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 
  556                    pWeb->findText(m_szFindText, QWebEnginePage::FindFlags(),
 
  557                                   [&](
const QWebEngineFindTextResult& result){
 
  558                                       if (result.numberOfMatches() == 0) {
 
  559                                           emit sigInformation(tr(
"\"%1\" not found.").arg(m_szFindText));
 
  561                                           emit sigInformation(tr(
"\"%1\" found: %2/%3").arg(m_szFindText, QString::number(result.activeMatch()), QString::number(result.numberOfMatches())));
 
  565                    pWeb->findText(m_szFindText, QWebEnginePage::FindFlags(), [
this](
bool found) {
 
  567                            emit sigInformation(tr(
"\"%1\" not found.").arg(m_szFindText));
 
  573    m_pFind->setShortcuts(QKeySequence::Find);
 
  574    m_pFind->setStatusTip(m_pFind->text());
 
  576    m_pFindNext = pMenu->addAction(
 
  577        QIcon::fromTheme(
"go-next"), tr(
"Find &Next"), 
this,
 
  580               if(pWeb && !m_szFindText.isEmpty()) {
 
  581                   pWeb->findText(m_szFindText);
 
  584    m_pFindNext->setShortcut(QKeySequence::FindNext);
 
  585    m_pFindNext->setText(m_pFindNext->text());
 
  587    m_pFindPrevious = pMenu->addAction(
 
  588        QIcon::fromTheme(
"go-previous"), tr(
"Find &Previous"), 
this,
 
  591           if(pWeb && !m_szFindText.isEmpty()) {
 
  592               pWeb->findText(m_szFindText, QWebEnginePage::FindBackward);
 
  595    m_pFindPrevious->setShortcut(QKeySequence::FindPrevious);
 
  596    m_pFindPrevious->setStatusTip(m_pFindPrevious->text());
 
  598    pMenu->addSeparator();
 
  599    m_pZoomOriginal = pMenu->addAction(
 
  600        QIcon::fromTheme(
"zoom-original"), tr(
"Original"));
 
  601    m_pZoomOriginal->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_0));
 
  602    m_pZoomOriginal->setStatusTip(tr(
"Original"));
 
  603    m_pZoomOriginal->setToolTip(tr(
"Original"));
 
  604    check = connect(m_pZoomOriginal, &QAction::triggered, 
this,
 
  608                            pWeb->setZoomFactor(1.0);
 
  611    m_pZoomIn = pMenu->addAction(QIcon::fromTheme(
"zoom-in"), tr(
"Zoom in"));
 
  612    m_pZoomIn->setShortcut(QKeySequence::ZoomIn);
 
  613    m_pZoomIn->setStatusTip(tr(
"Zoom in"));
 
  614    m_pZoomIn->setToolTip(tr(
"Zoom in"));
 
  616        m_pZoomIn, &QAction::triggered, 
this,
 
  620                pWeb->setZoomFactor(pWeb->zoomFactor() + 0.1);
 
  623    m_pZoomOut = pMenu->addAction(
 
  624        QIcon::fromTheme(
"zoom-out"), tr(
"Zoom out"));
 
  625    m_pZoomOut->setShortcut(QKeySequence::ZoomOut);
 
  626    m_pZoomOut->setStatusTip(tr(
"Zoom out"));
 
  627    m_pZoomOut->setToolTip(tr(
"Zoom out"));
 
  629        m_pZoomOut, &QAction::triggered, 
this,
 
  633                pWeb->setZoomFactor(pWeb->zoomFactor() - 0.1);
 
  637    pMenu->addSeparator();
 
  638#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0) 
  639    m_pPrint = pMenu->addAction(
 
  640        QIcon::fromTheme(
"document-print"), tr(
"Print"),
 
  641        this, &CFrmWebBrowser::slotPrint);
 
  642    m_pPrint->setVisible(
false);
 
  643    m_pPrintToPdf = pMenu->addAction(
 
  644        QIcon::fromTheme(
"document-print"), tr(
"Print to PDF"),
 
  645        this, &CFrmWebBrowser::slotPrintToPdf);
 
  648    pMenu->addAction(m_pDownload);
 
  650        m_pInspector = pMenu->addAction(QIcon::fromTheme(
"tools"), tr(
"Inspector"));
 
  651        check = connect(m_pInspector, &QAction::toggled,
 
  652                        this, &CFrmWebBrowser::slotInspector);
 
  654        m_pInspector->setCheckable(
true);
 
  655        m_pInspector->setEnabled(
false);
 
  662int CFrmWebBrowser::Start()
 
  665    if(m_pTab->count() == 0) {
 
  667        m_pAddPage->trigger();
 
  672int CFrmWebBrowser::Stop()
 
  676    for(
int i = 0; i < m_pTab->count(); i++) {
 
  685void CFrmWebBrowser::slotTabCurrentChanged(
int index)
 
  687    if(-1 == index) 
return;
 
  690        setWindowTitle(pWeb->title());
 
  691        setWindowIcon(pWeb->icon());
 
  692        m_pUrlLineEdit->setText(pWeb->url().toString());
 
  693        m_pProgressBar->setValue(pWeb->progress());
 
  695        auto page = pWeb->page();
 
  697            auto action = page->action(QWebEnginePage::Back);
 
  698            if(action && m_pBack) {
 
  699                m_pBack->setEnabled(action->isEnabled());
 
  701            action = page->action(QWebEnginePage::Forward);
 
  702            if(action && m_pForward) {
 
  703                m_pForward->setEnabled(action->isEnabled());
 
  705            action = page->action(QWebEnginePage::Reload);
 
  706            if(action && m_pRefresh)
 
  707                m_pRefresh->setEnabled(action->isEnabled());
 
  708            if(m_pRefresh->isEnabled())
 
  709                m_pToolBar->insertAction(m_pUrl, m_pRefresh);
 
  711                m_pToolBar->removeAction(m_pRefresh);
 
  712            action = page->action(QWebEnginePage::Stop);
 
  713            if(action && m_pStop)
 
  714                m_pStop->setEnabled(action->isEnabled());
 
  715            if(m_pStop->isEnabled())
 
  716                m_pToolBar->insertAction(m_pUrl, m_pStop);
 
  718                m_pToolBar->removeAction(m_pStop);
 
  720                m_pInspector->setChecked(CurrentView(ViewType::DevTools));
 
  724        setWindowTitle(tr(
"Web browser"));
 
  725        setWindowIcon(QIcon::fromTheme(
"web-browser"));
 
  726        m_pUrlLineEdit->setText(
"");
 
  727        m_pProgressBar->setValue(100);
 
  730            m_pInspector->setChecked(
false);
 
  735void CFrmWebBrowser::EnableAction(
bool enable)
 
  738        m_pBack->setEnabled(
false);
 
  740        m_pForward->setEnabled(
false);
 
  742        m_pRefresh->setEnabled(enable);
 
  744        m_pStop->setEnabled(
false);
 
  746        m_pFind->setEnabled(enable);
 
  748        m_pFindNext->setEnabled(enable);
 
  750        m_pFindPrevious->setEnabled(enable);
 
  752        m_pZoomOriginal->setEnabled(enable);
 
  754        m_pZoomIn->setEnabled(enable);
 
  756        m_pZoomOut->setEnabled(enable);
 
  758        m_pInspector->setEnabled(enable);
 
  761void CFrmWebBrowser::slotTabCloseRequested(
int index)
 
  763    qDebug(log) << 
"slotTabCloseRequested:" << index;
 
  764    if(-1 == index) 
return;
 
  765    auto pView = m_pTab->widget(index);
 
  767        pView->deleteLater();
 
  768    m_pTab->removeTab(index);
 
  771void CFrmWebBrowser::slotViewCloseRequested()
 
  773    CFrmWebView* p = qobject_cast<CFrmWebView*>(sender());
 
  775    int index = IndexOfTab(p);
 
  776    slotTabCloseRequested(index);
 
  779void CFrmWebBrowser::slotReturnPressed()
 
  781    QUrl u = QUrl::fromUserInput(m_pUrlLineEdit->text());
 
  782    qDebug(log) << u << m_pUrlLineEdit->text();
 
  786            szSearch = m_pPara->GetSearchEngine();
 
  787            u = szSearch.replace(m_pPara->GetSearchRelaceString(),
 
  788                                 QUrl::toPercentEncoding(m_pUrlLineEdit->text()));
 
  791    qDebug(log) << u << m_pUrlLineEdit->text();
 
  792    emit sigInformation(u.toString());
 
  795        pWeb = qobject_cast<CFrmWebView*>(CreateWindow(QWebEnginePage::WebBrowserTab));
 
  797    if(m_pGo->isVisible())
 
  798        m_pGo->setVisible(
false);
 
  801void CFrmWebBrowser::slotInspector(
bool checked)
 
  804    auto dev = CurrentView(ViewType::DevTools);
 
  805    if(pWeb && pWeb->page() && checked) {
 
  807            auto w = m_pTab->currentWidget();
 
  809            QSplitter *pSplitter = qobject_cast<QSplitter*>(w);
 
  810            if(!pSplitter || 1 != pSplitter->count()) 
return;
 
  811            dev = CreateWebView(pWeb->page()->profile()->isOffTheRecord());
 
  814                pSplitter->addWidget(dev);
 
  815                bool check = connect(pWeb, &CFrmWebView::sigDevToolsRequested,
 
  818                                             m_pInspector->setChecked(
true);
 
  824            pWeb->page()->setDevToolsPage(dev->page());
 
  829        pWeb->page()->setDevToolsPage(
nullptr);
 
  831            dev->setParent(
nullptr);
 
  837int CFrmWebBrowser::Load(QSettings &set)
 
  839    if(m_pPara && m_pPara->GetOpenPrevious()) {
 
  840        set.beginGroup(
"OpenPrevious");
 
  842        nCount = set.value(
"Count", 0).toInt();
 
  843        int nCurrent = set.value(
"Current",  -1).toInt();
 
  844        for(
int i = 0; i < nCount; i++)
 
  846            QString u = set.value(
"Url/" + QString::number(i)).toString();
 
  847            auto pView = CreateWindow(QWebEnginePage::WebBrowserTab);
 
  848            pView->load(QUrl(u));
 
  851            history = set.value(
"History/" + QString::number(i)).toByteArray();
 
  852            QDataStream d(&history, QIODevice::ReadWrite);
 
  853            d >> *pView->history();
 
  855        if(-1 < nCurrent && m_pTab->count() > nCurrent)
 
  856            m_pTab->setCurrentIndex(nCurrent);
 
  862int CFrmWebBrowser::Save(QSettings &set)
 
  864    if(m_pPara && m_pPara->GetOpenPrevious()) {
 
  865        set.beginGroup(
"OpenPrevious");
 
  866        set.setValue(
"Count", m_pTab->count());
 
  867        set.setValue(
"Current", m_pTab->currentIndex());
 
  869        for(
int i = 0; i < m_pTab->count(); i++) {
 
  872                set.setValue(
"Url/" + QString::number(i), v->url().toString());
 
  874                QDataStream d(&history, QIODevice::ReadWrite);
 
  876                set.setValue(
"History/" + QString::number(i), history);
 
  885void CFrmWebBrowser::slotPrint()
 
  889#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0) 
  891        pWeb->print(&printer);
 
  896void CFrmWebBrowser::slotPrintFinished(
bool success)
 
  898    if(success && m_pPara->GetPromptPrintFinished()) {
 
  899        QMessageBox::information(
this, tr(
"Print finished"),
 
  900                                 tr(
"Successfully printed"));
 
  904void CFrmWebBrowser::slotPrintToPdf()
 
  909        szPath += RabbitCommon::CDir::Instance()->GetDirUserData()
 
  910                  + QDir::separator() + 
"pdf";
 
  914        szPath += QDir::separator() + pWeb->page()->title() + 
".pdf";
 
  915        qDebug(log) << 
"pdf:" << szPath;
 
  916#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0) 
  917        pWeb->printToPdf(szPath);
 
  922void CFrmWebBrowser::slotPdfPrintingFinished(
const QString& szFile, 
bool success) {
 
  923    if(success && m_pPara->GetPromptPrintFinished())
 
  924        QMessageBox::information(
this, tr(
"Print to PDF finished"),
 
  925                                 tr(
"Successfully printed to PDF.") + 
"\n" 
  926                                     + tr(
"PDF file: ") + szFile);
 
  927    qDebug(log) << 
"Print to PDF:" << szFile << success;
 
void sigUpdateTitle()
Title or icon changed.