1 /*************************************************************************** 2 icons.cpp 3 ------------------- 4 begin : Sun Jun 25 2017 5 copyright : (C) 2017 by Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com> 6 (C) 2020 by Dawid Wróbel <me@dawidwrobel.com> 7 8 ***************************************************************************/ 9 10 /*************************************************************************** 11 * * 12 * This program is free software; you can redistribute it and/or modify * 13 * it under the terms of the GNU General Public License as published by * 14 * the Free Software Foundation; either version 2 of the License, or * 15 * (at your option) any later version. * 16 * * 17 ***************************************************************************/ 18 19 #include "icons.h" 20 21 #include <QHash> 22 #include <QString> 23 #include <QIcon> 24 #include <QPixmapCache> 25 #include <QPainter> 26 #include <QRegularExpression> 27 #include <QDir> 28 #include <QStandardPaths> 29 30 namespace Icons { 31 QHash<Icon, QString> sStandardIcons; 32 qHash(const Icon key,uint seed)33 uint qHash(const Icon key, uint seed) 34 { 35 return ::qHash(static_cast<uint>(key), seed); 36 } 37 qHash(const IconSet key,uint seed)38 uint qHash(const IconSet key, uint seed) 39 { 40 return ::qHash(static_cast<uint>(key), seed); 41 } 42 43 struct iconDescription { 44 Icon baseIcon; 45 Icon overlayIcon; 46 Qt::Corner corner; 47 }; 48 49 const QHash<Icon, QHash<IconSet, QString> > iconMappings{ 50 {Icon::AccountClosed, 51 {{IconSet::Common, QStringLiteral("account-types-closed")}, 52 {IconSet::Oxygen, QStringLiteral("dialog-close")}, 53 {IconSet::Breeze, QStringLiteral("dialog-close")}}}, 54 {Icon::ArrowDown, 55 {{IconSet::Common, QStringLiteral("arrow-down")}, 56 {IconSet::Tango, QStringLiteral("go-down")}}}, 57 {Icon::ArrowLeft, 58 {{IconSet::Common, QStringLiteral("arrow-left")}, 59 {IconSet::Tango, QStringLiteral("go-previous")}}}, 60 {Icon::ArrowRight, 61 {{IconSet::Common, QStringLiteral("arrow-right")}, 62 {IconSet::Tango, QStringLiteral("go-next")}}}, 63 {Icon::ArrowUp, 64 {{IconSet::Common, QStringLiteral("arrow-up")}, 65 {IconSet::Tango, QStringLiteral("go-up")}}}, 66 {Icon::Budget, 67 {{IconSet::Common, QStringLiteral("budget")}, 68 {IconSet::Oxygen, QStringLiteral("view-time-schedule-calculus")}, 69 {IconSet::Breeze, QStringLiteral("view-time-schedule-calculus")}}}, 70 {Icon::Calculator, 71 {{IconSet::Common, QStringLiteral("accessories-calculator")}}}, 72 {Icon::Configure, 73 {{IconSet::Common, QStringLiteral("configure")}, 74 {IconSet::Tango, QStringLiteral("preferences-system")}}}, 75 {Icon::DialogCancel, 76 {{IconSet::Common, QStringLiteral("dialog-cancel")}, 77 {IconSet::Tango, QStringLiteral("stop")}}}, 78 {Icon::DialogClose, {{IconSet::Common, QStringLiteral("dialog-close")}}}, 79 {Icon::DialogError, {{IconSet::Common, QStringLiteral("dialog-error")}}}, 80 {Icon::DialogInformation, 81 {{IconSet::Common, QStringLiteral("dialog-information")}}}, 82 {Icon::DialogOK, 83 {{IconSet::Common, QStringLiteral("dialog-ok")}, 84 {IconSet::Tango, QStringLiteral("finish")}}}, 85 {Icon::DialogOKApply, 86 {{IconSet::Common, QStringLiteral("dialog-ok-apply")}}}, 87 {Icon::DialogWarning, 88 {{IconSet::Common, QStringLiteral("dialog-warning")}}}, 89 {Icon::DocumentClose, 90 {{IconSet::Common, QStringLiteral("document-close")}, 91 {IconSet::Tango, QStringLiteral("stop")}}}, 92 {Icon::DocumentEdit, 93 {{IconSet::Common, QStringLiteral("document-edit")}, 94 {IconSet::Tango, QStringLiteral("text-editor")}}}, 95 {Icon::DocumentExport, 96 {{IconSet::Common, QStringLiteral("format-indent-more")}, 97 {IconSet::Oxygen, QStringLiteral("document-export")}, 98 {IconSet::Breeze, QStringLiteral("document-export")}}}, 99 {Icon::DocumentImport, 100 {{IconSet::Common, QStringLiteral("format-indent-less")}, 101 {IconSet::Oxygen, QStringLiteral("document-import")}, 102 {IconSet::Breeze, QStringLiteral("document-import")}}}, 103 {Icon::DocumentNew, {{IconSet::Common, QStringLiteral("document-new")}}}, 104 {Icon::DocumentOpen, 105 {{IconSet::Common, QStringLiteral("document-open")}}}, 106 {Icon::DocumentProperties, 107 {{IconSet::Common, QStringLiteral("document-properties")}}}, 108 {Icon::DocumentSave, 109 {{IconSet::Common, QStringLiteral("document-save")}}}, 110 {Icon::Download, 111 {{IconSet::Breeze, QStringLiteral("edit-download")}, 112 {IconSet::Common, QStringLiteral("go-down")}, 113 {IconSet::Oxygen, QStringLiteral("download")}}}, 114 {Icon::EditClear, {{IconSet::Common, QStringLiteral("edit-clear")}}}, 115 {Icon::EditCopy, {{IconSet::Common, QStringLiteral("edit-copy")}}}, 116 {Icon::EditDelete, {{IconSet::Common, QStringLiteral("edit-delete")}}}, 117 {Icon::Find, {{IconSet::Common, QStringLiteral("edit-find")}}}, 118 {Icon::EditRename, 119 {{IconSet::Common, QStringLiteral("edit-rename")}, 120 {IconSet::Tango, QStringLiteral("text-editor")}}}, 121 {Icon::EditUndo, {{IconSet::Common, QStringLiteral("edit-undo")}}}, 122 {Icon::Folder, {{IconSet::Common, QStringLiteral("folder")}}}, 123 {Icon::GoTo, {{IconSet::Common, QStringLiteral("go-jump")}}}, 124 {Icon::Help, {{IconSet::Common, QStringLiteral("help-contents")}}}, 125 {Icon::HideCategories, 126 {{IconSet::Common, QStringLiteral("hide-categories")}}}, 127 {Icon::HideReconciled, 128 {{IconSet::Common, QStringLiteral("hide-reconciled")}}}, 129 {Icon::KMyMoney, {{IconSet::Common, QStringLiteral("kmymoney")}}}, 130 {Icon::KeyEnter, 131 {{IconSet::Common, QStringLiteral("input-keyboard")}, 132 {IconSet::Oxygen, QStringLiteral("key-enter")}, 133 {IconSet::Breeze, QStringLiteral("key-enter")}}}, 134 {Icon::ListAdd, {{IconSet::Common, QStringLiteral("list-add")}}}, 135 {Icon::ListAddTag, {{IconSet::Common, QStringLiteral("list-add-tag")}}}, 136 {Icon::ListAddUser, 137 {{IconSet::Common, QStringLiteral("list-add-user")}}}, 138 {Icon::ListCollapse, 139 {{IconSet::Common, QStringLiteral("zoom-out")}, 140 {IconSet::Tango, QStringLiteral("list-remove")}}}, 141 {Icon::ListExpand, 142 {{IconSet::Common, QStringLiteral("zoom-in")}, 143 {IconSet::Tango, QStringLiteral("list-add")}}}, 144 {Icon::ListRemoveTag, 145 {{IconSet::Common, QStringLiteral("list-remove-tag")}}}, 146 {Icon::ListRemoveUser, 147 {{IconSet::Common, QStringLiteral("list-remove-user")}}}, 148 {Icon::MailMessage, 149 {{IconSet::Common, QStringLiteral("internet-mail")}, 150 {IconSet::Oxygen, QStringLiteral("mail-message")}, 151 {IconSet::Breeze, QStringLiteral("mail-message")}}}, 152 {Icon::MailMessageNew, 153 {{IconSet::Common, QStringLiteral("mail-message-new")}}}, 154 {Icon::MailReceive, {{IconSet::Common, QStringLiteral("mail-receive")}}}, 155 {Icon::MapOnlineAccount, 156 {{IconSet::Common, QStringLiteral("news-subscribe")}}}, 157 {Icon::Merge, 158 {{IconSet::Common, QStringLiteral("reconcile")}, 159 {IconSet::Oxygen, QStringLiteral("merge")}, 160 {IconSet::Breeze, QStringLiteral("merge")}}}, 161 {Icon::NewSchedule, 162 {{IconSet::Common, QStringLiteral("appointment-new")}}}, 163 {Icon::OfficeChartLine, 164 {{IconSet::Common, QStringLiteral("account-types-investments")}, 165 {IconSet::Oxygen, QStringLiteral("office-chart-line")}, 166 {IconSet::Breeze, QStringLiteral("office-chart-line")}, 167 {IconSet::Tango, QStringLiteral("report-line")}}}, 168 {Icon::OpenDatabase, {{IconSet::Common, QStringLiteral("server-database")}}}, 169 {Icon::Pause, 170 {{IconSet::Common, QStringLiteral("media-playback-pause")}}}, 171 {Icon::PayeeMerge, {{IconSet::Common, QStringLiteral("merge")}}}, 172 {Icon::PayeeRename, 173 {{IconSet::Common, QStringLiteral("user-properties")}, 174 {IconSet::Oxygen, QStringLiteral("payee-rename")}}}, 175 {Icon::PerformanceTest, 176 {{IconSet::Common, QStringLiteral("fork")}, 177 {IconSet::Breeze, QStringLiteral("speedometer")}}}, 178 {Icon::PreferencesColors, 179 {{IconSet::Common, QStringLiteral("preferences-desktop-color")}}}, 180 {Icon::PreferencesFonts, 181 {{IconSet::Common, QStringLiteral("preferences-desktop-font")}}}, 182 {Icon::PreferencesGeneral, 183 {{IconSet::Common, QStringLiteral("system-run")}, 184 {IconSet::Tango, QStringLiteral("media-playback-start")}}}, 185 {Icon::PreferencesIcons, 186 {{IconSet::Common, QStringLiteral("preferences-desktop-icon")}}}, 187 {Icon::PreferencesNetwork, 188 {{IconSet::Common, QStringLiteral("preferences-system-network")}}}, 189 {Icon::PreferencesPlugins, 190 {{IconSet::Common, QStringLiteral("network-disconnect")}}}, 191 {Icon::Reconcile, 192 {{IconSet::Common, QStringLiteral("reconcile")}, 193 {IconSet::Oxygen, QStringLiteral("merge")}, 194 {IconSet::Breeze, QStringLiteral("merge")}}}, 195 {Icon::Reconciled, 196 {{IconSet::Common, QStringLiteral("reconciled")}, 197 {IconSet::Oxygen, QStringLiteral("flag-green")}, 198 {IconSet::Breeze, QStringLiteral("flag-green")}}}, 199 {Icon::Refresh, 200 {{IconSet::Breeze, QStringLiteral("view-refresh")}, 201 {IconSet::Oxygen, QStringLiteral("refresh")}}}, 202 {Icon::Report, 203 {{IconSet::Common, QStringLiteral("application-vnd.oasis.opendocument.spreadsheet")}}}, 204 {Icon::Reverse, {{IconSet::Common, QStringLiteral("reverse")}}}, 205 {Icon::SeekForward, 206 {{IconSet::Common, QStringLiteral("media-seek-forward")}}}, 207 {Icon::SkipForward, 208 {{IconSet::Common, QStringLiteral("media-skip-forward")}}}, 209 {Icon::SortAscending, 210 {{IconSet::Common, QStringLiteral("go-up")}, 211 {IconSet::Oxygen, QStringLiteral("view-sort-ascending")}, 212 {IconSet::Breeze, QStringLiteral("view-sort-ascending")}}}, 213 {Icon::SortDescending, 214 {{IconSet::Common, QStringLiteral("go-down")}, 215 {IconSet::Oxygen, QStringLiteral("view-sort-descending")}, 216 {IconSet::Breeze, QStringLiteral("view-sort-descending")}}}, 217 {Icon::Split, 218 {{IconSet::Common, QStringLiteral("transaction-split")}, 219 {IconSet::Oxygen, QStringLiteral("split")}, 220 {IconSet::Breeze, QStringLiteral("split")}}}, 221 {Icon::TagRename, {{IconSet::Common, QStringLiteral("tag-rename")}}}, 222 {Icon::TaskAccepted, 223 {{IconSet::Common, QStringLiteral("task-accepted")}}}, 224 {Icon::TaskComplete, 225 {{IconSet::Common, QStringLiteral("task-complete")}}}, 226 {Icon::TaskOngoing, {{IconSet::Common, QStringLiteral("task-ongoing")}}}, 227 {Icon::TaskReject, {{IconSet::Common, QStringLiteral("task-reject")}}}, 228 {Icon::Warning, 229 {{IconSet::Common, QStringLiteral("dialog-warning")}}}, 230 {Icon::Tip, 231 {{IconSet::Common, QStringLiteral("info")}, 232 {IconSet::Oxygen, QStringLiteral("ktip")}}}, 233 {Icon::Unknown, {{IconSet::Common, QStringLiteral("unknown")}}}, 234 {Icon::UnmapOnlineAccount, 235 {{IconSet::Common, QStringLiteral("news-unsubscribe")}}}, 236 {Icon::UserProperties, 237 {{IconSet::Common, QStringLiteral("system-users")}, 238 {IconSet::Oxygen, QStringLiteral("user-properties")}, 239 {IconSet::Breeze, QStringLiteral("user-properties")}}}, 240 {Icon::Accounts, 241 {{IconSet::Common, QStringLiteral("account")}, 242 {IconSet::Oxygen, QStringLiteral("view-bank-account")}, 243 {IconSet::Breeze, QStringLiteral("view-bank-account")}}}, 244 {Icon::Asset, 245 {{IconSet::Common, QStringLiteral("account-types-asset")}, 246 {IconSet::Oxygen, QStringLiteral("view-bank-account")}, 247 {IconSet::Breeze, QStringLiteral("view-bank-account")}}}, 248 {Icon::Bank, 249 {{IconSet::Common, QStringLiteral("bank")}, 250 {IconSet::Oxygen, QStringLiteral("view-bank")}, 251 {IconSet::Breeze, QStringLiteral("view-bank")}}}, 252 {Icon::BankAccount, 253 {{IconSet::Common, QStringLiteral("account")}, 254 {IconSet::Oxygen, QStringLiteral("view-bank-account")}, 255 {IconSet::Breeze, QStringLiteral("view-bank-account")}}}, 256 {Icon::Calendar, 257 {{IconSet::Common, QStringLiteral("view-calendar")}}}, 258 {Icon::CalendarDay, 259 {{IconSet::Common, QStringLiteral("office-calendar")}, 260 {IconSet::Oxygen, QStringLiteral("view-calendar-day")}, 261 {IconSet::Breeze, QStringLiteral("view-calendar-day")}}}, 262 {Icon::Cash, 263 {{IconSet::Common, QStringLiteral("account-types-cash")}}}, 264 {Icon::Checking, 265 {{IconSet::Common, QStringLiteral("account-types-checking")}, 266 {IconSet::Oxygen, QStringLiteral("view-bank-account-checking")}, 267 {IconSet::Breeze, QStringLiteral("view-bank-account-checking")}}}, 268 {Icon::Close, {{IconSet::Common, QStringLiteral("view-close")}}}, 269 {Icon::CreditCard, 270 {{IconSet::Breeze, QStringLiteral("skrooge_credit_card")}, 271 {IconSet::Common, QStringLiteral("account-types-credit-card")}, 272 {IconSet::Oxygen, QStringLiteral("view-credit-card-account")}}}, 273 {Icon::Currencies, 274 {{IconSet::Common, QStringLiteral("view-currency-list")}}}, 275 {Icon::Equity, 276 {{IconSet::Common, QStringLiteral("account")}, 277 {IconSet::Oxygen, QStringLiteral("view-bank-account")}, 278 {IconSet::Breeze, QStringLiteral("view-bank-account")}}}, 279 {Icon::Expense, 280 {{IconSet::Breeze, QStringLiteral("view-categories-expenditures")}, 281 {IconSet::Common, QStringLiteral("account-types-expense")}, 282 {IconSet::Oxygen, QStringLiteral("view-expenses-categories")}}}, 283 {Icon::Filter, {{IconSet::Common, QStringLiteral("view-filter")}}}, 284 {Icon::FinancialCategories, 285 {{IconSet::Common, QStringLiteral("categories")}, 286 {IconSet::Oxygen, QStringLiteral("view-categories")}, 287 {IconSet::Breeze, QStringLiteral("view-categories")}, 288 {IconSet::Oxygen, QStringLiteral("view-financial-categories")}}}, 289 {Icon::Ledger, 290 {{IconSet::Common, QStringLiteral("ledger")}, 291 {IconSet::Oxygen, QStringLiteral("view-financial-list")}}}, 292 {Icon::Transaction, 293 {{IconSet::Common, QStringLiteral("ledger")}, 294 {IconSet::Oxygen, QStringLiteral("view-financial-transfer")}}}, 295 {Icon::Forecast, 296 {{IconSet::Common, QStringLiteral("forecast")}, 297 {IconSet::Oxygen, QStringLiteral("view-financial-forecast")}}}, 298 {Icon::Home, 299 {{IconSet::Common, QStringLiteral("home")}, 300 {IconSet::Oxygen, QStringLiteral("go-home")}, 301 {IconSet::Breeze, QStringLiteral("go-home")}}}, 302 {Icon::Income, 303 {{IconSet::Breeze, QStringLiteral("view-categories-incomes")}, 304 {IconSet::Common, QStringLiteral("account-types-income")}, 305 {IconSet::Oxygen, QStringLiteral("view-income-categories")}}}, 306 {Icon::Institution, 307 {{IconSet::Common, QStringLiteral("institution")}, 308 {IconSet::Oxygen, QStringLiteral("view-bank")}, 309 {IconSet::Breeze, QStringLiteral("view-bank")}}}, 310 {Icon::Institutions, 311 {{IconSet::Common, QStringLiteral("institution")}, 312 {IconSet::Oxygen, QStringLiteral("view-bank")}, 313 {IconSet::Breeze, QStringLiteral("view-bank")}}}, 314 {Icon::Investment, 315 {{IconSet::Common, QStringLiteral("investment")}, 316 {IconSet::Oxygen, QStringLiteral("view-investment")}}}, 317 {Icon::Investments, 318 {{IconSet::Common, QStringLiteral("investment")}, 319 {IconSet::Oxygen, QStringLiteral("view-investment")}}}, 320 {Icon::Liability, 321 {{IconSet::Common, QStringLiteral("account-types-liability")}, 322 {IconSet::Oxygen, QStringLiteral("view-loan")}}}, 323 {Icon::Loan, 324 {{IconSet::Common, QStringLiteral("account-types-loan")}, 325 {IconSet::Oxygen, QStringLiteral("view-loan")}}}, 326 {Icon::LoanAsset, 327 {{IconSet::Common, QStringLiteral("account-types-loan")}, 328 {IconSet::Oxygen, QStringLiteral("view-loan-asset")}}}, 329 {Icon::OnlineJobOutbox, 330 {{IconSet::Common, QStringLiteral("online-banking")}}}, 331 {Icon::Payees, 332 {{IconSet::Common, QStringLiteral("payee")}, 333 {IconSet::Oxygen, QStringLiteral("system-users")}, 334 {IconSet::Breeze, QStringLiteral("system-users")}}}, 335 {Icon::Reports, 336 {{IconSet::Common, QStringLiteral("report")}, 337 {IconSet::Oxygen, QStringLiteral("office-chart-bar")}, 338 {IconSet::Breeze, QStringLiteral("office-chart-bar")}}}, 339 {Icon::Savings, 340 {{IconSet::Common, QStringLiteral("account-types-savings")}, 341 {IconSet::Oxygen, QStringLiteral("view-bank-account-savings")}, 342 {IconSet::Breeze, QStringLiteral("view-bank-account-savings")}}}, 343 {Icon::Schedule, 344 {{IconSet::Common, QStringLiteral("schedule")}, 345 {IconSet::Oxygen, QStringLiteral("view-pim-calendar")}, 346 {IconSet::Breeze, QStringLiteral("view-pim-calendar")}}}, 347 {Icon::Stock, 348 {{IconSet::Common, QStringLiteral("account-types-investments")}, 349 {IconSet::Oxygen, QStringLiteral("view-stock-account")}}}, 350 {Icon::Tags, 351 {{IconSet::Common, QStringLiteral("bookmark-new")}, 352 {IconSet::Oxygen, QStringLiteral("mail-tagged")}, 353 {IconSet::Breeze, QStringLiteral("mail-tagged")}}}, 354 {Icon::TransactionDetails, 355 {{IconSet::Common, QStringLiteral("edit-find")}, 356 {IconSet::Oxygen, QStringLiteral("zoom-in")}, 357 {IconSet::Breeze, QStringLiteral("zoom-in")}}}, 358 {Icon::UpcomingEvents, 359 {{IconSet::Common, QStringLiteral("view-calendar-upcoming-events")}}}, 360 {Icon::ZoomIn, {{IconSet::Common, QStringLiteral("zoom-in")}}}, 361 {Icon::ZoomOut, {{IconSet::Common, QStringLiteral("zoom-out")}}}, 362 {Icon::Visibility, {{IconSet::Common, QStringLiteral("visibility")}}}, 363 {Icon::NoVisibility, {{IconSet::Common, QStringLiteral("hint")}}}, 364 {Icon::SelectAll, {{IconSet::Common, QStringLiteral("edit-select-all")}}} 365 }; 366 367 const QHash<Icon, iconDescription> sComposedIcons { 368 {Icon::InstitutionNew, {Icon::Bank, Icon::ListAdd, Qt::BottomRightCorner}}, 369 {Icon::InstitutionEdit, {Icon::Bank, Icon::DocumentEdit, Qt::BottomRightCorner}}, 370 {Icon::InstitutionDelete, {Icon::Bank, Icon::EditDelete, Qt::BottomRightCorner}}, 371 {Icon::AccountNew, {Icon::BankAccount, Icon::ListAdd, Qt::TopRightCorner}}, 372 {Icon::AccountFinishReconciliation, {Icon::Merge, Icon::DialogOK, Qt::BottomRightCorner}}, 373 {Icon::AccountEdit, {Icon::BankAccount, Icon::DocumentEdit, Qt::BottomRightCorner}}, 374 {Icon::AccountDelete, {Icon::BankAccount, Icon::EditDelete, Qt::BottomRightCorner}}, 375 {Icon::AccountClose, {Icon::BankAccount, Icon::DialogClose, Qt::BottomRightCorner}}, 376 {Icon::AccountReopen, {Icon::BankAccount, Icon::DialogOK, Qt::BottomRightCorner}}, 377 {Icon::AccountUpdate, {Icon::BankAccount, Icon::Download, Qt::BottomRightCorner}}, 378 {Icon::AccountUpdateAll, {Icon::BankAccount, Icon::Download, Qt::BottomRightCorner}}, 379 {Icon::AccountCreditTransfer, {Icon::BankAccount, Icon::MailMessageNew, Qt::BottomRightCorner}}, 380 {Icon::CategoryNew, {Icon::FinancialCategories, Icon::ListAdd, Qt::TopRightCorner}}, 381 {Icon::CategoryEdit, {Icon::FinancialCategories, Icon::DocumentEdit, Qt::BottomRightCorner}}, 382 {Icon::CategoryDelete, {Icon::FinancialCategories, Icon::EditDelete, Qt::BottomRightCorner}}, 383 {Icon::TransactionNew, {Icon::Transaction, Icon::ListAdd, Qt::TopRightCorner}}, 384 {Icon::TransactionEdit, {Icon::Transaction, Icon::DocumentEdit, Qt::BottomRightCorner}}, 385 {Icon::TransactionMatch, {Icon::Transaction, Icon::DocumentImport, Qt::BottomRightCorner}}, 386 {Icon::TransactionAccept, {Icon::Transaction, Icon::DialogOKApply, Qt::BottomRightCorner}}, 387 {Icon::InvestmentNew, {Icon::Investment, Icon::ListAdd, Qt::TopRightCorner}}, 388 {Icon::InvestmentEdit, {Icon::Investment, Icon::DocumentEdit, Qt::BottomRightCorner}}, 389 {Icon::InvestmentDelete, {Icon::Investment, Icon::EditDelete, Qt::BottomRightCorner}}, 390 {Icon::InvestmentOnlinePrice, {Icon::Investment, Icon::Download, Qt::BottomRightCorner}}, 391 {Icon::InvestmentOnlinePriceAll, {Icon::Investment, Icon::Download, Qt::BottomRightCorner}}, 392 {Icon::BudgetNew, {Icon::Budget, Icon::ListAdd, Qt::TopRightCorner}}, 393 {Icon::BudgetRename, {Icon::Budget, Icon::DocumentEdit, Qt::BottomRightCorner}}, 394 {Icon::BudgetDelete, {Icon::Budget, Icon::EditDelete, Qt::BottomRightCorner}}, 395 {Icon::BudgetCopy, {Icon::Budget, Icon::EditCopy, Qt::BottomRightCorner}}, 396 {Icon::PriceUpdate, {Icon::Currencies, Icon::Download, Qt::BottomRightCorner}} 397 }; 398 setUpMappings(const QString & themeName)399 KMM_ICONS_EXPORT void setUpMappings(const QString& themeName) 400 { 401 IconSet themeIconSet; 402 403 if (themeName.contains(QStringLiteral("oxygen"), Qt::CaseInsensitive)) 404 themeIconSet = IconSet::Oxygen; 405 else if (themeName.contains(QStringLiteral("tango"), Qt::CaseInsensitive)) 406 themeIconSet = IconSet::Tango; 407 // default to breeze mappings 408 else 409 themeIconSet = IconSet::Breeze; 410 411 for (auto iconDef = iconMappings.cbegin(); iconDef != iconMappings.cend(); ++iconDef) { 412 const auto icon = iconDef.key(); 413 auto name = iconDef.value().value(themeIconSet); 414 415 // get common mapping if theme-specific does not exist 416 if (name.isEmpty()) 417 name = iconDef.value().value(IconSet::Common); 418 419 sStandardIcons.insert(icon, name); 420 } 421 } 422 423 /** 424 * This method overlays an icon over another one, to get a composite one 425 * eg. an icon to add accounts 426 */ overlayIcon(iconDescription description,const int size=64)427 QIcon overlayIcon(iconDescription description, const int size = 64) 428 { 429 const auto iconName = sStandardIcons[description.baseIcon]; 430 const auto overlayName = sStandardIcons[description.overlayIcon]; 431 const auto corner = description.corner; 432 433 QPixmap pxIcon; 434 QString kyIcon = iconName + overlayName; 435 436 // If found in the cache, return quickly 437 if (QPixmapCache::find(kyIcon, pxIcon)) 438 return pxIcon; 439 440 // try to retrieve the main icon from cache 441 if (!QPixmapCache::find(iconName, pxIcon)) { 442 pxIcon = QIcon::fromTheme(iconName).pixmap(size); 443 QPixmapCache::insert(iconName, pxIcon); 444 } 445 446 if (overlayName.isEmpty()) // call from MyMoneyAccount::accountPixmap can have no overlay icon, so handle that appropriately 447 return pxIcon; 448 449 QPainter pixmapPainter(&pxIcon); 450 QPixmap pxOverlay = QIcon::fromTheme(overlayName).pixmap(size); 451 452 int x, y; 453 switch (corner) { 454 case Qt::TopLeftCorner: 455 x = 0; 456 y = 0; 457 break; 458 case Qt::TopRightCorner: 459 x = pxIcon.width() / 2; 460 y = 0; 461 break; 462 case Qt::BottomLeftCorner: 463 x = 0; 464 y = pxIcon.height() / 2; 465 break; 466 case Qt::BottomRightCorner: 467 default: 468 x = pxIcon.width() / 2; 469 y = pxIcon.height() / 2; 470 break; 471 } 472 pixmapPainter.drawPixmap(x, y, pxIcon.width() / 2, pxIcon.height() / 2, pxOverlay); 473 474 //save for later use 475 QPixmapCache::insert(kyIcon, pxIcon); 476 477 return pxIcon; 478 } 479 get(Icon icon)480 KMM_ICONS_EXPORT QIcon get(Icon icon) 481 { 482 if (sComposedIcons.contains(icon)) 483 return overlayIcon(sComposedIcons[icon]); 484 485 return QIcon::fromTheme(sStandardIcons[icon]); 486 } 487 iconCacheDir()488 QString iconCacheDir() 489 { 490 const QString cachePath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation); 491 if (QDir::root().mkpath(cachePath)) { 492 return cachePath; 493 } 494 return QString(); 495 } 496 storeIconInApplicationCache(const QString & name,const QIcon & icon)497 KMM_ICONS_EXPORT bool storeIconInApplicationCache(const QString& name, const QIcon& icon) 498 { 499 // split the icon name from the type 500 QRegularExpression iconPath(QStringLiteral("^(?<type>[a-zA-Z]+):(?<name>.+)"), QRegularExpression::CaseInsensitiveOption); 501 QRegularExpressionMatch matcher = iconPath.match(name); 502 if (matcher.hasMatch()) { 503 if (matcher.captured(QStringLiteral("type")).compare(QLatin1String("enum")) == 0) { 504 return true; 505 } else { 506 const QString cacheDir = iconCacheDir(); 507 if (!cacheDir.isEmpty()) { 508 return icon.pixmap(16).save(QString::fromLatin1("%1/%2-%3").arg(cacheDir, matcher.captured(QStringLiteral("type")), matcher.captured(QStringLiteral("name"))), "PNG"); 509 } 510 } 511 } 512 return false; 513 } 514 loadIconFromApplicationCache(const QString & name)515 KMM_ICONS_EXPORT QIcon loadIconFromApplicationCache(const QString& name) 516 { 517 const QHash<QString, Icon> sEnumIcons { 518 { QStringLiteral("Bank"), Icon::Bank }, 519 }; 520 521 // split the icon name from the type 522 QRegularExpression iconPath(QStringLiteral("^(?<type>[a-zA-Z]+):(?<name>.+)"), QRegularExpression::CaseInsensitiveOption); 523 QRegularExpressionMatch matcher = iconPath.match(name); 524 if (matcher.hasMatch()) { 525 if (matcher.captured(QStringLiteral("type")).compare(QLatin1String("enum")) == 0) { 526 // type is enum, so we use our own set of icons 527 const QString iconName = matcher.captured(QStringLiteral("name")); 528 if (sEnumIcons.contains(iconName)) { 529 return get(sEnumIcons[iconName]); 530 } 531 532 } else { 533 // otherwise, we use the type as part of the filename 534 const QString cacheDir = iconCacheDir(); 535 if (!cacheDir.isEmpty()) { 536 const QString filename = QString::fromLatin1("%1/%2-%3").arg(cacheDir, matcher.captured(QStringLiteral("type")), matcher.captured(QStringLiteral("name"))); 537 if (QFile::exists(filename)) { 538 return QIcon(filename); 539 } 540 } 541 } 542 } 543 return QIcon(); 544 } 545 } 546