File indexing completed on 2024-05-05 17:43:52
0001 /* 0002 SPDX-FileCopyrightText: 2018 Kai Uwe Broulik <kde@privat.broulik.de> 0003 0004 SPDX-License-Identifier: LGPL-2.1-or-later 0005 */ 0006 0007 #include "icons.h" 0008 0009 #include <QHash> 0010 #include <QRegularExpression> 0011 0012 QString Icons::actionIcon(const QString &actionName) 0013 { 0014 QString icon; 0015 0016 QString action = actionName; 0017 0018 if (action.isEmpty()) { 0019 return icon; 0020 } 0021 0022 static const QHash<QString, QString> s_icons{ 0023 {QStringLiteral("new"), QStringLiteral("document-new")}, // appmenu-gtk-module "New" 0024 {QStringLiteral("image-new"), QStringLiteral("document-new")}, // Gimp "New" item 0025 {QStringLiteral("adddirect"), QStringLiteral("document-new")}, // LibreOffice "New" item 0026 {QStringLiteral("filenew"), QStringLiteral("document-new")}, // Pluma "New" item 0027 {QStringLiteral("new-window"), QStringLiteral("window-new")}, 0028 {QStringLiteral("newwindow"), QStringLiteral("window-new")}, 0029 {QStringLiteral("yelp-window-new"), QStringLiteral("window-new")}, // Gnome help 0030 {QStringLiteral("new-tab"), QStringLiteral("tab-new")}, 0031 {QStringLiteral("open"), QStringLiteral("document-open")}, 0032 {QStringLiteral("open-location"), QStringLiteral("document-open-remote")}, 0033 {QStringLiteral("openremote"), QStringLiteral("document-open-remote")}, 0034 {QStringLiteral("save"), QStringLiteral("document-save")}, 0035 {QStringLiteral("save-as"), QStringLiteral("document-save-as")}, 0036 {QStringLiteral("saveas"), QStringLiteral("document-save-as")}, 0037 {QStringLiteral("save-all"), QStringLiteral("document-save-all")}, 0038 {QStringLiteral("saveall"), QStringLiteral("document-save-all")}, 0039 {QStringLiteral("import"), QStringLiteral("document-import")}, 0040 {QStringLiteral("export"), QStringLiteral("document-export")}, 0041 {QStringLiteral("exportto"), QStringLiteral("document-export")}, // LibreOffice 0042 {QStringLiteral("exporttopdf"), QStringLiteral("viewpdf")}, // LibreOffice, the icon it uses but the name is quite random 0043 {QStringLiteral("webhtml"), QStringLiteral("text-html")}, // LibreOffice 0044 {QStringLiteral("printpreview"), QStringLiteral("document-print-preview")}, 0045 {QStringLiteral("print-preview"), QStringLiteral("document-print-preview")}, 0046 {QStringLiteral("print"), QStringLiteral("document-print")}, 0047 {QStringLiteral("print-gtk"), QStringLiteral("document-print")}, // Gimp 0048 {QStringLiteral("mail-image"), QStringLiteral("mail-message-new")}, // Gimp 0049 {QStringLiteral("sendmail"), QStringLiteral("mail-message-new")}, // LibreOffice 0050 {QStringLiteral("sendviabluetooth"), QStringLiteral("preferences-system-bluetooth")}, // LibreOffice 0051 {QStringLiteral("sendviabluetooth"), QStringLiteral("preferences-system-bluetooth")}, // LibreOffice 0052 {QStringLiteral("document-properties"), QStringLiteral("document-properties")}, 0053 {QStringLiteral("close"), QStringLiteral("document-close")}, // appmenu-gtk-module "Close" 0054 {QStringLiteral("closedoc"), QStringLiteral("document-close")}, 0055 {QStringLiteral("close-all"), QStringLiteral("document-close")}, 0056 {QStringLiteral("closeall"), QStringLiteral("document-close")}, 0057 {QStringLiteral("closewin"), QStringLiteral("window-close")}, // LibreOffice 0058 {QStringLiteral("quit"), QStringLiteral("application-exit")}, 0059 0060 {QStringLiteral("undo"), QStringLiteral("edit-undo")}, 0061 {QStringLiteral("redo"), QStringLiteral("edit-redo")}, 0062 {QStringLiteral("revert"), QStringLiteral("document-revert")}, 0063 {QStringLiteral("cut"), QStringLiteral("edit-cut")}, 0064 {QStringLiteral("copy"), QStringLiteral("edit-copy")}, 0065 {QStringLiteral("paste"), QStringLiteral("edit-paste")}, 0066 {QStringLiteral("duplicate"), QStringLiteral("edit-duplicate")}, 0067 0068 {QStringLiteral("preferences"), QStringLiteral("settings-configure")}, 0069 {QStringLiteral("optionstreedialog"), QStringLiteral("settings-configure")}, // LibreOffice 0070 {QStringLiteral("keyboard-shortcuts"), QStringLiteral("configure-shortcuts")}, 0071 0072 {QStringLiteral("fullscreen"), QStringLiteral("view-fullscreen")}, 0073 0074 {QStringLiteral("find"), QStringLiteral("edit-find")}, 0075 {QStringLiteral("searchfind"), QStringLiteral("edit-find")}, 0076 {QStringLiteral("replace"), QStringLiteral("edit-find-replace")}, 0077 {QStringLiteral("searchreplace"), QStringLiteral("edit-find-replace")}, // LibreOffice 0078 {QStringLiteral("searchdialog"), QStringLiteral("edit-find-replace")}, // LibreOffice 0079 {QStringLiteral("find-replace"), QStringLiteral("edit-find-replace")}, // Inkscape 0080 {QStringLiteral("select-all"), QStringLiteral("edit-select-all")}, 0081 {QStringLiteral("selectall"), QStringLiteral("edit-select-all")}, 0082 {QStringLiteral("select-none"), QStringLiteral("edit-select-invert")}, 0083 {QStringLiteral("select-invert"), QStringLiteral("edit-select-invert")}, 0084 {QStringLiteral("invert-selection"), QStringLiteral("edit-select-invert")}, // Inkscape 0085 {QStringLiteral("check-spelling"), QStringLiteral("tools-check-spelling")}, 0086 {QStringLiteral("set-language"), QStringLiteral("set-language")}, 0087 0088 {QStringLiteral("increasesize"), QStringLiteral("zoom-in")}, 0089 {QStringLiteral("decreasesize"), QStringLiteral("zoom-out")}, 0090 {QStringLiteral("zoom-in"), QStringLiteral("zoom-in")}, 0091 {QStringLiteral("zoom-out"), QStringLiteral("zoom-out")}, 0092 {QStringLiteral("zoomfit"), QStringLiteral("zoom-fit-best")}, 0093 {QStringLiteral("zoom-fit-in"), QStringLiteral("zoom-fit-best")}, 0094 {QStringLiteral("show-guides"), QStringLiteral("show-guides")}, 0095 {QStringLiteral("show-grid"), QStringLiteral("show-grid")}, 0096 0097 {QStringLiteral("rotateclockwise"), QStringLiteral("object-rotate-right")}, 0098 {QStringLiteral("rotatecounterclockwise"), QStringLiteral("object-rotate-left")}, 0099 {QStringLiteral("fliphorizontally"), QStringLiteral("object-flip-horizontal")}, 0100 {QStringLiteral("image-flip-horizontal"), QStringLiteral("object-flip-horizontal")}, 0101 {QStringLiteral("flipvertically"), QStringLiteral("object-flip-vertical")}, 0102 {QStringLiteral("image-flip-vertical"), QStringLiteral("object-flip-vertical")}, 0103 {QStringLiteral("image-scale"), QStringLiteral("transform-scale")}, 0104 0105 {QStringLiteral("bold"), QStringLiteral("format-text-bold")}, 0106 {QStringLiteral("italic"), QStringLiteral("format-text-italic")}, 0107 {QStringLiteral("underline"), QStringLiteral("format-text-underline")}, 0108 {QStringLiteral("strikeout"), QStringLiteral("format-text-strikethrough")}, 0109 {QStringLiteral("superscript"), QStringLiteral("format-text-superscript")}, 0110 {QStringLiteral("subscript"), QStringLiteral("format-text-subscript")}, 0111 // "grow" is a bit unspecific to always set it to "grow font", so use the exact ID here 0112 {QStringLiteral(".uno:Grow"), QStringLiteral("format-font-size-more")}, // LibreOffice 0113 {QStringLiteral(".uno:Shrink"), QStringLiteral("format-font-size-less")}, // LibreOffice 0114 // also a bit unspecific? 0115 {QStringLiteral("alignleft"), QStringLiteral("format-justify-left")}, 0116 {QStringLiteral("alignhorizontalcenter"), QStringLiteral("format-justify-center")}, 0117 {QStringLiteral("alignright"), QStringLiteral("format-justify-right")}, 0118 {QStringLiteral("alignjustified"), QStringLiteral("format-justify-fill")}, 0119 {QStringLiteral("incrementindent"), QStringLiteral("format-indent-more")}, 0120 {QStringLiteral("decrementindent"), QStringLiteral("format-indent-less")}, 0121 {QStringLiteral("defaultbullet"), QStringLiteral("format-list-unordered")}, // LibreOffice 0122 {QStringLiteral("defaultnumbering"), QStringLiteral("format-list-ordered")}, // LibreOffice 0123 0124 {QStringLiteral("sortascending"), QStringLiteral("view-sort-ascending")}, 0125 {QStringLiteral("sortdescending"), QStringLiteral("view-sort-descending")}, 0126 0127 {QStringLiteral("autopilotmenu"), QStringLiteral("tools-wizard")}, // LibreOffice 0128 0129 {QStringLiteral("layers-new"), QStringLiteral("layer-new")}, 0130 {QStringLiteral("layers-duplicate"), QStringLiteral("layer-duplicate")}, 0131 {QStringLiteral("layers-delete"), QStringLiteral("layer-delete")}, 0132 {QStringLiteral("layers-anchor"), QStringLiteral("anchor")}, 0133 0134 {QStringLiteral("slideshow"), QStringLiteral("media-playback-start")}, // Gwenview uses this icon for that 0135 {QStringLiteral("playvideo"), QStringLiteral("media-playback-start")}, 0136 0137 {QStringLiteral("addtags"), QStringLiteral("tag-new")}, 0138 {QStringLiteral("newevent"), QStringLiteral("appointment-new")}, 0139 0140 {QStringLiteral("previous-document"), QStringLiteral("go-previous")}, 0141 {QStringLiteral("prevphoto"), QStringLiteral("go-previous")}, 0142 {QStringLiteral("next-document"), QStringLiteral("go-next")}, 0143 {QStringLiteral("nextphoto"), QStringLiteral("go-next")}, 0144 0145 {QStringLiteral("redeye"), QStringLiteral("redeyes")}, 0146 {QStringLiteral("crop"), QStringLiteral("transform-crop")}, 0147 {QStringLiteral("move"), QStringLiteral("transform-move")}, 0148 {QStringLiteral("rotate"), QStringLiteral("transform-rotate")}, 0149 {QStringLiteral("scale"), QStringLiteral("transform-scale")}, 0150 {QStringLiteral("shear"), QStringLiteral("transform-shear")}, 0151 {QStringLiteral("flip"), QStringLiteral("object-flip-horizontal")}, 0152 {QStringLiteral("flag"), QStringLiteral("flag-red")}, // is there a "mark" or "important" icon that isn't email? 0153 0154 {QStringLiteral("tools-measure"), QStringLiteral("measure")}, 0155 {QStringLiteral("tools-text"), QStringLiteral("draw-text")}, 0156 {QStringLiteral("tools-color-picker"), QStringLiteral("color-picker")}, 0157 {QStringLiteral("tools-paintbrush"), QStringLiteral("draw-brush")}, 0158 {QStringLiteral("tools-eraser"), QStringLiteral("draw-eraser")}, 0159 {QStringLiteral("tools-paintbrush"), QStringLiteral("draw-brush")}, 0160 0161 {QStringLiteral("help"), QStringLiteral("help-contents")}, 0162 {QStringLiteral("helpindex"), QStringLiteral("help-contents")}, 0163 {QStringLiteral("contents"), QStringLiteral("help-contents")}, 0164 {QStringLiteral("helpcontents"), QStringLiteral("help-contents")}, 0165 {QStringLiteral("context-help"), QStringLiteral("help-whatsthis")}, 0166 {QStringLiteral("extendedhelp"), QStringLiteral("help-whatsthis")}, // LibreOffice 0167 {QStringLiteral("helpreportproblem"), QStringLiteral("tools-report-bug")}, 0168 {QStringLiteral("sendfeedback"), QStringLiteral("tools-report-bug")}, // LibreOffice 0169 {QStringLiteral("about"), QStringLiteral("help-about")}, 0170 0171 {QStringLiteral("emptytrash"), QStringLiteral("trash-empty")}, 0172 {QStringLiteral("movetotrash"), QStringLiteral("user-trash-symbolic")}, 0173 0174 // Gnome help 0175 {QStringLiteral("yelp-application-larger-text"), QStringLiteral("format-font-size-more")}, 0176 {QStringLiteral("yelp-application-smaller-text"), QStringLiteral("format-font-size-less")}, // LibreOffice 0177 0178 // LibreOffice documents in its New menu 0179 {QStringLiteral("private:factory/swriter"), QStringLiteral("application-vnd.oasis.opendocument.text")}, 0180 {QStringLiteral("private:factory/scalc"), QStringLiteral("application-vnd.oasis.opendocument.spreadsheet")}, 0181 {QStringLiteral("private:factory/simpress"), QStringLiteral("application-vnd.oasis.opendocument.presentation")}, 0182 {QStringLiteral("private:factory/sdraw"), QStringLiteral("application-vnd.oasis.opendocument.graphics")}, 0183 {QStringLiteral("private:factory/swriter/web"), QStringLiteral("text-html")}, 0184 {QStringLiteral("private:factory/smath"), QStringLiteral("application-vnd.oasis.opendocument.formula")}, 0185 }; 0186 0187 // Sometimes we get additional arguments (?slot=123) we don't care about 0188 const int questionMarkIndex = action.indexOf(QLatin1Char('?')); 0189 if (questionMarkIndex > -1) { 0190 action.truncate(questionMarkIndex); 0191 } 0192 0193 icon = s_icons.value(action); 0194 0195 if (icon.isEmpty()) { 0196 const int dotIndex = action.indexOf(QLatin1Char('.')); // app., win., or unity. prefix 0197 0198 QString prefix; 0199 if (dotIndex > -1) { 0200 prefix = action.left(dotIndex); 0201 0202 action = action.mid(dotIndex + 1); 0203 } 0204 0205 // appmenu-gtk-module 0206 if (prefix == QLatin1String("unity")) { 0207 // Remove superfluous hyphens added by appmenu-gtk-module 0208 // First remove multiple subsequent ones 0209 static QRegularExpression subsequentHyphenRegExp(QStringLiteral("-{2,}")); 0210 action.replace(subsequentHyphenRegExp, QStringLiteral("-")); 0211 0212 // now we can be sure we only have a single hyphen at the start or end, remove it if needed 0213 if (action.startsWith(QLatin1Char('-'))) { 0214 action.remove(0, 1); 0215 } 0216 if (action.endsWith(QLatin1Char('-'))) { 0217 action.chop(1); 0218 } 0219 0220 // It also turns accelerators (&) into hyphens, so remove any hyphen that comes before 0221 // a lower-case letter ("mid sentence"), e.g. "P-references" 0222 static QRegularExpression strayHyphenRegExp(QStringLiteral("-(?=[a-z]+)")); 0223 action.remove(strayHyphenRegExp); 0224 } 0225 0226 icon = s_icons.value(action); 0227 } 0228 0229 if (icon.isEmpty()) { 0230 static const auto s_dup1Prefix = QStringLiteral("dup:1:"); // can it be dup2 also? 0231 if (action.startsWith(s_dup1Prefix)) { 0232 action = action.mid(s_dup1Prefix.length()); 0233 } 0234 0235 static const auto s_unoPrefix = QStringLiteral(".uno:"); // LibreOffice with appmenu-gtk 0236 if (action.startsWith(s_unoPrefix)) { 0237 action = action.mid(s_unoPrefix.length()); 0238 } 0239 0240 // LibreOffice's "Open" entry is always "OpenFromAppname" so we just chop that off 0241 if (action.startsWith(QLatin1String("OpenFrom"))) { 0242 action.truncate(4); // basically "Open" 0243 } 0244 0245 icon = s_icons.value(action); 0246 } 0247 0248 if (icon.isEmpty()) { 0249 static const auto s_commonPrefix = QStringLiteral("Common"); 0250 if (action.startsWith(s_commonPrefix)) { 0251 action = action.mid(s_commonPrefix.length()); 0252 } 0253 0254 icon = s_icons.value(action); 0255 } 0256 0257 if (icon.isEmpty()) { 0258 static const auto s_prefixes = QStringList{ 0259 // Gimp with appmenu-gtk 0260 QStringLiteral("file-"), 0261 QStringLiteral("edit-"), 0262 QStringLiteral("view-"), 0263 QStringLiteral("image-"), 0264 QStringLiteral("layers-"), 0265 QStringLiteral("colors-"), 0266 QStringLiteral("tools-"), 0267 QStringLiteral("plug-in-"), 0268 QStringLiteral("windows-"), 0269 QStringLiteral("dialogs-"), 0270 QStringLiteral("help-"), 0271 }; 0272 0273 for (const QString &prefix : s_prefixes) { 0274 if (action.startsWith(prefix)) { 0275 action = action.mid(prefix.length()); 0276 break; 0277 } 0278 } 0279 0280 icon = s_icons.value(action); 0281 } 0282 0283 if (icon.isEmpty()) { 0284 action = action.toLower(); 0285 icon = s_icons.value(action); 0286 } 0287 0288 if (icon.isEmpty()) { 0289 static const auto s_prefixes = QStringList{ 0290 // Pluma with appmenu-gtk 0291 QStringLiteral("file"), 0292 QStringLiteral("edit"), 0293 QStringLiteral("view"), 0294 QStringLiteral("help"), 0295 }; 0296 0297 for (const QString &prefix : s_prefixes) { 0298 if (action.startsWith(prefix)) { 0299 action = action.mid(prefix.length()); 0300 break; 0301 } 0302 } 0303 0304 icon = s_icons.value(action); 0305 } 0306 0307 return icon; 0308 }