void DocumentTest::testImageLocalDirectory() { Tellico::Config::setImageLocation(Tellico::Config::ImagesInLocalDir); // the default collection will use a temporary directory as a local image dir QVERIFY(!Tellico::ImageFactory::localDir().isEmpty()); QString tempDirName; QTemporaryDir tempDir; QVERIFY(tempDir.isValid()); tempDir.setAutoRemove(true); tempDirName = tempDir.path(); QString fileName = tempDirName + "/with-image.tc"; QString imageDirName = tempDirName + "/with-image_files/"; // copy a collection file that includes an image into the temporary directory QVERIFY(QFile::copy(QFINDTESTDATA("data/with-image.tc"), fileName)); Tellico::Data::Document* doc = Tellico::Data::Document::self(); QVERIFY(doc->openDocument(QUrl::fromLocalFile(fileName))); QCOMPARE(Tellico::ImageFactory::localDir(), imageDirName); Tellico::Data::CollPtr coll = doc->collection(); QVERIFY(coll); QCOMPARE(coll->type(), Tellico::Data::Collection::Book); QCOMPARE(coll->title(), QLatin1String("My Books")); QCOMPARE(coll->entries().size(), 1); Tellico::Data::EntryPtr e = coll->entries().at(0); QVERIFY(e); QCOMPARE(e->field(QLatin1String("cover")), QLatin1String("17b54b2a742c6d342a75f122d615a793.jpeg")); // save the document, so the images get copied out of the .tc file into the local image directory QVERIFY(doc->saveDocument(QUrl::fromLocalFile(fileName))); // verify that backup file gets created QVERIFY(QFile::exists(fileName + '~')); // check that the local image directory is created with the image file inside QDir imageDir(imageDirName); QVERIFY(imageDir.exists()); QVERIFY(imageDir.exists(e->field(QLatin1String("cover")))); // clear the internal image cache Tellico::ImageFactory::clean(true); // verify that the images are copied from the old directory when saving to a new file QString fileName2 = tempDirName + "/with-image2.tc"; QString imageDirName2 = tempDirName + "/with-image2_files/"; QVERIFY(doc->saveDocument(QUrl::fromLocalFile(fileName2))); QVERIFY(QFile::exists(fileName2)); QDir imageDir2(imageDirName2); QVERIFY(imageDir2.exists()); QVERIFY(imageDir2.exists(e->field(QLatin1String("cover")))); /*************************************************************************/ /* now also verify image directory when file name has multiple periods */ /* see https://bugs.kde.org/show_bug.cgi?id=348088 */ /* also have to check backwards compatibility with prior behavior */ /*************************************************************************/ QString fileName3 = tempDirName + "/with-image.1.tc"; QString imageDirName3 = tempDirName + "/with-image.1_files/"; // copy the collection file, which no longer contains the images inside QVERIFY(QFile::copy(fileName, fileName3)); QVERIFY(doc->openDocument(QUrl::fromLocalFile(fileName3))); QCOMPARE(Tellico::ImageFactory::localDir(), imageDirName3); QDir imageDir3(imageDirName3); // verify that the images can be loaded from the image directory that does NOT have multiple periods // since that was the behavior prior to the bug being fixed coll = doc->collection(); e = coll->entries().at(0); // image should not be in the next image dir yet since we haven't saved QVERIFY(!imageDir3.exists(e->field(QLatin1String("cover")))); QVERIFY(!Tellico::ImageFactory::imageById(e->field("cover")).isNull()); // now remove the first image from the first image directory, save the document, and verify that // the proper image exists and is written QVERIFY(imageDir.remove(e->field("cover"))); QVERIFY(!imageDir.exists(e->field(QLatin1String("cover")))); QVERIFY(doc->saveDocument(QUrl::fromLocalFile(fileName3))); // now the file should exist in the proper location QVERIFY(imageDir3.exists(e->field(QLatin1String("cover")))); // clear the cache Tellico::ImageFactory::clean(true); QVERIFY(!Tellico::ImageFactory::imageById(e->field("cover")).isNull()); // sanity check, the directory should not exists after QTemporaryDir destruction tempDir.remove(); QVERIFY(!QDir(tempDirName).exists()); }
void DetailedListView::addCollection(Tellico::Data::CollPtr coll_) { if(!coll_) { return; } const QString configGroup = QString::fromLatin1("Options - %1").arg(CollectionFactory::typeName(coll_)); KConfigGroup config(KGlobal::config(), configGroup); QString configN; if(coll_->type() == Data::Collection::Base) { KUrl url = Kernel::self()->URL(); for(int i = 0; i < Config::maxCustomURLSettings(); ++i) { KUrl u = config.readEntry(QString::fromLatin1("URL_%1").arg(i), KUrl()); if(u == url) { configN = QString::fromLatin1("_%1").arg(i); break; } } } // we don't want to immediately hide all these columns when adding fields disconnect(model(), SIGNAL(columnsInserted(const QModelIndex&, int, int)), this, SLOT(hideNewColumn(const QModelIndex&, int, int))); sourceModel()->setImagesAreAvailable(false); sourceModel()->setFields(coll_->fields()); connect(model(), SIGNAL(columnsInserted(const QModelIndex&, int, int)), this, SLOT(hideNewColumn(const QModelIndex&, int, int))); // we're not using saveState() and restoreState() since our columns are variable QStringList columnNames = config.readEntry(QLatin1String("ColumnNames") + configN, QStringList()); QList<int> columnWidths = config.readEntry(QLatin1String("ColumnWidths") + configN, QList<int>()); QList<int> columnOrder = config.readEntry(QLatin1String("ColumnOrder") + configN, QList<int>()); // just a broken-world check while(columnWidths.size() < columnNames.size()) { columnWidths << 0; } while(columnOrder.size() < columnNames.size()) { columnOrder << columnOrder.size(); } QList<int> currentColumnOrder; // now restore widths and order for(int ncol = 0; ncol < header()->count(); ++ncol) { int idx = columnNames.indexOf(columnFieldName(ncol)); // column width of 0 means hidden if(idx < 0 || columnWidths.at(idx) <= 0) { hideColumn(ncol); if(idx > -1) { currentColumnOrder << ncol; } } else { setColumnWidth(ncol, columnWidths.at(idx)); currentColumnOrder << ncol; } } const int maxCount = qMin(currentColumnOrder.size(), columnOrder.size()); for(int i = 0; i < maxCount; ++i) { header()->moveSection(header()->visualIndex(currentColumnOrder.at(i)), columnOrder.at(i)); } // always hide tables and paragraphs for(int ncol = 0; ncol < coll_->fields().count(); ++ncol) { Data::FieldPtr field = model()->headerData(ncol, Qt::Horizontal, FieldPtrRole).value<Data::FieldPtr>(); if(field) { if(field->type() == Data::Field::Table || field->type() == Data::Field::Para) { hideColumn(ncol); } } else { myDebug() << "no field for col" << ncol; } } // because some of the fields got hidden... updateHeaderMenu(); checkHeader(); sortModel()->setSortColumn(config.readEntry(QLatin1String("SortColumn") + configN, -1)); sortModel()->setSecondarySortColumn(config.readEntry(QLatin1String("PrevSortColumn") + configN, -1)); sortModel()->setTertiarySortColumn(config.readEntry(QLatin1String("Prev2SortColumn") + configN, -1)); const int order = config.readEntry(QLatin1String("SortOrder") + configN, static_cast<int>(Qt::AscendingOrder)); sortModel()->setSortOrder(static_cast<Qt::SortOrder>(order)); setUpdatesEnabled(false); m_loadingCollection = true; addEntries(coll_->entries()); m_loadingCollection = false; setUpdatesEnabled(true); header()->setSortIndicator(sortModel()->sortColumn(), sortModel()->sortOrder()); }