File indexing completed on 2021-12-23 10:45:19
0001 /* 0002 * SPDX-FileCopyrightText: 1999 Reginald Stadlbauer <reggie@kde.org> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kcharselectdia.h" 0008 0009 #include <QAction> 0010 #include <QApplication> 0011 #include <QClipboard> 0012 #include <QDir> 0013 #include <QFontDatabase> 0014 #include <QGridLayout> 0015 #include <QIcon> 0016 #include <QMenu> 0017 0018 #include <KActionCollection> 0019 #include <KBookmarkManager> 0020 #include <KBookmarkMenu> 0021 #include <KBookmarkOwner> 0022 #include <KConfigGroup> 0023 #include <KLocalizedString> 0024 #include <KSharedConfig> 0025 #include <KStandardAction> 0026 #include <KStandardShortcut> 0027 #include <KToggleAction> 0028 0029 class KCharSelectBookmarkOwner : public KBookmarkOwner 0030 { 0031 public: 0032 KCharSelectBookmarkOwner(KCharSelectDia *dia) 0033 : d(dia) 0034 { 0035 } 0036 ~KCharSelectBookmarkOwner() override 0037 { 0038 } 0039 0040 QString currentTitle() const override 0041 { 0042 uint ucs4 = d->charSelect->currentCodePoint(); 0043 if (QChar::isPrint(ucs4)) { 0044 return QString::fromUcs4(&ucs4, 1) + QLatin1Char(' ') + formatCodePoint(ucs4); 0045 } else { 0046 return formatCodePoint(ucs4); 0047 } 0048 } 0049 0050 QUrl currentUrl() const override 0051 { 0052 return QUrl(formatCodePoint(d->charSelect->currentCodePoint())); 0053 } 0054 0055 void openBookmark(const KBookmark &bm, Qt::MouseButtons, Qt::KeyboardModifiers) override 0056 { 0057 QString c = bm.url().toString(QUrl::PreferLocalFile | QUrl::RemoveScheme); 0058 if (c.startsWith(QLatin1String("U+"))) { 0059 uint uc = c.midRef(2).toUInt(nullptr, 16); 0060 d->charSelect->setCurrentCodePoint(uc); 0061 } 0062 } 0063 0064 private: 0065 static QString formatCodePoint(uint ucs4) 0066 { 0067 QString c = QString::number(ucs4, 16).toUpper(); 0068 while (c.length() < 4) { 0069 c.prepend(QLatin1Char('0')); 0070 } 0071 return QStringLiteral("U+") + c; 0072 } 0073 0074 private: 0075 KCharSelectDia *d; 0076 }; 0077 0078 /******************************************************************/ 0079 /* class KCharSelectDia */ 0080 /******************************************************************/ 0081 0082 //================================================================== 0083 KCharSelectDia::KCharSelectDia(QWidget *parent) 0084 : KXmlGuiWindow(parent) 0085 { 0086 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0087 KConfigGroup gr = config->group("General"); 0088 0089 vFont = gr.readEntry("selectedFont", QFontDatabase::systemFont(QFontDatabase::GeneralFont)); 0090 vChr = gr.readEntry("char", 33); 0091 _rtl = gr.readEntry("rtl", false); 0092 0093 QWidget *mainWidget = new QWidget(this); 0094 setCentralWidget(mainWidget); 0095 0096 grid = new QGridLayout(mainWidget); 0097 0098 // Add character selection widget from library kdeui 0099 charSelect = new KCharSelect(mainWidget, actionCollection()); 0100 charSelect->setAllPlanesEnabled(true); 0101 charSelect->setCurrentCodePoint(vChr); 0102 charSelect->setCurrentFont(vFont); 0103 charSelect->resize(charSelect->sizeHint()); 0104 connect(charSelect, &KCharSelect::currentCodePointChanged, this, &KCharSelectDia::charChanged); 0105 connect(charSelect, SIGNAL(codePointSelected(uint)), SLOT(add(uint))); 0106 0107 connect(charSelect, &KCharSelect::currentFontChanged, this, &KCharSelectDia::fontSelected); 0108 grid->addWidget(charSelect, 0, 0, 1, 4); 0109 0110 // Build line editor 0111 lined = new QLineEdit(mainWidget); 0112 lined->resize(lined->sizeHint()); 0113 lined->setClearButtonEnabled(true); 0114 0115 lined->setFont(vFont); 0116 0117 connect(lined, &QLineEdit::textChanged, this, &KCharSelectDia::lineEditChanged); 0118 grid->addWidget(lined, 1, 0, 1, 3); 0119 0120 bClip = new QPushButton(i18n("&To Clipboard"), mainWidget); 0121 bClip->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy"))); 0122 bClip->setFixedSize(bClip->sizeHint()); 0123 connect(bClip, &QPushButton::clicked, this, &KCharSelectDia::toClip); 0124 grid->addWidget(bClip, 1, 3); 0125 0126 // Build menu 0127 KStandardAction::quit(this, SLOT(close()), actionCollection()); 0128 0129 QAction *action = actionCollection()->addAction(QStringLiteral("copy_clip")); 0130 action->setText(i18n("&To Clipboard")); 0131 action->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy"))); 0132 connect(action, &QAction::triggered, this, &KCharSelectDia::toClip); 0133 actionCollection()->setDefaultShortcuts(action, KStandardShortcut::shortcut(KStandardShortcut::Copy)); 0134 0135 action = actionCollection()->addAction(QStringLiteral("copy_utf_8")); 0136 action->setText(i18n("To Clipboard &UTF-8")); 0137 connect(action, &QAction::triggered, this, &KCharSelectDia::toClipUTF8); 0138 action = actionCollection()->addAction(QStringLiteral("copy_html")); 0139 action->setText(i18n("To Clipboard &HTML")); 0140 connect(action, &QAction::triggered, this, &KCharSelectDia::toClipHTML); 0141 0142 action = actionCollection()->addAction(QStringLiteral("from_clip")); 0143 action->setText(i18n("&From Clipboard")); 0144 action->setIcon(QIcon::fromTheme(QStringLiteral("edit-paste"))); 0145 connect(action, &QAction::triggered, this, &KCharSelectDia::fromClip); 0146 actionCollection()->setDefaultShortcuts(action, KStandardShortcut::shortcut(KStandardShortcut::Paste)); 0147 action = actionCollection()->addAction(QStringLiteral("from_clip_utf8")); 0148 action->setText(i18n("From Clipboard UTF-8")); 0149 connect(action, &QAction::triggered, this, &KCharSelectDia::fromClipUTF8); 0150 0151 i18n("From Clipboard HTML"); // Intended for future use 0152 0153 action = actionCollection()->addAction(QStringLiteral("flip")); 0154 action->setText(i18n("&Flip Text")); 0155 connect(action, &QAction::triggered, this, &KCharSelectDia::flipText); 0156 0157 action = new KToggleAction(i18n("&Reverse Direction"), this); 0158 action->setChecked(_rtl); 0159 actionCollection()->addAction(QStringLiteral("rtl"), action); 0160 connect(action, &QAction::toggled, this, &KCharSelectDia::setRtl); 0161 0162 charSelect->setFocus(); 0163 0164 if (_rtl) 0165 lined->setAlignment(Qt::AlignRight); 0166 else 0167 lined->setAlignment(Qt::AlignLeft); 0168 0169 QString filename = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kcharselect/bookmarks.xml")); 0170 if (filename.isEmpty()) { 0171 filename = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/kcharselect"); 0172 QDir().mkpath(filename); 0173 filename += QStringLiteral("/bookmarks.xml"); 0174 } 0175 KBookmarkManager *manager = KBookmarkManager::managerForFile(filename, QStringLiteral("kcharselect")); 0176 0177 action = actionCollection()->addAction(QStringLiteral("bookmarks")); 0178 action->setText(i18n("Bookmarks")); 0179 QMenu *bmmenu = new QMenu(this); 0180 action->setMenu(bmmenu); 0181 0182 KBookmarkMenu *bm = new KBookmarkMenu(manager, new KCharSelectBookmarkOwner(this), bmmenu); 0183 actionCollection()->addActions(bmmenu->actions()); 0184 0185 bm->setParent(this); 0186 0187 setupGUI(ToolBar | Keys | Save | Create); 0188 } 0189 0190 //================================================================== 0191 void KCharSelectDia::closeEvent(QCloseEvent *event) 0192 { 0193 KSharedConfig::Ptr config = KSharedConfig::openConfig(); 0194 KConfigGroup gr = config->group("General"); 0195 0196 gr.writeEntry("selectedFont", vFont); 0197 gr.writeEntry("char", vChr); 0198 gr.writeEntry("rtl", _rtl); 0199 0200 KXmlGuiWindow::closeEvent(event); 0201 } 0202 0203 //================================================================== 0204 void KCharSelectDia::charChanged(uint _chr) 0205 { 0206 vChr = _chr; 0207 } 0208 0209 //================================================================== 0210 void KCharSelectDia::fontSelected(const QFont &_font) 0211 { 0212 lined->setFont(_font); 0213 0214 vFont = _font; 0215 } 0216 0217 //================================================================== 0218 void KCharSelectDia::add(uint _chr) 0219 { 0220 charChanged(_chr); 0221 0222 QString str = lined->text(); 0223 const int pos = lined->cursorPosition(); 0224 str.insert(pos, QString::fromUcs4(&_chr, 1)); 0225 lined->setText(str); 0226 lined->setCursorPosition(pos + QString::fromUcs4(&_chr, 1).size()); 0227 } 0228 0229 //================================================================== 0230 void KCharSelectDia::toClip() 0231 { 0232 QString str = lined->text(); 0233 if (str.isEmpty()) 0234 str = QString::fromUcs4(&vChr, 1); 0235 QClipboard *cb = QApplication::clipboard(); 0236 cb->setText(str, QClipboard::Clipboard); 0237 cb->setText(str, QClipboard::Selection); 0238 } 0239 0240 //================================================================== 0241 // UTF-8 is rapidly becoming the favored 8-bit encoding for 0242 // Unicode (iso10646-1). 0243 // 0244 void KCharSelectDia::toClipUTF8() 0245 { 0246 QClipboard *cb = QApplication::clipboard(); 0247 QString str = lined->text(); 0248 if (str.isEmpty()) 0249 str = QString::fromUcs4(&vChr, 1); 0250 cb->setText(QLatin1String(str.toUtf8())); 0251 } 0252 0253 //================================================================== 0254 // Put valid HTML 4.0 into the clipboard. Valid ISO-8859-1 Latin 1 0255 // characters are left undisturbed. Everything else, including the 0256 // "c0 control characters" often used by Windows, are clipped 0257 // as a HTML entity. 0258 // 0259 void KCharSelectDia::toClipHTML() 0260 { 0261 QClipboard *cb = QApplication::clipboard(); 0262 QString input; 0263 QString html; 0264 QChar tempchar; 0265 int i = 0; 0266 0267 input = lined->text(); 0268 if (input.isEmpty()) 0269 input = QString::fromUcs4(&vChr, 1); 0270 const int inputLength = input.length(); 0271 for (i = 0; i < inputLength; ++i) { 0272 tempchar = input.at(i); 0273 if (tempchar.toLatin1() && ((tempchar.unicode() < 128) || (tempchar.unicode() >= 128 + 32))) { 0274 html.append(input.at(i)); 0275 } else { 0276 html.append(QString::asprintf("&#x%x;", tempchar.unicode())); 0277 } 0278 } 0279 cb->setText(html); 0280 } 0281 0282 //================================================================== 0283 // 0284 void KCharSelectDia::fromClip() 0285 { 0286 QClipboard *cb = QApplication::clipboard(); 0287 lined->setText(cb->text()); 0288 } 0289 0290 //================================================================== 0291 // UTF-8 is rapidly becoming the favored 8-bit encoding for 0292 // Unicode (iso10646-1). This function is handy for decoding 0293 // UTF-8 found in legacy applications, consoles, filenames, webpages, 0294 // etc. 0295 // 0296 void KCharSelectDia::fromClipUTF8() 0297 { 0298 QClipboard *cb = QApplication::clipboard(); 0299 const QString str = cb->text(); 0300 0301 lined->setText(str.fromUtf8(str.toLatin1())); 0302 } 0303 0304 //================================================================== 0305 // Reverse the text held in the line edit buffer. This is crucial 0306 // for dealing with visual vs. logical representations of 0307 // right to left languages, and handy for working around all 0308 // manner of legacy character order issues. 0309 // 0310 void KCharSelectDia::flipText() 0311 { 0312 QString input; 0313 QString output; 0314 int i; 0315 0316 input = lined->text(); 0317 const int nbLength = input.length(); 0318 for (i = 0; i < nbLength; ++i) { 0319 output.prepend(input.at(i)); 0320 } 0321 lined->setText(output); 0322 } 0323 0324 //================================================================== 0325 void KCharSelectDia::setRtl(bool rtl) 0326 { 0327 _rtl = rtl; 0328 if (_rtl) 0329 lined->setAlignment(Qt::AlignRight); 0330 else 0331 lined->setAlignment(Qt::AlignLeft); 0332 } 0333 0334 //================================================================== 0335 void KCharSelectDia::lineEditChanged() 0336 { 0337 if (_rtl) { 0338 if (lined->cursorPosition()) 0339 lined->setCursorPosition(lined->cursorPosition() - 1); 0340 } 0341 }