File indexing completed on 2024-04-28 04:32:09
0001 /* 0002 * Copyright (C) 2012-2015 by Stephen Allewell 0003 * steve.allewell@gmail.com 0004 * 0005 * This program is free software; you can redistribute it and/or modify 0006 * it under the terms of the GNU General Public License as published by 0007 * the Free Software Foundation; either version 2 of the License, or 0008 * (at your option) any later version. 0009 */ 0010 0011 /** 0012 * @file 0013 * Implement the SymbolListWidget class 0014 */ 0015 0016 /** 0017 * @page library_list_widget SymbolListWidget 0018 * This class implements an extension to the QListWidget class that provides population of the widget 0019 * with the contents of a SymbolLibrary. For each Symbol in the library a QListWidgetItem is created 0020 * with a data item representing the Symbol identifier in the library and an icon at a given size that 0021 * is generated from the Symbol path. 0022 * 0023 * The widget is intended to be used in a dialog or main window and allows selection of a symbol to be 0024 * used for some purpose in the application. 0025 * 0026 * @image html ui-main-library.png "The user interface showing the library tab" 0027 */ 0028 0029 #include "SymbolListWidget.h" 0030 0031 #include <QApplication> 0032 #include <QPainter> 0033 #include <QPalette> 0034 #include <QPen> 0035 0036 #include <KLocalizedString> 0037 0038 #include "Stitch.h" 0039 #include "Symbol.h" 0040 #include "SymbolLibrary.h" 0041 0042 /** 0043 * Constructor. 0044 */ 0045 SymbolListWidget::SymbolListWidget(QWidget *parent) 0046 : QListWidget(parent) 0047 , m_library(nullptr) 0048 , m_lastIndex(0) 0049 { 0050 setResizeMode(QListView::Adjust); 0051 setViewMode(QListView::IconMode); 0052 setIconSize(24); 0053 } 0054 0055 /** 0056 * Set the size of the icons to be used. 0057 * The base QListWidget has the icon size and grid size set to this value. 0058 * 0059 * @param size the size in pixels 0060 */ 0061 void SymbolListWidget::setIconSize(int size) 0062 { 0063 m_size = size; 0064 QListWidget::setIconSize(QSize(m_size, m_size)); 0065 setGridSize(QSize(m_size, m_size)); 0066 } 0067 0068 /** 0069 * Populate the QListWidget with the QListWidgetItems for each Symbol in the SymbolLibrary. 0070 * An icon is created for each Symbol. 0071 * 0072 * @param library a pointer to the SymbolLibrary containing the Symbols 0073 */ 0074 void SymbolListWidget::loadFromLibrary(SymbolLibrary *library) 0075 { 0076 if (!library) { 0077 return; 0078 } 0079 0080 m_library = library; 0081 QList<qint16> keys = library->indexes(); 0082 0083 foreach (qint16 index, keys) { 0084 addSymbol(index, library->symbol(index)); 0085 } 0086 } 0087 0088 /** 0089 * Add an individual Symbol to the view. 0090 * 0091 * @param index the index of the Symbol 0092 * @param symbol a const reference to the Symbol to add 0093 * @return a pointer to a QListWidgetItem 0094 */ 0095 QListWidgetItem *SymbolListWidget::addSymbol(qint16 index, const Symbol &symbol) 0096 { 0097 QListWidgetItem *item = createItem(index); 0098 item->setIcon(createIcon(symbol, m_size)); 0099 0100 return item; 0101 } 0102 0103 /** 0104 * Enable the item so that it can be selected clearing the tooltip. 0105 * 0106 * @param index the index of the Symbol 0107 */ 0108 void SymbolListWidget::enableItem(qint16 index) 0109 { 0110 if (m_items.contains(index)) { 0111 m_items.value(index)->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); 0112 m_items.value(index)->setToolTip(QString()); 0113 } 0114 } 0115 0116 /** 0117 * Disable the item so that it can not be selected adding a tooltip to 0118 * show the user why. 0119 * 0120 * @param index the index of the Symbol 0121 */ 0122 void SymbolListWidget::disableItem(qint16 index) 0123 { 0124 if (m_items.contains(index)) { 0125 m_items.value(index)->setFlags(Qt::NoItemFlags); 0126 m_items.value(index)->setToolTip(QString(i18nc("A symbol that has been used", "Used"))); 0127 } 0128 } 0129 0130 /** 0131 * Remove a symbol item from the view. 0132 * 0133 * @param index the index of the item to remove 0134 */ 0135 void SymbolListWidget::removeSymbol(qint16 index) 0136 { 0137 if (m_items.contains(index)) { 0138 delete m_items.take(index); 0139 } 0140 } 0141 0142 /** 0143 * Set an item as the currently selected one. 0144 * 0145 * @param index the index of the item to be current 0146 */ 0147 void SymbolListWidget::setCurrent(qint16 index) 0148 { 0149 if (m_items.contains(index)) { 0150 m_items.value(index)->setSelected(true); 0151 } 0152 } 0153 0154 /** 0155 * If an item for the index currently exists return it otherwise create 0156 * an item to be inserted into the QListWidget. 0157 * The item created has a data entry added representing the index. 0158 * The items are inserted so that the Symbols are sorted by their index. 0159 * 0160 * @param index an index in the SymbolLibrary 0161 * 0162 * @return a pointer to the QListWidgetItem created 0163 */ 0164 QListWidgetItem *SymbolListWidget::createItem(qint16 index) 0165 { 0166 if (m_items.contains(index)) { 0167 return m_items.value(index); 0168 } 0169 0170 QListWidgetItem *item = new QListWidgetItem; 0171 item->setData(Qt::UserRole, index); 0172 m_items.insert(index, item); 0173 int i = index; 0174 0175 while (++i < m_lastIndex) { 0176 if (m_items.contains(i)) { 0177 break; 0178 } 0179 } 0180 0181 if (i >= m_lastIndex) { 0182 addItem(item); 0183 m_lastIndex = index; 0184 } else { 0185 insertItem(row(m_items[i]), item); 0186 } 0187 0188 return item; 0189 } 0190 0191 /** 0192 * Create a QIcon for the supplied Symbol. 0193 * 0194 * @param symbol a const reference to a Symbol 0195 * @param size a size for the icon 0196 * 0197 * @return a QIcon 0198 */ 0199 QIcon SymbolListWidget::createIcon(const Symbol &symbol, int size) 0200 { 0201 QPalette pal = QApplication::palette(); 0202 0203 QPixmap icon(size, size); 0204 icon.fill(Qt::transparent); 0205 0206 QPainter painter(&icon); 0207 painter.setRenderHint(QPainter::Antialiasing, true); 0208 painter.setWindow(0, 0, 1, 1); 0209 0210 QBrush brush = symbol.brush(); 0211 QPen pen = symbol.pen(); 0212 0213 brush.setColor(pal.color(QPalette::WindowText)); 0214 pen.setColor(pal.color(QPalette::WindowText)); 0215 0216 painter.setBrush(brush); 0217 painter.setPen(pen); 0218 painter.drawPath(symbol.path()); 0219 painter.end(); 0220 0221 return QIcon(icon); 0222 } 0223 0224 /** 0225 * Intercept the events system to discover if the theme has changed, this should invoke 0226 * an update to the icons used to display the correct colors. 0227 * 0228 * @param e a pointer to the events 0229 * 0230 * @return @c true if the event was accepted, @c false otherwise 0231 */ 0232 bool SymbolListWidget::event(QEvent *e) 0233 { 0234 bool accepted = QListWidget::event(e); 0235 0236 if (e->type() == QEvent::PaletteChange) { 0237 updateIcons(); 0238 } 0239 0240 return accepted; 0241 } 0242 0243 /** 0244 * Generate the icons for all the QListWidgetItems stored in m_items. 0245 */ 0246 void SymbolListWidget::updateIcons() 0247 { 0248 QMapIterator<qint16, QListWidgetItem *> i(m_items); 0249 0250 while (i.hasNext()) { 0251 i.next(); 0252 i.value()->setIcon(createIcon(m_library->symbol(i.key()), m_size)); 0253 } 0254 }