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 }