File indexing completed on 2024-04-28 05:51:09
0001 /* 0002 * SPDX-FileCopyrightText: 2002-2003 Jesper K. Pedersen <blackie@kde.org> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.0-only 0005 **/ 0006 0007 #include "kmultiformlistbox-multivisible.h" 0008 0009 #include <QBitmap> 0010 #include <QPushButton> 0011 #include <QVBoxLayout> 0012 0013 #include <KMessageBox> 0014 0015 #include "ccp.h" 0016 #include "indexWindow.h" 0017 #include "kmultiformlistboxfactory.h" 0018 0019 const int indexButtonWidth = 16; 0020 const int indexButtonHeight = 12; 0021 const uchar indexButtonBits[] = {0x00, 0x00, 0x00, 0x00, 0x0e, 0x02, 0x04, 0x02, 0x04, 0x02, 0xc4, 0x8a, 0022 0x24, 0x53, 0x14, 0x22, 0x14, 0x22, 0x24, 0x53, 0xce, 0x8a, 0x00, 0x00}; 0023 0024 KMultiFormListBoxMultiVisible::KMultiFormListBoxMultiVisible(KMultiFormListBoxFactory *fact, QWidget *parent) 0025 : QScrollArea(parent) 0026 { 0027 factory = fact; 0028 0029 // Initialize the element list 0030 elms = new WidgetList(); 0031 0032 QWidget *widget = new QWidget(); 0033 layout = new QVBoxLayout(widget); 0034 layout->setSpacing(0); 0035 layout->setContentsMargins(0, 0, 0, 0); 0036 setWidget(widget); 0037 setWidgetResizable(true); 0038 } 0039 0040 //---------------------------------------------------------------------- 0041 // This function returns a list of the elements in the KMultiFormListBox widget. 0042 //---------------------------------------------------------------------- 0043 KMultiFormListBoxEntryList KMultiFormListBoxMultiVisible::elements() 0044 { 0045 KMultiFormListBoxEntryList res; 0046 for (QWidget *child : *elms) { 0047 if (child->objectName() != QStringLiteral("separator")) { 0048 res.append((KMultiFormListBoxEntry *)child); 0049 } 0050 } 0051 return res; 0052 } 0053 0054 //---------------------------------------------------------------------- 0055 // This function is called whenever the KMultiFormListBox widget is resized. It is 0056 // necessary to ensure that the content of the clipper is resized. 0057 //---------------------------------------------------------------------- 0058 void KMultiFormListBoxMultiVisible::resizeEvent(QResizeEvent *e) 0059 { 0060 // The call of the super class ensures that the outer border is updated. 0061 QScrollArea::resizeEvent(e); 0062 0063 updateClipperContent(); 0064 } 0065 0066 void KMultiFormListBoxMultiVisible::updateClipperContent() 0067 { 0068 // Extract the current size of the clipper 0069 /* 0070 int ClipperWidth = clipper()->size().width(); 0071 int ClipperHeight = clipper()->size().height(); 0072 0073 // Initialize the calculation of the size of the new clipper. 0074 int totalHeight = 0; 0075 int maxWidth = ClipperWidth; 0076 int count = 0; 0077 0078 // calculate the required size. 0079 for (QWidget *child : *elms) { 0080 maxWidth = qMax(maxWidth, child->sizeHint().width()); 0081 if ( child->objectName() != "separator" ) { 0082 totalHeight += child->sizeHint().height(); 0083 count++; 0084 } 0085 else { 0086 totalHeight += child->size().height(); 0087 } 0088 } 0089 0090 // Calculate the extra height for the elements. 0091 int extra = 0; 0092 if (totalHeight < ClipperHeight && count != 0) { 0093 extra = (ClipperHeight - totalHeight) / count; 0094 totalHeight = ClipperHeight; 0095 } 0096 0097 // Now place the elements in the clipper. 0098 int yPos = 0; 0099 for (QWidget *child2 : *elms) { 0100 int h; 0101 if ( child2->objectName() != "separator" ) { 0102 h = child2->sizeHint().height(); 0103 h += extra; 0104 } 0105 else { 0106 h = child2->size().height(); 0107 } 0108 0109 moveChild(child2, 0,yPos); 0110 0111 child2->resize(maxWidth,h); 0112 yPos += h; 0113 } 0114 */ 0115 0116 // Finally call the resize procedure for the clipper to ensure that the 0117 // new sizes is shown properly. 0118 // resizeContents(maxWidth, totalHeight); 0119 } 0120 0121 void KMultiFormListBoxMultiVisible::addElement() 0122 { 0123 addElement(nullptr); 0124 } 0125 0126 void KMultiFormListBoxMultiVisible::addElement(KMultiFormListBoxEntry *after) 0127 { 0128 KMultiFormListBoxEntry *elm = factory->create(widget()); 0129 insertElmIntoWidget(elm, after); 0130 } 0131 0132 void KMultiFormListBoxMultiVisible::append(KMultiFormListBoxEntry *elm) 0133 { 0134 elm->setParent(widget()); 0135 insertElmIntoWidget(elm, nullptr); 0136 } 0137 0138 void KMultiFormListBoxMultiVisible::delElement(QWidget *elm) 0139 { 0140 int index = elms->indexOf(elm); 0141 QWidget *next = elms->at(index + 1); 0142 if (next->objectName() != QStringLiteral("separator")) { 0143 elms->removeOne(next); 0144 layout->removeWidget(next); 0145 } 0146 0147 elms->removeOne(elm); 0148 layout->removeWidget(elm); 0149 0150 updateClipperContent(); 0151 } 0152 0153 void KMultiFormListBoxMultiVisible::delAnElement() 0154 { 0155 delElement(elms->at(0)); 0156 } 0157 0158 void KMultiFormListBoxMultiVisible::insertElmIntoWidget(KMultiFormListBoxEntry *elm, KMultiFormListBoxEntry *after) 0159 { 0160 // Bind the index button if it exists. 0161 if (elm->indexButton()) { 0162 elm->indexButton()->setIcon(static_cast<QIcon>(QBitmap::fromData(QSize(indexButtonWidth, indexButtonHeight), indexButtonBits, QImage::Format_MonoLSB))); 0163 connect(elm->indexButton(), &QAbstractButton::clicked, elm, &KMultiFormListBoxEntry::acceptIndexButton); 0164 connect(elm, &KMultiFormListBoxEntry::gotoIndex, this, &KMultiFormListBoxMultiVisible::showIndexList); 0165 } 0166 0167 // Find the location to insert the new element. 0168 int index = elms->count(); 0169 if (after) { 0170 index = elms->indexOf(after); 0171 } 0172 0173 // Now show the new element. 0174 elms->insert(index, elm); 0175 layout->insertWidget(index, elm); 0176 elm->show(); 0177 ensureWidgetVisible(elm, 0, 0); 0178 // addChild(elm,0,0); // updateClipperContent will place the child correctly. 0179 0180 QWidget *sep = factory->separator(widget()); 0181 if (sep != nullptr) { 0182 sep->setObjectName(QStringLiteral("separator")); 0183 sep->show(); 0184 layout->insertWidget(index + 1, sep); // updateClipperContent will place the child correctly. 0185 elms->insert(index + 1, sep); 0186 } 0187 0188 updateClipperContent(); 0189 0190 showWidget(elm); // scroll to show the new widget. 0191 0192 // install cut'n'paste functionallity 0193 new CCP(this, elm); 0194 } 0195 0196 //---------------------------------------------------------------------- 0197 // This function shows the list of available Idx elements. 0198 //---------------------------------------------------------------------- 0199 void KMultiFormListBoxMultiVisible::showIndexList(KMultiFormListBoxEntry *elm) 0200 { 0201 indexWindow *menu = new indexWindow(); 0202 0203 // Insert the elements into the menu item. 0204 for (QWidget *child : *elms) { 0205 if (child->objectName() != QStringLiteral("separator")) { 0206 QString txt = ((KMultiFormListBoxEntry *)child)->idxString(); 0207 menu->insertItem(txt); 0208 } 0209 } 0210 0211 // Calculate the location of the window 0212 QPoint start; 0213 int width; 0214 elm->indexWindowPos(&start, &width); 0215 0216 // Show the window. 0217 int index = menu->exec(start, width); 0218 0219 if (index != -1) { 0220 for (QWidget *child : *elms) { 0221 if (child->objectName() != QLatin1String("separator")) { 0222 if (index == 0) { 0223 showWidget((KMultiFormListBoxEntry *)child); 0224 break; 0225 } 0226 index--; 0227 } 0228 } 0229 } 0230 delete menu; 0231 } 0232 0233 //---------------------------------------------------------------------- 0234 // Scroll to the loaction of the given KMultiFormListBoxEntry element. 0235 //---------------------------------------------------------------------- 0236 void KMultiFormListBoxMultiVisible::showWidget(KMultiFormListBoxEntry *elm) 0237 { 0238 ensureWidgetVisible(elm); 0239 } 0240 0241 void KMultiFormListBoxMultiVisible::cut(KMultiFormListBoxEntry *elm) 0242 { 0243 if (countElements(elms) == 1) { 0244 KMessageBox::information(this, i18n("Due to a bug, it is not possible to remove the last element."), i18n("Internal Error")); 0245 return; 0246 } 0247 0248 QDataStream stream(&clipboard, QIODeviceBase::WriteOnly); 0249 0250 stream.setVersion(QDataStream::Qt_3_1); 0251 factory->toStream(elm, stream); 0252 delElement(elm); 0253 } 0254 0255 void KMultiFormListBoxMultiVisible::copy(KMultiFormListBoxEntry *elm) 0256 { 0257 QDataStream stream(&clipboard, QIODeviceBase::WriteOnly); 0258 0259 stream.setVersion(QDataStream::Qt_3_1); 0260 factory->toStream(elm, stream); 0261 } 0262 0263 void KMultiFormListBoxMultiVisible::paste(KMultiFormListBoxEntry *oldElm) 0264 { 0265 if (clipboard.isEmpty()) { 0266 KMessageBox::information(this, i18n("There is no element on the clipboard to paste in.")); 0267 return; 0268 } 0269 0270 KMultiFormListBoxEntry *newElm = factory->create(widget()); 0271 QDataStream stream(&clipboard, QIODeviceBase::ReadOnly); 0272 0273 stream.setVersion(QDataStream::Qt_3_1); 0274 factory->fromStream(stream, newElm); 0275 insertElmIntoWidget(newElm, oldElm); 0276 } 0277 0278 int KMultiFormListBoxMultiVisible::countElements(WidgetList *elms) 0279 { 0280 int count = 0; 0281 0282 for (QWidget *child : *elms) { 0283 if (dynamic_cast<const KMultiFormListBoxEntry *>(child)) { 0284 count++; 0285 } 0286 } 0287 0288 return count; 0289 } 0290 0291 #include "moc_kmultiformlistbox-multivisible.cpp"