diff --git a/src/lib/app/mainapplication.cpp b/src/lib/app/mainapplication.cpp index 098a579f3..1d3ab3891 100644 --- a/src/lib/app/mainapplication.cpp +++ b/src/lib/app/mainapplication.cpp @@ -93,6 +93,7 @@ MainApplication::MainApplication(int &argc, char** argv) , m_isRestoring(false) , m_startingAfterCrash(false) , m_databaseConnected(false) + , m_registerQAppAssociation(0) { #if defined(Q_WS_X11) && !defined(NO_SYSTEM_DATAPATH) DATADIR = USE_DATADIR; @@ -254,10 +255,17 @@ MainApplication::MainApplication(int &argc, char** argv) int afterLaunch = settings.value("Web-URL-Settings/afterLaunch", 1).toInt(); settings.setValue("SessionRestore/isRunning", true); +#ifndef PORTABLE_BUILD + bool alwaysCheckDefaultBrowser = settings.value("Web-Browser-Settings/CheckDefaultBrowser", DEFAULT_CHECK_DEFAULTBROWSER).toBool(); + if (alwaysCheckDefaultBrowser) { + alwaysCheckDefaultBrowser = checkDefaultWebBrowser(); + settings.setValue("Web-Browser-Settings/CheckDefaultBrowser", alwaysCheckDefaultBrowser); + } +#endif + if (checkUpdates) { new Updater(qupzilla); } - if (m_startingAfterCrash || afterLaunch == 3) { m_restoreManager = new RestoreManager(m_activeProfil + "session.dat"); } @@ -808,6 +816,39 @@ void MainApplication::reloadUserStyleSheet() settings.endGroup(); } +bool MainApplication::checkDefaultWebBrowser() +{ + bool showAgain = true; + if (!associationManager()->isDefaultForAllCapabilities()) { + CheckMessageBox notDefaultDialog(&showAgain, getWindow()); + notDefaultDialog.setWindowTitle(tr("Default Browser")); + notDefaultDialog.setMessage(tr("QupZilla is not currently your default browser. Would you like to make it your default browser?")); + notDefaultDialog.setPixmap(style()->standardIcon(QStyle::SP_MessageBoxWarning).pixmap(32,32)); + notDefaultDialog.setShowAgainText(tr("Always perform this check when starting QupZilla.")); + + if (notDefaultDialog.exec() == QDialog::Accepted) { + associationManager()->registerAllAssociation(); + } + } + + return showAgain; +} + +RegisterQAppAssociation* MainApplication::associationManager() +{ + if (!m_registerQAppAssociation) { + QString desc = tr("QupZilla is a new, fast and secure open-source WWW browser. QupZilla is licensed under GPL version 3 or (at your option) any later version. It is based on WebKit core and Qt Framework."); + QString fileIconPath = QApplication::applicationFilePath() + ",1"; + QString appIconPath = QApplication::applicationFilePath() + ",0"; + m_registerQAppAssociation = new RegisterQAppAssociation("QupZilla", QApplication::applicationFilePath(), appIconPath, desc, this); + m_registerQAppAssociation->addCapability(".html", "QupZilla.HTML", "HTML File", fileIconPath, RegisterQAppAssociation::FileAssociation); + m_registerQAppAssociation->addCapability(".htm", "QupZilla.HTM", "HTM File", fileIconPath, RegisterQAppAssociation::FileAssociation); + m_registerQAppAssociation->addCapability("http", "QupZilla.HTTP", "URL:HyperText Transfer Protocol", appIconPath, RegisterQAppAssociation::UrlAssociation); + m_registerQAppAssociation->addCapability("https", "QupZilla.HTTPS", "URL:HyperText Transfer Protocol with Privacy", appIconPath, RegisterQAppAssociation::UrlAssociation); + } + return m_registerQAppAssociation; +} + QUrl MainApplication::userStyleSheet(const QString &filePath) const { // Set default white background for all sites diff --git a/src/lib/app/mainapplication.h b/src/lib/app/mainapplication.h index 8db04cf5c..dc6581ef6 100644 --- a/src/lib/app/mainapplication.h +++ b/src/lib/app/mainapplication.h @@ -24,6 +24,7 @@ #include #include +#include "registerqappassociation.h" #include "restoremanager.h" #include "qtsingleapplication.h" #include "qz_namespace.h" @@ -108,6 +109,7 @@ public: DatabaseWriter* dbWriter() { return m_dbWriter; } UserAgentManager* uaManager() { return m_uaManager; } RestoreManager* restoreManager() { return m_restoreManager; } + RegisterQAppAssociation* associationManager(); #ifdef Q_OS_MAC bool event(QEvent* e); @@ -123,6 +125,7 @@ public slots: void startPrivateBrowsing(); void reloadUserStyleSheet(); + bool checkDefaultWebBrowser(); signals: void message(Qz::AppMessageType mes, bool state); @@ -175,6 +178,8 @@ private: bool m_databaseConnected; QList m_postLaunchActions; + + RegisterQAppAssociation* m_registerQAppAssociation; }; #endif // MAINAPPLICATION_H diff --git a/src/lib/app/qz_namespace.h b/src/lib/app/qz_namespace.h index 08c15f8d5..8355361ae 100644 --- a/src/lib/app/qz_namespace.h +++ b/src/lib/app/qz_namespace.h @@ -96,8 +96,10 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(Qz::NewTabPositionFlags) #ifdef Q_OS_WIN #define DEFAULT_CHECK_UPDATES true +#define DEFAULT_CHECK_DEFAULTBROWSER true #else #define DEFAULT_CHECK_UPDATES false +#define DEFAULT_CHECK_DEFAULTBROWSER false #endif #ifdef Q_OS_WIN diff --git a/src/lib/lib.pro b/src/lib/lib.pro index 28d3b18dc..4fcfc4ec1 100644 --- a/src/lib/lib.pro +++ b/src/lib/lib.pro @@ -188,7 +188,8 @@ SOURCES += \ session/restoremanager.cpp \ network/schemehandlers/qupzillaschemehandler.cpp \ network/schemehandlers/adblockschemehandler.cpp \ - network/schemehandlers/fileschemehandler.cpp + network/schemehandlers/fileschemehandler.cpp \ + other/registerqappassociation.cpp HEADERS += \ webview/tabpreview.h \ @@ -345,7 +346,8 @@ HEADERS += \ network/schemehandlers/schemehandler.h \ network/schemehandlers/qupzillaschemehandler.h \ network/schemehandlers/adblockschemehandler.h \ - network/schemehandlers/fileschemehandler.h + network/schemehandlers/fileschemehandler.h \ + other/registerqappassociation.h FORMS += \ preferences/autofillmanager.ui \ diff --git a/src/lib/other/registerqappassociation.cpp b/src/lib/other/registerqappassociation.cpp new file mode 100644 index 000000000..916cf425a --- /dev/null +++ b/src/lib/other/registerqappassociation.cpp @@ -0,0 +1,506 @@ +/* ============================================================ +* Copyright (C) 2012 S. Razi Alavizadeh +* This file is part of QupZilla - WebKit based browser 2010-2012 +* by David Rosca +* +* 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 . +* ============================================================ */ + +#include "registerqappassociation.h" + +#ifdef Q_OS_WIN +#include "ShlObj.h" +#include +#endif + +#include +#include +#include + +RegisterQAppAssociation::RegisterQAppAssociation(QObject *parent) : + QObject(parent) +{ + setPerMachineRegisteration(false); +} + +RegisterQAppAssociation::RegisterQAppAssociation(const QString &appRegisteredName, const QString &appPath, const QString &appIcon, + const QString &appDesc, QObject *parent) + : QObject(parent) +{ + setPerMachineRegisteration(false); + setAppInfo(appRegisteredName, appPath, appIcon, appDesc); +} + +RegisterQAppAssociation::~RegisterQAppAssociation() +{ +} + +void RegisterQAppAssociation::addCapability(const QString &assocName, const QString &progId, + const QString &desc, const QString &iconPath, AssociationType type) +{ + _assocDescHash.insert(progId, QPair(desc, QDir::toNativeSeparators(iconPath))); + switch (type) { + case FileAssociation: + _fileAssocHash.insert(assocName, progId); + break; + case UrlAssociation: + _urlAssocHash.insert(assocName, progId); + break; + + default: + break; + } +} + +void RegisterQAppAssociation::removeCapability(const QString &assocName) +{ + _fileAssocHash.remove(assocName); + _urlAssocHash.remove(assocName); +} + +void RegisterQAppAssociation::setAppInfo(const QString &appRegisteredName, const QString &appPath, + const QString &appIcon, const QString &appDesc) +{ + _appRegisteredName = appRegisteredName; + _appPath = QDir::toNativeSeparators(appPath); + _appIcon = QDir::toNativeSeparators(appIcon); + _appDesc = appDesc; +} + +bool RegisterQAppAssociation::isPerMachineRegisteration() +{ +#ifdef Q_OS_WIN + return (_UserRootKey == "HKEY_LOCAL_MACHINE"); +#else + return false; +#endif +} + +void RegisterQAppAssociation::setPerMachineRegisteration(bool enable) +{ +#ifdef Q_OS_WIN + if (enable) { + _UserRootKey = "HKEY_LOCAL_MACHINE"; + } + else { + _UserRootKey = "HKEY_CURRENT_USER"; + } +#else + Q_UNUSED(enable) +#endif +} + +#ifdef Q_OS_WIN +bool RegisterQAppAssociation::registerAppCapabilities() +{ + if (!isVistaOrNewer()) { + return true; + } + // Vista and newer + QSettings regLocalMachine("HKEY_LOCAL_MACHINE", QSettings::NativeFormat); + QString capabilitiesKey = regLocalMachine.value("Software/RegisteredApplications/" + _appRegisteredName).toString(); + + if (capabilitiesKey.isEmpty()) { + regLocalMachine.setValue("Software/RegisteredApplications/" + _appRegisteredName, + QString("Software\\" + _appRegisteredName + "\\Capabilities")); + capabilitiesKey = regLocalMachine.value("Software/RegisteredApplications/" + _appRegisteredName).toString(); + + if (capabilitiesKey.isEmpty()) { + QMessageBox::warning(0, tr("Warning!"), + tr("There are some problems. Please, reinstall QupZilla.\n" + "Maybe relaunch with administrator right do a magic for you! ;)")); + return false; + } + } + + capabilitiesKey.replace("\\", "/"); + + QHash >::const_iterator it = _assocDescHash.constBegin(); + while (it != _assocDescHash.constEnd()) { + createProgId(it.key()); + ++it; + } + + regLocalMachine.setValue(capabilitiesKey + "/ApplicationDescription", _appDesc); + regLocalMachine.setValue(capabilitiesKey + "/ApplicationIcon", _appIcon); + regLocalMachine.setValue(capabilitiesKey + "/ApplicationName", _appRegisteredName); + + QHash::const_iterator i = _fileAssocHash.constBegin(); + while (i != _fileAssocHash.constEnd()) { + regLocalMachine.setValue(capabilitiesKey + "/FileAssociations/" + i.key(), i.value()); + ++i; + } + + i = _urlAssocHash.constBegin(); + while (i != _urlAssocHash.constEnd()) { + regLocalMachine.setValue(capabilitiesKey + "/URLAssociations/" + i.key(), i.value()); + ++i; + } + regLocalMachine.setValue(capabilitiesKey + "/Startmenu/StartMenuInternet", _appPath); + + return true; +} + +bool RegisterQAppAssociation::isVistaOrNewer() +{ + return (QSysInfo::windowsVersion() >= QSysInfo::WV_VISTA && + QSysInfo::windowsVersion() <= QSysInfo::WV_NT_based); +} +#endif + +void RegisterQAppAssociation::registerAssociation(const QString &assocName, AssociationType type) +{ +#ifdef Q_OS_WIN + if (isVistaOrNewer()) { // Vista and newer + IApplicationAssociationRegistration* pAAR; + + HRESULT hr = CoCreateInstance(CLSID_ApplicationAssociationRegistration, + NULL, + CLSCTX_INPROC, + __uuidof(IApplicationAssociationRegistration), + (void**)&pAAR); + if (SUCCEEDED(hr)) { + switch (type) { + case FileAssociation: + hr = pAAR->SetAppAsDefault(_appRegisteredName.toStdWString().c_str(), + assocName.toStdWString().c_str(), + AT_FILEEXTENSION); + break; + case UrlAssociation: + { + QSettings regCurrentUserRoot("HKEY_CURRENT_USER", QSettings::NativeFormat); + QString currentUrlDefault = + regCurrentUserRoot.value("Software/Microsoft/Windows/Shell/Associations/UrlAssociations/" + + assocName + "/UserChoice/Progid").toString(); + hr = pAAR->SetAppAsDefault(_appRegisteredName.toStdWString().c_str(), + assocName.toStdWString().c_str(), + AT_URLPROTOCOL); + if (SUCCEEDED(hr) + && !currentUrlDefault.isEmpty() + && currentUrlDefault != _urlAssocHash.value(assocName)) { + regCurrentUserRoot.setValue("Software/Classes" + + assocName + + "/shell/open/command/backup_progid", currentUrlDefault); + } + } + break; + + default: + break; + } + + pAAR->Release(); + } + } + else { // Older than Vista + QSettings regUserRoot(_UserRootKey, QSettings::NativeFormat); + regUserRoot.beginGroup("Software/Classes"); + QSettings regClassesRoot("HKEY_CLASSES_ROOT", QSettings::NativeFormat); + switch (type) { + case FileAssociation: + { + QString progId = _fileAssocHash.value(assocName); + createProgId(progId); + QString currentDefault = regClassesRoot.value(assocName + "/Default").toString(); + if (!currentDefault.isEmpty() + && currentDefault != progId + && regUserRoot.value(assocName + "/backup_val").toString() != progId) { + regUserRoot.setValue(assocName + "/backup_val", currentDefault); + } + regUserRoot.setValue(assocName + "/.", progId); + } + break; + case UrlAssociation: + { + QString progId = _urlAssocHash.value(assocName); + createProgId(progId); + QString currentDefault = regClassesRoot.value(assocName + "/shell/open/command/Default").toString(); + QString command = "\""+_appPath+"\" \"%1\""; + if (!currentDefault.isEmpty() + && currentDefault != command + && regUserRoot.value(assocName + "/shell/open/command/backup_val").toString() != command) { + regUserRoot.setValue(assocName + "/shell/open/command/backup_val", currentDefault); + } + + regUserRoot.setValue(assocName + "/shell/open/command/.", command); + regUserRoot.setValue(assocName + "/URL Protocol", ""); + break; + } + default: + break; + } + regUserRoot.endGroup(); + } +#else + Q_UNUSED(assocName) + Q_UNUSED(type) +#endif +} + +void RegisterQAppAssociation::registerAllAssociation() +{ +#ifdef Q_OS_WIN + if (isVistaOrNewer() && !registerAppCapabilities()) { + return; + } +#endif + + QHash::const_iterator i = _fileAssocHash.constBegin(); + while (i != _fileAssocHash.constEnd()) { + registerAssociation(i.key(), FileAssociation); + ++i; + } + + i = _urlAssocHash.constBegin(); + while (i != _urlAssocHash.constEnd()) { + registerAssociation(i.key(), UrlAssociation); + ++i; + } + +#ifdef Q_OS_WIN + if (!isVistaOrNewer()) { + // On Windows Vista or newer for updating icons 'pAAR->SetAppAsDefault()' + // calls 'SHChangeNotify()'. Thus, we just need care about older Windows. + SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSHNOWAIT, 0 ,0); + } +#endif +} + +void RegisterQAppAssociation::createProgId(const QString &progId) +{ +#ifdef Q_OS_WIN + QSettings regUserRoot(_UserRootKey, QSettings::NativeFormat); + regUserRoot.beginGroup("Software/Classes"); + QPair pair = _assocDescHash.value(progId); + regUserRoot.setValue(progId + "/.", pair.first); + regUserRoot.setValue(progId + "/shell/.", "open"); + regUserRoot.setValue(progId + "/DefaultIcon/.", pair.second); + regUserRoot.setValue(progId + "/shell/open/command/.", QString("\""+_appPath+"\" \"%1\"")); + regUserRoot.endGroup(); +#else + Q_UNUSED(progId) +#endif +} + +bool RegisterQAppAssociation::isDefaultApp(const QString &assocName, AssociationType type) +{ +#ifdef Q_OS_WIN + if (isVistaOrNewer()) { + QSettings regCurrentUserRoot("HKEY_CURRENT_USER", QSettings::NativeFormat); + switch (type) { + case FileAssociation: + { + regCurrentUserRoot.beginGroup("Software/Microsoft/Windows/CurrentVersion/Explorer/FileExts"); + if (regCurrentUserRoot.childGroups().contains(assocName, Qt::CaseInsensitive)) { + return (_fileAssocHash.value(assocName) + == regCurrentUserRoot.value(assocName + "/UserChoice/Progid")); + } + else { + regCurrentUserRoot.endGroup(); + return false; + } + break; + } + case UrlAssociation: + { + regCurrentUserRoot.beginGroup("Software/Microsoft/Windows/Shell/Associations/UrlAssociations"); + if (regCurrentUserRoot.childGroups().contains(assocName, Qt::CaseInsensitive)) { + return (_urlAssocHash.value(assocName) + == regCurrentUserRoot.value(assocName + "/UserChoice/Progid")); + } + else { + regCurrentUserRoot.endGroup(); + return false; + } + } + break; + + default: + break; + } + } + else { + QSettings regClassesRoot("HKEY_CLASSES_ROOT", QSettings::NativeFormat); + { + if (!regClassesRoot.childGroups().contains(assocName, Qt::CaseInsensitive)) { + return false; + } + } + switch (type) { + case FileAssociation: + { + return (_fileAssocHash.value(assocName) + == regClassesRoot.value(assocName + "/Default")); + } + break; + case UrlAssociation: + { + QString currentDefault = regClassesRoot.value(assocName + "/shell/open/command/Default").toString(); + currentDefault.remove("\""); + currentDefault.remove("%1"); + currentDefault = currentDefault.trimmed(); + return (_appPath == currentDefault); + } + break; + + default: + break; + } + } +#else + Q_UNUSED(assocName) + Q_UNUSED(type) +#endif + return false; +} + +bool RegisterQAppAssociation::isDefaultForAllCapabilities() +{ + bool result = true; + QHash::const_iterator i = _fileAssocHash.constBegin(); + while (i != _fileAssocHash.constEnd()) { + bool res = isDefaultApp(i.key(), FileAssociation); + result &= res; + ++i; + } + + i = _urlAssocHash.constBegin(); + while (i != _urlAssocHash.constEnd()) { + bool res = isDefaultApp(i.key(), UrlAssociation); + result &= res; + ++i; + } + return result; +} + +/***************************************/ +/******** CheckMessageBox Class ********/ +/***************************************/ + +CheckMessageBox::CheckMessageBox(bool *defaultShowAgainState, QWidget *parent, Qt::WindowFlags f) + : QDialog(parent, f | Qt::MSWindowsFixedSizeDialogHint), + _showAgainState(defaultShowAgainState) +{ + setupUi(); + if (defaultShowAgainState) { + showAgainCheckBox->setChecked(*defaultShowAgainState); + } + else { + showAgainCheckBox->hide(); + disconnect(showAgainCheckBox, SIGNAL(toggled(bool)), this, SLOT(showAgainStateChanged(bool))); + } +} + +CheckMessageBox::CheckMessageBox(const QString &msg, const QPixmap &pixmap, + const QString &str, bool *defaultShowAgainState, + QWidget *parent, Qt::WindowFlags f) + : QDialog(parent, f | Qt::MSWindowsFixedSizeDialogHint), + _showAgainState(defaultShowAgainState) +{ + setupUi(); + setMessage(msg); + setPixmap(pixmap); + if (defaultShowAgainState) { + setShowAgainText(str); + } +} + +CheckMessageBox::~CheckMessageBox() +{ +} + +void CheckMessageBox::setMessage(const QString &msg) +{ + messageLabel->setText(msg); +} + +void CheckMessageBox::setShowAgainText(const QString &str) +{ + showAgainCheckBox->setText(str); +} + +void CheckMessageBox::setPixmap(const QPixmap &pixmap) +{ + pixmapLabel->setPixmap(pixmap); +} + +void CheckMessageBox::setupUi() +{ + setObjectName(QString::fromUtf8("CheckMessageBox")); + gridLayout = new QGridLayout(this); + gridLayout->setObjectName(QString::fromUtf8("gridLayout")); + horizontalLayout = new QHBoxLayout(); + horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); + verticalLayout_2 = new QVBoxLayout(); + verticalLayout_2->setObjectName(QString::fromUtf8("verticalLayout_2")); + pixmapLabel = new QLabel(this); + pixmapLabel->setObjectName(QString::fromUtf8("pixmapLabel")); + + verticalLayout_2->addWidget(pixmapLabel); + + verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); + + verticalLayout_2->addItem(verticalSpacer); + + + horizontalLayout->addLayout(verticalLayout_2); + + verticalLayout = new QVBoxLayout(); + verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); + messageLabel = new QLabel(this); + messageLabel->setObjectName(QString::fromUtf8("messageLabel")); + messageLabel->setWordWrap(true); + + verticalLayout->addWidget(messageLabel); + + horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + + verticalLayout->addItem(horizontalSpacer); + + showAgainCheckBox = new QCheckBox(this); + showAgainCheckBox->setObjectName(QString::fromUtf8("showAgainCheckBox")); + + verticalLayout->addWidget(showAgainCheckBox); + + + horizontalLayout->addLayout(verticalLayout); + + + gridLayout->addLayout(horizontalLayout, 0, 0, 1, 1); + + buttonBox = new QDialogButtonBox(this); + buttonBox->setObjectName(QString::fromUtf8("buttonBox")); + buttonBox->setOrientation(Qt::Horizontal); + buttonBox->setStandardButtons(QDialogButtonBox::No|QDialogButtonBox::Yes); + + gridLayout->addWidget(buttonBox, 1, 0, 1, 1); + + connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + + if (_showAgainState) { + showAgainCheckBox->setChecked(*_showAgainState); + connect(showAgainCheckBox, SIGNAL(toggled(bool)), this, SLOT(showAgainStateChanged(bool))); + } + else { + showAgainCheckBox->hide(); + } +} + +void CheckMessageBox::showAgainStateChanged(bool checked) +{ + if (_showAgainState) { + *_showAgainState = checked; + } +} diff --git a/src/lib/other/registerqappassociation.h b/src/lib/other/registerqappassociation.h new file mode 100644 index 000000000..dcd856e44 --- /dev/null +++ b/src/lib/other/registerqappassociation.h @@ -0,0 +1,115 @@ +/* ============================================================ +* Copyright (C) 2012 S. Razi Alavizadeh +* This file is part of QupZilla - WebKit based browser 2010-2012 +* by David Rosca +* +* 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 . +* ============================================================ */ +#ifndef REGISTERQAPPASSOCIATION_H +#define REGISTERQAPPASSOCIATION_H + +#include +#include + +#include "qz_namespace.h" + +class QT_QUPZILLA_EXPORT RegisterQAppAssociation : public QObject +{ + Q_OBJECT +public: + explicit RegisterQAppAssociation(QObject* parent = 0); + explicit RegisterQAppAssociation(const QString &appRegisteredName, const QString &appPath, + const QString &appIcon = "", const QString &appDesc = "", QObject* parent = 0); + ~RegisterQAppAssociation(); + + enum AssociationType { + FileAssociation, + UrlAssociation + }; + + void addCapability(const QString &assocName, const QString &progId, + const QString &desc, const QString &iconPath, AssociationType type); + void removeCapability(const QString &assocName); + + void setAppInfo(const QString &appRegisteredName, const QString &appPath, + const QString &appIcon = "", const QString &appDesc = ""); + + bool isPerMachineRegisteration(); + void setPerMachineRegisteration(bool enable); +#ifdef Q_OS_WIN + bool registerAppCapabilities(); + bool isVistaOrNewer(); +#endif + void registerAssociation(const QString &assocName, AssociationType type); + void createProgId(const QString &progId); + + bool isDefaultApp(const QString &assocName, AssociationType type); + bool isDefaultForAllCapabilities(); + void registerAllAssociation(); + + +private: + QString _appRegisteredName; + QString _appPath; + QString _appIcon; + QString _appDesc; +#ifdef Q_OS_WIN + QString _UserRootKey; +#endif + + QHash _fileAssocHash; // (extention, progId) + QHash _urlAssocHash; // (protocol, progId) + QHash > _assocDescHash; // (progId, (desc, icon)) +}; + +#include +#include +#include +#include +#include + +class QT_QUPZILLA_EXPORT CheckMessageBox : public QDialog +{ + Q_OBJECT + +public: + CheckMessageBox(bool *defaultShowAgainState = 0, QWidget *parent = 0, Qt::WindowFlags f = 0); + CheckMessageBox(const QString &msg, const QPixmap &pixmap, + const QString &str, bool *defaultShowAgainState, + QWidget *parent = 0, Qt::WindowFlags f = 0); + ~CheckMessageBox(); + + void setMessage(const QString &msg); + void setShowAgainText(const QString &str); + void setPixmap(const QPixmap &pixmap); + +private: + void setupUi(); + + bool *_showAgainState; + QGridLayout *gridLayout; + QHBoxLayout *horizontalLayout; + QVBoxLayout *verticalLayout_2; + QLabel *pixmapLabel; + QSpacerItem *verticalSpacer; + QVBoxLayout *verticalLayout; + QLabel *messageLabel; + QSpacerItem *horizontalSpacer; + QCheckBox *showAgainCheckBox; + QDialogButtonBox *buttonBox; + +private slots: + void showAgainStateChanged(bool checked); +}; +#endif // REGISTERQAPPASSOCIATION_H diff --git a/src/lib/preferences/preferences.cpp b/src/lib/preferences/preferences.cpp index e8e930288..015342467 100644 --- a/src/lib/preferences/preferences.cpp +++ b/src/lib/preferences/preferences.cpp @@ -101,7 +101,24 @@ Preferences::Preferences(QupZilla* mainClass, QWidget* parent) ui->afterLaunch->setCurrentIndex(afterLaunch); ui->checkUpdates->setChecked(settings.value("Web-Browser-Settings/CheckUpdates", DEFAULT_CHECK_UPDATES).toBool()); ui->dontLoadTabsUntilSelected->setChecked(settings.value("Web-Browser-Settings/LoadTabsOnActivation", false).toBool()); - +#ifdef Q_OS_WIN + ui->checkDefaultBrowser->setChecked(settings.value("Web-Browser-Settings/CheckDefaultBrowser", DEFAULT_CHECK_DEFAULTBROWSER).toBool()); + if (mApp->associationManager()->isDefaultForAllCapabilities()) { + ui->checkNowDefaultBrowser->setText(tr("QupZilla is default")); + ui->checkNowDefaultBrowser->setEnabled(false); + } + else { + ui->checkNowDefaultBrowser->setText(tr("Make QupZilla default")); + ui->checkNowDefaultBrowser->setEnabled(true); + connect(ui->checkNowDefaultBrowser, SIGNAL(clicked()), this, SLOT(makeQupZillaDefault())); + } +#else // just Windows + ui->hSpacerDefaultBrowser->changeSize(0, 0, QSizePolicy::Fixed, QSizePolicy::Fixed); + ui->hLayoutDefaultBrowser->invalidate(); + delete ui->hLayoutDefaultBrowser; + delete ui->checkDefaultBrowser; + delete ui->checkNowDefaultBrowser; +#endif ui->newTabFrame->setVisible(false); if (m_newTabUrl.isEmpty()) { ui->newTab->setCurrentIndex(0); @@ -489,6 +506,16 @@ void Preferences::setNotificationPreviewVisible(bool state) } } +void Preferences::makeQupZillaDefault() +{ +#ifdef Q_OS_WIN + disconnect(ui->checkNowDefaultBrowser, SIGNAL(clicked()), this, SLOT(makeQupZillaDefault())); + mApp->associationManager()->registerAllAssociation(); + ui->checkNowDefaultBrowser->setText(tr("QupZilla is default")); + ui->checkNowDefaultBrowser->setEnabled(false); +#endif +} + void Preferences::allowCacheChanged(bool state) { ui->cacheFrame->setEnabled(state); @@ -868,7 +895,9 @@ void Preferences::saveSettings() settings.setValue("LoadTabsOnActivation", ui->dontLoadTabsUntilSelected->isChecked()); settings.setValue("DefaultZoom", ui->defaultZoom->value()); settings.setValue("XSSAuditing", ui->xssAuditing->isChecked()); - +#ifdef Q_OS_WIN + settings.setValue("CheckDefaultBrowser", ui->checkDefaultBrowser->isChecked()); +#endif //Cache settings.setValue("maximumCachedPages", ui->pagesInCache->value()); settings.setValue("AllowLocalCache", ui->allowCache->isChecked()); diff --git a/src/lib/preferences/preferences.h b/src/lib/preferences/preferences.h index 63c567936..0655b1002 100644 --- a/src/lib/preferences/preferences.h +++ b/src/lib/preferences/preferences.h @@ -88,6 +88,8 @@ private slots: void setNotificationPreviewVisible(bool state); + void makeQupZillaDefault(); + private: void closeEvent(QCloseEvent* event); diff --git a/src/lib/preferences/preferences.ui b/src/lib/preferences/preferences.ui index 4bfdff32b..9ba0631b6 100644 --- a/src/lib/preferences/preferences.ui +++ b/src/lib/preferences/preferences.ui @@ -164,11 +164,86 @@ - - - - <b>Launching</b> + + + + + 0 + + + + + + + + Use current + + + + + + + + + + QFrame::NoFrame + + QFrame::Raised + + + + 0 + + + 0 + + + 20 + + + 0 + + + + + Note: You cannot delete active profile. + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + Create New + + + + + + + false + + + + 0 + 0 + + + + Delete + + + + @@ -187,6 +262,16 @@ + + + + <b>Launching</b> + + + + + + @@ -270,105 +355,20 @@ - + <b>Profiles</b> - + Startup profile: - - - - - - - QFrame::NoFrame - - - QFrame::Raised - - - - 0 - - - 0 - - - 20 - - - 0 - - - - - Note: You cannot delete active profile. - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - Create New - - - - - - - false - - - - 0 - 0 - - - - Delete - - - - - - - - - - - 0 - - - - - - - - Use current - - - - - - @@ -376,35 +376,35 @@ - + Active profile: - + - + In order to change language, you must restart browser. - + <b>Language</b> - + @@ -427,7 +427,7 @@ - + @@ -437,7 +437,7 @@ - + Qt::Vertical @@ -450,6 +450,40 @@ + + + + + + Check to see if QupZilla is the default browser on startup + + + false + + + + + + + Check Now + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + +