/*! \param path The QFileInfo of the path to open (it can be a file, a folder, a symlink,...). \param source The place where the path was found. \param sourceIsAContainerFile Indicates if "source" is a container file. \return Returns a ResultOfOpening value indicating the result of the operation. */ TNxSpooler::ResultOfOpening TNxSpooler::openPath(QFileInfo &path, const QString &source, bool /* sourceIsAContainerFile (temporary unused parameter) */) const { QDEBUG_METHOD_NAME; // Object to store the arguments to some callings QStringList arguments; // Name of the application that can be used to open the file QString app; // Stores the result of opening the path. This will be the value to return TNxSpooler::ResultOfOpening opResult = TNxSpooler::OpeningError; // It has this default value // Folders and {paths that do not seem to exist (there are many cases)} are not managed in the next block if (!path.isDir() && path.exists()) { // Get the index of the file extension int i = m_settings.value("exts").toStringList().indexOf(path.suffix()); if (i == -1) { // This case can happen if the path to open was inside a container file syst.showError(tr("2208097 - NxSpooler is not configured to launch an application to open files " "like \"%1\", which was found inside \"%2\".\n\n" "The administrator of this computer should see if this is due to a mistake " "of the program that created the file, an incorrect configuration of " "NxSpooler, etc.") .arg(QDir::toNativeSeparators(path.fileName())) .arg(QDir::toNativeSeparators(source))); return TNxSpooler::OpeningError; } app = m_settings.value("apps").toStringList().value(i); // There's no problem if app.isEmpty() #ifdef Q_WS_WIN arguments << "/C" << "start" << "/wait" << app; #endif } // Note: this way it worked with paths like "smb://server/resource" in Linux arguments << QDir::toNativeSeparators(path.filePath()); // Folders and {paths that do not seem to exist (there are many cases)} are not managed in the next block if (path.exists() && !path.isDir()) { // For avoiding the problem of having a file still being formed // and trying to open it, we'll wait until it has a stable size path.setCaching(false); // To try to read the current information about the file qint64 file_size_in_instant_1, file_size_in_instant_2; do { // Get the size file_size_in_instant_1 = path.size(); syst.wait(750); // Refresh the information that we have about the file path.refresh(); file_size_in_instant_2 = path.size(); } while (file_size_in_instant_1 != file_size_in_instant_2); // Try to open the file #ifdef Q_WS_WIN if (syst.execute("cmd", arguments) == 0) opResult = TNxSpooler::OpeningOk; else opResult = TNxSpooler::OpeningError; #else // If the user is using Linux and he has not specified the name of the program to use, // execute the default program if (app.isEmpty()) { if (syst.execute(getDefaultProgramInLinux(), arguments) == 0) opResult = TNxSpooler::OpeningOk; else opResult = TNxSpooler::OpeningError; } else { if (syst.execute(app, arguments) == 0) opResult = TNxSpooler::OpeningOk; else opResult = TNxSpooler::OpeningError; } #endif } else { // it's a folder, or something that doesn't seem to exist (there are many cases) #ifdef Q_WS_WIN // Windows explorer has anti-standard behaviours: for example returning 1 if it could // open a file and also returning the same value in some cases that it couldn't if (syst.execute("explorer", arguments) == 1) opResult = TNxSpooler::OpeningOk; else opResult = TNxSpooler::OpeningError; #else if (syst.execute("xdg-open", arguments) == 0) opResult = TNxSpooler::OpeningOk; else opResult = TNxSpooler::OpeningError; #endif } return opResult; }