1
mirror of https://invent.kde.org/network/falkon.git synced 2024-12-24 12:46:35 +01:00

Added option to create search engine from <input> element on page.

- accessible in context menu on input
- added translations for plugins into resources so they can be loaded
- in access keys navigation plugin: lower case chars are choose first
This commit is contained in:
nowrep 2012-03-08 13:05:57 +01:00
parent 47a80e2b2a
commit 03db6da1a9
16 changed files with 159 additions and 32 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 840 B

After

Width:  |  Height:  |  Size: 935 B

View File

@ -53,6 +53,7 @@ WebSearchBar::WebSearchBar(QupZilla* mainClass, QWidget* parent)
, m_menu(new QMenu(this))
, m_pasteAndGoAction(0)
, m_clearAction(0)
, m_reloadingEngines(false)
{
setObjectName("websearchbar");
@ -118,6 +119,7 @@ void WebSearchBar::openSearchEnginesDialog()
void WebSearchBar::setupEngines()
{
disconnect(m_searchManager, SIGNAL(enginesChanged()), this, SLOT(setupEngines()));
m_reloadingEngines = true;
QString activeEngine = m_searchManager->startingEngineName();
@ -142,12 +144,13 @@ void WebSearchBar::setupEngines()
}
}
searchChanged(m_boxSearchType->currentItem(), false);
searchChanged(m_boxSearchType->currentItem());
connect(m_searchManager, SIGNAL(enginesChanged()), this, SLOT(setupEngines()));
m_reloadingEngines = false;
}
void WebSearchBar::searchChanged(const ButtonWithMenu::Item &item, bool reload)
void WebSearchBar::searchChanged(const ButtonWithMenu::Item &item)
{
setPlaceholderText(item.text);
m_completerModel->setStringList(QStringList());
@ -159,7 +162,7 @@ void WebSearchBar::searchChanged(const ButtonWithMenu::Item &item, bool reload)
m_searchManager->setActiveEngine(m_activeEngine);
if (reload && !text().isEmpty()) {
if (!m_reloadingEngines && !text().isEmpty()) {
search();
}
}

View File

@ -55,7 +55,7 @@ public:
explicit WebSearchBar(QupZilla* mainClass, QWidget* parent = 0);
private slots:
void searchChanged(const ButtonWithMenu::Item &item, bool reload = true);
void searchChanged(const ButtonWithMenu::Item &item);
void setupEngines();
void search();
@ -94,6 +94,8 @@ private:
QMenu* m_menu;
QAction* m_pasteAndGoAction;
QAction* m_clearAction;
bool m_reloadingEngines;
};
#endif // WEBSEARCHBAR_H

View File

@ -354,7 +354,7 @@ QString QupZillaSchemeReply::configPage()
QString allGroupsString;
QSettings* settings = Settings::globalSettings();
foreach(const QString & group, settings->childGroups()) {
QString groupString = QString("<tr><th colspan=\"2\">%1</th></tr>").arg(group);
QString groupString = QString("<tr><th colspan=\"2\">[%1]</th></tr>").arg(group);
settings->beginGroup(group);
foreach(const QString & key, settings->childKeys()) {

View File

@ -28,6 +28,8 @@ EditSearchEngine::EditSearchEngine(const QString &title, QWidget* parent)
ui->setupUi(this);
connect(ui->iconFromFile, SIGNAL(clicked()), this, SLOT(chooseIcon()));
ui->buttonBox->setFocus();
}
QString EditSearchEngine::name()

View File

@ -103,7 +103,8 @@ OpenSearchEngine* OpenSearchReader::read()
readNext();
}
if (!m_searchXml.contains(QLatin1String("http://a9.com/-/spec/opensearch/1.1/"))) {
if (!m_searchXml.contains(QLatin1String("http://a9.com/-/spec/opensearch/1.1/")) &&
!m_searchXml.contains(QLatin1String("http://www.mozilla.org/2006/browser/search/"))) {
raiseError(QObject::tr("The file is not an OpenSearch 1.1 file."));
return engine;
}

View File

@ -24,12 +24,11 @@
SearchEnginesDialog::SearchEnginesDialog(QWidget* parent)
: QDialog(parent)
, ui(new Ui::SearchEnginesDialog)
, m_manager(mApp->searchEnginesManager())
{
setAttribute(Qt::WA_DeleteOnClose);
ui->setupUi(this);
m_manager = mApp->searchEnginesManager();
connect(ui->add, SIGNAL(clicked()), this, SLOT(addEngine()));
connect(ui->remove, SIGNAL(clicked()), this, SLOT(removeEngine()));
connect(ui->edit, SIGNAL(clicked()), this, SLOT(editEngine()));

View File

@ -16,6 +16,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#include "searchenginesmanager.h"
#include "searchenginesdialog.h"
#include "editsearchengine.h"
#include "iconprovider.h"
#include "mainapplication.h"
#include "networkmanager.h"
@ -23,9 +25,11 @@
#include "opensearchengine.h"
#include "databasewriter.h"
#include "settings.h"
#include "webview.h"
#include <QNetworkReply>
#include <QMessageBox>
#include <QWebElement>
#define ENSURE_LOADED if (!m_settingsLoaded) loadSettings();
@ -140,10 +144,10 @@ void SearchEnginesManager::restoreDefaults()
duck.url = "https://duckduckgo.com/?q=%s&t=qupzilla";
duck.shortcut = "d";
addEngine(google, false);
addEngine(wiki, false);
addEngine(yt, false);
addEngine(duck, false);
addEngine(google);
addEngine(wiki);
addEngine(yt);
addEngine(duck);
emit enginesChanged();
}
@ -179,7 +183,7 @@ void SearchEnginesManager::editEngine(const Engine &before, const Engine &after)
addEngine(after);
}
void SearchEnginesManager::addEngine(const Engine &engine, bool emitSignal)
void SearchEnginesManager::addEngine(const Engine &engine)
{
ENSURE_LOADED;
@ -189,9 +193,72 @@ void SearchEnginesManager::addEngine(const Engine &engine, bool emitSignal)
m_allEngines.append(engine);
if (emitSignal) {
emit enginesChanged();
}
void SearchEnginesManager::addEngineFromForm(const QWebElement &element, WebView* view)
{
QWebElement formElement = element.parent();
while (!formElement.isNull()) {
if (formElement.tagName().toLower() == "form") {
break;
}
formElement = formElement.parent();
}
if (formElement.isNull()) {
return;
}
QUrl actionUrl = QUrl::fromEncoded(formElement.attribute("action").toUtf8());
if (actionUrl.isRelative()) {
actionUrl = view->url().resolved(actionUrl);
}
actionUrl.addQueryItem(element.attribute("name"), "%s");
QList<QPair<QByteArray, QByteArray> > queryItems;
QWebElementCollection allInputs = formElement.findAll("input");
foreach (QWebElement e, allInputs) {
if (element == e || !e.hasAttribute("name")) {
continue;
}
QPair<QByteArray, QByteArray> item;
item.first = QUrl::toPercentEncoding(e.attribute("name").toUtf8());
item.second = QUrl::toPercentEncoding(e.evaluateJavaScript("this.value").toByteArray());
queryItems.append(item);
}
actionUrl.setEncodedQueryItems(queryItems + actionUrl.encodedQueryItems());
SearchEngine engine;
engine.name = view->title();
engine.icon = view->icon();
engine.url = actionUrl.toString();
EditSearchEngine dialog(SearchEnginesDialog::tr("Add Search Engine"), view);
dialog.setName(engine.name);
dialog.setIcon(engine.icon);
dialog.setUrl(engine.url);
if (dialog.exec() != QDialog::Accepted) {
return;
}
engine.name = dialog.name();
engine.icon = dialog.icon();
engine.url = dialog.url();
engine.shortcut = dialog.shortcut();
if (engine.name.isEmpty() || engine.url.isEmpty()) {
return;
}
addEngine(engine);
}
void SearchEnginesManager::addEngine(OpenSearchEngine* engine)

View File

@ -26,6 +26,10 @@
#include "qz_namespace.h"
#include "opensearchengine.h"
class QWebElement;
class WebView;
class QT_QUPZILLA_EXPORT SearchEnginesManager : public QObject
{
Q_OBJECT
@ -55,7 +59,9 @@ public:
void addEngine(const QUrl &url);
void addEngine(OpenSearchEngine* engine);
void addEngine(const Engine &engine, bool emitSignal = true);
void addEngine(const Engine &engine);
void addEngineFromForm(const QWebElement &element, WebView *view);
void removeEngine(const Engine &engine);

View File

@ -504,6 +504,36 @@ bool WebView::isMediaElement(const QWebElement &element)
return (element.tagName().toLower() == "video" || element.tagName().toLower() == "audio");
}
void WebView::checkForForm(QMenu *menu, const QWebElement &element)
{
QWebElement parentElement = element.parent();
while (!parentElement.isNull()) {
if (parentElement.tagName().toLower() == "form") {
break;
}
parentElement = parentElement.parent();
}
if (parentElement.isNull()) {
return;
}
QString method = parentElement.hasAttribute("method") ? parentElement.attribute("method").toUpper() : "GET";
if (method == "GET") {
menu->addAction(QIcon(":icons/menu/search-icon.png"), tr("Create Search Engine"), this, SLOT(createSearchEngine()));
m_clickedElement = element;
}
}
void WebView::createSearchEngine()
{
mApp->searchEnginesManager()->addEngineFromForm(m_clickedElement, this);
}
void WebView::createContextMenu(QMenu* menu, const QWebHitTestResult &hitTest, const QPoint &pos)
{
if (!m_actionsHaveImages) {
@ -560,6 +590,10 @@ void WebView::createContextMenu(QMenu* menu, const QWebHitTestResult &hitTest, c
}
}
if (hitTest.element().tagName().toLower() == "input") {
checkForForm(menu, hitTest.element());
}
if (!selectedText().isEmpty()) {
createSelectedTextContextMenu(menu, hitTest);
}
@ -735,15 +769,15 @@ void WebView::createSelectedTextContextMenu(QMenu* menu, const QWebHitTestResult
void WebView::createMediaContextMenu(QMenu* menu, const QWebHitTestResult &hitTest)
{
m_mediaElement = hitTest.element();
m_clickedElement = hitTest.element();
if (m_mediaElement.isNull()) {
if (m_clickedElement.isNull()) {
return;
}
bool paused = m_mediaElement.evaluateJavaScript("this.paused").toBool();
bool muted = m_mediaElement.evaluateJavaScript("this.muted").toBool();
QUrl videoUrl = m_mediaElement.evaluateJavaScript("this.currentSrc").toUrl();
bool paused = m_clickedElement.evaluateJavaScript("this.paused").toBool();
bool muted = m_clickedElement.evaluateJavaScript("this.muted").toBool();
QUrl videoUrl = m_clickedElement.evaluateJavaScript("this.currentSrc").toUrl();
menu->addSeparator();
menu->addAction(paused ? tr("&Play") : tr("&Pause"), this, SLOT(pauseMedia()))->setIcon(QIcon::fromTheme(paused ? "media-playback-start" : "media-playback-pause"));
@ -756,25 +790,25 @@ void WebView::createMediaContextMenu(QMenu* menu, const QWebHitTestResult &hitTe
void WebView::pauseMedia()
{
bool paused = m_mediaElement.evaluateJavaScript("this.paused").toBool();
bool paused = m_clickedElement.evaluateJavaScript("this.paused").toBool();
if (paused) {
m_mediaElement.evaluateJavaScript("this.play()");
m_clickedElement.evaluateJavaScript("this.play()");
}
else {
m_mediaElement.evaluateJavaScript("this.pause()");
m_clickedElement.evaluateJavaScript("this.pause()");
}
}
void WebView::muteMedia()
{
bool muted = m_mediaElement.evaluateJavaScript("this.muted").toBool();
bool muted = m_clickedElement.evaluateJavaScript("this.muted").toBool();
if (muted) {
m_mediaElement.evaluateJavaScript("this.muted = false");
m_clickedElement.evaluateJavaScript("this.muted = false");
}
else {
m_mediaElement.evaluateJavaScript("this.muted = true");
m_clickedElement.evaluateJavaScript("this.muted = true");
}
}

View File

@ -92,6 +92,8 @@ protected slots:
void openUrlInSelectedTab();
void openUrlInBackgroundTab();
void createSearchEngine();
// Clicked frame actions
void loadClickedFrame();
@ -117,6 +119,7 @@ protected:
QUrl lastUrl();
bool isMediaElement(const QWebElement &element);
void checkForForm(QMenu* menu, const QWebElement &element);
void createContextMenu(QMenu* menu, const QWebHitTestResult &hitTest, const QPoint &pos);
void createPageContextMenu(QMenu* menu, const QPoint &pos);
@ -141,7 +144,7 @@ private:
QUrl m_aboutToLoadUrl;
QUrl m_lastUrl;
QWebElement m_mediaElement;
QWebElement m_clickedElement;
QWebFrame* m_clickedFrame;
QUrl m_clickedUrl;
bool m_actionsHaveImages;

View File

@ -16,8 +16,11 @@ FORMS += \
RESOURCES = akn_res.qrc
TRANSLATIONS = translations/cs_CZ.ts \
TRANSLATIONS = \
translations/cs_CZ.ts \
translations/sr_BA.ts \
translations/sr_RS.ts \
translations/de_DE.ts \
translations/zh_TW.ts \
include(../../plugins.pri)

View File

@ -276,7 +276,7 @@ void AKN_Handler::showAccessKeys()
continue;
}
QChar accessKey;
QString text = element.toPlainText().toUpper();
QString text = element.toPlainText().toLower();
for (int i = 0; i < text.count(); ++i) {
const QChar &c = text.at(i);
if (unusedKeys.contains(c)) {

View File

@ -5,5 +5,7 @@
<file>locale/cs_CZ.qm</file>
<file>locale/sr_BA.qm</file>
<file>locale/sr_RS.qm</file>
<file>locale/de_DE.qm</file>
<file>locale/zh_TW.qm</file>
</qresource>
</RCC>

View File

@ -24,10 +24,12 @@ FORMS += \
RESOURCES = mousegestures.qrc
TRANSLATIONS = translations/cs_CZ.ts \
TRANSLATIONS = \
translations/cs_CZ.ts \
translations/de_DE.ts \
translations/sk_SK.ts \
translations/sr_BA.ts \
translations/sr_RS.ts \
translations/de_DE.ts \
translations/zh_TW.ts \
include(../../plugins.pri)

View File

@ -13,7 +13,10 @@
<file>data/up-right.gif</file>
<file>data/copyright</file>
<file>locale/cs_CZ.qm</file>
<file>locale/de_DE.qm</file>
<file>locale/sk_SK.qm</file>
<file>locale/sr_BA.qm</file>
<file>locale/sr_RS.qm</file>
<file>locale/zh_TW.qm</file>
</qresource>
</RCC>