File indexing completed on 2024-05-05 05:00:08
0001 /* 0002 Add here all general options - those that apply to both web browsing and filemanagement mode 0003 0004 SPDX-FileCopyrightText: 1998 Sven Radej 0005 SPDX-FileCopyrightText: 1998 David Faure 0006 SPDX-FileCopyrightText: 2001 Waldo Bastian <bastian@kde.org> 0007 SPDX-FileCopyrightText: 2007 Nick Shaforostoff <shafff@ukr.net> 0008 */ 0009 0010 // Own 0011 #include "generalopts.h" 0012 0013 // Qt 0014 #include <QDBusConnection> 0015 #include <QDBusMessage> 0016 #include <QComboBox> 0017 #include <QFormLayout> 0018 #include <QGroupBox> 0019 #include <QLineEdit> 0020 #include <QLabel> 0021 #include <QStandardPaths> 0022 #include <QUrl> 0023 0024 // KDE 0025 #include <kbuildsycocaprogressdialog.h> 0026 #include <KConfigGroup> 0027 #include <KSharedConfig> 0028 #include <KMessageWidget> 0029 #include <KParts/PartLoader> 0030 #include <KLocalizedString> 0031 0032 // Keep in sync with konqueror.kcfg 0033 static const char DEFAULT_STARTPAGE[] = "konq:konqueror"; 0034 static const char DEFAULT_HOMEPAGE[] = "https://www.kde.org/"; 0035 // Keep in sync with the order in the combo 0036 enum StartPage { ShowAboutPage, ShowStartUrlPage, ShowBlankPage, ShowBookmarksPage }; 0037 0038 //----------------------------------------------------------------------------- 0039 0040 KKonqGeneralOptions::KKonqGeneralOptions(QObject *parent, const KPluginMetaData &md, const QVariantList &) 0041 : KCModule(parent, md), m_emptyStartUrlWarning(new KMessageWidget(widget())) 0042 { 0043 m_pConfig = KSharedConfig::openConfig(QStringLiteral("konquerorrc"), KConfig::NoGlobals); 0044 QVBoxLayout *lay = new QVBoxLayout(widget()); 0045 lay->setContentsMargins(0, 0, 0, 0); 0046 0047 addHomeUrlWidgets(lay); 0048 setNeedsSave(false); 0049 } 0050 0051 void KKonqGeneralOptions::addHomeUrlWidgets(QVBoxLayout *lay) 0052 { 0053 QFormLayout *formLayout = new QFormLayout; 0054 lay->addLayout(formLayout); 0055 0056 m_emptyStartUrlWarning->setText(i18nc("The user chose to use a custom start page but left the corresponding field empty", "Please, insert the custom start page")); 0057 m_emptyStartUrlWarning->setMessageType(KMessageWidget::Warning); 0058 m_emptyStartUrlWarning->setIcon(QIcon::fromTheme("dialog-warning")); 0059 m_emptyStartUrlWarning->hide(); 0060 formLayout->addRow(m_emptyStartUrlWarning); 0061 0062 QLabel *startLabel = new QLabel(i18nc("@label:listbox", "When a new &Tab is created"), widget()); 0063 0064 QWidget *containerWidget = new QWidget(widget()); 0065 QHBoxLayout *hboxLayout = new QHBoxLayout(containerWidget); 0066 hboxLayout->setContentsMargins(0, 0, 0, 0); 0067 formLayout->addRow(startLabel, containerWidget); 0068 0069 m_startCombo = new QComboBox(widget()); 0070 m_startCombo->setEditable(false); 0071 m_startCombo->addItem(i18nc("@item:inlistbox", "Show Introduction Page"), ShowAboutPage); 0072 m_startCombo->addItem(i18nc("@item:inlistbox", "Show My Start Page"), ShowStartUrlPage); 0073 m_startCombo->addItem(i18nc("@item:inlistbox", "Show Blank Page"), ShowBlankPage); 0074 m_startCombo->addItem(i18nc("@item:inlistbox", "Show My Bookmarks"), ShowBookmarksPage); 0075 startLabel->setBuddy(m_startCombo); 0076 connect(m_startCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &KKonqGeneralOptions::slotChanged); 0077 hboxLayout->addWidget(m_startCombo); 0078 0079 startURL = new QLineEdit(widget()); 0080 startURL->setWindowTitle(i18nc("@title:window", "Select Start Page")); 0081 hboxLayout->addWidget(startURL); 0082 connect(startURL, &QLineEdit::textChanged, this, &KKonqGeneralOptions::displayEmpytStartPageWarningIfNeeded); 0083 connect(startURL, &QLineEdit::textChanged, this, &KKonqGeneralOptions::slotChanged); 0084 0085 QString startstr = i18n("This is the URL of the web page " 0086 "Konqueror will show when starting."); 0087 startURL->setToolTip(startstr); 0088 connect(m_startCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [this](int idx) { 0089 startURL->setVisible(idx == ShowStartUrlPage); 0090 displayEmpytStartPageWarningIfNeeded(); 0091 }); 0092 startURL->hide(); 0093 0094 //// 0095 0096 QLabel *label = new QLabel(i18n("Home page:"), widget()); 0097 0098 homeURL = new QLineEdit(widget()); 0099 homeURL->setWindowTitle(i18nc("@title:window", "Select Home Page")); 0100 formLayout->addRow(label, homeURL); 0101 connect(homeURL, &QLineEdit::textChanged, this, &KKonqGeneralOptions::slotChanged); 0102 label->setBuddy(homeURL); 0103 0104 QString homestr = i18n("This is the URL of the web page where " 0105 "Konqueror will jump to when " 0106 "the \"Home\" button is pressed."); 0107 label->setToolTip(homestr); 0108 homeURL->setToolTip(homestr); 0109 0110 //// 0111 0112 QLabel *webLabel = new QLabel(i18n("Default web browser engine:"), widget()); 0113 0114 m_webEngineCombo = new QComboBox(widget()); 0115 m_webEngineCombo->setEditable(false); 0116 m_webEngineCombo->setSizeAdjustPolicy(QComboBox::AdjustToContents); 0117 formLayout->addRow(webLabel, m_webEngineCombo); 0118 webLabel->setBuddy(m_webEngineCombo); 0119 connect(m_webEngineCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &KKonqGeneralOptions::slotChanged); 0120 0121 QLabel *splitLabel = new QLabel(i18n("When splitting a view")); 0122 m_splitBehaviour = new QComboBox(widget()); 0123 //Keep items order in sync with KonqMainWindow::SplitBehaviour 0124 m_splitBehaviour->addItems({ 0125 i18n("Always duplicate current view"), 0126 i18n("Duplicate current view only for local files") 0127 }); 0128 splitLabel->setBuddy(m_splitBehaviour); 0129 formLayout->addRow(splitLabel, m_splitBehaviour); 0130 connect(m_splitBehaviour, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &KKonqGeneralOptions::slotChanged); 0131 0132 m_restoreLastState = new QCheckBox(i18n("When starting up, restore state from last time"), widget()); 0133 connect(m_restoreLastState, &QCheckBox::stateChanged, this, &KKonqGeneralOptions::slotChanged); 0134 formLayout->addRow(m_restoreLastState); 0135 } 0136 0137 KKonqGeneralOptions::~KKonqGeneralOptions() 0138 { 0139 } 0140 0141 void KKonqGeneralOptions::displayEmpytStartPageWarningIfNeeded() 0142 { 0143 if (startURL->isVisible() && startURL->text().isEmpty()) { 0144 m_emptyStartUrlWarning->animatedShow(); 0145 } else if (m_emptyStartUrlWarning->isVisible()) { 0146 m_emptyStartUrlWarning->animatedHide(); 0147 } 0148 } 0149 0150 static StartPage urlToStartPageEnum(const QString &startUrl) 0151 { 0152 if (startUrl == QLatin1String("konq:blank")) { 0153 return ShowBlankPage; 0154 } 0155 if (startUrl == QLatin1String("konq:") || startUrl == QLatin1String("konq:konqueror")) { 0156 return ShowAboutPage; 0157 } 0158 if (startUrl == QLatin1String("bookmarks:") || startUrl == QLatin1String("bookmarks:/")) { 0159 return ShowBookmarksPage; 0160 } 0161 return ShowStartUrlPage; 0162 } 0163 0164 static QString startPageEnumToUrl(StartPage startPage) 0165 { 0166 switch (startPage) { 0167 case ShowBlankPage: 0168 return QStringLiteral("konq:blank"); 0169 case ShowAboutPage: 0170 return QStringLiteral("konq:konqueror"); 0171 case ShowBookmarksPage: 0172 return QStringLiteral("bookmarks:/"); 0173 case ShowStartUrlPage: 0174 return QString(); 0175 } 0176 return QString(); 0177 } 0178 0179 void KKonqGeneralOptions::load() 0180 { 0181 KConfigGroup userSettings(m_pConfig, "UserSettings"); 0182 const QUrl homeUrl(QUrl(userSettings.readEntry("HomeURL", DEFAULT_HOMEPAGE))); 0183 const QUrl startUrl(QUrl(userSettings.readEntry("StartURL", DEFAULT_STARTPAGE))); 0184 homeURL->setText(homeUrl.toString()); 0185 startURL->setText(startUrl.toString()); 0186 const StartPage startPage = urlToStartPageEnum(startUrl.toString()); 0187 const int startComboIndex = m_startCombo->findData(startPage); 0188 Q_ASSERT(startComboIndex != -1); 0189 m_startCombo->setCurrentIndex(startComboIndex); 0190 0191 const bool alwaysDuplicateWhenSplitting = userSettings.readEntry("AlwaysDuplicatePageWhenSplittingView", true); 0192 m_splitBehaviour->setCurrentIndex(alwaysDuplicateWhenSplitting ? 0 : 1); 0193 0194 const bool restoreLastState = userSettings.readEntry(QStringLiteral("RestoreLastState"), false); 0195 m_restoreLastState->setChecked(restoreLastState); 0196 0197 m_webEngineCombo->clear(); 0198 // ## Well, the problem with using the trader to find the available parts, is that if a user 0199 // removed a part in keditfiletype text/html, it won't be in the list anymore. Oh well. 0200 QVector<KPluginMetaData> allParts = KParts::PartLoader::partsForMimeType(QStringLiteral("text/html")); 0201 QVector<KPluginMetaData> partOfferList; 0202 auto filter = [](const KPluginMetaData &md){ 0203 return !md.mimeTypes().contains(QStringLiteral("text/plain")); 0204 }; 0205 std::copy_if(allParts.constBegin(), allParts.constEnd(), std::back_inserter(partOfferList), filter); 0206 0207 //We need to remove duplicates caused by having parts with both plugin metadata and .desktop files being returned twice by KParts::PartLoader::partsForMimeType 0208 //TODO: remove this when this doesn't happen anymore (KF6?) 0209 std::sort(partOfferList.begin(), partOfferList.end(), [](const KPluginMetaData &md1, const KPluginMetaData &md2){return md1.pluginId() == md2.pluginId();}); 0210 auto unique = std::unique(partOfferList.begin(), partOfferList.end(), [](const KPluginMetaData &md1, const KPluginMetaData &md2){return md1.pluginId() == md2.pluginId();}); 0211 partOfferList.erase(unique, partOfferList.end()); 0212 for (const KPluginMetaData &md : partOfferList) { 0213 m_webEngineCombo->addItem(QIcon::fromTheme(md.iconName()), md.name(), md.pluginId()); 0214 } 0215 KCModule::load(); 0216 } 0217 0218 void KKonqGeneralOptions::defaults() 0219 { 0220 homeURL->setText(QUrl(DEFAULT_HOMEPAGE).toString()); 0221 startURL->setText(QUrl(DEFAULT_STARTPAGE).toString()); 0222 m_splitBehaviour->setCurrentIndex(0); 0223 m_restoreLastState->setChecked(false); 0224 0225 bool old = m_pConfig->readDefaults(); 0226 m_pConfig->setReadDefaults(true); 0227 load(); 0228 m_pConfig->setReadDefaults(old); 0229 #if QT_VERSION_MAJOR > 5 0230 setRepresentsDefaults(true); 0231 #endif 0232 } 0233 0234 void KKonqGeneralOptions::save() 0235 { 0236 KConfigGroup userSettings(m_pConfig, "UserSettings"); 0237 const int startComboIndex = m_startCombo->currentIndex(); 0238 const StartPage choice = static_cast<StartPage>(m_startCombo->itemData(startComboIndex).toInt()); 0239 QString startUrl(startPageEnumToUrl(static_cast<StartPage>(choice))); 0240 if (startUrl.isEmpty()) { 0241 startUrl = startURL->text(); 0242 } 0243 userSettings.writeEntry("StartURL", startUrl); 0244 userSettings.writeEntry("HomeURL", homeURL->text()); 0245 userSettings.writeEntry("AlwaysDuplicatePageWhenSplittingView", m_splitBehaviour->currentIndex() == 0); 0246 userSettings.writeEntry("RestoreLastState", m_restoreLastState->isChecked()); 0247 0248 if (m_webEngineCombo->currentIndex() > 0) { 0249 // The user changed the preferred web engine, save into mimeapps.list. 0250 const QString preferredWebEngine = m_webEngineCombo->itemData(m_webEngineCombo->currentIndex()).toString(); 0251 //qCDebug(KONQUEROR_LOG) << "preferredWebEngine=" << preferredWebEngine; 0252 0253 KSharedConfig::Ptr profile = KSharedConfig::openConfig(QStringLiteral("mimeapps.list"), KConfig::NoGlobals, QStandardPaths::ConfigLocation); 0254 KConfigGroup addedServices(profile, "Added KDE Service Associations"); 0255 for (const QString &mimeType: QStringList() << "text/html" << "application/xhtml+xml" << "application/xml") { 0256 QStringList services = addedServices.readXdgListEntry(mimeType); 0257 services.removeAll(preferredWebEngine); 0258 services.prepend(preferredWebEngine); // make it the preferred one 0259 addedServices.writeXdgListEntry(mimeType, services); 0260 } 0261 profile->sync(); 0262 0263 // kbuildsycoca is the one reading mimeapps.list, so we need to run it now 0264 KBuildSycocaProgressDialog::rebuildKSycoca(widget()); 0265 } 0266 m_pConfig->sync(); 0267 0268 // Send signal to all konqueror instances 0269 QDBusMessage message = 0270 QDBusMessage::createSignal(QStringLiteral("/KonqMain"), QStringLiteral("org.kde.Konqueror.Main"), QStringLiteral("reparseConfiguration")); 0271 QDBusConnection::sessionBus().send(message); 0272 KCModule::save(); 0273 } 0274 0275 void KKonqGeneralOptions::slotChanged() 0276 { 0277 setNeedsSave(true); 0278 } 0279