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:
parent
47a80e2b2a
commit
03db6da1a9
Binary file not shown.
Before Width: | Height: | Size: 840 B After Width: | Height: | Size: 935 B |
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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()) {
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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()));
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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)) {
|
||||
|
@ -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>
|
||||
|
@ -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)
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user