File indexing completed on 2024-04-28 17:06:04

0001 /*
0002     SPDX-FileCopyrightText: 2005 Csaba Karai <cskarai@freemail.hu>
0003     SPDX-FileCopyrightText: 2005-2022 Krusader Krew <https://krusader.org>
0004 
0005     Based on KRemoteEncodingPlugin from Dawit Alemayehu <adawit@kde.org>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #include "krremoteencodingmenu.h"
0011 
0012 // QtCore
0013 #include <QDebug>
0014 // QtWidgets
0015 #include <QMenu>
0016 
0017 #include <KCodecs/KCharsets>
0018 #include <KConfigCore/KConfig>
0019 #include <KConfigCore/KConfigGroup>
0020 #include <KI18n/KLocalizedString>
0021 #include <KIO/Scheduler>
0022 #include <KIOCore/KProtocolManager>
0023 #include <KXmlGui/KActionCollection>
0024 
0025 #include "../Panel/krpanel.h"
0026 #include "../Panel/panelfunc.h"
0027 #include "../compat.h"
0028 #include "../icon.h"
0029 #include "../krglobal.h"
0030 
0031 #define DATA_KEY QString::fromLatin1("Charset")
0032 
0033 KrRemoteEncodingMenu::KrRemoteEncodingMenu(const QString &text, const QString &iconName, KActionCollection *parent)
0034     : KActionMenu(Icon(iconName), text, parent)
0035     , settingsLoaded(false)
0036 {
0037     connect(menu(), &QMenu::aboutToShow, this, &KrRemoteEncodingMenu::slotAboutToShow);
0038 
0039     parent->addAction("changeremoteencoding", this);
0040 }
0041 
0042 void KrRemoteEncodingMenu::slotAboutToShow()
0043 {
0044     if (!settingsLoaded)
0045         loadSettings();
0046 
0047     // uncheck everything
0048     QList<QAction *> acts = menu()->actions();
0049     foreach (QAction *act, acts)
0050         act->setChecked(false);
0051 
0052     QString charset = currentCharacterSet();
0053     if (!charset.isEmpty()) {
0054         int id = 1;
0055         QStringList::Iterator it;
0056         for (it = encodingNames.begin(); it != encodingNames.end(); ++it, ++id)
0057             if ((*it).indexOf(charset) != -1)
0058                 break;
0059 
0060         bool found = false;
0061 
0062         foreach (QAction *act, acts) {
0063             if (act->data().canConvert<int>()) {
0064                 int idr = act->data().toInt();
0065 
0066                 if (idr == id) {
0067                     act->setChecked(found = true);
0068                     break;
0069                 }
0070             }
0071         }
0072 
0073         if (!found)
0074             qWarning() << Q_FUNC_INFO << "could not find entry for charset=" << charset;
0075     } else {
0076         foreach (QAction *act, acts) {
0077             if (act->data().canConvert<int>()) {
0078                 int idr = act->data().toInt();
0079 
0080                 if (idr == -2) {
0081                     act->setChecked(true);
0082                     break;
0083                 }
0084             }
0085         }
0086     }
0087 }
0088 
0089 QString KrRemoteEncodingMenu::currentCharacterSet()
0090 {
0091     QUrl currentURL = ACTIVE_PANEL->virtualPath();
0092     return KProtocolManager::charsetFor(currentURL);
0093 }
0094 
0095 void KrRemoteEncodingMenu::loadSettings()
0096 {
0097     settingsLoaded = true;
0098     encodingNames = KCharsets::charsets()->descriptiveEncodingNames();
0099 
0100     QMenu *qmenu = menu();
0101     disconnect(qmenu, &QMenu::triggered, this, &KrRemoteEncodingMenu::slotTriggered);
0102     connect(qmenu, &QMenu::triggered, this, &KrRemoteEncodingMenu::slotTriggered);
0103     qmenu->clear();
0104 
0105     QStringList::ConstIterator it;
0106     int count = 0;
0107     QAction *act;
0108 
0109     for (it = encodingNames.constBegin(); it != encodingNames.constEnd(); ++it) {
0110         act = qmenu->addAction(*it);
0111         act->setData(QVariant(++count));
0112         act->setCheckable(true);
0113     }
0114     qmenu->addSeparator();
0115 
0116     act = qmenu->addAction(i18n("Reload"));
0117     act->setCheckable(true);
0118     act->setData(QVariant(-1));
0119 
0120     act = qmenu->addAction(i18nc("Default encoding", "Default"));
0121     act->setCheckable(true);
0122     act->setData(QVariant(-2));
0123 }
0124 
0125 void KrRemoteEncodingMenu::slotTriggered(QAction *act)
0126 {
0127     if (!act || !act->data().canConvert<int>())
0128         return;
0129 
0130     int id = act->data().toInt();
0131 
0132     switch (id) {
0133     case -1:
0134         slotReload();
0135         return;
0136     case -2:
0137         chooseDefault();
0138         return;
0139     default:
0140         chooseEncoding(encodingNames[id - 1]);
0141     }
0142 }
0143 
0144 void KrRemoteEncodingMenu::chooseEncoding(QString encoding)
0145 {
0146     QUrl currentURL = ACTIVE_PANEL->virtualPath();
0147 
0148     KConfig config(("kio_" + currentURL.scheme() + "rc").toLatin1());
0149     QString host = currentURL.host();
0150 
0151     QString charset = KCharsets::charsets()->encodingForName(encoding);
0152 
0153     KConfigGroup group(&config, host);
0154     group.writeEntry(DATA_KEY, charset);
0155     config.sync();
0156 
0157     // Update the io-slaves...
0158     updateKIOSlaves();
0159 }
0160 
0161 void KrRemoteEncodingMenu::slotReload()
0162 {
0163     loadSettings();
0164 }
0165 
0166 void KrRemoteEncodingMenu::chooseDefault()
0167 {
0168     QUrl currentURL = ACTIVE_PANEL->virtualPath();
0169 
0170     // We have no choice but delete all higher domain level
0171     // settings here since it affects what will be matched.
0172     KConfig config(("kio_" + currentURL.scheme() + "rc").toLatin1());
0173 
0174     QStringList partList = currentURL.host().split('.', SKIP_EMPTY_PARTS);
0175     if (!partList.isEmpty()) {
0176         partList.erase(partList.begin());
0177 
0178         QStringList domains;
0179         // Remove the exact name match...
0180         domains << currentURL.host();
0181 
0182         while (partList.count()) {
0183             if (partList.count() == 2)
0184                 if (partList[0].length() <= 2 && partList[1].length() == 2)
0185                     break;
0186 
0187             if (partList.count() == 1)
0188                 break;
0189 
0190             domains << partList.join(".");
0191             partList.erase(partList.begin());
0192         }
0193 
0194         for (auto &domain : domains) {
0195             // qDebug() << "Domain to remove: " << *it;
0196             if (config.hasGroup(domain))
0197                 config.deleteGroup(domain);
0198             else if (config.group("").hasKey(domain))
0199                 config.group("").deleteEntry(domain); // don't know what group name is supposed to be XXX
0200         }
0201     }
0202     config.sync();
0203 
0204     updateKIOSlaves();
0205 }
0206 
0207 void KrRemoteEncodingMenu::updateKIOSlaves()
0208 {
0209     KIO::Scheduler::emitReparseSlaveConfiguration();
0210 
0211     // Reload the page with the new charset
0212     QTimer::singleShot(500, ACTIVE_FUNC, SLOT(refresh()));
0213 }