File indexing completed on 2024-03-24 17:24:34

0001 /**
0002  * SPDX-FileCopyrightText: (C) 2003 Sébastien Laoût <slaout@linux62.org>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "newbasketdialog.h"
0008 
0009 #include <QDialogButtonBox>
0010 #include <QHBoxLayout>
0011 #include <QLabel>
0012 #include <QLineEdit>
0013 #include <QLocale>
0014 #include <QPainter>
0015 #include <QPixmap>
0016 #include <QPushButton>
0017 #include <QVBoxLayout>
0018 
0019 #include <KComboBox>
0020 #include <KConfigGroup>
0021 #include <KGuiItem>
0022 #include <KIconButton>
0023 #include <KIconLoader>
0024 #include <KLocalizedString>
0025 #include <KMainWindow> //For Global::mainWindow()
0026 #include <KMessageBox>
0027 
0028 #include "basketfactory.h"
0029 #include "basketlistview.h"
0030 #include "basketscene.h"
0031 #include "bnpview.h"
0032 #include "global.h"
0033 #include "kcolorcombo2.h"
0034 #include "tools.h"
0035 #include "variouswidgets.h" //For HelpLabel
0036 
0037 /** class SingleSelectionKIconView: */
0038 
0039 SingleSelectionKIconView::SingleSelectionKIconView(QWidget *parent)
0040     : QListWidget(parent)
0041     , m_lastSelected(nullptr)
0042 {
0043     setViewMode(QListView::IconMode);
0044     connect(this, &SingleSelectionKIconView::currentItemChanged, this, &SingleSelectionKIconView::slotSelectionChanged);
0045 }
0046 
0047 QMimeData *SingleSelectionKIconView::dragObject()
0048 {
0049     return nullptr;
0050 }
0051 
0052 void SingleSelectionKIconView::slotSelectionChanged(QListWidgetItem *cur)
0053 {
0054     if (cur)
0055         m_lastSelected = cur;
0056 }
0057 
0058 /** class NewBasketDefaultProperties: */
0059 
0060 NewBasketDefaultProperties::NewBasketDefaultProperties()
0061     : icon(QString("org.kde.basket"))
0062     , backgroundImage(QString())
0063     , backgroundColor()
0064     , textColor()
0065     , freeLayout(false)
0066     , columnCount(1)
0067 {
0068 }
0069 
0070 /** class NewBasketDialog: */
0071 
0072 NewBasketDialog::NewBasketDialog(BasketScene *parentBasket, const NewBasketDefaultProperties &defaultProperties, QWidget *parent)
0073     : QDialog(parent)
0074     , m_defaultProperties(defaultProperties)
0075 {
0076     // QDialog options
0077     setWindowTitle(i18n("New Basket"));
0078 
0079     QWidget *mainWidget = new QWidget(this);
0080     QVBoxLayout *mainLayout = new QVBoxLayout;
0081     setLayout(mainLayout);
0082     mainLayout->addWidget(mainWidget);
0083 
0084     setObjectName("NewBasket");
0085     setModal(true);
0086 
0087     QWidget *page = new QWidget(this);
0088     QVBoxLayout *topLayout = new QVBoxLayout(page);
0089 
0090     // Icon, Name and Background Color:
0091     QHBoxLayout *nameLayout = new QHBoxLayout;
0092     // QHBoxLayout *nameLayout = new QHBoxLayout(this);
0093     m_icon = new KIconButton(page);
0094     m_icon->setIconType(KIconLoader::NoGroup, KIconLoader::Action);
0095     m_icon->setIconSize(16);
0096     m_icon->setIcon(m_defaultProperties.icon);
0097 
0098     int size = qMax(m_icon->sizeHint().width(), m_icon->sizeHint().height());
0099     m_icon->setFixedSize(size, size); // Make it square!
0100 
0101     m_icon->setToolTip(i18n("Icon"));
0102     m_name = new QLineEdit(/*i18n("Basket"), */ page);
0103     m_name->setMinimumWidth(m_name->fontMetrics().maxWidth() * 20);
0104     connect(m_name, &QLineEdit::textChanged, this, &NewBasketDialog::nameChanged);
0105 
0106     m_name->setToolTip(i18n("Name"));
0107     m_backgroundColor = new KColorCombo2(QColor(), palette().color(QPalette::Base), page);
0108     m_backgroundColor->setColor(QColor());
0109     m_backgroundColor->setFixedSize(m_backgroundColor->sizeHint());
0110     m_backgroundColor->setColor(m_defaultProperties.backgroundColor);
0111     m_backgroundColor->setToolTip(i18n("Background color"));
0112     nameLayout->addWidget(m_icon);
0113     nameLayout->addWidget(m_name);
0114     nameLayout->addWidget(m_backgroundColor);
0115     topLayout->addLayout(nameLayout);
0116 
0117     QHBoxLayout *layout = new QHBoxLayout;
0118     QPushButton *button = new QPushButton(page);
0119     KGuiItem::assign(button, KGuiItem(i18n("&Manage Templates..."), "configure"));
0120     connect(button, &QPushButton::clicked, this, &NewBasketDialog::manageTemplates);
0121     button->hide();
0122 
0123     // Compute the right template to use as the default:
0124     QString defaultTemplate = "free";
0125     if (!m_defaultProperties.freeLayout) {
0126         if (m_defaultProperties.columnCount == 1)
0127             defaultTemplate = "1column";
0128         else if (m_defaultProperties.columnCount == 2)
0129             defaultTemplate = "2columns";
0130         else
0131             defaultTemplate = "3columns";
0132     }
0133 
0134     // Empty:
0135     // * * * * *
0136     // Personal:
0137     // *To Do
0138     // Professional:
0139     // *Meeting Summary
0140     // Hobbies:
0141     // *
0142     m_templates = new SingleSelectionKIconView(page);
0143     m_templates->setSelectionMode(QAbstractItemView::SingleSelection);
0144     QListWidgetItem *lastTemplate = nullptr;
0145     QPixmap icon(40, 53);
0146 
0147     QPainter painter(&icon);
0148     painter.fillRect(0, 0, icon.width(), icon.height(), palette().color(QPalette::Base));
0149     painter.setPen(palette().color(QPalette::Text));
0150     painter.drawRect(0, 0, icon.width(), icon.height());
0151     painter.end();
0152     lastTemplate = new QListWidgetItem(icon, i18n("One column"), m_templates);
0153 
0154     if (defaultTemplate == "1column")
0155         m_templates->setCurrentItem(lastTemplate);
0156 
0157     painter.begin(&icon);
0158     painter.fillRect(0, 0, icon.width(), icon.height(), palette().color(QPalette::Base));
0159     painter.setPen(palette().color(QPalette::Text));
0160     painter.drawRect(0, 0, icon.width(), icon.height());
0161     painter.drawLine(icon.width() / 2, 0, icon.width() / 2, icon.height());
0162     painter.end();
0163     lastTemplate = new QListWidgetItem(icon, i18n("Two columns"), m_templates);
0164 
0165     if (defaultTemplate == "2columns")
0166         m_templates->setCurrentItem(lastTemplate);
0167 
0168     painter.begin(&icon);
0169     painter.fillRect(0, 0, icon.width(), icon.height(), palette().color(QPalette::Base));
0170     painter.setPen(palette().color(QPalette::Text));
0171     painter.drawRect(0, 0, icon.width(), icon.height());
0172     painter.drawLine(icon.width() / 3, 0, icon.width() / 3, icon.height());
0173     painter.drawLine(icon.width() * 2 / 3, 0, icon.width() * 2 / 3, icon.height());
0174     painter.end();
0175     lastTemplate = new QListWidgetItem(icon, i18n("Three columns"), m_templates);
0176 
0177     if (defaultTemplate == "3columns")
0178         m_templates->setCurrentItem(lastTemplate);
0179 
0180     painter.begin(&icon);
0181     painter.fillRect(0, 0, icon.width(), icon.height(), palette().color(QPalette::Base));
0182     painter.setPen(palette().color(QPalette::Text));
0183     painter.drawRect(0, 0, icon.width(), icon.height());
0184     painter.drawRect(icon.width() / 5, icon.width() / 5, icon.width() / 4, icon.height() / 8);
0185     painter.drawRect(icon.width() * 2 / 5, icon.width() * 2 / 5, icon.width() / 4, icon.height() / 8);
0186     painter.end();
0187     lastTemplate = new QListWidgetItem(icon, i18n("Free"), m_templates);
0188 
0189     if (defaultTemplate == "free")
0190         m_templates->setCurrentItem(lastTemplate);
0191 
0192     m_templates->setMinimumHeight(topLayout->minimumSize().width() * 9 / 16);
0193 
0194     QLabel *label = new QLabel(page);
0195     label->setText(i18n("&Template:"));
0196     label->setBuddy(m_templates);
0197     layout->addWidget(label, /*stretch=*/0, Qt::AlignBottom);
0198     layout->addStretch();
0199     layout->addWidget(button, /*stretch=*/0, Qt::AlignBottom);
0200     topLayout->addLayout(layout);
0201     topLayout->addWidget(m_templates);
0202 
0203     layout = new QHBoxLayout;
0204     m_createIn = new KComboBox(page);
0205     m_createIn->addItem(i18n("(Baskets)"));
0206     label = new QLabel(page);
0207     label->setText(i18n("C&reate in:"));
0208     label->setBuddy(m_createIn);
0209     HelpLabel *helpLabel = new HelpLabel(i18n("How is it useful?"),
0210                                          i18n("<p>Creating baskets inside of other baskets to form a hierarchy allows you to be more organized by eg.:</p><ul>"
0211                                               "<li>Grouping baskets by themes or topics;</li>"
0212                                               "<li>Grouping baskets in folders for different projects;</li>"
0213                                               "<li>Making sections with sub-baskets representing chapters or pages;</li>"
0214                                               "<li>Making a group of baskets to export together (to eg. email them to people).</li></ul>"),
0215                                          page);
0216     layout->addWidget(label);
0217     layout->addWidget(m_createIn);
0218     layout->addWidget(helpLabel);
0219     layout->addStretch();
0220     topLayout->addLayout(layout);
0221 
0222     m_basketsMap.clear();
0223     int index;
0224     m_basketsMap.insert(/*index=*/0, /*basket=*/0L);
0225     index = 1;
0226     for (int i = 0; i < Global::bnpView->topLevelItemCount(); i++) {
0227         index = populateBasketsList(Global::bnpView->topLevelItem(i), /*indent=*/1, /*index=*/index);
0228     }
0229 
0230     connect(m_templates, &QListWidget::itemDoubleClicked, this, &NewBasketDialog::slotOk);
0231     connect(m_templates, &QListWidget::itemActivated, this, &NewBasketDialog::returnPressed);
0232 
0233     mainLayout->addWidget(page);
0234 
0235     QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
0236     okButton = buttonBox->button(QDialogButtonBox::Ok);
0237     okButton->setDefault(true);
0238     okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
0239     connect(okButton, &QPushButton::clicked, this, &NewBasketDialog::slotOk);
0240     connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
0241     connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
0242     mainLayout->addWidget(buttonBox);
0243     okButton->setEnabled(false);
0244 
0245     if (parentBasket) {
0246         int index = 0;
0247 
0248         for (QMap<int, BasketScene *>::Iterator it = m_basketsMap.begin(); it != m_basketsMap.end(); ++it) {
0249             if (it.value() == parentBasket) {
0250                 index = it.key();
0251                 break;
0252             }
0253         }
0254 
0255         if (index <= 0)
0256             return;
0257 
0258         if (m_createIn->currentIndex() != index)
0259             m_createIn->setCurrentIndex(index);
0260     }
0261 
0262     m_name->setFocus();
0263 }
0264 
0265 void NewBasketDialog::returnPressed()
0266 {
0267     okButton->animateClick();
0268 }
0269 
0270 int NewBasketDialog::populateBasketsList(QTreeWidgetItem *item, int indent, int index)
0271 {
0272     static const int ICON_SIZE = 16;
0273     // Get the basket data:
0274     BasketScene *basket = ((BasketListViewItem *)item)->basket();
0275     QPixmap icon = KIconLoader::global()->loadIcon(basket->icon(),
0276                                                    KIconLoader::NoGroup,
0277                                                    ICON_SIZE,
0278                                                    KIconLoader::DefaultState,
0279                                                    QStringList(),
0280                                                    nullptr,
0281                                                    /*canReturnNull=*/false);
0282     icon = Tools::indentPixmap(icon, indent, 2 * ICON_SIZE / 3);
0283     m_createIn->addItem(icon, basket->basketName());
0284     m_basketsMap.insert(index, basket);
0285     ++index;
0286 
0287     for (int i = 0; i < item->childCount(); i++) {
0288         // Append children of item to the list:
0289         index = populateBasketsList(item->child(i), indent + 1, index);
0290     }
0291 
0292     return index;
0293 }
0294 
0295 NewBasketDialog::~NewBasketDialog()
0296 {
0297 }
0298 
0299 void NewBasketDialog::ensurePolished()
0300 {
0301     QDialog::ensurePolished();
0302     m_name->setFocus();
0303 }
0304 
0305 void NewBasketDialog::nameChanged(const QString &newName)
0306 {
0307     okButton->setEnabled(!newName.isEmpty());
0308 }
0309 
0310 void NewBasketDialog::slotOk()
0311 {
0312     QListWidgetItem *item = ((SingleSelectionKIconView *)m_templates)->selectedItem();
0313     QString templateName;
0314     if (!item)
0315         return;
0316     if (item->text() == i18n("One column"))
0317         templateName = "1column";
0318     if (item->text() == i18n("Two columns"))
0319         templateName = "2columns";
0320     if (item->text() == i18n("Three columns"))
0321         templateName = "3columns";
0322     if (item->text() == i18n("Free-form"))
0323         templateName = "free";
0324     if (item->text() == i18n("Mind map"))
0325         templateName = "mindmap";
0326 
0327     Global::bnpView->closeAllEditors();
0328 
0329     QString backgroundImage;
0330     QColor textColor;
0331     if (m_backgroundColor->color() == m_defaultProperties.backgroundColor) {
0332         backgroundImage = m_defaultProperties.backgroundImage;
0333         textColor = m_defaultProperties.textColor;
0334     }
0335 
0336     BasketFactory::newBasket(m_icon->icon(),
0337                              m_name->text(),
0338                              m_basketsMap[m_createIn->currentIndex()],
0339                              backgroundImage,
0340                              m_backgroundColor->color(),
0341                              textColor,
0342                              templateName);
0343 
0344     if (Global::activeMainWindow())
0345         Global::activeMainWindow()->show();
0346 }
0347 
0348 void NewBasketDialog::manageTemplates()
0349 {
0350     KMessageBox::information(this, "Wait a minute! There is no template for now: they will come with time... :-D");
0351 }
0352 
0353 #include "moc_newbasketdialog.cpp"