diff --git a/app/main.cpp b/app/main.cpp --- a/app/main.cpp +++ b/app/main.cpp @@ -138,7 +138,17 @@ if (command == "open") { QVector infos; stream >> infos; + + QVector files, directories; + for(const auto &info: infos) + if (info.isDirectory()) + directories << info; + else + files << info; + openFiles(infos); + for(const auto &urlinfo: infos) + ICore::self()->projectController()->openProjectForUrl(urlinfo.url); } else { qCWarning(APP) << "Unknown remote command: " << command; } @@ -198,7 +208,7 @@ QDBusReply result = iface.call(QStringLiteral("openDocumentSimple"), file.url.toString(), file.cursor.line(), file.cursor.column()); if ( ! result.value() ) { QTextStream err(stderr); - err << i18n("Could not open file %1.", file.url.toDisplayString(QUrl::PreferLocalFile)) << "\n"; + err << i18n("Could not open file '%1'.", file.url.toDisplayString(QUrl::PreferLocalFile)) << "\n"; errors_occured = true; } } @@ -209,6 +219,29 @@ return errors_occured; } +/// Performs a DBus call to open the given @p files in the running kdev instance identified by @p pid +/// Returns the exit status +static int openProjectInRunningInstance(const QVector& paths, qint64 pid) +{ + const QString service = QStringLiteral("org.kdevelop.kdevelop-%1").arg(pid); + QDBusInterface iface(service, QStringLiteral("/org/kdevelop/ProjectController"), QStringLiteral("org.kdevelop.ProjectController")); + int errors = 0; + + foreach ( const UrlInfo& path, paths ) { + QDBusReply result = iface.call(QStringLiteral("openProjectForUrl"), path.url.toString()); + if ( !result.isValid() ) { + QTextStream err(stderr); + err << i18n("Could not open project '%1': %2", path.url.toDisplayString(QUrl::PreferLocalFile), result.error().message()) << "\n"; + ++errors; + } + } + // make the window visible + QDBusMessage makeVisible = QDBusMessage::createMethodCall( service, QStringLiteral("/kdevelop/MainWindow"), QStringLiteral("org.kdevelop.MainWindow"), + QStringLiteral("ensureVisible") ); + QDBusConnection::sessionBus().asyncCall( makeVisible ); + return errors; +} + /// Gets the PID of a running KDevelop instance, eventually asking the user if there is more than one. /// Returns -1 in case there are no running sessions. static qint64 getRunningSessionPid() @@ -470,16 +503,22 @@ // Handle extra arguments, which stand for files to open QVector initialFiles; + QVector initialDirectories; foreach (const QString &file, parser.positionalArguments()) { - initialFiles.append(UrlInfo(file)); + UrlInfo uinfo(file); + if (uinfo.isDirectory()) { + initialDirectories.append(uinfo); + } else { + initialFiles.append(uinfo); + } } const auto availableSessionInfos = KDevelop::SessionController::availableSessionInfos(); - if (!initialFiles.isEmpty() && !parser.isSet(QStringLiteral("new-session"))) { + if ((!initialFiles.isEmpty() || !initialDirectories.isEmpty()) && !parser.isSet(QStringLiteral("new-session"))) { #if KDEVELOP_SINGLE_APP if (app.isRunning()) { - bool success = app.sendMessage(serializeOpenFilesMessage(initialFiles)); + bool success = app.sendMessage(serializeOpenFilesMessage(initialFiles << initialDirectories)); if (success) { return 0; } @@ -496,8 +535,9 @@ } else { pid = getRunningSessionPid(); } + if ( pid > 0 ) { - return openFilesInRunningInstance(initialFiles, pid); + return openFilesInRunningInstance(initialFiles, pid) + openProjectInRunningInstance(initialDirectories, pid); } // else there are no running sessions, and the generated list of files will be opened below. #endif @@ -729,6 +769,9 @@ core->runControllerInternal()->execute(debugStr, launch); } else { openFiles(initialFiles); + + for(const auto &urlinfo: initialDirectories) + core->projectController()->openProjectForUrl(urlinfo.url); } #if KDEVELOP_SINGLE_APP diff --git a/app/urlinfo.h b/app/urlinfo.h --- a/app/urlinfo.h +++ b/app/urlinfo.h @@ -86,6 +86,11 @@ } } + bool isDirectory() const + { + return url.isLocalFile() && QDir(url.toLocalFile()).exists() && !cursor.isValid(); + } + /** * url computed out of the passed path */