File indexing completed on 2023-09-24 08:19:50
0001 /* ============================================================ 0002 * 0003 * This file is a part of KDE project 0004 * 0005 * 0006 * Date : 2009-07-05 0007 * Description : A combobox delegate to display in image lists. 0008 * 0009 * Copyright (C) 2009 by Pieter Edelman <pieter dot edelman at gmx dot net> 0010 * 0011 * This program is free software; you can redistribute it 0012 * and/or modify it under the terms of the GNU General 0013 * Public License as published by the Free Software Foundation; 0014 * either version 2, or (at your option) any later version. 0015 * 0016 * This program is distributed in the hope that it will be useful, 0017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0019 * GNU General Public License for more details. 0020 * 0021 * ============================================================ */ 0022 0023 #include "comboboxdelegate.h" 0024 0025 // Qt includes 0026 0027 #include <QApplication> 0028 #include <QComboBox> 0029 #include <QPaintEvent> 0030 #include <QStyleOption> 0031 0032 // Local includes 0033 0034 #include "kipiplugins_debug.h" 0035 0036 namespace KIPIFlickrPlugin 0037 { 0038 0039 ComboBoxDelegate::ComboBoxDelegate(KPImagesList* const parent, const QMap<int, QString>& items) 0040 : QAbstractItemDelegate(parent), 0041 m_parent(parent), 0042 m_items(items), 0043 m_rowEdited(-1) 0044 { 0045 // Figure out the maximum width of a displayed item from the items list and 0046 // save it in the m_size parameter. 0047 QFontMetrics listFont = parent->fontMetrics(); 0048 m_size = QSize(0, listFont.height()); 0049 int tmpWidth = 0; 0050 QMapIterator<int, QString> i(m_items); 0051 0052 while (i.hasNext()) 0053 { 0054 i.next(); 0055 tmpWidth = listFont.width(i.value()); 0056 0057 if (tmpWidth > m_size.width()) 0058 { 0059 m_size.setWidth(tmpWidth); 0060 } 0061 } 0062 } 0063 0064 void ComboBoxDelegate::startEditing(QTreeWidgetItem* item, int column) 0065 { 0066 // Start editing the item. This is part of a hack to make sure the item text 0067 // doesn't get painted whenever a combobox is drawn (otherwise the text can 0068 // be seen around the edges of the combobox. This method breaks the OO 0069 // paradigm. 0070 m_rowEdited = m_parent->listView()->currentIndex().row(); 0071 item->setFlags(item->flags() | Qt::ItemIsEditable); 0072 m_parent->listView()->editItem(item, column); 0073 item->setFlags(item->flags() & ~Qt::ItemIsEditable); 0074 } 0075 0076 void ComboBoxDelegate::paint(QPainter* painter, 0077 const QStyleOptionViewItem& option, 0078 const QModelIndex& index) const 0079 { 0080 // Draw a panel item primitive element as background. 0081 QStyle* const style = QApplication::style(); 0082 style->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter); 0083 0084 // If the element that gets painted is not currently edited, the item text 0085 // should be displayed. 0086 // Note that this method to detect which item is edited is a horrible hack 0087 // to work around the fact that there's no reliable way to detect if an item 0088 // is being edited from the parameters (although the documentation suggests 0089 // QStyle::State_Editing should be set in the option.flags parameter). 0090 if (m_rowEdited != index.row()) 0091 { 0092 // Get the currently selected index in the items list. 0093 int currIndex = (index.data()).value<int>(); 0094 0095 // PE: These values are found by trial and error. I don't have any idea 0096 // if it's actually correct, but it seems to work across all themes. 0097 QPalette::ColorRole textColor = QPalette::Text; 0098 0099 if (option.state & QStyle::State_Selected) 0100 { 0101 textColor = QPalette::HighlightedText; 0102 } 0103 0104 // Draw the text. 0105 style->drawItemText(painter, option.rect, option.displayAlignment, 0106 option.palette, true, m_items[currIndex], 0107 textColor); 0108 } 0109 } 0110 0111 QSize ComboBoxDelegate::sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const 0112 { 0113 // Return the size based on the widest item in the items list. 0114 return m_size; 0115 } 0116 0117 QWidget* ComboBoxDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, 0118 const QModelIndex&) const 0119 { 0120 // This method returns the widget that should be used to edit the current 0121 // element, which is in this case a QComboBox with the items supplied by 0122 // the user items list on construction. 0123 QComboBox* const cb = new QComboBox(parent); 0124 QMapIterator<int, QString> i(m_items); 0125 0126 while (i.hasNext()) 0127 { 0128 i.next(); 0129 cb->addItem(i.value(), QVariant(i.key())); 0130 } 0131 0132 // Set the geometry 0133 cb->setGeometry(option.rect); 0134 0135 // If the index is changed, the editing should be finished and the editor 0136 // destroyed. 0137 connect(cb, SIGNAL(activated(int)), 0138 this, SLOT(slotCommitAndCloseEditor(int))); 0139 0140 // To keep track of the item being edited, the m_rowEdited parameter should 0141 // be reset when the editor is destroyed. 0142 connect(cb, SIGNAL(destroyed(QObject*)), 0143 this, SLOT(slotResetEditedState(QObject*))); 0144 0145 return cb; 0146 } 0147 0148 void ComboBoxDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const 0149 { 0150 // Scroll the combobox to the current selected state on initialization. 0151 QComboBox* const cb = qobject_cast<QComboBox*>(editor); 0152 0153 for (int i = 0; i < cb->count(); ++i) 0154 { 0155 if (cb->itemData(i).toInt() == index.data().toInt()) 0156 { 0157 cb->setCurrentIndex(i); 0158 } 0159 } 0160 } 0161 0162 void ComboBoxDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, 0163 const QModelIndex& index) const 0164 { 0165 // Write the data to the model when finishing has completed. 0166 QComboBox* const cb = qobject_cast<QComboBox*>(editor); 0167 int selected = cb->itemData(cb->currentIndex()).toInt(); 0168 model->setData(index, selected); 0169 } 0170 0171 void ComboBoxDelegate::slotCommitAndCloseEditor(int) 0172 { 0173 // Emit the proper signals when editing has finished. 0174 QComboBox* const editor = qobject_cast<QComboBox*>(sender()); 0175 Q_EMIT commitData(editor); 0176 Q_EMIT closeEditor(editor); 0177 } 0178 0179 void ComboBoxDelegate::slotResetEditedState(QObject*) 0180 { 0181 m_rowEdited = -1; 0182 } 0183 0184 } // namespace KIPIFlickrPlugin 0185 0186 #include "moc_comboboxdelegate.cpp"