File indexing completed on 2024-05-19 05:01:24

0001 /*
0002     SPDX-FileCopyrightText: 2009 Nokia Corporation and /or its subsidiary(-ies)
0003     SPDX-FileCopyrightText: 2006 George Staikos <staikos@kde.org>
0004     SPDX-FileCopyrightText: 2006 Dirk Mueller <mueller@kde.org>
0005     SPDX-FileCopyrightText: 2006 Zack Rusin <zack@kde.org>
0006     SPDX-FileCopyrightText: 2006 Simon Hausmann <hausmann@kde.org>
0007 
0008     SPDX-License-Identifier: BSD-2-Clause
0009 */
0010 
0011 #include <KAboutData>
0012 #include <QDebug>
0013 #include <KUriFilter>
0014 #include <KLineEdit>
0015 #include <KPluginMetaData>
0016 #include <webenginepart.h>
0017 #include <profile.h>
0018 
0019 #include <QJsonDocument>
0020 #include <QInputDialog>
0021 
0022 //#include <QUiLoader>
0023 //#include <QWebEnginePage>
0024 #include <QWebEngineView>
0025 //#include <QWebFrame>
0026 #include <QWebEngineSettings>
0027 //#include <QWebElement>
0028 //#include <QWebElementCollection>
0029 
0030 #if !defined(QT_NO_PRINTER)
0031 #include <QPrintPreviewDialog>
0032 #endif
0033 
0034 #include <QAction>
0035 #include <QCompleter>
0036 #include <QMainWindow>
0037 #include <QMenu>
0038 #include <QMenuBar>
0039 #include <QProgressBar>
0040 #include <QStatusBar>
0041 #include <QStringListModel>
0042 #include <QToolBar>
0043 #include <QToolTip>
0044 #include <QDir>
0045 #include <QFile>
0046 #include <QVector>
0047 #include <QTextStream>
0048 #include <QApplication>
0049 #include <KLocalizedString>
0050 #include <QCommandLineParser>
0051 
0052 
0053 class MainWindow : public QMainWindow
0054 {
0055     Q_OBJECT
0056 public:
0057     MainWindow(const QString& url = QString()): currentZoom(100) {
0058         QJsonObject jo = QJsonDocument::fromJson(
0059             "{ \"KPlugin\": {\n"
0060             " \"Id\": \"webenginepart\",\n"
0061             " \"Name\": \"WebEngine\",\n"
0062             " \"Version\": \"0.1\"\n"
0063             "}\n}").object();
0064         KPluginMetaData metaData(jo, QString());
0065         view = new WebEnginePart(this, nullptr, metaData);
0066         setCentralWidget(view->widget());
0067 
0068         connect(view->view(), &QWebEngineView::loadFinished,
0069                 this, &MainWindow::loadFinished);
0070         connect(view->view(), SIGNAL(titleChanged(QString)),
0071                 this, SLOT(setWindowTitle(QString)));
0072         connect(view->view()->page(), SIGNAL(linkHovered(QString)),
0073                 this, SLOT(showLinkHover(QString)));
0074         connect(view->view()->page(), SIGNAL(windowCloseRequested()), this, SLOT(deleteLater()));
0075 
0076         setupUI();
0077 
0078         QUrl qurl(KUriFilter::self()->filteredUri(url, QStringList() << QStringLiteral("kshorturifilter")));
0079         if (qurl.isValid()) {
0080             urlEdit->setText(qurl.toEncoded());
0081             view->openUrl(qurl);
0082 
0083             // the zoom values are chosen to be like in Mozilla Firefox 3
0084             zoomLevels << 30 << 50 << 67 << 80 << 90;
0085             zoomLevels << 100;
0086             zoomLevels << 110 << 120 << 133 << 150 << 170 << 200 << 240 << 300;
0087         }
0088     }
0089 
0090     QWebEnginePage* webPage() const {
0091         return view->view()->page();
0092     }
0093 
0094     QWebEngineView* webView() const {
0095         return view->view();
0096     }
0097 
0098 protected slots:
0099 
0100     void changeLocation() {
0101         QUrl url (KUriFilter::self()->filteredUri(urlEdit->text(), QStringList() << QStringLiteral("kshorturifilter")));
0102         view->openUrl(url);
0103         view->view()->setFocus(Qt::OtherFocusReason);
0104     }
0105 
0106     void loadFinished() {
0107         urlEdit->setText(view->url().toString());
0108 
0109         QUrl::FormattingOptions opts;
0110         opts |= QUrl::RemoveScheme;
0111         opts |= QUrl::RemoveUserInfo;
0112         opts |= QUrl::StripTrailingSlash;
0113         QString s = view->url().toString(opts);
0114         s = s.mid(2);
0115         if (s.isEmpty())
0116             return;
0117 
0118         if (!urlList.contains(s))
0119             urlList += s;
0120         urlModel.setStringList(urlList);
0121     }
0122 
0123     void showLinkHover(const QString &link) {
0124         statusBar()->showMessage(link);
0125     }
0126 
0127     void zoomIn() {
0128         int i = zoomLevels.indexOf(currentZoom);
0129         Q_ASSERT(i >= 0);
0130         if (i < zoomLevels.count() - 1)
0131             currentZoom = zoomLevels[i + 1];
0132 
0133         view->view()->setZoomFactor(qreal(currentZoom)/100.0);
0134     }
0135 
0136     void zoomOut() {
0137         int i = zoomLevels.indexOf(currentZoom);
0138         Q_ASSERT(i >= 0);
0139         if (i > 0)
0140             currentZoom = zoomLevels[i - 1];
0141 
0142         view->view()->setZoomFactor(qreal(currentZoom)/100.0);
0143     }
0144 
0145     void resetZoom()
0146     {
0147        currentZoom = 100;
0148        view->view()->setZoomFactor(1.0);
0149     }
0150 
0151     void toggleZoomTextOnly(bool b)
0152     {
0153 //        view->view()->page()->settings()->setAttribute(QWebEngineSettings::ZoomTextOnly, b);
0154     }
0155 
0156     void print() {
0157 #if !defined(QT_NO_PRINTER)
0158         QScopedPointer<QPrintPreviewDialog> dlg (new QPrintPreviewDialog(this));
0159         connect(dlg.data(), SIGNAL(paintRequested(QPrinter*)),
0160                 view, SLOT(print(QPrinter*)));
0161         dlg->exec();
0162 #endif
0163     }
0164 
0165     void setEditable(bool on) {
0166 //        view->view()->page()->setContentEditable(on);
0167         formatMenuAction->setVisible(on);
0168     }
0169 
0170     void dumpHtml() {
0171         view->view()->page()->toHtml([](const QString& text) {
0172             qDebug() << "HTML: " << text;
0173         });
0174     }
0175 
0176     void selectElements() {
0177         bool ok;
0178         QString str = QInputDialog::getText(this, i18nc("input dialog window title for selecting html elements", "Select elements"),
0179                                             i18nc("input dialog text for selecting html elements", "Choose elements"), QLineEdit::Normal,
0180                                             QStringLiteral("a"), &ok);
0181         if (ok && !str.isEmpty()) {
0182             //QWebElementCollection collection = view->page()->mainFrame()->findAllElements(str);
0183             //const int count = collection.count();
0184             //for (int i=0; i < count; i++)
0185             //    collection.at(i).setStyleProperty("background-color", "yellow");
0186             //statusBar()->showMessage(i18np("%1 element selected", "%1 elements selected", count), 5000);
0187         }
0188     }
0189 
0190 public slots:
0191 
0192     void newWindow(const QString &url = QString()) {
0193         MainWindow *mw = new MainWindow(url);
0194         mw->show();
0195     }
0196 
0197 private:
0198 
0199     QVector<int> zoomLevels;
0200     int currentZoom;
0201 
0202     // create the status bar, tool bar & menu
0203     void setupUI() {
0204         progress = new QProgressBar(this);
0205         progress->setRange(0, 100);
0206         progress->setMinimumSize(100, 20);
0207         progress->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
0208         progress->hide();
0209         statusBar()->addPermanentWidget(progress);
0210 
0211         connect(view->view(), SIGNAL(loadProgress(int)), progress, SLOT(show()));
0212         connect(view->view(), SIGNAL(loadProgress(int)), progress, SLOT(setValue(int)));
0213         connect(view->view(), SIGNAL(loadFinished(bool)), progress, SLOT(hide()));
0214 
0215         urlEdit = new KLineEdit(this);
0216         urlEdit->setSizePolicy(QSizePolicy::Expanding, urlEdit->sizePolicy().verticalPolicy());
0217         connect(urlEdit, SIGNAL(returnPressed()),
0218                 SLOT(changeLocation()));
0219         QCompleter *completer = new QCompleter(this);
0220         urlEdit->setCompleter(completer);
0221         completer->setModel(&urlModel);
0222 
0223         QToolBar *bar = addToolBar(QStringLiteral("Navigation"));
0224         bar->addAction(view->view()->pageAction(QWebEnginePage::Back));
0225         bar->addAction(view->view()->pageAction(QWebEnginePage::Forward));
0226         bar->addAction(view->view()->pageAction(QWebEnginePage::Reload));
0227         bar->addAction(view->view()->pageAction(QWebEnginePage::Stop));
0228         bar->addWidget(urlEdit);
0229 
0230         QMenu *fileMenu = menuBar()->addMenu(i18n("&File"));
0231         QAction *newWindow = fileMenu->addAction(i18n("New Window"), this, SLOT(newWindow()));
0232 
0233         fileMenu->addAction(i18n("Print"), this, SLOT(print()));
0234         fileMenu->addAction(i18n("Close"), this, SLOT(close()));
0235 
0236         QMenu *editMenu = menuBar()->addMenu(i18n("&Edit"));
0237         editMenu->addAction(view->view()->pageAction(QWebEnginePage::Undo));
0238         editMenu->addAction(view->view()->pageAction(QWebEnginePage::Redo));
0239         editMenu->addSeparator();
0240         editMenu->addAction(view->view()->pageAction(QWebEnginePage::Cut));
0241         editMenu->addAction(view->view()->pageAction(QWebEnginePage::Copy));
0242         editMenu->addAction(view->view()->pageAction(QWebEnginePage::Paste));
0243         editMenu->addSeparator();
0244         QAction *setEditable = editMenu->addAction(i18n("Set Editable"), this, SLOT(setEditable(bool)));
0245         setEditable->setCheckable(true);
0246 
0247         QMenu *viewMenu = menuBar()->addMenu(i18n("&View"));
0248         viewMenu->addAction(view->view()->pageAction(QWebEnginePage::Stop));
0249         viewMenu->addAction(view->view()->pageAction(QWebEnginePage::Reload));
0250         viewMenu->addSeparator();
0251         QAction *zoomIn = viewMenu->addAction(i18n("Zoom &In"), this, SLOT(zoomIn()));
0252         QAction *zoomOut = viewMenu->addAction(i18n("Zoom &Out"), this, SLOT(zoomOut()));
0253         QAction *resetZoom = viewMenu->addAction(i18n("Reset Zoom"), this, SLOT(resetZoom()));
0254         QAction *zoomTextOnly = viewMenu->addAction(i18n("Zoom Text Only"), this, SLOT(toggleZoomTextOnly(bool)));
0255         zoomTextOnly->setCheckable(true);
0256         zoomTextOnly->setChecked(false);
0257         viewMenu->addSeparator();
0258         viewMenu->addAction(i18n("Dump HTML"), this, SLOT(dumpHtml()));
0259 
0260 #if 0
0261         QMenu *formatMenu = new QMenu(i18n("F&ormat"));
0262         formatMenuAction = menuBar()->addMenu(formatMenu);
0263         formatMenuAction->setVisible(false);
0264         formatMenu->addAction(view->view()->pageAction(QWebEnginePage::ToggleBold));
0265         formatMenu->addAction(view->view()->pageAction(QWebEnginePage::ToggleItalic));
0266         formatMenu->addAction(view->view()->pageAction(QWebEnginePage::ToggleUnderline));
0267         QMenu *writingMenu = formatMenu->addMenu(i18n("Writing Direction"));
0268         writingMenu->addAction(view->view()->pageAction(QWebEnginePage::SetTextDirectionDefault));
0269         writingMenu->addAction(view->view()->pageAction(QWebEnginePage::SetTextDirectionLeftToRight));
0270         writingMenu->addAction(view->view()->pageAction(QWebEnginePage::SetTextDirectionRightToLeft));
0271 #endif
0272         newWindow->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_N));
0273         view->view()->pageAction(QWebEnginePage::Back)->setShortcut(QKeySequence::Back);
0274         view->view()->pageAction(QWebEnginePage::Stop)->setShortcut(Qt::Key_Escape);
0275         view->view()->pageAction(QWebEnginePage::Forward)->setShortcut(QKeySequence::Forward);
0276         view->view()->pageAction(QWebEnginePage::Reload)->setShortcut(QKeySequence::Refresh);
0277         view->view()->pageAction(QWebEnginePage::Undo)->setShortcut(QKeySequence::Undo);
0278         view->view()->pageAction(QWebEnginePage::Redo)->setShortcut(QKeySequence::Redo);
0279         view->view()->pageAction(QWebEnginePage::Cut)->setShortcut(QKeySequence::Cut);
0280         view->view()->pageAction(QWebEnginePage::Copy)->setShortcut(QKeySequence::Copy);
0281         view->view()->pageAction(QWebEnginePage::Paste)->setShortcut(QKeySequence::Paste);
0282         zoomIn->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Plus));
0283         zoomOut->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Minus));
0284         resetZoom->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_0));
0285 //        view->view()->pageAction(QWebEnginePage::ToggleBold)->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_B));
0286 //        view->view()->pageAction(QWebEnginePage::ToggleItalic)->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_I));
0287 //        view->view()->pageAction(QWebEnginePage::ToggleUnderline)->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_U));
0288 
0289         QMenu *toolsMenu = menuBar()->addMenu(i18n("&Tools"));
0290         toolsMenu->addAction(i18n("Select elements..."), this, SLOT(selectElements()));
0291 
0292     }
0293 
0294     WebEnginePart *view;
0295     KLineEdit *urlEdit;
0296     QProgressBar *progress;
0297 
0298     QAction *formatMenuAction;
0299 
0300     QStringList urlList;
0301     QStringListModel urlModel;
0302 };
0303 
0304 class URLLoader : public QObject
0305 {
0306     Q_OBJECT
0307 public:
0308     URLLoader(QWebEngineView* view, const QString& inputFileName)
0309         : m_view(view)
0310         , m_stdOut(stdout)
0311     {
0312         init(inputFileName);
0313     }
0314 
0315 public slots:
0316     void loadNext()
0317     {
0318         QString qstr;
0319         if (getUrl(qstr)) {
0320             QUrl url(qstr, QUrl::StrictMode);
0321             if (url.isValid()) {
0322                 m_stdOut << "Loading " << qstr << " ......" << Qt::endl;
0323                 m_view->load(url);
0324             } else
0325                 loadNext();
0326         } else
0327             disconnect(m_view, nullptr, this, nullptr);
0328     }
0329 
0330 private:
0331     void init(const QString& inputFileName)
0332     {
0333         QFile inputFile(inputFileName);
0334         if (inputFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
0335             QTextStream stream(&inputFile);
0336             QString line;
0337             while (true) {
0338                 line = stream.readLine();
0339                 if (line.isNull())
0340                     break;
0341                 m_urls.append(line);
0342             }
0343         } else {
0344             qDebug() << "Can't open list file";
0345             exit(0);
0346         }
0347         m_index = 0;
0348         inputFile.close();
0349     }
0350 
0351     bool getUrl(QString& qstr)
0352     {
0353         if (m_index == m_urls.size())
0354             return false;
0355 
0356         qstr = m_urls[m_index++];
0357         return true;
0358     }
0359 
0360 private:
0361     QVector<QString> m_urls;
0362     int m_index;
0363     QWebEngineView* m_view;
0364     QTextStream m_stdOut;
0365 };
0366 
0367 
0368 int main(int argc, char **argv)
0369 {
0370     KAboutData about(QStringLiteral("KDELauncher"), i18n("KDELauncher"), QStringLiteral("0.0000013"));
0371     QApplication app(argc, argv);
0372     QCommandLineParser parser;
0373     KAboutData::setApplicationData(about);
0374     about.setupCommandLine(&parser);
0375     parser.process(app);
0376     about.processCommandLine(&parser);
0377 
0378     QString url = QStringLiteral("%1/%2").arg(QDir::homePath()).arg(QStringLiteral("index.html"));
0379 
0380     const QStringList args = app.arguments();
0381 
0382     if (args.contains(QStringLiteral("-r"))) {
0383         // robotized
0384         QString listFile = args.at(2);
0385         if (!(args.count() == 3) && QFile::exists(listFile)) {
0386             qDebug() << "Usage: KDELauncher -r listfile";
0387             exit(0);
0388         }
0389         MainWindow window;
0390         QWebEngineView *view = window.webView();
0391         URLLoader loader(view, listFile);
0392         QObject::connect(view, SIGNAL(loadFinished(bool)), &loader, SLOT(loadNext()));
0393         loader.loadNext();
0394         window.show();
0395         return app.exec();
0396     } else {
0397         if (args.count() > 1)
0398             url = args.at(1);
0399 
0400         MainWindow window(url);
0401 
0402         // Opens every given urls in new windows
0403         for (int i = 2; i < args.count(); i++)
0404             window.newWindow(args.at(i));
0405 
0406         window.show();
0407         return app.exec();
0408     }
0409 }
0410 
0411 #include "webenginepart_tester.moc"