]> cloud.milkyroute.net Git - dolphin.git/blob - src/views/dolphinremoteencoding.cpp
Merge branch 'release/21.12'
[dolphin.git] / src / views / dolphinremoteencoding.cpp
1 /*
2 * SPDX-FileCopyrightText: 2009 Rahman Duran <rahman.duran@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 /*
8 * This code is largely based on the kremoteencodingplugin
9 * SPDX-FileCopyrightText: 2003 Thiago Macieira <thiago.macieira@kdemail.net>
10 * Distributed under the same terms.
11 */
12
13 #include "dolphinremoteencoding.h"
14
15 #include "dolphinviewactionhandler.h"
16 #include "dolphindebug.h"
17
18 #include <KActionCollection>
19 #include <KActionMenu>
20 #include <KCharsets>
21 #include <KConfig>
22 #include <KConfigGroup>
23 #include <KIO/Scheduler>
24 #include <KLocalizedString>
25 #include <KProtocolInfo>
26 #include <KProtocolManager>
27
28 #include <QMenu>
29
30 #define DATA_KEY QStringLiteral("Charset")
31
32 DolphinRemoteEncoding::DolphinRemoteEncoding(QObject* parent, DolphinViewActionHandler* actionHandler)
33 :QObject(parent),
34 m_actionHandler(actionHandler),
35 m_loaded(false),
36 m_idDefault(0)
37 {
38 m_menu = new KActionMenu(QIcon::fromTheme(QStringLiteral("character-set")), i18n("Select Remote Charset"), this);
39 m_actionHandler->actionCollection()->addAction(QStringLiteral("change_remote_encoding"), m_menu);
40 connect(m_menu->menu(), &QMenu::aboutToShow,
41 this, &DolphinRemoteEncoding::slotAboutToShow);
42
43 m_menu->setEnabled(false);
44 m_menu->setPopupMode(QToolButton::InstantPopup);
45 }
46
47 DolphinRemoteEncoding::~DolphinRemoteEncoding()
48 {
49 }
50
51 void DolphinRemoteEncoding::slotReload()
52 {
53 loadSettings();
54 }
55
56 void DolphinRemoteEncoding::loadSettings()
57 {
58 m_loaded = true;
59 m_encodingDescriptions = KCharsets::charsets()->descriptiveEncodingNames();
60
61 fillMenu();
62 }
63
64 void DolphinRemoteEncoding::slotAboutToOpenUrl()
65 {
66 QUrl oldURL = m_currentURL;
67 m_currentURL = m_actionHandler->currentView()->url();
68
69 if (m_currentURL.scheme() != oldURL.scheme()) {
70 // This plugin works on ftp, fish, etc.
71 // everything whose type is T_FILESYSTEM except for local files
72 if (!m_currentURL.isLocalFile() &&
73 KProtocolManager::outputType(m_currentURL) == KProtocolInfo::T_FILESYSTEM) {
74
75 m_menu->setEnabled(true);
76 loadSettings();
77 } else {
78 m_menu->setEnabled(false);
79 }
80 return;
81 }
82
83 if (m_currentURL.host() != oldURL.host()) {
84 updateMenu();
85 }
86 }
87
88 void DolphinRemoteEncoding::fillMenu()
89 {
90 QMenu* menu = m_menu->menu();
91 menu->clear();
92
93 menu->addAction(i18n("Default"), this, SLOT(slotDefault()), 0)->setCheckable(true);
94 for (int i = 0; i < m_encodingDescriptions.size();i++) {
95 QAction* action = new QAction(m_encodingDescriptions.at(i), this);
96 action->setCheckable(true);
97 action->setData(i);
98 menu->addAction(action);
99 }
100 menu->addSeparator();
101
102 menu->addAction(i18n("Reload"), this, SLOT(slotReload()), 0);
103 m_idDefault = m_encodingDescriptions.size() + 2;
104
105 connect(menu, &QMenu::triggered, this, &DolphinRemoteEncoding::slotItemSelected);
106 }
107
108 void DolphinRemoteEncoding::updateMenu()
109 {
110 if (!m_loaded) {
111 loadSettings();
112 }
113
114 // uncheck everything
115 for (int i = 0; i < m_menu->menu()->actions().count(); i++) {
116 m_menu->menu()->actions().at(i)->setChecked(false);
117 }
118
119 const QString charset = KCharsets::charsets()->descriptionForEncoding(KProtocolManager::charsetFor(m_currentURL));
120 if (!charset.isEmpty()) {
121 int id = 0;
122 bool isFound = false;
123 for (int i = 0; i < m_encodingDescriptions.size(); i++) {
124 if (m_encodingDescriptions.at(i) == charset) {
125 isFound = true;
126 id = i;
127 break;
128 }
129 }
130
131 qCDebug(DolphinDebug) << "URL=" << m_currentURL << " charset=" << charset;
132
133 if (!isFound) {
134 qCWarning(DolphinDebug) << "could not find entry for charset=" << charset ;
135 } else {
136 m_menu->menu()->actions().at(id)->setChecked(true);
137 }
138 } else {
139 m_menu->menu()->actions().at(m_idDefault)->setChecked(true);
140 }
141
142 }
143
144 void DolphinRemoteEncoding::slotAboutToShow()
145 {
146 if (!m_loaded) {
147 loadSettings();
148 }
149 updateMenu();
150 }
151
152 void DolphinRemoteEncoding::slotItemSelected(QAction* action)
153 {
154 if (action) {
155 int id = action->data().toInt();
156
157 KConfig config(("kio_" + m_currentURL.scheme() + "rc").toLatin1());
158 QString host = m_currentURL.host();
159 if (m_menu->menu()->actions().at(id)->isChecked()) {
160 QString charset = KCharsets::charsets()->encodingForName(m_encodingDescriptions.at(id));
161 KConfigGroup cg(&config, host);
162 cg.writeEntry(DATA_KEY, charset);
163 config.sync();
164
165 // Update the io-slaves...
166 updateView();
167 }
168 }
169 }
170
171 void DolphinRemoteEncoding::slotDefault()
172 {
173 // We have no choice but delete all higher domain level
174 // settings here since it affects what will be matched.
175 KConfig config(("kio_" + m_currentURL.scheme() + "rc").toLatin1());
176
177 QStringList partList = m_currentURL.host().split('.', Qt::SkipEmptyParts);
178 if (!partList.isEmpty()) {
179 partList.erase(partList.begin());
180
181 QStringList domains;
182 // Remove the exact name match...
183 domains << m_currentURL.host();
184
185 while (!partList.isEmpty()) {
186 if (partList.count() == 2) {
187 if (partList[0].length() <= 2 && partList[1].length() == 2) {
188 break;
189 }
190 }
191
192 if (partList.count() == 1) {
193 break;
194 }
195
196 domains << partList.join(QLatin1Char('.'));
197 partList.erase(partList.begin());
198 }
199
200 for (QStringList::const_iterator it = domains.constBegin(); it != domains.constEnd();++it) {
201 qCDebug(DolphinDebug) << "Domain to remove: " << *it;
202 if (config.hasGroup(*it)) {
203 config.deleteGroup(*it);
204 } else if (config.group("").hasKey(*it)) {
205 config.group("").deleteEntry(*it); //don't know what group name is supposed to be XXX
206 }
207 }
208 }
209 config.sync();
210
211 // Update the io-slaves.
212 updateView();
213 }
214
215 void DolphinRemoteEncoding::updateView()
216 {
217 KIO::Scheduler::emitReparseSlaveConfiguration();
218 // Reload the page with the new charset
219 m_actionHandler->currentView()->setUrl(m_currentURL);
220 m_actionHandler->currentView()->reload();
221 }
222