5

I believe that there is no native functions in QtWebKit to use SpellChecker.

Is there any way to get the fields (<textarea>, <input> and <tagName contenteditable=true>) of the current page and highlight specific words (add underline only words possibly wrong)?

[edit]

I need to add "visual effect" (underline) to the Words and not the dom elements, for example if I have a html like this:

<textarea>Helllo world!</textarea>

only the word "Helllo" will be underlined, example: enter image description here

Thank you.

Protomen
  • 9,471
  • 9
  • 57
  • 124

1 Answers1

-2

UPDATE:

No, as far as I can tell from poking and prodding at QtWebKit, you can't format the contents of a textarea.

Format text in a <textarea>?

You could maybe replace it with a div that looks and acts like a textarea, and then insert some tags around specific words.

But near as I can tell from working on this question, it isn't possible with QWebElement.

You could go and ask the trolls and see if they have any suggestions.

Here is the code that got the closest. When the webpage comes up, right click on different places on the page.

main.cpp

#include <QApplication>
#include "webview.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    WebView w;
    w.show();

    return a.exec();
}

webview.h

#ifndef WEBVIEW_H
#define WEBVIEW_H

#include <QWebView>
#include <QContextMenuEvent>


class WebView : public QWebView
{
    Q_OBJECT

public:
    explicit WebView(QWidget *parent = 0);
    ~WebView();

public slots:
    void contextMenuEvent(QContextMenuEvent *);

private:
};

#endif // WEBVIEW_H

webview.cpp

#include "webview.h"
#include <QWebFrame>
#include <QWebElement>
#include <QWebElementCollection>
#include <QDebug>

WebView::WebView(QWidget *parent) :
    QWebView(parent)
{
    this->setUrl(QUrl("http://www.w3schools.com/tags/tag_textarea.asp"));

    // right click on different parts of the web page
}

WebView::~WebView(){ }

void WebView::contextMenuEvent(QContextMenuEvent * cme)
{
    QPoint pos = cme->pos();

    QWebHitTestResult whtr = this->page()->frameAt(pos)->hitTestContent(pos);

    QWebElement we = whtr.element();

    if(we.isNull())
    {
        qDebug() << "WebElement is null.";
    }
    else
    {

        qDebug() << we.tagName() << "OuterXML <<<<<" << we.toOuterXml() << ">>>>>";
        qDebug() << we.tagName() << "InnerXML <<<<<" << we.toInnerXml() << ">>>>>";
        qDebug() << we.tagName() << "PlainText <<<<<" << we.toPlainText() << ">>>>>";


        // TODO: replace the lines below with a better way of extracting words from the DOM and the HTML tags
        // This current method modifies tags instead of just the text inside tags.
        QStringList list = we.toPlainText().split(' ');
        for(int i = 0; i < list.size(); i++)
        {
            // TODO: Insert dictionary logic here when examining words
            if(list.at(i).size() > 5)
            {
                list[i] = "<span class=\"sp\" style=\"border-bottom: 1px dotted red;\">" + list.at(i) + "</span>";
            }
        }
        qDebug() << list.join(" ");
        we.setInnerXml(list.join(" "));
        qDebug() << "-------------------------------------------";
    }
}

So after some additional research (after some changes to your question) here is the method I would look into:

When a right click is performed on the page, the QWidget (your QWebView) sends out a QContextMenuEvent.

http://qt-project.org/doc/qt-4.8/qcontextmenuevent.html#details

Get the position out of that event, and then drill down into your web page to find out what it was for:

Get the web frame at the click location...

QWebFrame * QWebPage::frameAt ( const QPoint & pos ) const

Do a hit test content at the location...

QWebHitTestResult QWebFrame::hitTestContent ( const QPoint & pos ) const

Query the element out of the hit test...

QWebElement QWebHitTestResult::element () const

Double check that the content is editable by the user...

bool QWebHitTestResult::isContentEditable () const

But that is about as far as I have gotten on this research project.

If you restyle the webelements on the page to have a span tag of your misspelled class, then you could look for those and then either create your own popup menu, or edit the contextMenu of the QWebView right then.

So, no, there is not a context menu for elements on the page, but you can simulate it, if you find the element that is clicked on, and then change the contextMenu for the QWidget.

http://qt-project.org/doc/qt-4.8/webkit-simpleselector.html

void Window::on_elementLineEdit_returnPressed()
{
    QWebFrame *frame = webView->page()->mainFrame();

    QWebElement document = frame->documentElement();
    QWebElementCollection elements = document.findAll(elementLineEdit->text());

    foreach (QWebElement element, elements)
        element.setAttribute("style", "background-color: #f0f090");
}

http://qt-project.org/doc/qt-4.8/mainwindows-menus.html

void MainWindow::contextMenuEvent(QContextMenuEvent *event)
{
    QMenu menu(this);
    menu.addAction(cutAct);
    menu.addAction(copyAct);
    menu.addAction(pasteAct);
    menu.exec(event->globalPos());
}

Again, I hope that helps.

As far as awesome examples of using QWebKit, there is this project:

How to create Web History for my Browser

https://code.google.com/p/arora/

I did a search on the repo for "spell" and "spellcheck" and nothing useful came up.

As far as tweaking the html on the fly, the Fancy Browser example shows how it's done:

http://qt-project.org/doc/qt-4.8/webkit-fancybrowser-mainwindow-cpp.html

void MainWindow::rotateImages(bool invert)
{
    QString code;
    if (invert)
        code = "$('img').each( function () { $(this).css('-webkit-transition', '-webkit-transform 2s'); $(this).css('-webkit-transform', 'rotate(180deg)') } )";
    else
        code = "$('img').each( function () { $(this).css('-webkit-transition', '-webkit-transform 2s'); $(this).css('-webkit-transform', 'rotate(0deg)') } )";
    view->page()->mainFrame()->evaluateJavaScript(code);
}

They just use jquery and run additional javascript on a loaded page.

So you could probably substitute "$('img').each( for "$('textarea').each( and act on the text of an area.

You could also run a regex on the page or use an html parser to find all the <textarea> blocks.

Hope that helps.

Community
  • 1
  • 1
phyatt
  • 18,472
  • 5
  • 61
  • 80
  • I can get all DOM elements using `QWebElement`, what I need is "underline" specific words insides of a ` – Protomen Jul 13 '13 at 00:11
  • Thanks again, but as I said **"word"** not **"dom element"** (highlight specific words), see the conventional browsers have spellcheck, each misspelled word is underlined. That's what I need, probably getting add "underline" Achieve add "events" easily (since my difficulty is to add visual effect for word). Could you help me? (Note: I edited my question, see the "example") – Protomen Jul 15 '13 at 21:02
  • Instead of completely dropping everything out of your question, it is useful to put EDITED or UPDATED. That way when people see what I have put for my answer, they don't think I completely miss what you are asking about. The specific context menu for individual words is possible, but tricky. That is what my answer is pointing at. There are jquery libraries that go and underline and put in links where you can do spell checking. http://jquery-spellchecker.badsyntax.co/ A similar setup can be applied using the javascript renderer in webkit. – phyatt Jul 15 '13 at 21:54
  • this *"jquery"* is not even close to what I need (it only works in `contentEditable=true`), *contextMenu* is not my difficulty, the problem is to apply add underline the words. I added a picture of a spell checker to make it easier for you. Thank you for your interest. – Protomen Jul 16 '13 at 00:52
  • This *"FakeTextarea"* can affect the functioning of the sites I access (since I'm developing a web browser to different websites, not only to my page). Unfortunately it was just making a **faketextarea**, I would prefer to do with *javascript* on the server itself, but it is not the case. Even so thank the suggestions and their creative ideas. – Protomen Jul 16 '13 at 17:42
  • *@phyatt: No, as far as I can tell from poking and prodding at QtWebKit, you can't format the contents of a textarea*. Thanks for trying again, but this is something that was already clear, it is also clear that somehow the browsers based on *Webkit* (Safari, Chrome and Flock) can do it (it is clear that there is stylized fact, is probably something overlapped or external deployment (non-webkit)), so I still think your answer invalid. – Protomen Jul 17 '13 at 17:01
  • I've only looked at `QtWebKit` and `QWidget` and all the other Qt things inbetween. Not the actual WebKit. http://en.wikipedia.org/wiki/WebKit Maybe there is a `webkit` expert out there that can answer your question. – phyatt Jul 18 '13 at 16:27
  • Thanks for trying and please do not get me wrong, but unfortunately many question I asked (both in the *SO*, and in other *forums* and *Q&A*) had responses similar to your last comment. And at least "60%" of the questions had answers fairly simple. I'm not asking you to guess the solution, just do not try to apply a "solution" that has to do with the question. I ask you again do not get me wrong. – Protomen Jul 18 '13 at 19:22