File indexing completed on 2024-05-05 12:57:25
0001 /* 0002 * Copyright (C) 2010-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 #include "LibraryManagerDlg.h" 0012 0013 #include <QClipboard> 0014 #include <QDir> 0015 #include <QFileInfoList> 0016 #include <QHelpEvent> 0017 #include <QInputDialog> 0018 #include <QMimeData> 0019 #include <QStandardPaths> 0020 #include <QToolTip> 0021 0022 #include <KHelpClient> 0023 #include <KLocalizedString> 0024 #include <KMessageBox> 0025 #include <kwidgetsaddons_version.h> 0026 0027 #include "LibraryFilePathsDlg.h" 0028 #include "LibraryListWidgetItem.h" 0029 #include "LibraryPatternPropertiesDlg.h" 0030 #include "LibraryTreeWidgetItem.h" 0031 #include "Pattern.h" 0032 0033 #include "configuration.h" 0034 0035 LibraryManagerDlg::LibraryManagerDlg(QWidget *parent) 0036 : QDialog(parent) 0037 { 0038 setWindowTitle(i18n("Library Manager")); 0039 0040 ui.setupUi(this); 0041 0042 refreshLibraries(); 0043 0044 ui.LibraryTree->setContextMenuPolicy(Qt::CustomContextMenu); 0045 ui.LibraryIcons->setContextMenuPolicy(Qt::CustomContextMenu); 0046 ui.LibraryIcons->changeIconSize(Configuration::icon_DefaultSize()); 0047 ui.IconSizeSlider->setValue(Configuration::icon_DefaultSize()); 0048 } 0049 0050 LibraryTreeWidgetItem *LibraryManagerDlg::currentLibrary() 0051 { 0052 return static_cast<LibraryTreeWidgetItem *>(ui.LibraryTree->currentItem()); 0053 } 0054 0055 bool LibraryManagerDlg::event(QEvent *event) 0056 { 0057 if (event->type() == QEvent::ToolTip) { 0058 QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event); 0059 QString tip; 0060 0061 if (ui.LibraryTree->topLevelItemCount() == 0) { 0062 tip = i18n( 0063 "The Library Manager can be used to store\nreusable patterns for insertion into\nnew patterns.\n\nThere are no library categories " 0064 "defined.\nClick the Help button for information on creating\nand populating libraries."); 0065 } else { 0066 if (ui.LibraryTree->currentItem() == nullptr) { 0067 tip = i18n("Select a library to show the associated patterns."); 0068 } else if (ui.LibraryIcons->count() == 0) { 0069 tip = i18n("There are no patterns defined\nfor this library.\n\nClick the Help button for information\non creating and populating libraries."); 0070 } 0071 } 0072 0073 if (!tip.isEmpty()) { 0074 QToolTip::showText(helpEvent->globalPos(), tip); 0075 } else { 0076 QToolTip::hideText(); 0077 } 0078 0079 return true; 0080 } 0081 0082 return QWidget::event(event); 0083 } 0084 0085 void LibraryManagerDlg::hideEvent(QHideEvent *event) 0086 { 0087 KConfigGroup(KSharedConfig::openConfig(), QStringLiteral("DialogSizes")).writeEntry(QStringLiteral("LibraryManagerDlg"), size()); 0088 0089 QDialog::hideEvent(event); 0090 } 0091 0092 void LibraryManagerDlg::showEvent(QShowEvent *event) 0093 { 0094 QDialog::showEvent(event); 0095 0096 if (KConfigGroup(KSharedConfig::openConfig(), QStringLiteral("DialogSizes")).hasKey(QStringLiteral("LibraryManagerDlg"))) { 0097 resize(KConfigGroup(KSharedConfig::openConfig(), QStringLiteral("DialogSizes")).readEntry(QStringLiteral("LibraryManagerDlg"), QSize())); 0098 } 0099 } 0100 0101 void LibraryManagerDlg::setCellSize(double cellWidth, double cellHeight) 0102 { 0103 ui.LibraryIcons->setCellSize(cellWidth, cellHeight); 0104 } 0105 0106 void LibraryManagerDlg::on_LibraryTree_customContextMenuRequested(const QPoint &position) 0107 { 0108 m_contextMenu.clear(); 0109 m_contextMenu.addAction(i18n("New Category"), this, &LibraryManagerDlg::newCategory); 0110 0111 if ((m_contextTreeItem = static_cast<LibraryTreeWidgetItem *>(ui.LibraryTree->itemAt(position)))) { 0112 m_contextMenu.addAction(i18n("Add to Export List"), this, &LibraryManagerDlg::addLibraryToExportList); 0113 m_contextMenu.addAction(i18n("Properties..."), this, &LibraryManagerDlg::libraryProperties); 0114 0115 if (QApplication::clipboard()->mimeData()->hasFormat(QStringLiteral("application/kxstitch"))) { 0116 m_contextMenu.addAction(i18n("Paste"), this, &LibraryManagerDlg::pasteFromClipboard); 0117 } 0118 } 0119 0120 m_contextMenu.popup(QCursor::pos()); 0121 } 0122 0123 void LibraryManagerDlg::on_LibraryIcons_customContextMenuRequested(const QPoint &position) 0124 { 0125 m_contextMenu.clear(); 0126 0127 if ((m_contextListItem = static_cast<LibraryListWidgetItem *>(ui.LibraryIcons->itemAt(position)))) { 0128 m_contextMenu.addAction(i18n("Properties..."), this, &LibraryManagerDlg::patternProperties); 0129 // m_contextMenu.addAction(i18n("Add to Export List"), this, SLOT(addPatternToExportList())); 0130 // m_contextMenu.addAction(i18n("Copy"), this, SLOT(copyToClipboard())); 0131 m_contextMenu.addAction(i18n("Delete"), this, &LibraryManagerDlg::deletePattern); 0132 m_contextMenu.popup(QCursor::pos()); 0133 } else { 0134 if (QApplication::clipboard()->mimeData()->hasFormat(QStringLiteral("application/kxstitch")) && ui.LibraryTree->selectedItems().count() == 1) { 0135 m_contextMenu.addAction(i18n("Paste"), this, &LibraryManagerDlg::pasteFromClipboard); 0136 m_contextMenu.popup(QCursor::pos()); 0137 } 0138 } 0139 } 0140 0141 void LibraryManagerDlg::on_LibraryTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *) 0142 { 0143 ui.LibraryIcons->clear(); 0144 LibraryTreeWidgetItem *libraryTreeWidgetItem = dynamic_cast<LibraryTreeWidgetItem *>(current); 0145 0146 for (LibraryPattern *libraryPattern = libraryTreeWidgetItem->first(); libraryPattern; libraryPattern = libraryTreeWidgetItem->next()) { 0147 LibraryListWidgetItem *libraryListWidgetItem = new LibraryListWidgetItem(ui.LibraryIcons, libraryPattern); 0148 libraryPattern->setLibraryListWidgetItem(libraryListWidgetItem); 0149 } 0150 } 0151 0152 void LibraryManagerDlg::on_IconSizeSlider_valueChanged(int size) 0153 { 0154 ui.LibraryIcons->changeIconSize(size); 0155 } 0156 0157 void LibraryManagerDlg::on_DialogButtonBox_rejected() 0158 { 0159 reject(); 0160 } 0161 0162 void LibraryManagerDlg::on_DialogButtonBox_helpRequested() 0163 { 0164 KHelpClient::invokeHelp(QStringLiteral("PatternLibraryDialog"), QStringLiteral("kxstitch")); 0165 } 0166 0167 void LibraryManagerDlg::newCategory() 0168 { 0169 QString category; 0170 0171 bool ok = false; 0172 bool exists = false; 0173 0174 category = QInputDialog::getText(this, i18n("Create Category"), i18n("Category Name"), QLineEdit::Normal, QString(), &ok); 0175 0176 if (!ok) 0177 return; // user cancelled 0178 0179 if (m_contextTreeItem) { 0180 for (int i = 0; i < m_contextTreeItem->childCount(); ++i) { 0181 if (m_contextTreeItem->child(i)->text(0) == category) { 0182 exists = true; 0183 } 0184 } 0185 } else { 0186 QList<QTreeWidgetItem *> rootItems = ui.LibraryTree->findItems(category, Qt::MatchExactly); 0187 0188 if (!rootItems.isEmpty()) { 0189 exists = true; 0190 } 0191 } 0192 0193 if (exists) { 0194 KMessageBox::error(this, i18n("This category already exists."), i18n("Category Exists")); 0195 return; 0196 } 0197 0198 LibraryTreeWidgetItem *newItem; 0199 0200 if (m_contextTreeItem) { 0201 newItem = new LibraryTreeWidgetItem(m_contextTreeItem, category); 0202 } else { 0203 newItem = new LibraryTreeWidgetItem(ui.LibraryTree, category); 0204 } 0205 0206 QString path; 0207 QFileInfo fileInfo; 0208 0209 if (m_contextTreeItem) { 0210 fileInfo.setFile(m_contextTreeItem->path()); 0211 path = m_contextTreeItem->path(); 0212 0213 if (!fileInfo.isWritable()) { 0214 path.remove(0, path.indexOf(QLatin1String("/library"))); 0215 path.prepend(QStandardPaths::writableLocation(QStandardPaths::DataLocation)); 0216 } 0217 } else { 0218 path = QString::fromLatin1("%1/%2").arg(QStandardPaths::writableLocation(QStandardPaths::DataLocation)).arg(QLatin1String("library")); 0219 } 0220 0221 path = QString::fromLatin1("%1/%2").arg(path, category); 0222 0223 if (QDir().mkpath(path)) { 0224 newItem->addPath(path); 0225 } 0226 0227 ui.LibraryTree->setCurrentItem(newItem); 0228 } 0229 0230 void LibraryManagerDlg::addLibraryToExportList() 0231 { 0232 } 0233 0234 void LibraryManagerDlg::libraryProperties() 0235 { 0236 QPointer<LibraryFilePathsDlg> dialog = new LibraryFilePathsDlg(this, m_contextTreeItem->text(0), m_contextTreeItem->paths()); 0237 dialog->exec(); 0238 delete dialog; 0239 } 0240 0241 void LibraryManagerDlg::pasteFromClipboard() 0242 { 0243 LibraryTreeWidgetItem *item = static_cast<LibraryTreeWidgetItem *>(ui.LibraryTree->currentItem()); 0244 Pattern *pattern = new Pattern(); 0245 QByteArray data = QApplication::clipboard()->mimeData()->data(QStringLiteral("application/kxstitch")); 0246 QDataStream stream(&data, QIODevice::ReadOnly); 0247 stream >> *pattern; 0248 item->addPattern(new LibraryPattern(pattern)); 0249 on_LibraryTree_currentItemChanged(static_cast<QTreeWidgetItem *>(item), nullptr); 0250 } 0251 0252 void LibraryManagerDlg::patternProperties() 0253 { 0254 LibraryPattern *libraryPattern = m_contextListItem->libraryPattern(); 0255 QPointer<LibraryPatternPropertiesDlg> dialog = new LibraryPatternPropertiesDlg(this, 0256 libraryPattern->key(), 0257 libraryPattern->modifiers(), 0258 libraryPattern->baseline(), 0259 libraryPattern->pattern()->palette().schemeName(), 0260 libraryPattern->pattern()->stitches().width(), 0261 libraryPattern->pattern()->stitches().height(), 0262 m_contextListItem->icon()); 0263 0264 if (dialog->exec()) { 0265 libraryPattern->setKeyModifiers(dialog->key(), dialog->modifiers()); 0266 libraryPattern->setBaseline(dialog->baseline()); 0267 } 0268 0269 delete dialog; 0270 } 0271 0272 void LibraryManagerDlg::addPatternToExportList() 0273 { 0274 } 0275 0276 void LibraryManagerDlg::copyToClipboard() 0277 { 0278 } 0279 0280 void LibraryManagerDlg::deletePattern() 0281 { 0282 #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 100, 0) 0283 if (KMessageBox::warningTwoActions(nullptr, 0284 #else 0285 if (KMessageBox::warningYesNo(nullptr, 0286 #endif 0287 i18n("Delete this pattern."), 0288 QString(), 0289 KStandardGuiItem::del(), 0290 KStandardGuiItem::cancel()) 0291 #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 100, 0) 0292 == KMessageBox::PrimaryAction) { 0293 #else 0294 == KMessageBox::Yes) { 0295 #endif 0296 static_cast<LibraryTreeWidgetItem *>(ui.LibraryTree->currentItem())->deletePattern(m_contextListItem->libraryPattern()); 0297 delete m_contextListItem; 0298 } 0299 } 0300 0301 void LibraryManagerDlg::refreshLibraries() 0302 { 0303 ui.LibraryTree->clear(); 0304 QStringList libraryDirectories = QStandardPaths::locateAll(QStandardPaths::DataLocation, QStringLiteral("library"), QStandardPaths::LocateDirectory); 0305 QStringListIterator libraryDirectoriesIterator(libraryDirectories); 0306 0307 while (libraryDirectoriesIterator.hasNext()) { 0308 recurseLibraryDirectory(nullptr, libraryDirectoriesIterator.next()); 0309 } 0310 } 0311 0312 void LibraryManagerDlg::recurseLibraryDirectory(LibraryTreeWidgetItem *parent, const QString &path) 0313 { 0314 QDir directory(path); 0315 const QFileInfoList directoryEntries = directory.entryInfoList(); 0316 QListIterator<QFileInfo> fileInfoListIterator(directoryEntries); 0317 0318 while (fileInfoListIterator.hasNext()) { 0319 QFileInfo fileInfo = fileInfoListIterator.next(); 0320 0321 if (fileInfo.isDir()) { 0322 if (fileInfo.fileName() != QLatin1String(".") && fileInfo.fileName() != QLatin1String("..")) { 0323 LibraryTreeWidgetItem *libraryTreeWidgetItem = nullptr; 0324 QString subPath = QString::fromLatin1("%1/%2").arg(path, fileInfo.fileName()); 0325 0326 if (parent) { 0327 int children = parent->childCount(); 0328 int childIndex = 0; 0329 0330 while (childIndex < children) { 0331 libraryTreeWidgetItem = dynamic_cast<LibraryTreeWidgetItem *>(parent->child(childIndex)); 0332 0333 if (libraryTreeWidgetItem->text(0) == fileInfo.fileName()) { 0334 break; 0335 } else { 0336 libraryTreeWidgetItem = nullptr; 0337 } 0338 0339 childIndex++; 0340 } 0341 } else { 0342 QList<QTreeWidgetItem *> rootNodes = ui.LibraryTree->findItems(fileInfo.fileName(), Qt::MatchExactly, 0); 0343 0344 if (!rootNodes.isEmpty()) { 0345 libraryTreeWidgetItem = dynamic_cast<LibraryTreeWidgetItem *>(rootNodes[0]); 0346 } 0347 } 0348 0349 if (libraryTreeWidgetItem == nullptr) { 0350 if (parent) { 0351 libraryTreeWidgetItem = new LibraryTreeWidgetItem(parent, fileInfo.fileName()); 0352 } else { 0353 libraryTreeWidgetItem = new LibraryTreeWidgetItem(ui.LibraryTree, fileInfo.fileName()); 0354 ui.LibraryTree->sortItems(0, Qt::AscendingOrder); 0355 } 0356 } 0357 0358 libraryTreeWidgetItem->addPath(subPath); 0359 recurseLibraryDirectory(libraryTreeWidgetItem, subPath); 0360 } 0361 } 0362 } 0363 } 0364 0365 #include "moc_LibraryManagerDlg.cpp"