1
mirror of https://invent.kde.org/network/falkon.git synced 2024-11-11 01:22:10 +01:00

Added GreaseMonkey + PIM plugins

This commit is contained in:
nowrep 2012-07-11 18:30:00 +02:00
parent edb2e6d624
commit 014fa12159
63 changed files with 5821 additions and 10 deletions

View File

@ -23,6 +23,7 @@
#include "mainapplication.h"
#include <QMenu>
#include <QTimer>
#include <QMessageBox>
#include <QInputDialog>
@ -152,6 +153,14 @@ void AdBlockDialog::learnAboutRules()
mApp->addNewTab(QUrl("http://adblockplus.org/en/filters"));
}
void AdBlockDialog::loadSubscriptions()
{
for (int i = 0; i < tabWidget->count(); ++i) {
AdBlockTreeWidget* treeWidget = qobject_cast<AdBlockTreeWidget*>(tabWidget->widget(i));
treeWidget->refresh();
}
}
void AdBlockDialog::load()
{
if (m_loaded || !adblockCheckBox->isChecked()) {
@ -164,4 +173,6 @@ void AdBlockDialog::load()
}
m_loaded = true;
QTimer::singleShot(50, this, SLOT(loadSubscriptions()));
}

View File

@ -51,9 +51,10 @@ private slots:
void aboutToShowMenu();
void learnAboutRules();
private:
void loadSubscriptions();
void load();
private:
AdBlockManager* m_manager;
AdBlockTreeWidget* m_currentTreeWidget;
AdBlockSubscription* m_currentSubscription;

View File

@ -92,7 +92,6 @@ void AdBlockSubscription::loadSubscription(const QStringList &disabledRules)
QFile file(m_filePath);
if (!file.exists()) {
qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "File does not exists" << m_filePath;
QTimer::singleShot(0, this, SLOT(updateSubscription()));
return;
}

View File

@ -19,7 +19,6 @@
#include "adblocksubscription.h"
#include <QMenu>
#include <QTimer>
#include <QKeyEvent>
#include <QClipboard>
#include <QApplication>
@ -39,8 +38,6 @@ AdBlockTreeWidget::AdBlockTreeWidget(AdBlockSubscription* subscription, QWidget*
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequested(QPoint)));
connect(this, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(itemChanged(QTreeWidgetItem*)));
connect(m_subscription, SIGNAL(subscriptionUpdated()), this, SLOT(subscriptionUpdated()));
QTimer::singleShot(100, this, SLOT(refresh()));
}
AdBlockSubscription* AdBlockTreeWidget::subscription() const

View File

@ -35,6 +35,7 @@ public:
AdBlockSubscription* subscription() const;
void showRule(const AdBlockRule* rule);
void refresh();
public slots:
void addRule();
@ -45,7 +46,6 @@ private slots:
void itemChanged(QTreeWidgetItem* item);
void copyFilter();
void refresh();
void subscriptionUpdated();
private:

View File

@ -107,7 +107,7 @@ void DesktopNotificationsFactory::nativeNotificationPreview()
#if defined(Q_WS_X11) && !defined(DISABLE_DBUS)
QFile tmp(QDir::tempPath() + "/qupzilla_notif.png");
tmp.open(QFile::WriteOnly);
QPixmap(":icons/preferences/stock_dialog-question.png").save(tmp.fileName());
QPixmap(":icons/preferences/dialog-question.png").save(tmp.fileName());
QDBusInterface dbus("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications", QDBusConnection::sessionBus());
QVariantList args;

View File

@ -60,7 +60,7 @@ bool AKN_Plugin::testPlugin()
{
// Let's be sure, require latest version of QupZilla
return (QupZilla::VERSION == "1.2.0");
return (QupZilla::VERSION == "1.3.0");
}
QTranslator* AKN_Plugin::getTranslator(const QString &locale)

View File

@ -0,0 +1,49 @@
TARGET = GreaseMonkey
os2: TARGET = GreaseMo
SOURCES += gm_plugin.cpp \
gm_manager.cpp \
gm_script.cpp \
gm_urlmatcher.cpp \
gm_downloader.cpp \
gm_addscriptdialog.cpp \
gm_notification.cpp \
settings/gm_settings.cpp \
settings/gm_settingslistdelegate.cpp \
settings/gm_settingsscriptinfo.cpp \
settings/gm_settingslistwidget.cpp
HEADERS += gm_plugin.h \
gm_manager.h \
gm_script.h \
gm_urlmatcher.h \
gm_downloader.h \
gm_addscriptdialog.h \
gm_notification.h \
settings/gm_settings.h \
settings/gm_settingslistdelegate.h \
settings/gm_settingsscriptinfo.h \
settings/gm_settingslistwidget.h
FORMS += \
gm_addscriptdialog.ui \
gm_notification.ui \
settings/gm_settings.ui \
settings/gm_settingsscriptinfo.ui
RESOURCES += greasemonkey.qrc
TRANSLATIONS = \
translations/cs_CZ.ts \
translations/de_DE.ts \
translations/fr_FR.ts \
translations/sr_BA.ts \
translations/sr_RS.ts \
srcdir = $$(QUPZILLA_SRCDIR)
equals(srcdir, "") {
include(../../plugins.pri)
}
else {
include($$srcdir/src/plugins.pri)
}

View File

@ -0,0 +1,111 @@
if(typeof GM_xmlhttpRequest === "undefined") {
GM_xmlhttpRequest = function(/* object */ details) {
details.method = details.method.toUpperCase() || "GET";
if(!details.url) {
throw("GM_xmlhttpRequest requires an URL.");
}
// build XMLHttpRequest object
var oXhr = new XMLHttpRequest;
// run it
if(oXhr) {
if("onreadystatechange" in details)
oXhr.onreadystatechange = function() { details.onreadystatechange(oXhr) };
if("onload" in details)
oXhr.onload = function() { details.onload(oXhr) };
if("onerror" in details)
oXhr.onerror = function() { details.onerror(oXhr) };
oXhr.open(details.method, details.url, true);
if("headers" in details)
for(var header in details.headers)
oXhr.setRequestHeader(header, details.headers[header]);
if("data" in details)
oXhr.send(details.data);
else
oXhr.send();
} else
throw ("This Browser is not supported, please upgrade.")
}
}
if(typeof GM_addStyle === "undefined") {
function GM_addStyle(/* String */ styles) {
var head = document.getElementsByTagName("head")[0];
if (head === undefined) {
document.onreadystatechange = function() {
if (document.readyState == "interactive") {
var oStyle = document.createElement("style");
oStyle.setAttribute("type", "text\/css");
oStyle.appendChild(document.createTextNode(styles));
document.getElementsByTagName("head")[0].appendChild(oStyle);
}
}
}
else {
var oStyle = document.createElement("style");
oStyle.setAttribute("type", "text\/css");
oStyle.appendChild(document.createTextNode(styles));
head.appendChild(oStyle);
}
}
}
if(typeof GM_log === "undefined") {
function GM_log(log) {
if(console)
console.log(log);
}
}
if(typeof GM_openInTab === "undefined") {
function GM_openInTab(url) {
window.open(url)
}
}
// Define unsafe window
var unsafeWindow = window;
window.wrappedJSObject = unsafeWindow;
// GM_registerMenuCommand not supported
if(typeof GM_registerMenuCommand === "undefined") {
function GM_registerMenuCommand(caption, commandFunc, accessKey) { }
}
// GM Resource not supported
if(typeof GM_getResourceText === "undefined") {
function GM_getResourceText(resourceName) {
throw ("QupZilla: GM Resource is not supported!");
}
}
if(typeof GM_getResourceURL === "undefined") {
function GM_getResourceURL(resourceName) {
throw ("QupZilla: GM Resource is not supported!");
}
}
// GM Settings not supported
if(typeof GM_getValue === "undefined") {
function GM_getValue(name, defaultValue) {
return defaultValue;
}
}
if(typeof GM_setValue === "undefined") {
function GM_setValue(name, value) { }
}
if(typeof GM_deleteValue === "undefined") {
function GM_deleteValue(name) { }
}
if(typeof GM_listValues === "undefined") {
function GM_listValues() {
return new Array("");
}
}

View File

@ -0,0 +1 @@
if(typeof GM_xmlhttpRequest==="undefined")GM_xmlhttpRequest=function(details){details.method=details.method.toUpperCase()||"GET";if(!details.url)throw"GM_xmlhttpRequest requires an URL.";var oXhr=new XMLHttpRequest;if(oXhr){if("onreadystatechange"in details)oXhr.onreadystatechange=function(){details.onreadystatechange(oXhr)};if("onload"in details)oXhr.onload=function(){details.onload(oXhr)};if("onerror"in details)oXhr.onerror=function(){details.onerror(oXhr)};oXhr.open(details.method,details.url,true);if("headers"in details)for(var header in details.headers)oXhr.setRequestHeader(header,details.headers[header]);if("data"in details)oXhr.send(details.data);else oXhr.send()}else throw"This Browser is not supported, please upgrade.";};if(typeof GM_addStyle==="undefined"){function GM_addStyle(styles){var head=document.getElementsByTagName("head")[0];if(head===undefined)document.onreadystatechange=function(){if(document.readyState=="interactive"){var oStyle=document.createElement("style");oStyle.setAttribute("type","text/css");oStyle.appendChild(document.createTextNode(styles));document.getElementsByTagName("head")[0].appendChild(oStyle)}};else{var oStyle=document.createElement("style");oStyle.setAttribute("type","text/css");oStyle.appendChild(document.createTextNode(styles));head.appendChild(oStyle)}}}if(typeof GM_log==="undefined"){function GM_log(log){if(console)console.log(log)}}if(typeof GM_openInTab==="undefined"){function GM_openInTab(url){window.open(url)}}var unsafeWindow=window;window.wrappedJSObject=unsafeWindow;if(typeof GM_registerMenuCommand==="undefined"){function GM_registerMenuCommand(caption,commandFunc,accessKey){}}if(typeof GM_getResourceText==="undefined"){function GM_getResourceText(resourceName){throw"QupZilla: GM Resource is not supported!";}}if(typeof GM_getResourceURL==="undefined"){function GM_getResourceURL(resourceName){throw"QupZilla: GM Resource is not supported!";}}if(typeof GM_getValue==="undefined"){function GM_getValue(name,defaultValue){return defaultValue}}if(typeof GM_setValue==="undefined"){function GM_setValue(name,value){}}if(typeof GM_deleteValue==="undefined"){function GM_deleteValue(name){}}if(typeof GM_listValues==="undefined"){function GM_listValues(){return new Array("")}};

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,94 @@
/* ============================================================
* GreaseMonkey plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#include "gm_addscriptdialog.h"
#include "ui_gm_addscriptdialog.h"
#include "gm_script.h"
#include "gm_manager.h"
#include "gm_notification.h"
#include "mainapplication.h"
#include "qupzilla.h"
#include "tabwidget.h"
#include "tabbedwebview.h"
#include "globalfunctions.h"
#include <QFile>
#include <QDir>
GM_AddScriptDialog::GM_AddScriptDialog(GM_Manager* manager, GM_Script* script, QWidget* parent)
: QDialog(parent)
, ui(new Ui::GM_AddScriptDialog)
, m_manager(manager)
, m_script(script)
{
ui->setupUi(this);
QString runsAt;
QString dontRunsAt;
const QStringList &include = script->include();
const QStringList &exclude = script->exclude();
if (!include.isEmpty()) {
runsAt = tr("<p>runs at<br/><i>%1</i></p>").arg(include.join("<br/>"));
}
if (!exclude.isEmpty()) {
dontRunsAt = tr("<p>does not run at<br/><i>%1</i></p>").arg(exclude.join("<br/>"));
}
QString scriptInfo = QString("<b>%1</b> %2<br/>%3 %4 %5").arg(script->name(), script->version(), script->description(), runsAt, dontRunsAt);
ui->textBrowser->setText(scriptInfo);
connect(ui->showSource, SIGNAL(clicked()), this, SLOT(showSource()));
connect(this, SIGNAL(accepted()), this, SLOT(accepted()));
}
void GM_AddScriptDialog::showSource()
{
QupZilla* qz = mApp->getWindow();
if (!qz) {
return;
}
const QString &tmpFileName = qz_ensureUniqueFilename(QDir::tempPath() + "/tmp-userscript.js");
if (QFile::copy(m_script->fileName(), tmpFileName)) {
int index = qz->tabWidget()->addView(QUrl::fromLocalFile(tmpFileName), Qz::NT_SelectedTabAtTheEnd);
TabbedWebView* view = qz->weView(index);
view->addNotification(new GM_Notification(m_manager, tmpFileName, m_script->fileName()));
}
reject();
}
void GM_AddScriptDialog::accepted()
{
QString message = tr("Cannot install script");
if (m_manager->addScript(m_script)) {
message = tr("'%1' installed successfully").arg(m_script->name());
}
m_manager->showNotification(message);
}
GM_AddScriptDialog::~GM_AddScriptDialog()
{
delete ui;
}

View File

@ -0,0 +1,51 @@
/* ============================================================
* GreaseMonkey plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#ifndef GM_ADDSCRIPTDIALOG_H
#define GM_ADDSCRIPTDIALOG_H
#include <QDialog>
namespace Ui
{
class GM_AddScriptDialog;
}
class GM_Script;
class GM_Manager;
class GM_AddScriptDialog : public QDialog
{
Q_OBJECT
public:
explicit GM_AddScriptDialog(GM_Manager* manager, GM_Script* script, QWidget* parent);
~GM_AddScriptDialog();
private slots:
void showSource();
void accepted();
private:
Ui::GM_AddScriptDialog* ui;
GM_Manager* m_manager;
GM_Script* m_script;
};
#endif // GM_ADDSCRIPTDIALOG_H

View File

@ -0,0 +1,169 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GM_AddScriptDialog</class>
<widget class="QDialog" name="GM_AddScriptDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>422</width>
<height>379</height>
</rect>
</property>
<property name="windowTitle">
<string>GreaseMonkey Installation</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="greasemonkey.qrc">:/gm/data/icon.png</pixmap>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>&lt;h3&gt;GreaseMonkey Installation&lt;/h3&gt;</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>You are about to install this userscript into GreaseMonkey:</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QTextBrowser" name="textBrowser"/>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>&lt;b&gt;You should only install scripts from sources you trust!&lt;/b&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Are you sure you want to install it?</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="showSource">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Show source code of script</string>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::No|QDialogButtonBox::Yes</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources>
<include location="greasemonkey.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>GM_AddScriptDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>GM_AddScriptDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -0,0 +1,155 @@
/* ============================================================
* GreaseMonkey plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#include "gm_downloader.h"
#include "gm_addscriptdialog.h"
#include "gm_manager.h"
#include "gm_script.h"
#include "webpage.h"
#include "followredirectreply.h"
#include "mainapplication.h"
#include "networkmanager.h"
#include "globalfunctions.h"
#include <QFile>
#include <QSettings>
#include <QRegExp>
#include <QDebug>
GM_Downloader::GM_Downloader(const QNetworkRequest &request, GM_Manager* manager)
: QObject()
, m_manager(manager)
{
m_reply = new FollowRedirectReply(request.url(), mApp->networkManager());
connect(m_reply, SIGNAL(finished()), this, SLOT(scriptDownloaded()));
QVariant v = request.attribute((QNetworkRequest::Attribute)(QNetworkRequest::User + 100));
WebPage* webPage = static_cast<WebPage*>(v.value<void*>());
if (WebPage::isPointerSafeToUse(webPage)) {
m_widget = webPage->view();
}
}
void GM_Downloader::scriptDownloaded()
{
if (m_reply != qobject_cast<FollowRedirectReply*>(sender())) {
deleteLater();
return;
}
QByteArray response = m_reply->readAll();
if (m_reply->error() == QNetworkReply::NoError && response.contains("// ==UserScript==")) {
const QString &filePath = m_manager->scriptsDirectory() + qz_getFileNameFromUrl(m_reply->url());
m_fileName = qz_ensureUniqueFilename(filePath);
QFile file(m_fileName);
if (!file.open(QFile::WriteOnly)) {
qWarning() << "GreaseMonkey: Cannot open file for writing" << m_fileName;
deleteLater();
return;
}
file.write(response);
file.close();
QSettings settings(m_manager->settinsPath() + "greasemonkey/requires/requires.ini", QSettings::IniFormat);
settings.beginGroup("Files");
QRegExp rx("@require(.*)\\n");
rx.setMinimal(true);
rx.indexIn(response);
for (int i = 1; i <= rx.captureCount(); ++i) {
const QString &url = rx.cap(i).trimmed();
if (!url.isEmpty() && !settings.contains(url)) {
m_requireUrls.append(QUrl(url));
}
}
}
m_reply->deleteLater();
m_reply = 0;
downloadRequires();
}
void GM_Downloader::requireDownloaded()
{
if (m_reply != qobject_cast<FollowRedirectReply*>(sender())) {
deleteLater();
return;
}
QByteArray response = m_reply->readAll();
if (m_reply->error() == QNetworkReply::NoError && !response.isEmpty()) {
const QString &filePath = m_manager->settinsPath() + "/greasemonkey/requires/require.js";
const QString &fileName = qz_ensureUniqueFilename(filePath, "%1");
QFile file(fileName);
if (!file.open(QFile::WriteOnly)) {
qWarning() << "GreaseMonkey: Cannot open file for writing" << fileName;
deleteLater();
return;
}
file.write(response);
file.close();
QSettings settings(m_manager->settinsPath() + "greasemonkey/requires/requires.ini", QSettings::IniFormat);
settings.beginGroup("Files");
settings.setValue(m_reply->originalUrl().toString(), fileName);
}
m_reply->deleteLater();
m_reply = 0;
downloadRequires();
}
void GM_Downloader::downloadRequires()
{
if (!m_requireUrls.isEmpty()) {
m_reply = new FollowRedirectReply(m_requireUrls.takeFirst(), mApp->networkManager());
connect(m_reply, SIGNAL(finished()), this, SLOT(requireDownloaded()));
}
else {
bool deleteScript = true;
GM_Script* script = new GM_Script(m_manager, m_fileName);
if (script->isValid()) {
if (!m_manager->containsScript(script->fullName())) {
GM_AddScriptDialog dialog(m_manager, script, m_widget);
deleteScript = dialog.exec() != QDialog::Accepted;
}
else {
m_manager->showNotification(tr("'%1' is already installed").arg(script->name()));
}
}
if (deleteScript) {
delete script;
QFile(m_fileName).remove();
}
deleteLater();
}
}

View File

@ -0,0 +1,57 @@
/* ============================================================
* GreaseMonkey plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#ifndef GM_DOWNLOADER_H
#define GM_DOWNLOADER_H
#include <QObject>
#include <QList>
#include <QUrl>
class QNetworkRequest;
class GM_Manager;
class FollowRedirectReply;
class GM_Downloader : public QObject
{
Q_OBJECT
public:
explicit GM_Downloader(const QNetworkRequest &request, GM_Manager* manager);
signals:
public slots:
private slots:
void scriptDownloaded();
void requireDownloaded();
private:
void downloadRequires();
GM_Manager* m_manager;
FollowRedirectReply* m_reply;
QWidget* m_widget;
QString m_fileName;
QList<QUrl> m_requireUrls;
};
#endif // GM_DOWNLOADER_H

View File

@ -0,0 +1,241 @@
/* ============================================================
* GreaseMonkey plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#include "gm_manager.h"
#include "gm_script.h"
#include "gm_downloader.h"
#include "settings/gm_settings.h"
#include "webpage.h"
#include "globalfunctions.h"
#include "mainapplication.h"
#include "desktopnotificationsfactory.h"
#include <QTimer>
#include <QDir>
#include <QWebFrame>
#include <QSettings>
#include <QDebug>
GM_Manager::GM_Manager(const QString &sPath, QObject* parent)
: QObject(parent)
, m_settingsPath(sPath)
{
QTimer::singleShot(0, this, SLOT(load()));
}
void GM_Manager::showSettings(QWidget* parent)
{
GM_Settings settings(this, parent);
settings.exec();
}
void GM_Manager::downloadScript(const QNetworkRequest &request)
{
new GM_Downloader(request, this);
}
QString GM_Manager::settinsPath() const
{
return m_settingsPath;
}
QString GM_Manager::scriptsDirectory() const
{
return m_settingsPath + "/greasemonkey/";
}
QString GM_Manager::requireScripts(const QStringList &urlList) const
{
QDir requiresDir(m_settingsPath + "greasemonkey/requires");
if (!requiresDir.exists() || urlList.isEmpty()) {
return QString();
}
QSettings settings(m_settingsPath + "greasemonkey/requires/requires.ini", QSettings::IniFormat);
settings.beginGroup("Files");
QString script;
foreach(const QString & url, urlList) {
if (settings.contains(url)) {
const QString &fileName = settings.value(url).toString();
script.append(qz_readAllFileContents(fileName).trimmed() + '\n');
}
}
return script;
}
void GM_Manager::saveSettings()
{
QSettings settings(m_settingsPath + "extensions.ini", QSettings::IniFormat);
settings.beginGroup("GreaseMonkey");
settings.setValue("disabledScripts", m_disabledScripts);
}
QList<GM_Script*> GM_Manager::allScripts() const
{
QList<GM_Script*> list;
list.append(m_startScripts);
list.append(m_endScripts);
return list;
}
bool GM_Manager::containsScript(const QString &fullName) const
{
foreach(GM_Script * script, m_startScripts) {
if (fullName == script->fullName()) {
return true;
}
}
foreach(GM_Script * script, m_endScripts) {
if (fullName == script->fullName()) {
return true;
}
}
return false;
}
void GM_Manager::enableScript(GM_Script* script)
{
script->setEnabled(true);
m_disabledScripts.removeOne(script->fullName());
}
void GM_Manager::disableScript(GM_Script* script)
{
script->setEnabled(false);
m_disabledScripts.append(script->fullName());
}
bool GM_Manager::addScript(GM_Script* script)
{
if (!script) {
return false;
}
if (script->startAt() == GM_Script::DocumentStart) {
m_startScripts.append(script);
}
else {
m_endScripts.append(script);
}
emit scriptsChanged();
return true;
}
bool GM_Manager::removeScript(GM_Script* script)
{
if (!script) {
return false;
}
if (script->startAt() == GM_Script::DocumentStart) {
m_startScripts.removeOne(script);
}
else {
m_endScripts.removeOne(script);
}
m_disabledScripts.removeOne(script->fullName());
QFile::remove(script->fileName());
delete script;
emit scriptsChanged();
return true;
}
void GM_Manager::showNotification(const QString &message, const QString &title)
{
QPixmap icon(":gm/data/icon.png");
mApp->desktopNotifications()->showNotification(icon, title.isEmpty() ? tr("GreaseMonkey") : title, message);
}
void GM_Manager::pageLoadStart()
{
QWebFrame* frame = qobject_cast<QWebFrame*>(sender());
if (!frame) {
return;
}
const QString &urlScheme = frame->url().scheme();
const QString &urlString = frame->url().toEncoded();
if (!canRunOnScheme(urlScheme)) {
return;
}
foreach(GM_Script * script, m_startScripts) {
if (script->match(urlString)) {
frame->evaluateJavaScript(m_bootstrap + script->script());
}
}
foreach(GM_Script * script, m_endScripts) {
if (script->match(urlString)) {
const QString &jscript = QString("window.addEventListener(\"DOMContentLoaded\","
"function(e) { %1 }, false);").arg(m_bootstrap + script->script());
frame->evaluateJavaScript(jscript);
}
}
}
void GM_Manager::load()
{
QDir gmDir(m_settingsPath + "greasemonkey");
if (!gmDir.exists()) {
gmDir.mkdir(m_settingsPath + "greasemonkey");
}
if (!gmDir.exists("requires")) {
gmDir.mkdir("requires");
}
QSettings settings(m_settingsPath + "extensions.ini", QSettings::IniFormat);
settings.beginGroup("GreaseMonkey");
m_disabledScripts = settings.value("disabledScripts", QStringList()).toStringList();
foreach(const QString & fileName, gmDir.entryList(QStringList("*.js"), QDir::Files)) {
const QString &absolutePath = gmDir.absoluteFilePath(fileName);
GM_Script* script = new GM_Script(this, absolutePath);
if (m_disabledScripts.contains(script->fullName())) {
script->setEnabled(false);
}
if (script->startAt() == GM_Script::DocumentStart) {
m_startScripts.append(script);
}
else {
m_endScripts.append(script);
}
}
m_bootstrap = qz_readAllFileContents(":gm/data/bootstrap.min.js");
}
bool GM_Manager::canRunOnScheme(const QString &scheme)
{
return (scheme == "http" || scheme == "https" || scheme == "data" || scheme == "ftp");
}

View File

@ -0,0 +1,75 @@
/* ============================================================
* GreaseMonkey plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#ifndef GM_MANAGER_H
#define GM_MANAGER_H
#include <QObject>
#include <QStringList>
class QUrl;
class QNetworkRequest;
class GM_Script;
class GM_Manager : public QObject
{
Q_OBJECT
public:
explicit GM_Manager(const QString &sPath, QObject* parent = 0);
void showSettings(QWidget* parent);
void downloadScript(const QNetworkRequest &request);
QString settinsPath() const;
QString scriptsDirectory() const;
QString requireScripts(const QStringList &urlList) const;
void saveSettings();
QList<GM_Script*> allScripts() const;
bool containsScript(const QString &fullName) const;
void enableScript(GM_Script* script);
void disableScript(GM_Script* script);
bool addScript(GM_Script* script);
bool removeScript(GM_Script* script);
void showNotification(const QString &message, const QString &title = QString());
static bool canRunOnScheme(const QString &scheme);
signals:
void scriptsChanged();
public slots:
void pageLoadStart();
private slots:
void load();
private:
QString m_settingsPath;
QString m_bootstrap;
QStringList m_disabledScripts;
QList<GM_Script*> m_endScripts;
QList<GM_Script*> m_startScripts;
};
#endif // GM_MANAGER_H

View File

@ -0,0 +1,68 @@
/* ============================================================
* GreaseMonkey plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#include "gm_notification.h"
#include "ui_gm_notification.h"
#include "gm_manager.h"
#include "gm_script.h"
#include "iconprovider.h"
#include <QFile>
GM_Notification::GM_Notification(GM_Manager* manager, const QString &tmpfileName, const QString &fileName)
: AnimatedWidget(AnimatedWidget::Down, 300, 0)
, ui(new Ui::GM_Notification)
, m_manager(manager)
, m_tmpFileName(tmpfileName)
, m_fileName(fileName)
{
ui->setupUi(widget());
ui->close->setIcon(qIconProvider->standardIcon(QStyle::SP_DialogCloseButton));
connect(ui->install, SIGNAL(clicked()), this, SLOT(installScript()));
connect(ui->close, SIGNAL(clicked()), this, SLOT(hide()));
startAnimation();
}
void GM_Notification::installScript()
{
bool success = false;
GM_Script* script = 0;
QString message = tr("Cannot install script");
if (QFile::copy(m_tmpFileName, m_fileName)) {
script = new GM_Script(m_manager, m_fileName);
success = m_manager->addScript(script);
}
if (success) {
message = tr("'%1' installed successfully").arg(script->name());
}
m_manager->showNotification(message);
hide();
}
GM_Notification::~GM_Notification()
{
delete ui;
}

View File

@ -0,0 +1,51 @@
/* ============================================================
* GreaseMonkey plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#ifndef GM_NOTIFICATION_H
#define GM_NOTIFICATION_H
#include "animatedwidget.h"
namespace Ui
{
class GM_Notification;
}
class GM_Manager;
class GM_Script;
class GM_Notification : public AnimatedWidget
{
Q_OBJECT
public:
explicit GM_Notification(GM_Manager* manager, const QString &tmpfileName, const QString &fileName);
~GM_Notification();
private slots:
void installScript();
private:
Ui::GM_Notification* ui;
GM_Manager* m_manager;
QString m_tmpFileName;
QString m_fileName;
};
#endif // GM_NOTIFICATION_H

View File

@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GM_Notification</class>
<widget class="QWidget" name="GM_Notification">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>820</width>
<height>36</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="topMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="minimumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="pixmap">
<pixmap resource="greasemonkey.qrc">:/gm/data/icon.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>This script can be installed with the GreaseMonkey plugin.</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="install">
<property name="text">
<string>Install</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="close">
<property name="text">
<string/>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="greasemonkey.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -0,0 +1,103 @@
/* ============================================================
* GreaseMonkey plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#include "gm_plugin.h"
#include "gm_manager.h"
#include "qupzilla.h"
#include "webpage.h"
#include "pluginproxy.h"
#include "mainapplication.h"
#include "emptynetworkreply.h"
#include <QTranslator>
#include <QNetworkRequest>
GM_Plugin::GM_Plugin()
: QObject()
, m_manager(0)
{
}
PluginSpec GM_Plugin::pluginSpec()
{
PluginSpec spec;
spec.name = "GreaseMonkey";
spec.info = "Userscripts for QupZilla";
spec.description = "Provides support for userscripts (www.userscripts.org)";
spec.version = "0.1.1";
spec.author = "David Rosca <nowrep@gmail.com>";
spec.icon = QPixmap(":gm/data/icon.png");
spec.hasSettings = true;
return spec;
}
void GM_Plugin::init(const QString &sPath)
{
m_manager = new GM_Manager(sPath, this);
m_settingsPath = sPath;
connect(mApp->plugins(), SIGNAL(webPageCreated(WebPage*)), this, SLOT(webPageCreated(WebPage*)));
}
void GM_Plugin::unload()
{
m_manager->saveSettings();
delete m_manager;
}
bool GM_Plugin::testPlugin()
{
return (QupZilla::VERSION == "1.3.0");
}
QTranslator* GM_Plugin::getTranslator(const QString &locale)
{
QTranslator* translator = new QTranslator(this);
translator->load(locale, ":/gm/locale/");
return translator;
}
void GM_Plugin::showSettings(QWidget* parent)
{
m_manager->showSettings(parent);
}
QNetworkReply* GM_Plugin::createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice* outgoingData)
{
Q_UNUSED(outgoingData)
int type = request.attribute((QNetworkRequest::Attribute)(QNetworkRequest::User + 101), -1).toInt();
if (op == QNetworkAccessManager::GetOperation && QWebPage::NavigationType(type) == QWebPage::NavigationTypeLinkClicked) {
const QString &urlString = request.url().toString(QUrl::RemoveFragment | QUrl::RemoveQuery);
if (urlString.endsWith(".user.js")) {
m_manager->downloadScript(request);
return new EmptyNetworkReply;
}
}
return 0;
}
void GM_Plugin::webPageCreated(WebPage* page)
{
connect(page->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), m_manager, SLOT(pageLoadStart()));
}
Q_EXPORT_PLUGIN2(GreaseMonkey, GM_Plugin)

View File

@ -0,0 +1,52 @@
/* ============================================================
* GreaseMonkey plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#ifndef GM_PLUGIN_H
#define GM_PLUGIN_H
#include "plugininterface.h"
class WebPage;
class GM_Manager;
class GM_Plugin : public QObject, public PluginInterface
{
Q_OBJECT
Q_INTERFACES(PluginInterface)
public:
explicit GM_Plugin();
PluginSpec pluginSpec();
void init(const QString &sPath);
void unload();
bool testPlugin();
QTranslator* getTranslator(const QString &locale);
void showSettings(QWidget* parent = 0);
QNetworkReply* createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice* outgoingData);
private slots:
void webPageCreated(WebPage* page);
private:
GM_Manager* m_manager;
QString m_settingsPath;
};
#endif // GM_PLUGIN_H

View File

@ -0,0 +1,236 @@
/* ============================================================
* GreaseMonkey plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#include "gm_script.h"
#include "gm_manager.h"
#include <QFile>
#include <QRegExp>
#include <QStringList>
#include <QWebFrame>
#include <QDebug>
#include <QElapsedTimer>
GM_Script::GM_Script(GM_Manager* manager, const QString &filePath)
: m_manager(manager)
, m_namespace("GreaseMonkeyNS")
, m_startAt(DocumentEnd)
, m_fileName(filePath)
, m_enabled(true)
, m_valid(false)
{
parseScript(filePath);
}
bool GM_Script::isValid() const
{
return m_valid;
}
QString GM_Script::name() const
{
return m_name;
}
QString GM_Script::nameSpace() const
{
return m_namespace;
}
QString GM_Script::fullName() const
{
return QString("%1/%2").arg(m_namespace, m_name);
}
QString GM_Script::description() const
{
return m_description;
}
QString GM_Script::version() const
{
return m_version;
}
QUrl GM_Script::downloadUrl() const
{
return m_downloadUrl;
}
GM_Script::StartAt GM_Script::startAt() const
{
return m_startAt;
}
bool GM_Script::isEnabled() const
{
return m_enabled;
}
void GM_Script::setEnabled(bool enable)
{
m_enabled = enable;
}
QStringList GM_Script::include() const
{
QStringList list;
foreach(const GM_UrlMatcher & matcher, m_include) {
list.append(matcher.pattern());
}
return list;
}
QStringList GM_Script::exclude() const
{
QStringList list;
foreach(const GM_UrlMatcher & matcher, m_exclude) {
list.append(matcher.pattern());
}
return list;
}
QString GM_Script::script() const
{
return m_script;
}
QString GM_Script::fileName() const
{
return m_fileName;
}
bool GM_Script::match(const QString &urlString)
{
if (!m_enabled) {
return false;
}
foreach(const GM_UrlMatcher & matcher, m_exclude) {
if (matcher.match(urlString)) {
return false;
}
}
foreach(const GM_UrlMatcher & matcher, m_include) {
if (matcher.match(urlString)) {
return true;
}
}
return false;
}
void GM_Script::parseScript(const QString &filePath)
{
QFile file(filePath);
if (!file.open(QFile::ReadOnly)) {
qWarning() << "GreaseMonkey: Cannot open file for reading" << filePath;
return;
}
QString fileData = QString::fromUtf8(file.readAll());
QRegExp rx("// ==UserScript==(.*)// ==/UserScript==");
rx.indexIn(fileData);
QString metadataBlock = rx.cap(1).trimmed();
if (metadataBlock.isEmpty()) {
qWarning() << "GreaseMonkey: File does not contain metadata block" << filePath;
return;
}
QStringList requireList;
const QStringList &lines = metadataBlock.split('\n');
foreach(QString line, lines) {
if (!line.startsWith("// @")) {
continue;
}
line = line.mid(3).replace('\t', ' ');
int index = line.indexOf(' ');
if (index < 0) {
continue;
}
const QString &key = line.left(index).trimmed();
const QString &value = line.mid(index + 1).trimmed();
// Ignored values:
// @resource
// @unwrap
if (key.isEmpty() || value.isEmpty()) {
continue;
}
if (key == "@name") {
m_name = value;
}
else if (key == "@namespace") {
m_namespace = value;
}
else if (key == "@description") {
m_description = value;
}
else if (key == "@version") {
m_version = value;
}
else if (key == "@updateURL") {
m_downloadUrl = QUrl(value);
}
else if (key == "@include" || key == "@match") {
m_include.append(GM_UrlMatcher(value));
}
else if (key == "@exclude" || key == "@exclude_match") {
m_exclude.append(GM_UrlMatcher(value));
}
else if (key == "@require") {
requireList.append(value);
}
else if (key == "@run-at") {
if (value == "document-end") {
m_startAt = DocumentEnd;
}
else if (value == "document-start") {
m_startAt = DocumentStart;
}
}
else if (key == "@downloadURL" && m_downloadUrl.isEmpty()) {
m_downloadUrl = QUrl(value);
}
}
if (m_include.isEmpty()) {
m_include.append(GM_UrlMatcher("*"));
}
int index = fileData.indexOf("// ==/UserScript==") + 18;
QString script = fileData.mid(index).trimmed();
script.prepend(m_manager->requireScripts(requireList));
script = QString("(function(){%1})();").arg(script);
m_script = script;
m_valid = !script.isEmpty();
}

View File

@ -0,0 +1,83 @@
/* ============================================================
* GreaseMonkey plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#ifndef GM_SCRIPT_H
#define GM_SCRIPT_H
#include "gm_urlmatcher.h"
#include <QObject>
#include <QList>
#include <QUrl>
class QWebFrame;
class GM_Manager;
class GM_UrlMatcher;
class GM_Script
{
public:
GM_Script(GM_Manager* manager, const QString &filePath);
enum StartAt { DocumentStart, DocumentEnd };
bool isValid() const;
QString name() const;
QString nameSpace() const;
QString fullName() const;
QString description() const;
QString version() const;
QUrl downloadUrl() const;
StartAt startAt() const;
bool isEnabled() const;
void setEnabled(bool enable);
QStringList include() const;
QStringList exclude() const;
QString script() const;
QString fileName() const;
bool match(const QString &urlString);
private:
void parseScript(const QString &filePath);
GM_Manager* m_manager;
QString m_name;
QString m_namespace;
QString m_description;
QString m_version;
QList<GM_UrlMatcher> m_include;
QList<GM_UrlMatcher> m_exclude;
QUrl m_downloadUrl;
StartAt m_startAt;
QString m_script;
QString m_fileName;
bool m_enabled;
bool m_valid;
};
#endif // GM_SCRIPT_H

View File

@ -0,0 +1,103 @@
/* ============================================================
* GreaseMonkey plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#include "gm_urlmatcher.h"
#include <QDebug>
#include <QStringList>
bool wildcardMatch(const QString &string, const QString &pattern)
{
int stringSize = string.size();
int patternSize = pattern.size();
bool startsWithWildcard = pattern[0] == '*';
bool endsWithWildcard = pattern[patternSize - 1] == '*';
const QStringList &parts = pattern.split('*');
int pos = 0;
if (startsWithWildcard) {
pos = string.indexOf(parts.at(1));
if (pos == -1) {
return false;
}
}
foreach(const QString & part, parts) {
pos = string.indexOf(part, pos);
if (pos == -1) {
return false;
}
}
if (!endsWithWildcard && stringSize - pos != parts.last().size()) {
return false;
}
return true;
}
GM_UrlMatcher::GM_UrlMatcher(const QString &pattern)
: m_pattern(pattern)
, m_useRegExp(false)
{
parsePattern(m_pattern);
}
QString GM_UrlMatcher::pattern() const
{
return m_pattern;
}
bool GM_UrlMatcher::match(const QString &urlString) const
{
if (m_useRegExp) {
return m_regExp.indexIn(urlString) != -1;
}
else {
return wildcardMatch(urlString, m_matchString);
}
}
void GM_UrlMatcher::parsePattern(QString pattern)
{
if (pattern.startsWith('/') && pattern.endsWith('/')) {
pattern = pattern.mid(1);
pattern = pattern.left(pattern.size() - 1);
m_regExp = QRegExp(pattern, Qt::CaseInsensitive);
m_useRegExp = true;
return;
}
if (pattern.contains(".tld")) {
pattern.replace(QRegExp("(\\W)"), "\\\\1")
.replace(QRegExp("\\*+"), "*")
.replace(QRegExp("^\\\\\\|"), "^")
.replace(QRegExp("\\\\\\|$"), "$")
.replace(QRegExp("\\\\\\*"), ".*")
.replace("\\.tld", "\\.[a-z.]{2,6}");
m_useRegExp = true;
m_regExp = QRegExp(pattern, Qt::CaseInsensitive);
}
else {
m_matchString = pattern;
}
}

View File

@ -0,0 +1,44 @@
/* ============================================================
* GreaseMonkey plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#ifndef GM_URLMATCHER_H
#define GM_URLMATCHER_H
#include <QString>
#include <QRegExp>
class GM_UrlMatcher
{
public:
GM_UrlMatcher(const QString &pattern);
QString pattern() const;
bool match(const QString &urlString) const;
private:
void parsePattern(QString pattern);
QString m_pattern;
QString m_matchString;
QRegExp m_regExp;
bool m_useRegExp;
};
#endif // GM_URLMATCHER_H

View File

@ -0,0 +1,12 @@
<RCC>
<qresource prefix="/gm">
<file>data/icon.png</file>
<file>data/bootstrap.min.js</file>
<file>data/script.png</file>
<file>locale/cs_CZ.qm</file>
<file>locale/de_DE.qm</file>
<file>locale/fr_FR.qm</file>
<file>locale/sr_BA.qm</file>
<file>locale/sr_RS.qm</file>
</qresource>
</RCC>

View File

@ -0,0 +1,154 @@
/* ============================================================
* GreaseMonkey plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#include "gm_settings.h"
#include "ui_gm_settings.h"
#include "gm_settingsscriptinfo.h"
#include "../gm_manager.h"
#include "../gm_script.h"
#include "mainapplication.h"
#include <QDesktopServices>
#include <QMessageBox>
GM_Settings::GM_Settings(GM_Manager* manager, QWidget* parent)
: QDialog(parent)
, ui(new Ui::GM_Settings)
, m_manager(manager)
{
ui->setupUi(this);
connect(ui->listWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(showItemInfo(QListWidgetItem*)));
connect(ui->listWidget, SIGNAL(removeItemRequested(QListWidgetItem*)), this, SLOT(removeItem(QListWidgetItem*)));
connect(ui->openDirectory, SIGNAL(clicked()), this, SLOT(openScriptsDirectory()));
connect(ui->link, SIGNAL(clicked(QPoint)), this, SLOT(openUserscripts()));
loadScripts();
}
void GM_Settings::openUserscripts()
{
mApp->addNewTab(QUrl("http://www.userscripts.org"));
close();
}
void GM_Settings::showItemInfo(QListWidgetItem* item)
{
GM_Script* script = getScript(item);
if (!script) {
return;
}
GM_SettingsScriptInfo info(script, this);
info.exec();
}
void GM_Settings::removeItem(QListWidgetItem* item)
{
GM_Script* script = getScript(item);
if (!script) {
return;
}
QMessageBox::StandardButton button = QMessageBox::question(this, tr("Remove script"),
tr("Are you sure you want to remove '%1'?").arg(script->name()),
QMessageBox::Yes | QMessageBox::No);
if (button == QMessageBox::Yes && m_manager->removeScript(script)) {
delete item;
}
}
void GM_Settings::itemChanged(QListWidgetItem* item)
{
GM_Script* script = getScript(item);
if (!script) {
return;
}
if (item->checkState() == Qt::Checked) {
m_manager->enableScript(script);
}
else {
m_manager->disableScript(script);
}
}
void GM_Settings::openScriptsDirectory()
{
QDesktopServices::openUrl(QUrl::fromLocalFile(m_manager->scriptsDirectory()));
}
void GM_Settings::loadScripts()
{
disconnect(ui->listWidget, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*)));
foreach(GM_Script * script, m_manager->allScripts()) {
QListWidgetItem* item = new QListWidgetItem(ui->listWidget);
QIcon icon = QIcon(":/gm/data/script.png");
item->setIcon(icon);
item->setText(script->name());
item->setData(Qt::UserRole, script->version());
item->setData(Qt::UserRole + 1, script->description());
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
item->setCheckState(script->isEnabled() ? Qt::Checked : Qt::Unchecked);
item->setData(Qt::UserRole + 10, qVariantFromValue((void*)script));
ui->listWidget->addItem(item);
}
ui->listWidget->sortItems();
bool itemMoved;
do {
itemMoved = false;
for (int i = 0; i < ui->listWidget->count(); ++i) {
QListWidgetItem* topItem = ui->listWidget->item(i);
QListWidgetItem* bottomItem = ui->listWidget->item(i + 1);
if (!topItem || !bottomItem) {
continue;
}
if (topItem->checkState() == Qt::Unchecked && bottomItem->checkState() == Qt::Checked) {
QListWidgetItem* item = ui->listWidget->takeItem(i + 1);
ui->listWidget->insertItem(i, item);
itemMoved = true;
}
}
}
while (itemMoved);
connect(ui->listWidget, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*)));
}
GM_Script* GM_Settings::getScript(QListWidgetItem* item)
{
if (!item) {
return 0;
}
GM_Script* script = static_cast<GM_Script*>(item->data(Qt::UserRole + 10).value<void*>());
return script;
}
GM_Settings::~GM_Settings()
{
delete ui;
}

View File

@ -0,0 +1,58 @@
/* ============================================================
* GreaseMonkey plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#ifndef GM_SETTINGS_H
#define GM_SETTINGS_H
#include <QDialog>
namespace Ui
{
class GM_Settings;
}
class QListWidgetItem;
class GM_Manager;
class GM_Script;
class GM_Settings : public QDialog
{
Q_OBJECT
public:
explicit GM_Settings(GM_Manager* manager, QWidget* parent = 0);
~GM_Settings();
private slots:
void showItemInfo(QListWidgetItem* item);
void removeItem(QListWidgetItem* item);
void itemChanged(QListWidgetItem* item);
void openScriptsDirectory();
void openUserscripts();
private:
void loadScripts();
inline GM_Script* getScript(QListWidgetItem* item);
Ui::GM_Settings* ui;
GM_Manager* m_manager;
};
#endif // GM_SETTINGS_H

View File

@ -0,0 +1,263 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GM_Settings</class>
<widget class="QDialog" name="GM_Settings">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>512</width>
<height>416</height>
</rect>
</property>
<property name="windowTitle">
<string>GreaseMonkey Scripts</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../greasemonkey.qrc">:/gm/data/icon.png</pixmap>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>&lt;h3&gt;GreaseMonkey Scripts&lt;/h3&gt;</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Double clicking script will show additional information</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="GM_SettingsListWidget" name="listWidget">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="uniformItemSizes">
<bool>true</bool>
</property>
<property name="selectionRectVisible">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>2</number>
</property>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>More scripts can be downloaded from</string>
</property>
</widget>
</item>
<item>
<widget class="ClickableLabel" name="link">
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="text">
<string notr="true">userscripts.org</string>
</property>
<property name="html-link-look" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QPushButton" name="openDirectory">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Open scripts directory</string>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ClickableLabel</class>
<extends>QLabel</extends>
<header>clickablelabel.h</header>
</customwidget>
<customwidget>
<class>GM_SettingsListWidget</class>
<extends>QListWidget</extends>
<header>settings/gm_settingslistwidget.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../greasemonkey.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>GM_Settings</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>GM_Settings</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -0,0 +1,136 @@
/* ============================================================
* GreaseMonkey plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#include "gm_settingslistdelegate.h"
#include "iconprovider.h"
#include <QPainter>
#include <QListWidget>
#include <QApplication>
GM_SettingsListDelegate::GM_SettingsListDelegate(QObject* parent)
: QStyledItemDelegate(parent)
, m_rowHeight(0)
, m_padding(0)
{
m_removePixmap = qIconProvider->standardIcon(QStyle::SP_DialogCloseButton).pixmap(16);
}
int GM_SettingsListDelegate::padding() const
{
return m_padding;
}
void GM_SettingsListDelegate::paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QStyleOptionViewItemV4 opt = option;
initStyleOption(&opt, index);
const QWidget* w = opt.widget;
const QStyle* style = w ? w->style() : QApplication::style();
const int height = opt.rect.height();
const int center = height / 2 + opt.rect.top();
// Prepare title font
QFont titleFont = opt.font;
titleFont.setBold(true);
titleFont.setPointSize(titleFont.pointSize() + 1);
const QFontMetrics titleMetrics(titleFont);
const QPalette::ColorRole colorRole = opt.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text;
int leftPosition = m_padding;
int rightPosition = opt.rect.right() - m_padding - 16; // 16 for remove button
// Draw background
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, w);
// Draw checkbox
const int checkboxSize = 18;
const int checkboxYPos = center - (checkboxSize / 2);
QStyleOptionViewItemV4 opt2 = opt;
opt2.checkState == Qt::Checked ? opt2.state |= QStyle::State_On : opt2.state |= QStyle::State_Off;
QRect styleCheckBoxRect = style->subElementRect(QStyle::SE_ViewItemCheckIndicator, &opt2, w);
opt2.rect = QRect(leftPosition, checkboxYPos, styleCheckBoxRect.width(), styleCheckBoxRect.height());
style->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &opt2, painter, w);
leftPosition = opt2.rect.right() + m_padding;
// Draw icon
const int iconSize = 32;
const int iconYPos = center - (iconSize / 2);
QRect iconRect(leftPosition, iconYPos, iconSize, iconSize);
QPixmap pixmap = index.data(Qt::DecorationRole).value<QIcon>().pixmap(iconSize);
painter->drawPixmap(iconRect, pixmap);
leftPosition = iconRect.right() + m_padding;
// Draw script name
const QString &name = index.data(Qt::DisplayRole).toString();
const int leftTitleEdge = leftPosition + 2;
const int rightTitleEdge = rightPosition - m_padding;
const int leftPosForVersion = titleMetrics.width(name) + m_padding;
QRect nameRect(leftTitleEdge, opt.rect.top() + m_padding, rightTitleEdge - leftTitleEdge, titleMetrics.height());
painter->setFont(titleFont);
style->drawItemText(painter, nameRect, Qt::AlignLeft, opt.palette, true, name, colorRole);
// Draw version
const QString &version = index.data(Qt::UserRole).toString();
QRect versionRect(nameRect.x() + leftPosForVersion, nameRect.y(), rightTitleEdge - leftPosForVersion, titleMetrics.height());
QFont versionFont = titleFont;
versionFont.setBold(false);
painter->setFont(versionFont);
style->drawItemText(painter, versionRect, Qt::AlignLeft, opt.palette, true, version, colorRole);
// Draw description
const int infoYPos = nameRect.bottom() + opt.fontMetrics.leading();
QRect infoRect(nameRect.x(), infoYPos, nameRect.width(), opt.fontMetrics.height());
const QString &info = opt.fontMetrics.elidedText(index.data(Qt::UserRole + 1).toString(), Qt::ElideRight, infoRect.width());
painter->setFont(opt.font);
style->drawItemText(painter, infoRect, Qt::TextSingleLine | Qt::AlignLeft, opt.palette, true, info, colorRole);
// Draw remove button
const int removeIconSize = 16;
const int removeIconYPos = center - (removeIconSize / 2);
QRect removeIconRect(rightPosition, removeIconYPos, removeIconSize, removeIconSize);
painter->drawPixmap(removeIconRect, m_removePixmap);
}
QSize GM_SettingsListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
Q_UNUSED(index)
if (!m_rowHeight) {
QStyleOptionViewItemV4 opt(option);
initStyleOption(&opt, index);
const QWidget* w = opt.widget;
const QStyle* style = w ? w->style() : QApplication::style();
const int padding = style->pixelMetric(QStyle::PM_FocusFrameHMargin, 0) + 1;
QFont titleFont = opt.font;
titleFont.setBold(true);
titleFont.setPointSize(titleFont.pointSize() + 1);
m_padding = padding > 5 ? padding : 5;
const QFontMetrics titleMetrics(titleFont);
m_rowHeight = 2 * m_padding + opt.fontMetrics.leading() + opt.fontMetrics.height() + titleMetrics.height();
}
return QSize(200, m_rowHeight);
}

View File

@ -0,0 +1,40 @@
/* ============================================================
* GreaseMonkey plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#ifndef GM_SETTINGSLISTDELEGATE_H
#define GM_SETTINGSLISTDELEGATE_H
#include <QStyledItemDelegate>
class GM_SettingsListDelegate : public QStyledItemDelegate
{
public:
explicit GM_SettingsListDelegate(QObject* parent = 0);
int padding() const;
void paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
private:
QPixmap m_removePixmap;
mutable int m_rowHeight;
mutable int m_padding;
};
#endif // GM_SETTINGSLISTDELEGATE_H

View File

@ -0,0 +1,66 @@
/* ============================================================
* GreaseMonkey plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#include "gm_settingslistwidget.h"
#include "gm_settingslistdelegate.h"
#include <QMouseEvent>
#include <QDebug>
GM_SettingsListWidget::GM_SettingsListWidget(QWidget* parent)
: QListWidget(parent)
, m_delegate(new GM_SettingsListDelegate(this))
{
setItemDelegate(m_delegate);
}
void GM_SettingsListWidget::mousePressEvent(QMouseEvent* event)
{
if (containsRemoveIcon(event->pos())) {
emit removeItemRequested(itemAt(event->pos()));
return;
}
QListWidget::mousePressEvent(event);
}
void GM_SettingsListWidget::mouseDoubleClickEvent(QMouseEvent* event)
{
if (containsRemoveIcon(event->pos())) {
emit removeItemRequested(itemAt(event->pos()));
return;
}
QListWidget::mouseDoubleClickEvent(event);
}
bool GM_SettingsListWidget::containsRemoveIcon(const QPoint &pos) const
{
QListWidgetItem* item = itemAt(pos);
if (!item) {
return false;
}
const QRect &rect = visualItemRect(item);
const int removeIconPosition = rect.right() - m_delegate->padding() - 16;
const int center = rect.height() / 2 + rect.top();
const int removeIconYPos = center - (16 / 2);
QRect removeIconRect(removeIconPosition, removeIconYPos, 16, 16);
return removeIconRect.contains(pos);
}

View File

@ -0,0 +1,46 @@
/* ============================================================
* GreaseMonkey plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#ifndef GM_SETTINGSLISTWIDGET_H
#define GM_SETTINGSLISTWIDGET_H
#include <QListWidget>
class GM_SettingsListDelegate;
class GM_SettingsListWidget : public QListWidget
{
Q_OBJECT
public:
explicit GM_SettingsListWidget(QWidget* parent = 0);
signals:
void removeItemRequested(QListWidgetItem* item);
public slots:
private:
bool containsRemoveIcon(const QPoint &pos) const;
void mousePressEvent(QMouseEvent* event);
void mouseDoubleClickEvent(QMouseEvent* event);
GM_SettingsListDelegate* m_delegate;
};
#endif // GM_SETTINGSLISTWIDGET_H

View File

@ -0,0 +1,41 @@
/* ============================================================
* GreaseMonkey plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#include "gm_settingsscriptinfo.h"
#include "ui_gm_settingsscriptinfo.h"
#include "../gm_script.h"
GM_SettingsScriptInfo::GM_SettingsScriptInfo(GM_Script* script, QWidget* parent) :
QDialog(parent),
ui(new Ui::GM_SettingsScriptInfo)
{
ui->setupUi(this);
setWindowTitle(tr("Script Details of %1").arg(script->name()));
ui->name->setText(script->fullName());
ui->version->setText(script->version());
ui->url->setText(script->downloadUrl().toString());
ui->startAt->setText(script->startAt() == GM_Script::DocumentStart ? "document-start" : "document-end");
ui->description->setText(script->description());
ui->include->setText(script->include().join("<br/>"));
ui->exclude->setText(script->exclude().join("<br/>"));
}
GM_SettingsScriptInfo::~GM_SettingsScriptInfo()
{
delete ui;
}

View File

@ -0,0 +1,42 @@
/* ============================================================
* GreaseMonkey plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#ifndef GM_SETTINGSSCRIPTINFO_H
#define GM_SETTINGSSCRIPTINFO_H
#include <QDialog>
namespace Ui
{
class GM_SettingsScriptInfo;
}
class GM_Script;
class GM_SettingsScriptInfo : public QDialog
{
Q_OBJECT
public:
explicit GM_SettingsScriptInfo(GM_Script* script, QWidget* parent = 0);
~GM_SettingsScriptInfo();
private:
Ui::GM_SettingsScriptInfo* ui;
};
#endif // GM_SETTINGSSCRIPTINFO_H

View File

@ -0,0 +1,191 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GM_SettingsScriptInfo</class>
<widget class="QDialog" name="GM_SettingsScriptInfo">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>485</width>
<height>408</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Name:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Version:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>URL:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Start at:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Description:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Runs at:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Does not run at:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="SqueezeLabelV2" name="name">
<property name="text">
<string/>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="startAt">
<property name="text">
<string/>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="SqueezeLabelV2" name="url">
<property name="text">
<string/>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="version">
<property name="text">
<string/>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QTextBrowser" name="description"/>
</item>
<item row="5" column="1">
<widget class="QTextBrowser" name="include"/>
</item>
<item row="6" column="1">
<widget class="QTextBrowser" name="exclude"/>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>SqueezeLabelV2</class>
<extends>QLabel</extends>
<header>squeezelabelv2.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>GM_SettingsScriptInfo</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>GM_SettingsScriptInfo</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -0,0 +1,177 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="cs_CZ">
<context>
<name>GM_AddScriptDialog</name>
<message>
<location filename="../gm_addscriptdialog.ui" line="14"/>
<source>GreaseMonkey Installation</source>
<translation>Instalace GreaseMonkey</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.ui" line="51"/>
<source>&lt;h3&gt;GreaseMonkey Installation&lt;/h3&gt;</source>
<translation>&lt;h3&gt;Instalace GreaseMonkey&lt;/h3&gt;</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.ui" line="73"/>
<source>You are about to install this userscript into GreaseMonkey:</source>
<translation>Chystáte se nainstalovat tento uživatelský skript do GreaseMonkey:</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.ui" line="86"/>
<source>&lt;b&gt;You should only install scripts from sources you trust!&lt;/b&gt;</source>
<translation>&lt;b&gt;Měli byste instalovat pouze scripty z ověřených zdrojů!&lt;b/&gt;</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.ui" line="96"/>
<source>Are you sure you want to install it?</source>
<translation>Opravdu chcete tento skript nainstalovat?</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.ui" line="114"/>
<source>Show source code of script</source>
<translation>Zobrazit zdrojový kód skriptu</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.cpp" line="48"/>
<source>&lt;p&gt;runs at&lt;br/&gt;&lt;i&gt;%1&lt;/i&gt;&lt;/p&gt;</source>
<translation>&lt;p&gt;spouští se na&lt;br/&gt;&lt;i&gt;%1&lt;/i&gt;&lt;/p&gt;</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.cpp" line="52"/>
<source>&lt;p&gt;does not run at&lt;br/&gt;&lt;i&gt;%1&lt;/i&gt;&lt;/p&gt;</source>
<translation>&lt;p&gt;nespouští se na&lt;br/&gt;&lt;i&gt;%1&lt;/i&gt;&lt;/p&gt;</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.cpp" line="82"/>
<source>Cannot install script</source>
<translation>Nelze nainstalovat skript</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.cpp" line="85"/>
<source>&apos;%1&apos; installed successfully</source>
<translation>&apos;%1&apos; úspěšně nainstalován</translation>
</message>
</context>
<context>
<name>GM_Downloader</name>
<message>
<location filename="../gm_downloader.cpp" line="144"/>
<source>&apos;%1&apos; is already installed</source>
<translation>&apos;%1&apos; již je nainstalován</translation>
</message>
</context>
<context>
<name>GM_Manager</name>
<message>
<location filename="../gm_manager.cpp" line="172"/>
<source>GreaseMonkey</source>
<translation>GreaseMonkey</translation>
</message>
</context>
<context>
<name>GM_Notification</name>
<message>
<location filename="../gm_notification.ui" line="45"/>
<source>This script can be installed with the GreaseMonkey plugin.</source>
<translation>Tento skript může být nainstalován do GreaseMonkey rozšíření.</translation>
</message>
<message>
<location filename="../gm_notification.ui" line="65"/>
<source>Install</source>
<translation>Instalovat</translation>
</message>
<message>
<location filename="../gm_notification.cpp" line="49"/>
<source>Cannot install script</source>
<translation>Nelze nainstalovat skript</translation>
</message>
<message>
<location filename="../gm_notification.cpp" line="57"/>
<source>&apos;%1&apos; installed successfully</source>
<translation>&apos;%1&apos; úspěšně nainstalován</translation>
</message>
</context>
<context>
<name>GM_Settings</name>
<message>
<location filename="../settings/gm_settings.ui" line="14"/>
<source>GreaseMonkey Scripts</source>
<translation>GreaseMonkey Skripty</translation>
</message>
<message>
<location filename="../settings/gm_settings.ui" line="51"/>
<source>&lt;h3&gt;GreaseMonkey Scripts&lt;/h3&gt;</source>
<translation>&lt;h3&gt;GreaseMonkey Skripty&lt;/h3&gt;</translation>
</message>
<message>
<location filename="../settings/gm_settings.ui" line="73"/>
<source>Double clicking script will show additional information</source>
<translation>Dvojtý klik na skript zobrazí podrobnosti</translation>
</message>
<message>
<location filename="../settings/gm_settings.ui" line="153"/>
<source>More scripts can be downloaded from</source>
<translation>Více skriptů lze stáhnout z</translation>
</message>
<message>
<location filename="../settings/gm_settings.ui" line="196"/>
<source>Open scripts directory</source>
<translation>Otevřít složku se skripty</translation>
</message>
<message>
<location filename="../settings/gm_settings.cpp" line="68"/>
<source>Remove script</source>
<translation>Odstranit skript</translation>
</message>
<message>
<location filename="../settings/gm_settings.cpp" line="69"/>
<source>Are you sure you want to remove &apos;%1&apos;?</source>
<translation>Opravdu chcete odstranit &apos;%1&apos;?</translation>
</message>
</context>
<context>
<name>GM_SettingsScriptInfo</name>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="19"/>
<source>Name:</source>
<translation>Název:</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="29"/>
<source>Version:</source>
<translation>Verze:</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="39"/>
<source>URL:</source>
<translation>URL:</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="49"/>
<source>Start at:</source>
<translation>Běží na:</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="59"/>
<source>Description:</source>
<translation>Popis:</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="69"/>
<source>Runs at:</source>
<translation>Spouští se na:</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="79"/>
<source>Does not run at:</source>
<translation>Nespouští se na:</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.cpp" line="27"/>
<source>Script Details of %1</source>
<translation>Detaily skriptu %1</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,177 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="de_DE">
<context>
<name>GM_AddScriptDialog</name>
<message>
<location filename="../gm_addscriptdialog.ui" line="14"/>
<source>GreaseMonkey Installation</source>
<translation>GreaseMonkey Installation</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.ui" line="51"/>
<source>&lt;h3&gt;GreaseMonkey Installation&lt;/h3&gt;</source>
<translation>&lt;h3&gt;GreaseMonkey Installation&lt;/h3&gt;</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.ui" line="73"/>
<source>You are about to install this userscript into GreaseMonkey:</source>
<translation>Sie sind im Begriff, dieses Skript in GreaseMonkey zu installieren:</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.ui" line="86"/>
<source>&lt;b&gt;You should only install scripts from sources you trust!&lt;/b&gt;</source>
<translation>&lt;b&gt;Installieren Sie nur Skripte aus vertrauenswürdigen Quellen!&lt;/b&gt;</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.ui" line="96"/>
<source>Are you sure you want to install it?</source>
<translation>Möchten Sie es wirklich installieren?</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.ui" line="114"/>
<source>Show source code of script</source>
<translation>Quelltext anzeigen</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.cpp" line="48"/>
<source>&lt;p&gt;runs at&lt;br/&gt;&lt;i&gt;%1&lt;/i&gt;&lt;/p&gt;</source>
<translation>&lt;p&gt;startet bei&lt;br/&gt;&lt;i&gt;%1&lt;/i&gt;&lt;/p&gt;</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.cpp" line="52"/>
<source>&lt;p&gt;does not run at&lt;br/&gt;&lt;i&gt;%1&lt;/i&gt;&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gm_addscriptdialog.cpp" line="82"/>
<source>Cannot install script</source>
<translation type="unfinished">Skript kann nicht installiert werden</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.cpp" line="85"/>
<source>&apos;%1&apos; installed successfully</source>
<translation type="unfinished">&apos;%1&apos; erfolgreich installiert</translation>
</message>
</context>
<context>
<name>GM_Downloader</name>
<message>
<location filename="../gm_downloader.cpp" line="144"/>
<source>&apos;%1&apos; is already installed</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>GM_Manager</name>
<message>
<location filename="../gm_manager.cpp" line="172"/>
<source>GreaseMonkey</source>
<translation>GreaseMonkey</translation>
</message>
</context>
<context>
<name>GM_Notification</name>
<message>
<location filename="../gm_notification.ui" line="45"/>
<source>This script can be installed with the GreaseMonkey plugin.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gm_notification.ui" line="65"/>
<source>Install</source>
<translation>Installieren</translation>
</message>
<message>
<location filename="../gm_notification.cpp" line="49"/>
<source>Cannot install script</source>
<translation type="unfinished">Skript kann nicht installiert werden</translation>
</message>
<message>
<location filename="../gm_notification.cpp" line="57"/>
<source>&apos;%1&apos; installed successfully</source>
<translation type="unfinished">&apos;%1&apos; erfolgreich installiert</translation>
</message>
</context>
<context>
<name>GM_Settings</name>
<message>
<location filename="../settings/gm_settings.ui" line="14"/>
<source>GreaseMonkey Scripts</source>
<translation>GreaseMonkey Skripte</translation>
</message>
<message>
<location filename="../settings/gm_settings.ui" line="51"/>
<source>&lt;h3&gt;GreaseMonkey Scripts&lt;/h3&gt;</source>
<translation>&lt;h3&gt;GreaseMonkey Skripte&lt;/h3&gt;</translation>
</message>
<message>
<location filename="../settings/gm_settings.ui" line="73"/>
<source>Double clicking script will show additional information</source>
<translation>Für weitere Informationen bitte doppelklicken</translation>
</message>
<message>
<location filename="../settings/gm_settings.ui" line="153"/>
<source>More scripts can be downloaded from</source>
<translation>Weitere Skripte herunterladen von</translation>
</message>
<message>
<location filename="../settings/gm_settings.ui" line="196"/>
<source>Open scripts directory</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/gm_settings.cpp" line="68"/>
<source>Remove script</source>
<translation>Skript entfernen</translation>
</message>
<message>
<location filename="../settings/gm_settings.cpp" line="69"/>
<source>Are you sure you want to remove &apos;%1&apos;?</source>
<translation>Möchten Sie &apos;%1&apos; wirklich entfernen?</translation>
</message>
</context>
<context>
<name>GM_SettingsScriptInfo</name>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="19"/>
<source>Name:</source>
<translation>Name:</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="29"/>
<source>Version:</source>
<translation>Version:</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="39"/>
<source>URL:</source>
<translation>URL:</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="49"/>
<source>Start at:</source>
<translation>Beginnen bei:</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="59"/>
<source>Description:</source>
<translation>Beschreibung:</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="69"/>
<source>Runs at:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="79"/>
<source>Does not run at:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.cpp" line="27"/>
<source>Script Details of %1</source>
<translation>Skript Details von %1</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,177 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="fr_FR">
<context>
<name>GM_AddScriptDialog</name>
<message>
<location filename="../gm_addscriptdialog.ui" line="14"/>
<source>GreaseMonkey Installation</source>
<translation>Installation de GreaseMonkey</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.ui" line="51"/>
<source>&lt;h3&gt;GreaseMonkey Installation&lt;/h3&gt;</source>
<translation>&lt;h3&gt;Installation de GreaseMonkey&lt;/h3&gt;</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.ui" line="73"/>
<source>You are about to install this userscript into GreaseMonkey:</source>
<translation>Vous êtes sur le point d&apos;installer ce script via GreaseMonkey :</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.ui" line="86"/>
<source>&lt;b&gt;You should only install scripts from sources you trust!&lt;/b&gt;</source>
<translation>&lt;b&gt;N&apos;installez que des script provenant de sources sûres !&lt;/b&gt;</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.ui" line="96"/>
<source>Are you sure you want to install it?</source>
<translation>Etes vous sûr de vouloir installer ce script ?</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.ui" line="114"/>
<source>Show source code of script</source>
<translation>Montrer le code source</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.cpp" line="48"/>
<source>&lt;p&gt;runs at&lt;br/&gt;&lt;i&gt;%1&lt;/i&gt;&lt;/p&gt;</source>
<translation>&lt;p&gt;Lancer&lt;br/&gt;&lt;i&gt;%1&lt;/i&gt;&lt;/p&gt;</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.cpp" line="52"/>
<source>&lt;p&gt;does not run at&lt;br/&gt;&lt;i&gt;%1&lt;/i&gt;&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gm_addscriptdialog.cpp" line="82"/>
<source>Cannot install script</source>
<translation type="unfinished">Installation du script impossible</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.cpp" line="85"/>
<source>&apos;%1&apos; installed successfully</source>
<translation type="unfinished">&apos;%1&apos; Installation réussie</translation>
</message>
</context>
<context>
<name>GM_Downloader</name>
<message>
<location filename="../gm_downloader.cpp" line="144"/>
<source>&apos;%1&apos; is already installed</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>GM_Manager</name>
<message>
<location filename="../gm_manager.cpp" line="172"/>
<source>GreaseMonkey</source>
<translation>GreaseMonkey</translation>
</message>
</context>
<context>
<name>GM_Notification</name>
<message>
<location filename="../gm_notification.ui" line="45"/>
<source>This script can be installed with the GreaseMonkey plugin.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../gm_notification.ui" line="65"/>
<source>Install</source>
<translation>Installer</translation>
</message>
<message>
<location filename="../gm_notification.cpp" line="49"/>
<source>Cannot install script</source>
<translation type="unfinished">Installation du script impossible</translation>
</message>
<message>
<location filename="../gm_notification.cpp" line="57"/>
<source>&apos;%1&apos; installed successfully</source>
<translation type="unfinished">&apos;%1&apos; Installation réussie</translation>
</message>
</context>
<context>
<name>GM_Settings</name>
<message>
<location filename="../settings/gm_settings.ui" line="14"/>
<source>GreaseMonkey Scripts</source>
<translation>Scripts de GreaseMonkey</translation>
</message>
<message>
<location filename="../settings/gm_settings.ui" line="51"/>
<source>&lt;h3&gt;GreaseMonkey Scripts&lt;/h3&gt;</source>
<translation>&lt;h3&gt;Scripts de GreaseMonkey&lt;/h3&gt;</translation>
</message>
<message>
<location filename="../settings/gm_settings.ui" line="73"/>
<source>Double clicking script will show additional information</source>
<translation>Un double clique sur le script vous montrera des informations supplémentaires</translation>
</message>
<message>
<location filename="../settings/gm_settings.ui" line="153"/>
<source>More scripts can be downloaded from</source>
<translation>Des scripts complémentaires peuvent être téléchargés ici</translation>
</message>
<message>
<location filename="../settings/gm_settings.ui" line="196"/>
<source>Open scripts directory</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/gm_settings.cpp" line="68"/>
<source>Remove script</source>
<translation>Supprimer le script</translation>
</message>
<message>
<location filename="../settings/gm_settings.cpp" line="69"/>
<source>Are you sure you want to remove &apos;%1&apos;?</source>
<translation>Etes vous sûr de vouloir supprimer &apos;%1&apos; ?</translation>
</message>
</context>
<context>
<name>GM_SettingsScriptInfo</name>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="19"/>
<source>Name:</source>
<translation>Nom :</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="29"/>
<source>Version:</source>
<translation>Version :</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="39"/>
<source>URL:</source>
<translation>URL :</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="49"/>
<source>Start at:</source>
<translation>Commencer à partir de :</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="59"/>
<source>Description:</source>
<translation>Description :</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="69"/>
<source>Runs at:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="79"/>
<source>Does not run at:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.cpp" line="27"/>
<source>Script Details of %1</source>
<translation>Détails du script %1</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,177 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="sr_BA">
<context>
<name>GM_AddScriptDialog</name>
<message>
<location filename="../gm_addscriptdialog.ui" line="14"/>
<source>GreaseMonkey Installation</source>
<translation>Инсталација GreaseMonkey скрипте</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.ui" line="51"/>
<source>&lt;h3&gt;GreaseMonkey Installation&lt;/h3&gt;</source>
<translation>&lt;h3&gt;Инсталација GreaseMonkey скрипте&lt;/h3&gt;</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.ui" line="73"/>
<source>You are about to install this userscript into GreaseMonkey:</source>
<translation>Инсталираћете ову скрипту у GreaseMonkey:</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.ui" line="86"/>
<source>&lt;b&gt;You should only install scripts from sources you trust!&lt;/b&gt;</source>
<translation>&lt;b&gt;Инсталирајте само скрипте од извора којима вјерујете!&lt;/b&gt;</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.ui" line="96"/>
<source>Are you sure you want to install it?</source>
<translation>Желите ли заиста да је инсталирате?</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.ui" line="114"/>
<source>Show source code of script</source>
<translation>Прикажи изворни кôд скрипте</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.cpp" line="48"/>
<source>&lt;p&gt;runs at&lt;br/&gt;&lt;i&gt;%1&lt;/i&gt;&lt;/p&gt;</source>
<translation>&lt;p&gt;покреће се на&lt;br/&gt;&lt;i&gt;%1&lt;/i&gt;&lt;/p&gt;</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.cpp" line="52"/>
<source>&lt;p&gt;does not run at&lt;br/&gt;&lt;i&gt;%1&lt;/i&gt;&lt;/p&gt;</source>
<translation>&lt;p&gt;не покреће се на&lt;br/&gt;&lt;i&gt;%1&lt;/i&gt;&lt;/p&gt;</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.cpp" line="82"/>
<source>Cannot install script</source>
<translation type="unfinished">Не могу да инсталирам скрипту</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.cpp" line="85"/>
<source>&apos;%1&apos; installed successfully</source>
<translation type="unfinished">%1 је успјешно инсталирана</translation>
</message>
</context>
<context>
<name>GM_Downloader</name>
<message>
<location filename="../gm_downloader.cpp" line="144"/>
<source>&apos;%1&apos; is already installed</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>GM_Manager</name>
<message>
<location filename="../gm_manager.cpp" line="172"/>
<source>GreaseMonkey</source>
<translation>GreaseMonkey</translation>
</message>
</context>
<context>
<name>GM_Notification</name>
<message>
<location filename="../gm_notification.ui" line="45"/>
<source>This script can be installed with the GreaseMonkey plugin.</source>
<translation>Ова скрипта може бити инсталирана помоћу GreaseMonkey проширења.</translation>
</message>
<message>
<location filename="../gm_notification.ui" line="65"/>
<source>Install</source>
<translation>Инсталирај</translation>
</message>
<message>
<location filename="../gm_notification.cpp" line="49"/>
<source>Cannot install script</source>
<translation type="unfinished">Не могу да инсталирам скрипту</translation>
</message>
<message>
<location filename="../gm_notification.cpp" line="57"/>
<source>&apos;%1&apos; installed successfully</source>
<translation type="unfinished">%1 је успјешно инсталирана</translation>
</message>
</context>
<context>
<name>GM_Settings</name>
<message>
<location filename="../settings/gm_settings.ui" line="14"/>
<source>GreaseMonkey Scripts</source>
<translation>GreaseMonkey скрипте</translation>
</message>
<message>
<location filename="../settings/gm_settings.ui" line="51"/>
<source>&lt;h3&gt;GreaseMonkey Scripts&lt;/h3&gt;</source>
<translation>&lt;h3&gt;GreaseMonkey скрипте&lt;/h3&gt;</translation>
</message>
<message>
<location filename="../settings/gm_settings.ui" line="73"/>
<source>Double clicking script will show additional information</source>
<translation>Двоклик ће вам приказати додатне податке</translation>
</message>
<message>
<location filename="../settings/gm_settings.ui" line="153"/>
<source>More scripts can be downloaded from</source>
<translation>Скрипте можете преузети са</translation>
</message>
<message>
<location filename="../settings/gm_settings.ui" line="196"/>
<source>Open scripts directory</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/gm_settings.cpp" line="68"/>
<source>Remove script</source>
<translation>Уклони скрипту</translation>
</message>
<message>
<location filename="../settings/gm_settings.cpp" line="69"/>
<source>Are you sure you want to remove &apos;%1&apos;?</source>
<translation>Желите ли заиста да уклоните %1?</translation>
</message>
</context>
<context>
<name>GM_SettingsScriptInfo</name>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="19"/>
<source>Name:</source>
<translation>Име:</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="29"/>
<source>Version:</source>
<translation>Издање:</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="39"/>
<source>URL:</source>
<translation>УРЛ:</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="49"/>
<source>Start at:</source>
<translation>Покреће се при:</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="59"/>
<source>Description:</source>
<translation>Опис:</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="69"/>
<source>Runs at:</source>
<translation>Покреће се на:</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="79"/>
<source>Does not run at:</source>
<translation>Не покреће се на:</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.cpp" line="27"/>
<source>Script Details of %1</source>
<translation>Детаљи скрипте %1</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,177 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="sr_RS">
<context>
<name>GM_AddScriptDialog</name>
<message>
<location filename="../gm_addscriptdialog.ui" line="14"/>
<source>GreaseMonkey Installation</source>
<translation>Инсталација GreaseMonkey скрипте</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.ui" line="51"/>
<source>&lt;h3&gt;GreaseMonkey Installation&lt;/h3&gt;</source>
<translation>&lt;h3&gt;Инсталација GreaseMonkey скрипте&lt;/h3&gt;</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.ui" line="73"/>
<source>You are about to install this userscript into GreaseMonkey:</source>
<translation>Инсталираћете ову скрипту у GreaseMonkey:</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.ui" line="86"/>
<source>&lt;b&gt;You should only install scripts from sources you trust!&lt;/b&gt;</source>
<translation>&lt;b&gt;Инсталирајте само скрипте од извора којима верујете!&lt;/b&gt;</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.ui" line="96"/>
<source>Are you sure you want to install it?</source>
<translation>Желите ли заиста да је инсталирате?</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.ui" line="114"/>
<source>Show source code of script</source>
<translation>Прикажи изворни кôд скрипте</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.cpp" line="48"/>
<source>&lt;p&gt;runs at&lt;br/&gt;&lt;i&gt;%1&lt;/i&gt;&lt;/p&gt;</source>
<translation>&lt;p&gt;покреће се на&lt;br/&gt;&lt;i&gt;%1&lt;/i&gt;&lt;/p&gt;</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.cpp" line="52"/>
<source>&lt;p&gt;does not run at&lt;br/&gt;&lt;i&gt;%1&lt;/i&gt;&lt;/p&gt;</source>
<translation>&lt;p&gt;не покреће се на&lt;br/&gt;&lt;i&gt;%1&lt;/i&gt;&lt;/p&gt;</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.cpp" line="82"/>
<source>Cannot install script</source>
<translation type="unfinished">Не могу да инсталирам скрипту</translation>
</message>
<message>
<location filename="../gm_addscriptdialog.cpp" line="85"/>
<source>&apos;%1&apos; installed successfully</source>
<translation type="unfinished">%1 је успешно инсталирана</translation>
</message>
</context>
<context>
<name>GM_Downloader</name>
<message>
<location filename="../gm_downloader.cpp" line="144"/>
<source>&apos;%1&apos; is already installed</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>GM_Manager</name>
<message>
<location filename="../gm_manager.cpp" line="172"/>
<source>GreaseMonkey</source>
<translation>GreaseMonkey</translation>
</message>
</context>
<context>
<name>GM_Notification</name>
<message>
<location filename="../gm_notification.ui" line="45"/>
<source>This script can be installed with the GreaseMonkey plugin.</source>
<translation>Ова скрипта може бити инсталирана помоћу GreaseMonkey проширења.</translation>
</message>
<message>
<location filename="../gm_notification.ui" line="65"/>
<source>Install</source>
<translation>Инсталирај</translation>
</message>
<message>
<location filename="../gm_notification.cpp" line="49"/>
<source>Cannot install script</source>
<translation type="unfinished">Не могу да инсталирам скрипту</translation>
</message>
<message>
<location filename="../gm_notification.cpp" line="57"/>
<source>&apos;%1&apos; installed successfully</source>
<translation type="unfinished">%1 је успешно инсталирана</translation>
</message>
</context>
<context>
<name>GM_Settings</name>
<message>
<location filename="../settings/gm_settings.ui" line="14"/>
<source>GreaseMonkey Scripts</source>
<translation>GreaseMonkey скрипте</translation>
</message>
<message>
<location filename="../settings/gm_settings.ui" line="51"/>
<source>&lt;h3&gt;GreaseMonkey Scripts&lt;/h3&gt;</source>
<translation>&lt;h3&gt;GreaseMonkey скрипте&lt;/h3&gt;</translation>
</message>
<message>
<location filename="../settings/gm_settings.ui" line="73"/>
<source>Double clicking script will show additional information</source>
<translation>Двоклик ће вам приказати додатне податке</translation>
</message>
<message>
<location filename="../settings/gm_settings.ui" line="153"/>
<source>More scripts can be downloaded from</source>
<translation>Скрипте можете преузети са</translation>
</message>
<message>
<location filename="../settings/gm_settings.ui" line="196"/>
<source>Open scripts directory</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../settings/gm_settings.cpp" line="68"/>
<source>Remove script</source>
<translation>Уклони скрипту</translation>
</message>
<message>
<location filename="../settings/gm_settings.cpp" line="69"/>
<source>Are you sure you want to remove &apos;%1&apos;?</source>
<translation>Желите ли заиста да уклоните %1?</translation>
</message>
</context>
<context>
<name>GM_SettingsScriptInfo</name>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="19"/>
<source>Name:</source>
<translation>Име:</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="29"/>
<source>Version:</source>
<translation>Издање:</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="39"/>
<source>URL:</source>
<translation>УРЛ:</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="49"/>
<source>Start at:</source>
<translation>Покреће се при:</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="59"/>
<source>Description:</source>
<translation>Опис:</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="69"/>
<source>Runs at:</source>
<translation>Покреће се на:</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.ui" line="79"/>
<source>Does not run at:</source>
<translation>Не покреће се на:</translation>
</message>
<message>
<location filename="../settings/gm_settingsscriptinfo.cpp" line="27"/>
<source>Script Details of %1</source>
<translation>Детаљи скрипте %1</translation>
</message>
</context>
</TS>

View File

@ -63,7 +63,7 @@ bool MouseGesturesPlugin::testPlugin()
{
// Let's be sure, require latest version of QupZilla
return (QupZilla::VERSION == "1.2.0");
return (QupZilla::VERSION == "1.3.0");
}
QTranslator* MouseGesturesPlugin::getTranslator(const QString &locale)

33
src/plugins/PIM/PIM.pro Normal file
View File

@ -0,0 +1,33 @@
TARGET = PIM
os2: TARGET = PIM
SOURCES = \
PIM_plugin.cpp \
PIM_handler.cpp \
PIM_settings.cpp
HEADERS = \
PIM_plugin.h \
PIM_handler.h \
PIM_settings.h
FORMS += \
PIM_settings.ui
RESOURCES = PIM_res.qrc
TRANSLATIONS = \
translations/cs_CZ.ts \
translations/de_DE.ts \
translations/fr_FR.ts \
translations/sr_BA.ts \
translations/sr_RS.ts \
translations/zh_TW.ts \
srcdir = $$(QUPZILLA_SRCDIR)
equals(srcdir, "") {
include(../../plugins.pri)
}
else {
include($$srcdir/src/plugins.pri)
}

View File

@ -0,0 +1,221 @@
/* ============================================================
* Personal Information Manager plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
* Copyright (C) 2012 Mladen Pejaković <pejakm@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#include "PIM_handler.h"
#include "PIM_settings.h"
#include "webview.h"
#include "webpage.h"
#include <QApplication>
#include <QSettings>
#include <QWebPage>
#include <QWebFrame>
#include <QLabel>
#include <QToolTip>
PIM_Handler::PIM_Handler(const QString &sPath, QObject* parent)
: QObject(parent)
, m_settingsFile(sPath + "extensions.ini")
, m_loaded(false)
{
}
void PIM_Handler::loadSettings()
{
QSettings settings(m_settingsFile, QSettings::IniFormat);
settings.beginGroup("PIM");
m_allInfo[PI_LastName] = settings.value("LastName", "").toString();
m_allInfo[PI_FirstName] = settings.value("FirstName", "").toString();
m_allInfo[PI_Email] = settings.value("Email", "").toString();
m_allInfo[PI_Mobile] = settings.value("Mobile", "").toString();
m_allInfo[PI_Phone] = settings.value("Phone", "").toString();
m_allInfo[PI_Address] = settings.value("Address", "").toString();
m_allInfo[PI_City] = settings.value("City", "").toString();
m_allInfo[PI_Zip] = settings.value("Zip", "").toString();
m_allInfo[PI_State] = settings.value("State", "").toString();
m_allInfo[PI_Country] = settings.value("Country", "").toString();
m_allInfo[PI_HomePage] = settings.value("HomePage", "").toString();
m_allInfo[PI_Special1] = settings.value("Special1", "").toString();
m_allInfo[PI_Special2] = settings.value("Special2", "").toString();
m_allInfo[PI_Special3] = settings.value("Special3", "").toString();
settings.endGroup();
m_translations[PI_LastName] = tr("Last Name");
m_translations[PI_FirstName] = tr("First Name");
m_translations[PI_Email] = tr("E-mail");
m_translations[PI_Mobile] = tr("Mobile");
m_translations[PI_Phone] = tr("Phone");
m_translations[PI_Address] = tr("Address");
m_translations[PI_City] = tr("City");
m_translations[PI_Zip] = tr("ZIP Code");
m_translations[PI_State] = tr("State/Region");
m_translations[PI_Country] = tr("Country");
m_translations[PI_HomePage] = tr("Home Page");
m_translations[PI_Special1] = tr("Custom 1");
m_translations[PI_Special2] = tr("Custom 2");
m_translations[PI_Special3] = tr("Custom 3");
m_infoMatches[PI_LastName] << "lastname" << "surname";
m_infoMatches[PI_FirstName] << "firstname" << "name";
m_infoMatches[PI_Email] << "email" << "e-mail" << "mail";
m_infoMatches[PI_Mobile] << "mobile" << "mobilephone";
m_infoMatches[PI_Phone] << "phone" << "telephone";
m_infoMatches[PI_Address] << "address";
m_infoMatches[PI_City] << "city";
m_infoMatches[PI_Zip] << "zip";
m_infoMatches[PI_State] << "state" << "region";
m_infoMatches[PI_Country] << "country";
m_infoMatches[PI_HomePage] << "homepage" << "www";
m_loaded = true;
}
void PIM_Handler::showSettings(QWidget* parent)
{
PIM_Settings* settings = new PIM_Settings(m_settingsFile, parent);
settings->show();
connect(settings, SIGNAL(accepted()), this, SLOT(loadSettings()));
}
void PIM_Handler::populateWebViewMenu(QMenu* menu, WebView* view, const QWebHitTestResult &hitTest)
{
m_view = view;
m_element = hitTest.element();
if (!hitTest.isContentEditable()) {
return;
}
if (!m_loaded) {
loadSettings();
}
QMenu* pimMenu = new QMenu(tr("Insert Personal Information"));
pimMenu->setIcon(QIcon(":/PIM/data/PIM.png"));
for (int i = 0; i < PI_Max; ++i) {
const QString &info = m_allInfo[PI_Type(i)];
if (info.isEmpty()) {
continue;
}
QAction* action = pimMenu->addAction(m_translations[PI_Type(i)], this, SLOT(pimInsert()));
action->setData(info);
}
pimMenu->addSeparator();
pimMenu->addAction(tr("Edit"), this, SLOT(showSettings()));
menu->addMenu(pimMenu);
menu->addSeparator();
}
bool PIM_Handler::keyPress(WebView* view, QKeyEvent* event)
{
if (!view) {
return false;
}
bool isEnter = event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter;
if (!isEnter || event->modifiers() != Qt::ControlModifier) {
return false;
}
const QWebElement &document = view->page()->mainFrame()->documentElement();
const QWebElementCollection elements = document.findAll("input[type=\"text\"]");
foreach(QWebElement element, elements) {
const QString &name = element.attribute("name");
if (name.isEmpty()) {
continue;
}
PI_Type match = nameMatch(name);
if (match != PI_Invalid) {
element.evaluateJavaScript(QString("this.value = \"%1\"").arg(m_allInfo[match]));
}
}
return true;
}
void PIM_Handler::webPageCreated(WebPage* page)
{
connect(page, SIGNAL(loadFinished(bool)), this, SLOT(pageLoadFinished()));
}
void PIM_Handler::pimInsert()
{
QAction* action = qobject_cast<QAction*>(sender());
if (m_element.isNull() || !action) {
return;
}
QString info = action->data().toString();
info.replace('"', "\\\"");
m_element.evaluateJavaScript(QString("var newVal = this.value.substring(0, this.selectionStart) + \"%1\" + this.value.substring(this.selectionEnd); this.value = newVal;").arg(info));
}
void PIM_Handler::pageLoadFinished()
{
WebPage* page = qobject_cast<WebPage*>(sender());
if (!page) {
return;
}
if (!m_loaded) {
loadSettings();
}
const QWebElement &document = page->mainFrame()->documentElement();
const QWebElementCollection elements = document.findAll("input[type=\"text\"]");
foreach(QWebElement element, elements) {
const QString &name = element.attribute("name");
if (name.isEmpty()) {
continue;
}
PI_Type match = nameMatch(name);
if (match != PI_Invalid) {
element.setStyleProperty("-webkit-appearance", "none");
element.setStyleProperty("-webkit-box-shadow", "inset 0 0 2px 1px #EEE000");
}
}
}
PIM_Handler::PI_Type PIM_Handler::nameMatch(const QString &name)
{
for (int i = 0; i < PI_Max; ++i) {
if (!m_allInfo[PI_Type(i)].isEmpty()) {
foreach(const QString & n, m_infoMatches[PI_Type(i)]) {
if (name == n) {
return PI_Type(i);
}
if (name.contains(n)) {
return PI_Type(i);
}
}
}
}
return PI_Invalid;
}

View File

@ -0,0 +1,87 @@
/* ============================================================
* Personal Information Manager plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
* Copyright (C) 2012 Mladen Pejaković <pejakm@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#ifndef PIM_HANDLER_H
#define PIM_HANDLER_H
#include <QObject>
#include <QWebElement>
#include <QMessageBox>
#include <QWebHitTestResult>
#include <QMenu>
#include <QWeakPointer>
#include <QHash>
class WebView;
class WebPage;
class PIM_Handler : public QObject
{
Q_OBJECT
public:
explicit PIM_Handler(const QString &sPath, QObject* parent = 0);
void populateWebViewMenu(QMenu* menu, WebView* view, const QWebHitTestResult &hitTest);
bool keyPress(WebView* view, QKeyEvent* event);
signals:
public slots:
void webPageCreated(WebPage* page);
void showSettings(QWidget* parent = 0);
private slots:
void loadSettings();
void pimInsert();
void pageLoadFinished();
private:
enum PI_Type {
PI_LastName = 0,
PI_FirstName = 1,
PI_Email = 2,
PI_Mobile = 3,
PI_Phone = 4,
PI_Address = 5,
PI_City = 6,
PI_Zip = 7,
PI_State = 8,
PI_Country = 9,
PI_HomePage = 10,
PI_Special1 = 11,
PI_Special2 = 12,
PI_Special3 = 13,
PI_Max = 14,
PI_Invalid = 128
};
PI_Type nameMatch(const QString &name);
QHash<PI_Type, QString> m_allInfo;
QHash<PI_Type, QStringList> m_infoMatches;
QHash<PI_Type, QString> m_translations;
QWeakPointer<WebView> m_view;
QWebElement m_element;
QString m_settingsFile;
bool m_loaded;
};
#endif // PIM_HANDLER_H

View File

@ -0,0 +1,97 @@
/* ============================================================
* Personal Information Manager plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
* Copyright (C) 2012 Mladen Pejaković <pejakm@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#include "PIM_plugin.h"
#include "PIM_handler.h"
#include "PIM_settings.h"
#include "mainapplication.h"
#include "pluginproxy.h"
#include "qupzilla.h"
#include "webview.h"
#include <QTranslator>
PIM_Plugin::PIM_Plugin()
: QObject()
, m_handler(0)
{
}
PluginSpec PIM_Plugin::pluginSpec()
{
PluginSpec spec;
spec.name = "PIM";
spec.info = "Personal Information Manager";
spec.description = "Adds ability for Qupzilla to store some personal data";
spec.version = "0.0.1";
spec.author = QString::fromUtf8("Mladen Pejaković <pejakm@gmail.com>");
spec.icon = QPixmap(":/PIM/data/PIM.png");
spec.hasSettings = true;
return spec;
}
void PIM_Plugin::init(const QString &sPath)
{
m_handler = new PIM_Handler(sPath, this);
QZ_REGISTER_EVENT_HANDLER(PluginProxy::KeyPressHandler);
connect(mApp->plugins(), SIGNAL(webPageCreated(WebPage*)), m_handler, SLOT(webPageCreated(WebPage*)));
}
void PIM_Plugin::unload()
{
m_handler->deleteLater();
}
bool PIM_Plugin::testPlugin()
{
// Let's be sure, require latest version of QupZilla
return (QupZilla::VERSION == "1.3.0");
}
QTranslator* PIM_Plugin::getTranslator(const QString &locale)
{
QTranslator* translator = new QTranslator();
translator->load(locale, ":/PIM/locale/");
return translator;
}
void PIM_Plugin::showSettings(QWidget* parent)
{
m_handler->showSettings(parent);
}
void PIM_Plugin::populateWebViewMenu(QMenu* menu, WebView* view, const QWebHitTestResult &r)
{
m_handler->populateWebViewMenu(menu, view, r);
}
bool PIM_Plugin::keyPress(const Qz::ObjectName &type, QObject* obj, QKeyEvent* event)
{
if (type == Qz::ON_WebView) {
WebView* view = qobject_cast<WebView*>(obj);
return m_handler->keyPress(view, event);
}
return false;
}
Q_EXPORT_PLUGIN2(PIM, PIM_Plugin)

View File

@ -0,0 +1,54 @@
/* ============================================================
* Personal Information Manager plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
* Copyright (C) 2012 Mladen Pejaković <pejakm@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#ifndef PIM_PLUGIN_H
#define PIM_PLUGIN_H
#include "plugininterface.h"
class WebPage;
class QupZilla;
class PIM_Handler;
class PIM_Plugin : public QObject, public PluginInterface
{
Q_OBJECT
Q_INTERFACES(PluginInterface)
public:
PIM_Plugin();
PluginSpec pluginSpec();
void init(const QString &sPath);
void unload();
bool testPlugin();
QTranslator* getTranslator(const QString &locale);
void showSettings(QWidget* parent = 0);
void populateWebViewMenu(QMenu* menu, WebView* view, const QWebHitTestResult &r);
bool keyPress(const Qz::ObjectName &type, QObject* obj, QKeyEvent* event);
private slots:
void webPageCreated(WebPage* page);
private:
PIM_Handler* m_handler;
};
#endif // PIM_PLUGIN_H

View File

@ -0,0 +1,10 @@
<RCC>
<qresource prefix="/PIM">
<file>data/PIM.png</file>
<file>locale/cs_CZ.qm</file>
<file>locale/de_DE.qm</file>
<file>locale/fr_FR.qm</file>
<file>locale/sr_BA.qm</file>
<file>locale/sr_RS.qm</file>
</qresource>
</RCC>

View File

@ -0,0 +1,79 @@
/* ============================================================
* Personal Information Manager plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
* Copyright (C) 2012 Mladen Pejaković <pejakm@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#include "PIM_settings.h"
#include "ui_PIM_settings.h"
#include "PIM_handler.h"
#include <QSettings>
PIM_Settings::PIM_Settings(const QString &settingsFile, QWidget* parent)
: QDialog(parent)
, ui(new Ui::PIM_Settings)
, m_settingsFile(settingsFile)
{
setAttribute(Qt::WA_DeleteOnClose);
ui->setupUi(this);
QSettings settings(m_settingsFile, QSettings::IniFormat);
settings.beginGroup("PIM");
ui->pim_firstname->setText(settings.value("FirstName", "").toString());
ui->pim_lastname->setText(settings.value("LastName", "").toString());
ui->pim_email->setText(settings.value("Email", "").toString());
ui->pim_phone->setText(settings.value("Phone", "").toString());
ui->pim_mobile->setText(settings.value("Mobile", "").toString());
ui->pim_address->setText(settings.value("Address", "").toString());
ui->pim_city->setText(settings.value("City", "").toString());
ui->pim_zip->setText(settings.value("Zip", "").toString());
ui->pim_state->setText(settings.value("State", "").toString());
ui->pim_country->setText(settings.value("Country", "").toString());
ui->pim_homepage->setText(settings.value("HomePage", "").toString());
ui->pim_special1->setText(settings.value("Special1", "").toString());
ui->pim_special2->setText(settings.value("Special2", "").toString());
ui->pim_special3->setText(settings.value("Special3", "").toString());
settings.endGroup();
connect(this, SIGNAL(accepted()), this, SLOT(dialogAccepted()));
}
void PIM_Settings::dialogAccepted()
{
QSettings settings(m_settingsFile, QSettings::IniFormat);
settings.beginGroup("PIM");
settings.setValue("FirstName", ui->pim_firstname->text());
settings.setValue("LastName", ui->pim_lastname->text());
settings.setValue("Email", ui->pim_email->text());
settings.setValue("Phone", ui->pim_phone->text());
settings.setValue("Mobile", ui->pim_mobile->text());
settings.setValue("Address", ui->pim_address->text());
settings.setValue("City", ui->pim_city->text());
settings.setValue("Zip", ui->pim_zip->text());
settings.setValue("State", ui->pim_state->text());
settings.setValue("Country", ui->pim_country->text());
settings.setValue("HomePage", ui->pim_homepage->text());
settings.setValue("Special1", ui->pim_special1->text());
settings.setValue("Special2", ui->pim_special2->text());
settings.setValue("Special3", ui->pim_special3->text());
settings.endGroup();
}
PIM_Settings::~PIM_Settings()
{
delete ui;
}

View File

@ -0,0 +1,48 @@
/* ============================================================
* Personal Information Manager plugin for QupZilla
* Copyright (C) 2012 David Rosca <nowrep@gmail.com>
* Copyright (C) 2012 Mladen Pejaković <pejakm@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#ifndef PIM_SETTINGS_H
#define PIM_SETTINGS_H
#include <QDialog>
namespace Ui
{
class PIM_Settings;
}
class PIM_Handler;
class PIM_Settings : public QDialog
{
Q_OBJECT
public:
explicit PIM_Settings(const QString &settingsFile, QWidget* parent = 0);
~PIM_Settings();
private slots:
void dialogAccepted();
private:
Ui::PIM_Settings* ui;
QString m_settingsFile;
};
#endif // PIM_SETTINGS_H

View File

@ -0,0 +1,313 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PIM_Settings</class>
<widget class="QDialog" name="PIM_Settings">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>539</width>
<height>346</height>
</rect>
</property>
<property name="windowTitle">
<string>PIM Settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="pixmap">
<pixmap resource="PIM_res.qrc">:/PIM/data/PIM.png</pixmap>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>&lt;h2&gt;Personal Information Manager&lt;/h2&gt;</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_14">
<property name="text">
<string>Your personal information that will be used on webpages.</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Phone:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="pim_address"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Address:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Last Name:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="pim_firstname"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>First Name:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="pim_phone"/>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="pim_mobile"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Mobile Phone:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>City:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="pim_lastname"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>E-mail:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLineEdit" name="pim_city"/>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="pim_email"/>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_9">
<property name="text">
<string>ZIP Code:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLineEdit" name="pim_zip"/>
</item>
<item row="1" column="2">
<widget class="QLabel" name="label_10">
<property name="text">
<string>State/Region:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLineEdit" name="pim_state"/>
</item>
<item row="2" column="2">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Country:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QLineEdit" name="pim_country"/>
</item>
<item row="3" column="2">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Home Page:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QLineEdit" name="pim_homepage"/>
</item>
<item row="4" column="2">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Custom 1:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="4" column="3">
<widget class="QLineEdit" name="pim_special1"/>
</item>
<item row="5" column="2">
<widget class="QLabel" name="label_17">
<property name="text">
<string>Custom 2:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="5" column="3">
<widget class="QLineEdit" name="pim_special2"/>
</item>
<item row="6" column="2">
<widget class="QLabel" name="label_18">
<property name="text">
<string>Custom 3:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="6" column="3">
<widget class="QLineEdit" name="pim_special3"/>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_13">
<property name="text">
<string>&lt;b&gt;Note:&lt;/b&gt; Press Ctrl+ENTER to autofill form fields for which QupZilla finds personal entries.</string>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="PIM_res.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>PIM_Settings</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>PIM_Settings</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

19
src/plugins/PIM/test.html Normal file
View File

@ -0,0 +1,19 @@
<html><head>
<title>Test</title>
<meta content="">
<style>body {line-height: 1.4} label {width: 200px;} input {width: 250px;}</style>
</head>
<body>
<label for="name">First Name: </label><input type="text" id="name" name="firstname"><br>
<label for="surname">Last Name: </label><input type="text" id="surname" name="lastname"><br>
<label for="e-mail">E-mail: </label><input type="text" id="e-mail" name="e-mail"><br>
<label for="phone">Phone: </label><input type="text" id="phone" name="phone"><br>
<label for="mobilephone">Mobile: </label><input type="text" id="mobilephone" name="mobilephone"><br>
<label for="homepage">Website: </label><input type="text" id="homepage" name="homepage"><br>
<label for="address">Address: </label><input type="text" id="address" name="address"><br>
<label for="city">City: </label><input type="text" id="city" name="city" style=""><br>
<label for="zip">Postal code: </label><input type="text" id="zip" name="zip"><br>
<label for="country">Country: </label><input type="text" id="country" name="country"><br>
<label for="state">State/Region: </label><input type="text" id="state" name="state"><br>
</body></html>

View File

@ -0,0 +1,180 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="cs_CZ">
<context>
<name>PIM_Handler</name>
<message>
<location filename="../PIM_handler.cpp" line="59"/>
<source>Last Name</source>
<translation>Jméno</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="60"/>
<source>First Name</source>
<translation>Příjmení</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="61"/>
<source>E-mail</source>
<translation>E-mail</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="62"/>
<source>Mobile</source>
<translation>Mobilní telefon</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="63"/>
<source>Phone</source>
<translation>Telefon</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="64"/>
<source>Address</source>
<translation>Adresa</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="65"/>
<source>City</source>
<translation>Město</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="66"/>
<source>ZIP Code</source>
<translation>PSČ</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="67"/>
<source>State/Region</source>
<translation>Oblast/Stát</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="68"/>
<source>Country</source>
<translation>Země</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="69"/>
<source>Home Page</source>
<translation>Domovská stránka</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="70"/>
<source>Custom 1</source>
<translation>Vlastní 1</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="71"/>
<source>Custom 2</source>
<translation>Vlastní 2</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="72"/>
<source>Custom 3</source>
<translation>Vlastní 3</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="110"/>
<source>Insert Personal Information</source>
<translation>Vložit osobní údaj</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="124"/>
<source>Edit</source>
<translation>Upravit</translation>
</message>
</context>
<context>
<name>PIM_Settings</name>
<message>
<location filename="../PIM_settings.ui" line="14"/>
<source>PIM Settings</source>
<translation>PIM Nastavení</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="42"/>
<source>&lt;h2&gt;Personal Information Manager&lt;/h2&gt;</source>
<translation>&lt;h2&gt;Správce osobních údajů&lt;/h2&gt;</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="64"/>
<source>Your personal information that will be used on webpages.</source>
<translation>Vaše osobní údaje které budou použity na stránkách.</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="76"/>
<source>Phone:</source>
<translation>Telefon:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="89"/>
<source>Address:</source>
<translation>Adresa:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="99"/>
<source>Last Name:</source>
<translation>Jméno:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="112"/>
<source>First Name:</source>
<translation>Příjmení:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="128"/>
<source>Mobile Phone:</source>
<translation>Mobilní telefon:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="138"/>
<source>City:</source>
<translation>Město:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="151"/>
<source>E-mail:</source>
<translation>E-mail:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="167"/>
<source>ZIP Code:</source>
<translation>PSČ:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="180"/>
<source>State/Region:</source>
<translation>Oblast/Stát:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="193"/>
<source>Country:</source>
<translation>Země:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="206"/>
<source>Home Page:</source>
<translation>Domovská stránka:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="219"/>
<source>Custom 1:</source>
<translation>Vlastní 1:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="232"/>
<source>Custom 2:</source>
<translation>Vlastní 2:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="245"/>
<source>Custom 3:</source>
<translation>Vlastní 3:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="260"/>
<source>&lt;b&gt;Note:&lt;/b&gt; Press Ctrl+ENTER to autofill form fields for which QupZilla finds personal entries.</source>
<translation>&lt;b&gt;Poznámka:&lt;/b&gt; Ctrl+ENTER slouží k automatickému vyplnění známých polí na stránce.</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,180 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="de_DE" sourcelanguage="en_US">
<context>
<name>PIM_Handler</name>
<message>
<location filename="../PIM_handler.cpp" line="60"/>
<source>First Name</source>
<translation>Vorname</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="59"/>
<source>Last Name</source>
<translation>Nachname</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="61"/>
<source>E-mail</source>
<translation>E-Mail</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="63"/>
<source>Phone</source>
<translation>Telefon</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="62"/>
<source>Mobile</source>
<translation>Mobiltelefon</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="64"/>
<source>Address</source>
<translation>Adresse</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="65"/>
<source>City</source>
<translation>Stadt</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="66"/>
<source>ZIP Code</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="67"/>
<source>State/Region</source>
<translation>Bundesland/ Region</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="68"/>
<source>Country</source>
<translation>Land</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="69"/>
<source>Home Page</source>
<translation>Homepage</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="70"/>
<source>Custom 1</source>
<translation type="unfinished">Benutzerdefiniert 3: {1?}</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="71"/>
<source>Custom 2</source>
<translation type="unfinished">Benutzerdefiniert 3: {2?}</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="72"/>
<source>Custom 3</source>
<translation type="unfinished">Benutzerdefiniert 3: {3?}</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="110"/>
<source>Insert Personal Information</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="124"/>
<source>Edit</source>
<translation>Bearbeiten</translation>
</message>
</context>
<context>
<name>PIM_Settings</name>
<message>
<location filename="../PIM_settings.ui" line="14"/>
<source>PIM Settings</source>
<translation>PIM Einstellungen</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="112"/>
<source>First Name:</source>
<translation>Vorname:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="99"/>
<source>Last Name:</source>
<translation>Nachname:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="76"/>
<source>Phone:</source>
<translation>Telefon:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="128"/>
<source>Mobile Phone:</source>
<translation>Mobiltelefon:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="89"/>
<source>Address:</source>
<translation>Adresse:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="42"/>
<source>&lt;h2&gt;Personal Information Manager&lt;/h2&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="64"/>
<source>Your personal information that will be used on webpages.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="138"/>
<source>City:</source>
<translation>Stadt:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="151"/>
<source>E-mail:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="167"/>
<source>ZIP Code:</source>
<translation>Postleitzahl:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="180"/>
<source>State/Region:</source>
<translation>Bundesland/ Region:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="193"/>
<source>Country:</source>
<translation>Land:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="206"/>
<source>Home Page:</source>
<translation>Homepage:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="219"/>
<source>Custom 1:</source>
<translation>Benutzerdefiniert 1:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="232"/>
<source>Custom 2:</source>
<translation>Benutzerdefiniert 2:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="245"/>
<source>Custom 3:</source>
<translation>Benutzerdefiniert 3:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="260"/>
<source>&lt;b&gt;Note:&lt;/b&gt; Press Ctrl+ENTER to autofill form fields for which QupZilla finds personal entries.</source>
<translation>&lt;b&gt;Note:&lt;/b&gt; Drücken Sie STRG+ENTER um die Formularfelder automatisch ausfüllen zu lassen.</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,180 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="fr_FR">
<context>
<name>PIM_Handler</name>
<message>
<location filename="../PIM_handler.cpp" line="59"/>
<source>Last Name</source>
<translation>Nom</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="60"/>
<source>First Name</source>
<translation>Prénom</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="61"/>
<source>E-mail</source>
<translation>E-mail</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="62"/>
<source>Mobile</source>
<translation>Téléphone mobile</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="63"/>
<source>Phone</source>
<translation>Téléphone fixe</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="64"/>
<source>Address</source>
<translation>Adresse</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="65"/>
<source>City</source>
<translation>Ville</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="66"/>
<source>ZIP Code</source>
<translation>Code postal</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="67"/>
<source>State/Region</source>
<translation>Région</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="68"/>
<source>Country</source>
<translation>Pays</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="69"/>
<source>Home Page</source>
<translation>Site Web</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="70"/>
<source>Custom 1</source>
<translation>Informations complémentaires 1</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="71"/>
<source>Custom 2</source>
<translation>Informations complémentaires 2</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="72"/>
<source>Custom 3</source>
<translation>Informations complémentaires 3</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="110"/>
<source>Insert Personal Information</source>
<translation>Insérer vos informations personnelles</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="124"/>
<source>Edit</source>
<translation>Modifier</translation>
</message>
</context>
<context>
<name>PIM_Settings</name>
<message>
<location filename="../PIM_settings.ui" line="14"/>
<source>PIM Settings</source>
<translation>Paramétres PIM</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="42"/>
<source>&lt;h2&gt;Personal Information Manager&lt;/h2&gt;</source>
<translation>&lt;h2&gt;Gestionnaire d&apos;informations personnelles (PIM)&lt;/h2&gt;</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="64"/>
<source>Your personal information that will be used on webpages.</source>
<translation>Vos informations personnelles pouvant être utilisées dans les pages Web. </translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="76"/>
<source>Phone:</source>
<translation>Téléphone :</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="89"/>
<source>Address:</source>
<translation>Adresse :</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="99"/>
<source>Last Name:</source>
<translation>Nom :</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="112"/>
<source>First Name:</source>
<translation>Prénom :</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="128"/>
<source>Mobile Phone:</source>
<translation>Téléphone mobile :</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="138"/>
<source>City:</source>
<translation>Ville :</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="151"/>
<source>E-mail:</source>
<translation>E-mail :</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="167"/>
<source>ZIP Code:</source>
<translation>Code postal :</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="180"/>
<source>State/Region:</source>
<translation>Région :</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="193"/>
<source>Country:</source>
<translation>Pays :</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="206"/>
<source>Home Page:</source>
<translation>Site Web :</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="219"/>
<source>Custom 1:</source>
<translation>Informations complémentaires 1 :</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="232"/>
<source>Custom 2:</source>
<translation>Informations complémentaires 2 :</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="245"/>
<source>Custom 3:</source>
<translation>Informations complémentaires 3 :</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="260"/>
<source>&lt;b&gt;Note:&lt;/b&gt; Press Ctrl+ENTER to autofill form fields for which QupZilla finds personal entries.</source>
<translation>&lt;b&gt;Note:&lt;/b&gt; Appuyer sur Ctrl+ENTER pour autocompléter les champs dont QupZilla dispose.d&apos;informations.</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,180 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="sr_BA" sourcelanguage="en_US">
<context>
<name>PIM_Handler</name>
<message>
<location filename="../PIM_handler.cpp" line="60"/>
<source>First Name</source>
<translation>Име</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="59"/>
<source>Last Name</source>
<translation>Презиме</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="61"/>
<source>E-mail</source>
<translation>Е-адресу</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="63"/>
<source>Phone</source>
<translation>Бр. телефона</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="62"/>
<source>Mobile</source>
<translation>Бр. мобилног</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="64"/>
<source>Address</source>
<translation>Адресу</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="65"/>
<source>City</source>
<translation>Град</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="66"/>
<source>ZIP Code</source>
<translation>Пошт. број</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="67"/>
<source>State/Region</source>
<translation>Сав. држ./регију</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="68"/>
<source>Country</source>
<translation>Државу</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="69"/>
<source>Home Page</source>
<translation>Домаћу страницу</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="70"/>
<source>Custom 1</source>
<translation>Посебно 1</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="71"/>
<source>Custom 2</source>
<translation>Посебно 2</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="72"/>
<source>Custom 3</source>
<translation>Посебно 3</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="110"/>
<source>Insert Personal Information</source>
<translation>Уметни лични податак</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="124"/>
<source>Edit</source>
<translation>Уреди</translation>
</message>
</context>
<context>
<name>PIM_Settings</name>
<message>
<location filename="../PIM_settings.ui" line="14"/>
<source>PIM Settings</source>
<translation>ПИМ подешавања</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="112"/>
<source>First Name:</source>
<translation>Име:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="99"/>
<source>Last Name:</source>
<translation>Презиме:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="76"/>
<source>Phone:</source>
<translation>Број телефона:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="128"/>
<source>Mobile Phone:</source>
<translation>Број мобилног тел:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="89"/>
<source>Address:</source>
<translation>Адреса:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="42"/>
<source>&lt;h2&gt;Personal Information Manager&lt;/h2&gt;</source>
<translation>&lt;h2&gt;Менаџер личних података&lt;/h2&gt;</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="64"/>
<source>Your personal information that will be used on webpages.</source>
<translation>Ваши лични подаци које можете да користите на веб страницама.</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="138"/>
<source>City:</source>
<translation>Град:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="151"/>
<source>E-mail:</source>
<translation>Е-адреса:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="167"/>
<source>ZIP Code:</source>
<translation>Поштански број:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="180"/>
<source>State/Region:</source>
<translation>Савезна држ./регија:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="193"/>
<source>Country:</source>
<translation>Држава:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="206"/>
<source>Home Page:</source>
<translation>Домаћа страница:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="219"/>
<source>Custom 1:</source>
<translation>Посебно 1:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="232"/>
<source>Custom 2:</source>
<translation>Посебно 2:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="245"/>
<source>Custom 3:</source>
<translation>Посебно 3:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="260"/>
<source>&lt;b&gt;Note:&lt;/b&gt; Press Ctrl+ENTER to autofill form fields for which QupZilla finds personal entries.</source>
<translation>&lt;b&gt;Напомена:&lt;/b&gt; Притисните Ctrl+ENTER да бисте аутоматски попунили поља за која Капзила пронађе личне податке.</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,180 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="sr_RS" sourcelanguage="en_US">
<context>
<name>PIM_Handler</name>
<message>
<location filename="../PIM_handler.cpp" line="60"/>
<source>First Name</source>
<translation>Име</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="59"/>
<source>Last Name</source>
<translation>Презиме</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="61"/>
<source>E-mail</source>
<translation>Е-адресу</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="63"/>
<source>Phone</source>
<translation>Бр. телефона</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="62"/>
<source>Mobile</source>
<translation>Бр. мобилног</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="64"/>
<source>Address</source>
<translation>Адресу</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="65"/>
<source>City</source>
<translation>Град</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="66"/>
<source>ZIP Code</source>
<translation>Пошт. број</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="67"/>
<source>State/Region</source>
<translation>Сав. држ./регију</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="68"/>
<source>Country</source>
<translation>Државу</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="69"/>
<source>Home Page</source>
<translation>Домаћу страницу</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="70"/>
<source>Custom 1</source>
<translation>Посебно 1</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="71"/>
<source>Custom 2</source>
<translation>Посебно 2</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="72"/>
<source>Custom 3</source>
<translation>Посебно 3</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="110"/>
<source>Insert Personal Information</source>
<translation>Уметни лични податак</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="124"/>
<source>Edit</source>
<translation>Уреди</translation>
</message>
</context>
<context>
<name>PIM_Settings</name>
<message>
<location filename="../PIM_settings.ui" line="14"/>
<source>PIM Settings</source>
<translation>ПИМ подешавања</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="112"/>
<source>First Name:</source>
<translation>Име:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="99"/>
<source>Last Name:</source>
<translation>Презиме:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="76"/>
<source>Phone:</source>
<translation>Број телефона:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="128"/>
<source>Mobile Phone:</source>
<translation>Број мобилног тел:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="89"/>
<source>Address:</source>
<translation>Адреса:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="42"/>
<source>&lt;h2&gt;Personal Information Manager&lt;/h2&gt;</source>
<translation>&lt;h2&gt;Менаџер личних података&lt;/h2&gt;</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="64"/>
<source>Your personal information that will be used on webpages.</source>
<translation>Ваши лични подаци које можете да користите на веб страницама.</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="138"/>
<source>City:</source>
<translation>Град:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="151"/>
<source>E-mail:</source>
<translation>Е-адреса:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="167"/>
<source>ZIP Code:</source>
<translation>Пошт. број:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="180"/>
<source>State/Region:</source>
<translation>Савезна држ./регија:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="193"/>
<source>Country:</source>
<translation>Држава:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="206"/>
<source>Home Page:</source>
<translation>Домаћа страница:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="219"/>
<source>Custom 1:</source>
<translation>Посебно 1:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="232"/>
<source>Custom 2:</source>
<translation>Посебно 2:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="245"/>
<source>Custom 3:</source>
<translation>Посебно 3:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="260"/>
<source>&lt;b&gt;Note:&lt;/b&gt; Press Ctrl+ENTER to autofill form fields for which QupZilla finds personal entries.</source>
<translation>&lt;b&gt;Напомена:&lt;/b&gt; Притисните Ctrl+ENTER да бисте аутоматски попунили поља за која Капзила пронађе личне податке.</translation>
</message>
</context>
</TS>

View File

@ -0,0 +1,180 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="zh_TW" sourcelanguage="en_US">
<context>
<name>PIM_Handler</name>
<message>
<location filename="../PIM_handler.cpp" line="60"/>
<source>First Name</source>
<translation></translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="59"/>
<source>Last Name</source>
<translation></translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="61"/>
<source>E-mail</source>
<translation></translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="63"/>
<source>Phone</source>
<translation></translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="66"/>
<source>ZIP Code</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="70"/>
<source>Custom 1</source>
<translation type="unfinished"> 3: {1?}</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="71"/>
<source>Custom 2</source>
<translation type="unfinished"> 3: {2?}</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="72"/>
<source>Custom 3</source>
<translation type="unfinished"> 3: {3?}</translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="110"/>
<source>Insert Personal Information</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="62"/>
<source>Mobile</source>
<translation></translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="64"/>
<source>Address</source>
<translation></translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="65"/>
<source>City</source>
<translation></translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="67"/>
<source>State/Region</source>
<translation> / </translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="68"/>
<source>Country</source>
<translation></translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="69"/>
<source>Home Page</source>
<translation></translation>
</message>
<message>
<location filename="../PIM_handler.cpp" line="124"/>
<source>Edit</source>
<translation></translation>
</message>
</context>
<context>
<name>PIM_Settings</name>
<message>
<location filename="../PIM_settings.ui" line="14"/>
<source>PIM Settings</source>
<translation>PIM </translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="112"/>
<source>First Name:</source>
<translation>:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="99"/>
<source>Last Name:</source>
<translation>:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="76"/>
<source>Phone:</source>
<translation>:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="128"/>
<source>Mobile Phone:</source>
<translation>:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="89"/>
<source>Address:</source>
<translation>:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="42"/>
<source>&lt;h2&gt;Personal Information Manager&lt;/h2&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="64"/>
<source>Your personal information that will be used on webpages.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="138"/>
<source>City:</source>
<translation>:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="151"/>
<source>E-mail:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="167"/>
<source>ZIP Code:</source>
<translation>:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="180"/>
<source>State/Region:</source>
<translation> / :</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="193"/>
<source>Country:</source>
<translation>:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="206"/>
<source>Home Page:</source>
<translation>:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="219"/>
<source>Custom 1:</source>
<translation> 1:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="232"/>
<source>Custom 2:</source>
<translation> 2:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="245"/>
<source>Custom 3:</source>
<translation> 3:</translation>
</message>
<message>
<location filename="../PIM_settings.ui" line="260"/>
<source>&lt;b&gt;Note:&lt;/b&gt; Press Ctrl+ENTER to autofill form fields for which QupZilla finds personal entries.</source>
<translation>&lt;b&gt;:&lt;/b&gt; Ctrl+EnterQupZilla</translation>
</message>
</context>
</TS>

View File

@ -89,7 +89,7 @@ bool TestPlugin::testPlugin()
//There should be some testing if plugin is loaded correctly
//If this function returns false, plugin is automatically unloaded
return (QupZilla::VERSION == "1.2.0");
return (QupZilla::VERSION == "1.3.0");
}
QTranslator* TestPlugin::getTranslator(const QString &locale)