File indexing completed on 2024-04-21 15:12:03
0001 /************************************************************************ 0002 * * 0003 * This file is part of Kooka, a scanning/OCR application using * 0004 * Qt <http://www.qt.io> and KDE Frameworks <http://www.kde.org>. * 0005 * * 0006 * Copyright (C) 2000-2016 Klaas Freitag <freitag@suse.de> * 0007 * Jonathan Marten <jjm@keelhaul.me.uk> * 0008 * * 0009 * Kooka is free software; you can redistribute it and/or modify it * 0010 * under the terms of the GNU Library General Public License as * 0011 * published by the Free Software Foundation and appearing in the * 0012 * file COPYING included in the packaging of this file; either * 0013 * version 2 of the License, or (at your option) any later version. * 0014 * * 0015 * As a special exception, permission is given to link this program * 0016 * with any version of the KADMOS OCR/ICR engine (a product of * 0017 * reRecognition GmbH, Kreuzlingen), and distribute the resulting * 0018 * executable without including the source code for KADMOS in the * 0019 * source distribution. * 0020 * * 0021 * This program is distributed in the hope that it will be useful, * 0022 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0024 * GNU General Public License for more details. * 0025 * * 0026 * You should have received a copy of the GNU General Public * 0027 * License along with this program; see the file COPYING. If * 0028 * not, see <http://www.gnu.org/licenses/>. * 0029 * * 0030 ************************************************************************/ 0031 0032 #include "galleryroot.h" 0033 0034 #ifdef HAVE_ERRNO_H 0035 #include <errno.h> 0036 #endif 0037 #ifdef HAVE_STRERROR 0038 #include <string.h> 0039 #endif 0040 #ifdef HAVE_SYS_STAT_H 0041 #include <sys/stat.h> 0042 #endif 0043 #ifdef HAVE_SYS_TYPES_H 0044 #include <sys/types.h> 0045 #endif 0046 0047 #include <qdir.h> 0048 #include <qstandardpaths.h> 0049 0050 #include <kwidgetsaddons_version.h> 0051 #include <klocalizedstring.h> 0052 #include <kmessagebox.h> 0053 #include <kstandardguiitem.h> 0054 0055 #include "kookasettings.h" 0056 #include "kooka_logging.h" 0057 0058 // Support for the gallery location - moved here from KookaPref so that it 0059 // can be used in the core library. Before that is was part of the Previewer 0060 // class in libkscan. 0061 0062 0063 // The global resolved gallery location, static so that the user is only asked 0064 // at most once in an application run. No need to use Q_GLOBAL_STATIC, because 0065 // its initialisation is guarded with the flag. 0066 static QUrl sGalleryRoot; 0067 static bool sGalleryLocated = false; 0068 0069 0070 // Get the user's configured KDE documents path. It may not exist yet, in 0071 // which case QDir::canonicalPath() will fail - try QDir::absolutePath() in 0072 // this case. If all else fails then the last resort is the home directory. 0073 static QString docsPath() 0074 { 0075 QString docpath = QDir(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)).canonicalPath(); 0076 if (docpath.isEmpty()) { 0077 docpath = QDir(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)).absolutePath(); 0078 } 0079 if (docpath.isEmpty()) { 0080 docpath = QFile::decodeName(getenv("HOME")); 0081 } 0082 return (docpath); 0083 } 0084 0085 0086 // TODO: maybe save a .directory file there which shows a 'scanner' logo? 0087 static QString createGallery(const QDir &d, bool *success = nullptr) 0088 { 0089 if (!d.exists()) // does not already exist 0090 { 0091 if (mkdir(QFile::encodeName(d.path()).constData(), 0755) != 0) 0092 { // using mkdir(2) so that we can 0093 // get the errno if it fails 0094 #ifdef HAVE_STRERROR 0095 const char *reason = strerror(errno); 0096 #else 0097 const char *reason = ""; 0098 #endif 0099 QString docs = docsPath(); 0100 KMessageBox::error(nullptr, 0101 xi18nc("@info", "Unable to create the directory <filename>%1</filename>" 0102 "<nl/>for the Kooka gallery" 0103 #ifdef HAVE_STRERROR 0104 " - %3." 0105 #else 0106 "." 0107 #endif 0108 "<nl/><nl/>Your document directory <filename>%2</filename>" 0109 "<nl/>will be used." 0110 "<nl/><nl/>Check the document directory setting and permissions.", 0111 d.absolutePath(), docs, reason), 0112 i18n("Error creating gallery")); 0113 0114 if (success != nullptr) *success = false; 0115 return (docs); 0116 } 0117 } 0118 0119 if (success != nullptr) { 0120 *success = true; 0121 } 0122 return (d.absolutePath()); 0123 } 0124 0125 0126 static QString findGalleryRoot() 0127 { 0128 QString galleryName = KookaSettings::galleryName(); // may be base name or absolute path 0129 if (galleryName.isEmpty()) 0130 { 0131 qCWarning(KOOKA_LOG) << "Gallery name not configured"; 0132 return (QString()); 0133 } 0134 0135 QString oldpath = QStandardPaths::locate(QStandardPaths::AppDataLocation, "ScanImages", QStandardPaths::LocateDirectory); 0136 bool oldexists = !oldpath.isEmpty(); 0137 0138 QString newpath(galleryName); 0139 if (!QDir::isAbsolutePath(galleryName)) 0140 { 0141 QString docpath = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); 0142 newpath = docpath+'/'+galleryName; // already an absolute path 0143 } 0144 0145 QDir newdir(newpath); 0146 bool newexists = newdir.exists(); 0147 0148 qCDebug(KOOKA_LOG) << "old" << oldpath << "exists" << oldexists; 0149 qCDebug(KOOKA_LOG) << "new" << newpath << "exists" << newexists; 0150 0151 QString dir; 0152 0153 if (!oldexists && !newexists) { // no directories present 0154 dir = createGallery(newdir); // create and use new 0155 } else if (!oldexists && newexists) { // only new exists 0156 dir = newpath; // fine, just use that 0157 } else if (oldexists && !newexists) { // only old exists 0158 #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 100, 0) 0159 if (KMessageBox::questionTwoActions(nullptr, 0160 #else 0161 if (KMessageBox::questionYesNo(nullptr, 0162 #endif 0163 xi18nc("@info", 0164 "An old Kooka gallery was found at <filename>%1</filename>." 0165 "<nl/>The preferred new location is now <filename>%2</filename>." 0166 "<nl/><nl/>Do you want to create a new gallery at the new location?", 0167 oldpath, newpath), 0168 i18n("Create New Gallery"), 0169 KGuiItem(i18nc("@action:button", "Create New"), QStringLiteral("folder-new")), 0170 KGuiItem(i18nc("@action:button", "Continue With Old"), QStringLiteral("dialog-cancel")), 0171 "GalleryNoMigrate") 0172 #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 100, 0) 0173 == KMessageBox::PrimaryAction) { 0174 #else 0175 == KMessageBox::Yes) { 0176 #endif 0177 // yes, create new 0178 bool created; 0179 dir = createGallery(newdir, &created); 0180 if (created) { // new created OK 0181 KMessageBox::information(nullptr, 0182 xi18nc("@info", 0183 "Kooka will use the new gallery, <link url=\"file:%1\"><filename>%1</filename></link>." 0184 "<nl/><nl/>If you wish to add the images from your old gallery <link url=\"file:%2\"><filename>%2</filename></link>," 0185 "<nl/>then you may do so by simply copying or moving the files.", 0186 newpath, oldpath), 0187 i18n("New Gallery Created"), 0188 QString(), 0189 KMessageBox::Notify | KMessageBox::AllowLink); 0190 } 0191 } else { // no, don't create 0192 dir = oldpath; // stay with old location 0193 } 0194 } else { // both exist 0195 KMessageBox::information(nullptr, 0196 xi18nc("@info", 0197 "Kooka will use the new gallery, <link url=\"file:%1\"><filename>%1</filename></link>." 0198 "<nl/><nl/>If you wish to add the images from your old gallery <link url=\"file:%2\"><filename>%2</filename></link>," 0199 "<nl/>then you may do so by simply copying or moving the files.", 0200 newpath, oldpath), 0201 i18n("Old Gallery Exists"), 0202 "GalleryNoRemind", 0203 KMessageBox::Notify | KMessageBox::AllowLink); 0204 dir = newpath; // just use new one 0205 } 0206 0207 if (!dir.endsWith("/")) dir += "/"; 0208 qCDebug(KOOKA_LOG) << "using" << dir; 0209 return (dir); 0210 } 0211 0212 0213 QUrl GalleryRoot::root() 0214 { 0215 if (!sGalleryLocated) 0216 { 0217 sGalleryRoot = QUrl::fromLocalFile(findGalleryRoot()); 0218 if (!sGalleryRoot.isValid()) qCWarning(KOOKA_LOG) << "root not valid!"; 0219 sGalleryLocated = true; 0220 } 0221 0222 return (sGalleryRoot); 0223 }