1 #ifndef _KVI_ICONMANAGER_H_ 2 #define _KVI_ICONMANAGER_H_ 3 //============================================================================= 4 // 5 // File : KviIconManager.h 6 // Creation date : Sat Jun 24 2000 14:49:24 by Szymon Stefanek 7 // 8 // This file is part of the KVIrc IRC client distribution 9 // Copyright (C) 2000-2010 Szymon Stefanek (pragma at kvirc dot net) 10 // Copyright (C) 2011 Elvio Basello (hellvis69 at gmail dot com) 11 // 12 // This program is FREE software. You can redistribute it and/or 13 // modify it under the terms of the GNU General Public License 14 // as published by the Free Software Foundation; either version 2 15 // of the License, or (at your option) any later version. 16 // 17 // This program is distributed in the HOPE that it will be USEFUL, 18 // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 20 // See the GNU General Public License for more details. 21 // 22 // You should have received a copy of the GNU General Public License 23 // along with this program. If not, write to the Free Software Foundation, 24 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 25 // 26 //============================================================================= 27 28 /** 29 * \file KviIconManager.h 30 * \author Szymon Stefanek 31 * \brief Icon manager 32 */ 33 34 #include "kvi_settings.h" 35 #include "KviAvatar.h" 36 #include "KviCString.h" 37 #include "KviPointerHashTable.h" 38 #include "KviTimeUtils.h" 39 40 #include <QObject> 41 #include <QPixmap> 42 #include <QWidget> 43 44 #include <array> 45 46 #define KVI_BIGICON_DISCONNECTED "kvi_bigicon_disconnected.png" 47 #define KVI_BIGICON_CONNECTING "kvi_bigicon_connecting.png" 48 #define KVI_BIGICON_CONNECTED "kvi_bigicon_connected.png" 49 #define KVI_BIGICON_TOOLS "kvi_bigicon_tools.png" 50 #define KVI_BIGICON_ACTIONS "kvi_bigicon_actions.png" 51 #define KVI_BIGICON_USERACTION "kvi_bigicon_useraction.png" 52 #define KVI_BIGICON_FOLDER "kvi_bigicon_folder.png" 53 #define KVI_BIGICON_UNKNOWN "kvi_bigicon_unknown.png" 54 #define KVI_BIGICON_SEPARATOR "kvi_bigicon_separator.png" 55 #define KVI_BIGICON_KVS "kvi_bigicon_kvs.png" 56 #define KVI_BIGICON_THEME "kvi_bigicon_theme.png" 57 #define KVI_BIGICON_ADDONS "kvi_bigicon_addons.png" 58 59 #define KVI_BIGICON_HELP "kvi_bigicon_help.png" 60 #define KVI_BIGICON_HELPINDEX "kvi_bigicon_helpindex.png" 61 #define KVI_BIGICON_HELPBACK "kvi_bigicon_helpback.png" 62 #define KVI_BIGICON_HELPFORWARD "kvi_bigicon_helpforward.png" 63 #define KVI_BIGICON_HELPCLOSE "kvi_bigicon_helpclose.png" 64 #define KVI_BIGICON_HELPSEARCH "kvi_bigicon_helpsearch.png" 65 66 #define KVI_BIGICON_OPEN "kvi_bigicon_open.png" 67 #define KVI_BIGICON_SAVE "kvi_bigicon_save.png" 68 #define KVI_BIGICON_REMOVE "kvi_bigicon_remove.png" 69 #define KVI_BIGICON_WWW "kvi_bigicon_www.png" 70 #define KVI_BIGICON_PACK "kvi_bigicon_pack.png" 71 #define KVI_BIGICON_SCREENSHOT "kvi_bigicon_screenshot.png" 72 #define KVI_BIGICON_REGUSERS "kvi_bigicon_regusers.png" 73 74 #define KVI_SMALLICONS_SUBDIRECTORY "coresmall" 75 #define KVI_SMALLICONS_PREFIX "kcs_" 76 77 // FIXME: this should be removed 78 #define KVI_SMALLICONS_IMAGELIB_PREFIX "kvi_smallicon_" 79 80 #define KVI_USERCHANSTATE_IMAGE_NAME "kvi_userchanstate.png" 81 #define KVI_ACTIVITYMETER_IMAGE_NAME "kvi_activitymeter.png" 82 83 #define KVI_REFRESH_IMAGE_NAME "kvi_icon_refresh.png" 84 85 class KVIRC_API KviIconWidget; 86 87 /** 88 * \class KviCachedPixmap 89 * \brief Class for holding a cached pixmap 90 */ 91 class KVIRC_API KviCachedPixmap 92 { 93 public: 94 /** 95 * \brief Constructs the KviCachedPixmap object 96 * \param pPix The image object 97 * \param szPath The path of the image 98 * \warning The pixmap MUST be allocated with new QPixmap(). This class takes the ownership 99 * \return KviCachedPixmap 100 */ 101 KviCachedPixmap(QPixmap * pPix, const QString & szPath); 102 103 /** 104 * \brief Destroys the KviCachedPixmap object 105 */ 106 ~KviCachedPixmap(); 107 108 private: 109 QString m_szPath; 110 kvi_time_t m_tLastAccess; 111 QPixmap * m_pPixmap = nullptr; 112 unsigned int m_uSize; 113 114 public: 115 /** 116 * \brief Returns the image 117 * \return QPixmap * 118 */ pixmap()119 QPixmap * pixmap() const { return m_pPixmap; } 120 121 /** 122 * \brief Returns the path of the image 123 * \return const QString & 124 */ path()125 const QString & path() const { return m_szPath; } 126 127 /** 128 * \brief Returns the size of the image 129 * \return unsigned int 130 */ size()131 unsigned int size() const { return m_uSize; } 132 133 /** 134 * \brief Returns the time the image was last accessed 135 * \return kvi_time_t 136 */ lastAccessTime()137 kvi_time_t lastAccessTime() const { return m_tLastAccess; } 138 139 /** 140 * \brief Updates the time the image was last accessed 141 * \return void 142 */ 143 void updateLastAccessTime(); 144 }; 145 146 /** 147 * \class KviIconManager 148 * \brief This class manages the images used by KVIrc. 149 * 150 * We handle three types of images: builtin small icons, builtin big icons and generic images. 151 * The builtin small icons are in the pics/coresmall directory (this is to optimize the directory 152 * size since it's a linear search...), are 16x16 in size and are indexed by numbers in a way that 153 * their access is really fast. The icons used here are used mostly in KviIrcView (but not 154 * exclusively). 155 * The builtin big icons are (actually) just generic images that are eventually scaled to 32x32 156 * if needed. One can request a builtin small icon indexed by number to be scaled to the size of 157 * 32x32 as a big icon too. 158 * The generic images are just "any" image that the underlying Qt engine is able to load. They are 159 * loaded by (relative) path and cached by name. 160 */ 161 class KVIRC_API KviIconManager : public QObject 162 { 163 Q_OBJECT 164 public: 165 /** 166 * \enum SmallIcon 167 * \brief Contains all KVIrc's small icons 168 */ 169 enum SmallIcon 170 { 171 None = 0, 172 Close = 1, 173 History = 2, 174 HistoryOff = 3, 175 UserMode = 4, 176 DefaultIcon = 5, 177 Dock = 6, 178 UnDock = 7, 179 QuitApp = 8, 180 Console = 9, 181 Save = 10, 182 ParserError = 11, 183 ParserWarning = 12, 184 Server = 13, 185 World = 14, 186 Proxy = 15, 187 KVIrc = 16, 188 Cut = 17, 189 Copy = 18, 190 Paste = 19, 191 Options = 20, 192 SocketMessage = 21, 193 SocketWarning = 22, 194 SocketError = 23, 195 SystemError = 24, 196 Raw = 25, 197 SystemWarning = 26, 198 SystemMessage = 27, 199 UnHandled = 28, 200 ServerInfo = 29, 201 Motd = 30, 202 Channel = 31, 203 HideDoubleView = 32, 204 ShowDoubleView = 33, 205 Op = 34, 206 Voice = 35, 207 ServerPing = 36, 208 ShowListView = 37, 209 HideListView = 38, 210 Join = 39, 211 Part = 40, 212 Unrecognized = 41, 213 Topic = 42, 214 Accept = 43, 215 Discard = 44, 216 OwnPrivMsg = 45, 217 ChanPrivMsg = 46, 218 Query = 47, 219 QueryPrivMsg = 48, 220 Help = 49, 221 QuestionMark = 50, 222 CtcpReply = 51, 223 CtcpRequestReplied = 52, 224 CtcpRequestIgnored = 53, 225 CtcpRequestFlood = 54, 226 CtcpRequestUnknown = 55, 227 Action = 56, 228 Avatar = 57, 229 Quit = 58, 230 Split = 59, 231 QuitSplit = 60, 232 Nick = 61, 233 DeOp = 62, 234 DeVoice = 63, 235 Mode = 64, 236 Key = 65, 237 Limit = 66, 238 Ban = 67, 239 UnBan = 68, 240 BanExcept = 69, 241 BanUnExcept = 70, 242 InviteExcept = 71, 243 InviteUnExcept = 72, 244 ChanMode = 73, 245 ChanModeHide = 74, 246 Who = 75, 247 Editor = 76, 248 DccRequest = 77, 249 DccMsg = 78, 250 DccError = 79, 251 IconManager = 80, 252 ScriptCenter = 81, 253 Bomb = 82, 254 Event = 83, 255 EventNoHandlers = 84, 256 Handler = 85, 257 HandlerDisabled = 86, 258 NickNameProblem = 87, 259 WhoisUser = 88, 260 WhoisChannels = 89, 261 WhoisIdle = 90, 262 WhoisServer = 91, 263 WhoisOther = 92, 264 Time = 93, 265 NotifyOnLine = 94, 266 NotifyOffLine = 95, 267 Locked = 96, 268 UnLocked = 97, 269 LockedOff = 98, 270 UnLockedOff = 99, 271 OwnPrivMsgCrypted = 100, 272 ChanPrivMsgCrypted = 101, 273 QueryPrivMsgCrypted = 102, 274 DccChatMsg = 103, 275 DccChatMsgCrypted = 104, 276 Irc = 105, 277 Folder = 106, 278 Home = 107, 279 BookMarks = 108, 280 Spy = 109, 281 Kick = 110, 282 Linux = 111, 283 Links = 112, 284 RegUsers = 113, 285 TrayIcon = 114, 286 UnsetMode = 115, 287 Favorite = 116, 288 Toolbar = 117, 289 ServerFavorite = 118, 290 Log = 119, 291 Remove = 120, 292 File = 121, 293 Icq = 122, 294 IcqYellow = 123, 295 IcqRed = 124, 296 IcqBlue = 125, 297 IcqLightGreen = 126, 298 IcqLightYellow = 127, 299 Message = 128, 300 MessageSent = 129, 301 BlueSquare = 130, 302 VioletSquare = 131, 303 YellowSquare = 132, 304 GreenSquare = 133, 305 BlackSquare = 134, 306 RedSquare = 135, 307 CyanSquare = 136, 308 DarkGreenSquare = 137, 309 Terminal = 138, 310 WallOps = 139, 311 Invisible = 140, 312 ServerNotice = 141, 313 Gnutella = 142, 314 Search = 143, 315 Files = 144, 316 NewNetwork = 145, 317 Package = 146, 318 NewServer = 147, 319 Idea = 148, 320 Colors = 149, 321 Gui = 150, 322 IrcView = 151, 323 Alias = 152, 324 ChannelNotice = 153, 325 ChannelNoticeCrypted = 154, 326 QueryNotice = 155, 327 QueryNoticeCrypted = 156, 328 MenuBar = 157, 329 Popup = 158, 330 Prologue = 159, 331 Epilogue = 160, 332 SharedFiles = 161, 333 CtcpReplyUnknown = 162, 334 Canvas = 163, 335 NickServ = 164, 336 ChanServ = 165, 337 DccVoice = 166, 338 Play = 167, 339 Record = 168, 340 KickOff = 169, 341 Away = 170, 342 Ident = 171, 343 HomePage = 172, 344 List = 173, 345 HalfOp = 174, 346 HalfDeOp = 175, 347 Invite = 176, 348 MultiMedia = 177, 349 User = 178, 350 Input = 179, 351 Messages = 180, 352 QueryTrace = 181, 353 NoChannel = 182, 354 BroadcastPrivMsg = 183, 355 BroadcastNotice = 184, 356 Url = 185, 357 RawEvent = 186, 358 RawEventNoHandlers = 187, 359 MeKick = 188, 360 MeOp = 189, 361 MeVoice = 190, 362 MeDeOp = 191, 363 MeDeVoice = 192, 364 MeHalfOp = 193, 365 MeDeHalfOp = 194, 366 MeBan = 195, 367 MeUnBan = 196, 368 MeBanExcept = 197, 369 MeBanUnExcept = 198, 370 MeInviteExcept = 199, 371 MeInviteUnExcept = 200, 372 ClassicWindowList = 201, 373 TreeWindowList = 202, 374 Ignore = 203, 375 UserList = 204, 376 Stats = 205, 377 PopupMenu = 206, 378 ServerConfiguration = 207, 379 Irc0 = 208, 380 Irc1 = 209, 381 Irc2 = 210, 382 Irc3 = 211, 383 Irc4 = 212, 384 Irc5 = 213, 385 Heart = 214, 386 HeartBroken = 215, 387 Rose = 216, 388 BigGrin = 217, 389 BigGrinGlasses = 218, 390 BigGrinEyes = 219, 391 TextExclamative = 220, 392 TextPoints = 221, 393 Kiss = 222, 394 Surprised1 = 223, 395 Ugly = 224, 396 Angry = 225, 397 Surprised2 = 226, 398 Smile = 227, 399 Tongue = 228, 400 Ssl = 229, 401 Cry = 230, 402 Eye = 231, 403 DeadChannel = 232, 404 DeadQuery = 233, 405 Sound = 234, 406 ToolBarEditor = 235, 407 TextEncoding = 236, 408 NewItem = 237, 409 NewItemByWizard = 238, 410 DeleteItem = 239, 411 EditItem = 240, 412 FileTransfer = 241, 413 ChanAdmin = 242, 414 ChanUnAdmin = 243, 415 MeChanAdmin = 244, 416 MeChanUnAdmin = 245, 417 UserOp = 246, 418 DeUserOp = 247, 419 MeUserOp = 248, 420 MeDeUserOp = 249, 421 Applet = 250, 422 Spam = 251, 423 Transparent = 252, 424 Notifier = 253, 425 UserWindow = 254, 426 StatusBar = 255, 427 NotAway = 256, 428 Plus = 257, 429 Minus = 258, 430 BinaryText = 259, 431 ChanOwner = 260, 432 ChanUnOwner = 261, 433 MeChanOwner = 262, 434 MeChanUnOwner = 263, 435 Afraid = 264, 436 Teeth = 265, 437 SysMonitor = 266, 438 SayColors = 267, 439 Finger = 268, 440 HighlightText = 269, 441 TearSmile = 270, 442 Shy = 271, 443 ServerError = 272, 444 Cafe = 273, 445 Addons = 274, 446 ChanOwnerAway = 275, 447 OpAway = 276, 448 VoiceAway = 277, 449 ChanAdminAway = 278, 450 UserOpAway = 279, 451 HalfOpAway = 280, 452 ClassEditor = 281, 453 Demoralized = 282, 454 Slurp = 283, 455 NameSpace = 284, 456 SaySmile = 285, 457 SayKvs = 286, 458 ThemeOptions = 287, 459 Bug = 288, 460 Refresh = 289, 461 Theme = 290, 462 ScreenShot = 291, 463 Update = 292, 464 NotUpdate = 293, 465 FailUpdate = 294, 466 UnreadText = 295, 467 IrcOp = 296, 468 IrcOpAway = 297, 469 DeIrcOp = 298, 470 MeIrcOp = 299, 471 MeDeIrcOp = 300, 472 Angel = 301, 473 Clown = 302, 474 Devil = 303, 475 InLove = 304, 476 Ninja = 305, 477 Pirate = 306, 478 Puke = 307, 479 Rage = 308, 480 Class = 309, 481 ClassNotBuilt = 310, 482 Function = 311, 483 SexMale = 312, 484 SexFemale = 313, 485 IrcBot = 314, 486 AlienIrcOp = 315, 487 MemoServ = 316, 488 Info = 317, 489 Warning = 318, 490 Shield = 319, 491 RawEventEditor = 320, 492 EventEditor = 321, 493 ActionEditor = 322, 494 AliasEditor = 323, 495 PopupEditor = 324, 496 Dcc = 325, 497 Socket = 326, 498 Cake = 327, 499 HandIly = 328, 500 ThumbDown = 329, 501 ThumbUp = 330, 502 FacePalm = 331, 503 Identity = 332, 504 NickPopup = 333, 505 Tools = 334, 506 FavoriteOff = 335, 507 NewProxy = 336, 508 ActionCrypted = 337, 509 TopicCrypted = 338, 510 CtcpCrypted = 339, 511 OwnAction = 340, 512 OwnActionCrypted = 341, 513 IconCount = 342 514 }; 515 516 /** 517 * \brief Creates the icon manager object 518 * \return KviIconManager 519 */ 520 KviIconManager(); 521 522 /** 523 * \brief Destroys the icon manager object 524 */ 525 ~KviIconManager(); 526 527 private: 528 std::array<QPixmap *,IconCount> m_smallIcons = { { nullptr } }; 529 KviIconWidget * m_pIconWidget = nullptr; 530 KviPointerHashTable<QString, KviCachedPixmap> * m_pCachedImages = nullptr; 531 KviPointerHashTable<QString, int> * m_pIconNames = nullptr; 532 unsigned int m_uCacheTotalSize = 0; 533 unsigned int m_uCacheMaxSize = 1024 * 1024; // 1 MiB 534 535 public: 536 /** 537 * \brief Returns the image 538 * \param szId The ID of the image 539 * This can be a filename or a number that indicates an internal pixmap. 0 stands 540 * for "any" 541 * \param bCanBeNumber Whether the image is specified by a number, especially for 542 * scripts or popups 543 * \param pRetPath Holds the path of the image 544 * \warning Don't store this pointer! 545 * 546 * \return QPixmap * 547 */ 548 QPixmap * getImage(const QString & szId, bool bCanBeNumber = true, QString * pRetPath = nullptr); 549 550 /** 551 * \brief Returns the cached pixmap of the image 552 * \param szName The name of the image 553 * \warning Don't store this pointer! 554 * The returned pointer is owned by the icon manager and can be deleted at any time 555 * \return KviCachedPixmap * 556 */ 557 KviCachedPixmap * getPixmapWithCache(const QString & szName); 558 559 /** 560 * \brief Returns the cached pixmap of the image and scales it on load 561 * \param szName The name of the image 562 * \param iMaxWidth The max width to scale 563 * \param iMaxHeight The max height to scale 564 * \warning Don't store this pointer! 565 * The returned pointer is owned by the icon manager and can be deleted at any time 566 * \return KviCachedPixmap * 567 */ 568 KviCachedPixmap * getPixmapWithCacheScaleOnLoad(const QString & szName, int iMaxWidth, int iMaxHeight); 569 570 /** 571 * \brief Returns the pixmap of the image 572 * \param szName The name of the image 573 * \warning Don't store this pointer! 574 * The returned pointer is owned by the icon manager and can be deleted at any time 575 * \return QPixmap * 576 */ getPixmap(const QString & szName)577 QPixmap * getPixmap(const QString & szName) 578 { 579 KviCachedPixmap * pPix = getPixmapWithCache(szName); 580 return pPix ? pPix->pixmap() : nullptr; 581 } 582 583 /** 584 * \brief Returns the big icon 585 * \param szName The icon to get 586 * \note This one never fails... if the icon isn't there, then a default 32x32 image 587 * is returned 588 * \return QPixmap * 589 */ 590 QPixmap * getBigIcon(const QString & szName); 591 592 /** 593 * \brief Returns the small icon 594 * \param eIcon The icon to get 595 * \note This one never fails... if the icon isn't there, then a default 16x16 image 596 * is returned 597 * \return QPixmap * 598 */ getSmallIcon(SmallIcon eIcon)599 QPixmap * getSmallIcon(SmallIcon eIcon) { return eIcon < IconCount ? (m_smallIcons[eIcon] ? m_smallIcons[eIcon] : loadSmallIcon(eIcon)) : nullptr; } 600 601 /** 602 * \brief Returns the small icon 603 * \param iIcon The icon to get 604 * \note This one never fails... if the icon isn't there, then a default 16x16 image 605 * is returned. This is provided for convenience 606 * \return QPixmap * 607 */ getSmallIcon(int iIcon)608 QPixmap * getSmallIcon(int iIcon) { return iIcon < IconCount ? (m_smallIcons[iIcon] ? m_smallIcons[iIcon] : loadSmallIcon(iIcon)) : nullptr; } 609 610 /** 611 * \brief Returns the name of the small icon 612 * \param eIcon The icon to get 613 * \return const char * 614 */ 615 const char * getSmallIconName(SmallIcon eIcon); 616 617 /** 618 * \brief Returns the name of the small icon 619 * \param iIcon The icon to get 620 * \note This is provided for convenience 621 * \return const char * 622 */ 623 const char * getSmallIconName(int iIcon); 624 625 /** 626 * \brief Returns the resource name of the small icon 627 * \param eIcon The icon to get 628 * \return QString 629 */ 630 QString getSmallIconResourceName(SmallIcon eIcon); 631 632 /** 633 * \brief Returns the name of the small icon 634 * \param iIcon The icon to get 635 * \return KviIconManager::SmallIcon 636 */ 637 SmallIcon iconName(int iIcon); 638 639 /** 640 * \brief Returns the index of the small icon 641 * \param szName The name of the icon 642 * \return int 643 */ 644 int getSmallIconIdFromName(const QString & szName); 645 646 /** 647 * \brief Returns the avatar 648 * If szLocalPath is empty then szName can be the identification string for the 649 * avatar 650 * If szName is empty then it is found from szLocalPath 651 * \param szLocalPath The local path of the avatar 652 * \param szName The name of the avatar 653 * \return KviAvatar * 654 */ 655 KviAvatar * getAvatar(const QString & szLocalPath, const QString & szName); 656 657 /** 658 * \brief Returns the url of the image in cache 659 * \param szName The path of the image 660 * \return void 661 */ 662 void urlToCachedFileName(QString & szName); 663 664 /** 665 * \brief Clears the cache! 666 * \return void 667 */ 668 void clearCache(); 669 670 /** 671 * \brief Reloads all images 672 * \return void 673 */ 674 void reloadImages(); 675 676 //void cacheCleanup(); 677 protected: 678 void addToCache(const QString & szName, KviCachedPixmap * pPix); 679 680 /** 681 * \brief Returns the icon 682 * \param iIdx The ID of the icon 683 * \return QPixmap * 684 */ 685 QPixmap * loadSmallIcon(int iIdx); 686 687 /** 688 * \brief Initializes the Qt resource backend 689 * \return void 690 */ 691 void initQResourceBackend(); 692 public slots: 693 /** 694 * \brief Shows the table of icons 695 * \return void 696 */ 697 void showIconWidget(); 698 protected slots: 699 /** 700 * \brief Called when we close the table of icons 701 * \return void 702 */ 703 void iconWidgetClosed(); 704 }; 705 706 /** 707 * \class KviIconWidget 708 * \brief The widget with holds the table of icons 709 */ 710 class KVIRC_API KviIconWidget : public QWidget 711 { 712 Q_OBJECT 713 public: 714 /** 715 * \brief Constructs the icon table widget 716 * \param pPar The parent object 717 * \return KviIconWidget 718 */ 719 KviIconWidget(QWidget * pPar = nullptr); 720 721 /** 722 * \brief Destroys the icon table widget 723 */ 724 ~KviIconWidget(); 725 726 protected: 727 /** 728 * \brief Initializes the table containing the icons 729 * \return void 730 */ 731 void init(); 732 733 void closeEvent(QCloseEvent * pEvent) override; 734 bool eventFilter(QObject * pObject, QEvent * pEvent) override; 735 signals: 736 /** 737 * \brief Emitted when we close the table widget 738 * \return void 739 */ 740 void closed(); 741 742 /** 743 * \brief Emitted when we select an icon from the table 744 * \param eIcon The index of the icon selected 745 * \return void 746 */ 747 void selected(KviIconManager::SmallIcon eIcon); 748 }; 749 750 extern KVIRC_API KviIconManager * g_pIconManager; 751 752 #endif //_KVI_ICONMANAGER_H_ 753