diff --git a/CMakeLists.txt b/CMakeLists.txt index 0062e0beb..5df238838 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -180,8 +180,6 @@ if(APPLE) set( SOCKETAPI_TEAM_IDENTIFIER_PREFIX "" CACHE STRING "SocketApi prefix (including a following dot) that must match the codesign key's TeamIdentifier/Organizational Unit" ) endif() -set(OWNCLOUD_PLACEHOLDER_SUFFIX ".owncloud" CACHE STRING "Placeholder suffix (must start with a .)") - if(BUILD_CLIENT) if(APPLE AND BUILD_UPDATER) find_package(Sparkle) diff --git a/NEXTCLOUD.cmake b/NEXTCLOUD.cmake index ec5830a4f..870cad83e 100644 --- a/NEXTCLOUD.cmake +++ b/NEXTCLOUD.cmake @@ -9,6 +9,7 @@ set( APPLICATION_ICON_NAME "Nextcloud" ) set( APPLICATION_SERVER_URL "" CACHE STRING "URL for the server to use. If entered, the UI field will be pre-filled with it" ) set( APPLICATION_SERVER_URL_ENFORCE ON ) # If set and APPLICATION_SERVER_URL is defined, the server can only connect to the pre-defined URL set( APPLICATION_REV_DOMAIN "com.nextcloud.desktopclient" ) +set( APPLICATION_PLACEHOLDER_SUFFIX "nextcloud" CACHE STRING "Placeholder suffix (not including the .)") set( LINUX_PACKAGE_SHORTNAME "nextcloud" ) set( LINUX_APPLICATION_ID "${APPLICATION_REV_DOMAIN}.${LINUX_PACKAGE_SHORTNAME}") diff --git a/admin/win/nsi/lib/fileassoc.nsh b/admin/win/nsi/lib/fileassoc.nsh new file mode 100644 index 000000000..87e6caf10 --- /dev/null +++ b/admin/win/nsi/lib/fileassoc.nsh @@ -0,0 +1,120 @@ +; fileassoc.nsh +; File association helper macros +; Written by Saivert +; See http://nsis.sourceforge.net/FileAssoc +; +; Features automatic backup system and UPDATEFILEASSOC macro for +; shell change notification. +; +; |> How to use <| +; To associate a file with an application so you can double-click it in explorer, use +; the APP_ASSOCIATE macro like this: +; +; Example: +; !insertmacro APP_ASSOCIATE "txt" "myapp.textfile" "Description of txt files" \ +; "$INSTDIR\myapp.exe,0" "Open with myapp" "$INSTDIR\myapp.exe $\"%1$\"" +; +; Never insert the APP_ASSOCIATE macro multiple times, it is only ment +; to associate an application with a single file and using the +; the "open" verb as default. To add more verbs (actions) to a file +; use the APP_ASSOCIATE_ADDVERB macro. +; +; Example: +; !insertmacro APP_ASSOCIATE_ADDVERB "myapp.textfile" "edit" "Edit with myapp" \ +; "$INSTDIR\myapp.exe /edit $\"%1$\"" +; +; To have access to more options when registering the file association use the +; APP_ASSOCIATE_EX macro. Here you can specify the verb and what verb is to be the +; standard action (default verb). +; +; And finally: To remove the association from the registry use the APP_UNASSOCIATE +; macro. Here is another example just to wrap it up: +; !insertmacro APP_UNASSOCIATE "txt" "myapp.textfile" +; +; |> Note <| +; When defining your file class string always use the short form of your application title +; then a period (dot) and the type of file. This keeps the file class sort of unique. +; Examples: +; Winamp.Playlist +; NSIS.Script +; Photoshop.JPEGFile +; +; |> Tech info <| +; The registry key layout for a file association is: +; HKEY_CLASSES_ROOT +; = <"description"> +; shell +; = <"menu-item text"> +; command = <"command string"> +; + +!macro APP_ASSOCIATE EXT FILECLASS DESCRIPTION ICON COMMANDTEXT COMMAND + ; Backup the previously associated file class + ReadRegStr $R0 HKCR ".${EXT}" "" + WriteRegStr HKCR ".${EXT}" "${FILECLASS}_backup" "$R0" + + WriteRegStr HKCR ".${EXT}" "" "${FILECLASS}" + + WriteRegStr HKCR "${FILECLASS}" "" `${DESCRIPTION}` + WriteRegStr HKCR "${FILECLASS}\DefaultIcon" "" `${ICON}` + WriteRegStr HKCR "${FILECLASS}\shell" "" "open" + WriteRegStr HKCR "${FILECLASS}\shell\open" "" `${COMMANDTEXT}` + WriteRegStr HKCR "${FILECLASS}\shell\open\command" "" `${COMMAND}` +!macroend + +!macro APP_ASSOCIATE_EX EXT FILECLASS DESCRIPTION ICON VERB DEFAULTVERB SHELLNEW COMMANDTEXT COMMAND + ; Backup the previously associated file class + ReadRegStr $R0 HKCR ".${EXT}" "" + WriteRegStr HKCR ".${EXT}" "${FILECLASS}_backup" "$R0" + + WriteRegStr HKCR ".${EXT}" "" "${FILECLASS}" + StrCmp "${SHELLNEW}" "0" +2 + WriteRegStr HKCR ".${EXT}\ShellNew" "NullFile" "" + + WriteRegStr HKCR "${FILECLASS}" "" `${DESCRIPTION}` + WriteRegStr HKCR "${FILECLASS}\DefaultIcon" "" `${ICON}` + WriteRegStr HKCR "${FILECLASS}\shell" "" `${DEFAULTVERB}` + WriteRegStr HKCR "${FILECLASS}\shell\${VERB}" "" `${COMMANDTEXT}` + WriteRegStr HKCR "${FILECLASS}\shell\${VERB}\command" "" `${COMMAND}` +!macroend + +!macro APP_ASSOCIATE_ADDVERB FILECLASS VERB COMMANDTEXT COMMAND + WriteRegStr HKCR "${FILECLASS}\shell\${VERB}" "" `${COMMANDTEXT}` + WriteRegStr HKCR "${FILECLASS}\shell\${VERB}\command" "" `${COMMAND}` +!macroend + +!macro APP_ASSOCIATE_REMOVEVERB FILECLASS VERB + DeleteRegKey HKCR `${FILECLASS}\shell\${VERB}` +!macroend + + +!macro APP_UNASSOCIATE EXT FILECLASS + ; Backup the previously associated file class + ReadRegStr $R0 HKCR ".${EXT}" `${FILECLASS}_backup` + WriteRegStr HKCR ".${EXT}" "" "$R0" + + DeleteRegKey HKCR `${FILECLASS}` +!macroend + +!macro APP_ASSOCIATE_GETFILECLASS OUTPUT EXT + ReadRegStr ${OUTPUT} HKCR ".${EXT}" "" +!macroend + + +; !defines for use with SHChangeNotify +!ifdef SHCNE_ASSOCCHANGED +!undef SHCNE_ASSOCCHANGED +!endif +!define SHCNE_ASSOCCHANGED 0x08000000 +!ifdef SHCNF_FLUSH +!undef SHCNF_FLUSH +!endif +!define SHCNF_FLUSH 0x1000 + +!macro UPDATEFILEASSOC +; Using the system.dll plugin to call the SHChangeNotify Win32 API function so we +; can update the shell. + System::Call "shell32::SHChangeNotify(i,i,i,i) (${SHCNE_ASSOCCHANGED}, ${SHCNF_FLUSH}, 0, 0)" +!macroend + +;EOF diff --git a/cmake/modules/NSIS.template.in b/cmake/modules/NSIS.template.in index 7dcb0af87..982faf3f1 100644 --- a/cmake/modules/NSIS.template.in +++ b/cmake/modules/NSIS.template.in @@ -7,6 +7,8 @@ !define APPLICATION_CMD_EXECUTABLE "@APPLICATION_EXECUTABLE@cmd.exe" !define APPLICATION_DOMAIN "@APPLICATION_DOMAIN@" !define APPLICATION_LICENSE "@APPLICATION_LICENSE@" +!define APPLICATION_PLACEHOLDER_SUFFIX "@APPLICATION_PLACEHOLDER_SUFFIX@" +!define APPLICATION_PLACEHOLDER_FILECLASS "@APPLICATION_EXECUTABLE@.@APPLICATION_PLACEHOLDER_SUFFIX@" !define WIN_SETUP_BITMAP_PATH "@WIN_SETUP_BITMAP_PATH@" !define CRASHREPORTER_EXECUTABLE "@CRASHREPORTER_EXECUTABLE@" @@ -100,6 +102,8 @@ ReserveFile "${NSISDIR}\Plugins\InstallOptions.dll" !include Library.nsh ;Used by the COM registration for shell extensions !include x64.nsh ;Used to determine the right arch for the shell extensions +!include ${source_path}/admin/win/nsi/lib/fileassoc.nsh + ;----------------------------------------------------------------------------- ; Memento selections stored in registry. ;----------------------------------------------------------------------------- @@ -469,6 +473,9 @@ Section "${APPLICATION_NAME}" SEC_APPLICATION ;CSync configs File "${SOURCE_PATH}/sync-exclude.lst" + ;Add file association + !insertmacro APP_ASSOCIATE "${APPLICATION_PLACEHOLDER_SUFFIX}" "${APPLICATION_PLACEHOLDER_FILECLASS}" "Placeholder for Remote File" "$INSTDIR\${APPLICATION_EXECUTABLE},0" "Download" "$INSTDIR\${APPLICATION_EXECUTABLE} $\"%1$\"" + SectionEnd !ifdef OPTION_SECTION_SC_SHELL_EXT @@ -646,6 +653,9 @@ Section Uninstall DeleteRegKey HKCR "${APPLICATION_NAME}" + ;Remove file association + !insertmacro APP_UNASSOCIATE "${APPLICATION_PLACEHOLDER_SUFFIX}" "${APPLICATION_PLACEHOLDER_FILECLASS}" + ;Shell extension !ifdef OPTION_SECTION_SC_SHELL_EXT !define LIBRARY_COM diff --git a/config.h.in b/config.h.in index 0983b6ba1..f6074b166 100644 --- a/config.h.in +++ b/config.h.in @@ -26,7 +26,8 @@ #cmakedefine APPLICATION_WIZARD_HEADER_BACKGROUND_COLOR "@APPLICATION_WIZARD_HEADER_BACKGROUND_COLOR@" #cmakedefine APPLICATION_WIZARD_HEADER_TITLE_COLOR "@APPLICATION_WIZARD_HEADER_TITLE_COLOR@" #cmakedefine APPLICATION_WIZARD_USE_CUSTOM_LOGO "@APPLICATION_WIZARD_USE_CUSTOM_LOGO@" -#cmakedefine OWNCLOUD_PLACEHOLDER_SUFFIX "@OWNCLOUD_PLACEHOLDER_SUFFIX@" +#cmakedefine APPLICATION_PLACEHOLDER_SUFFIX "@APPLICATION_PLACEHOLDER_SUFFIX@" +#define APPLICATION_DOTPLACEHOLDER_SUFFIX "." APPLICATION_PLACEHOLDER_SUFFIX #cmakedefine ZLIB_FOUND @ZLIB_FOUND@ diff --git a/src/gui/application.cpp b/src/gui/application.cpp index d7be07740..77bfaeef0 100644 --- a/src/gui/application.cpp +++ b/src/gui/application.cpp @@ -193,7 +193,7 @@ Application::Application(int &argc, char **argv) AbstractNetworkJob::httpTimeout = cfg.timeout(); ExcludedFiles::setupPlaceholderExclude( - cfg.excludeFile(ConfigFile::UserScope), OWNCLOUD_PLACEHOLDER_SUFFIX); + cfg.excludeFile(ConfigFile::UserScope), APPLICATION_DOTPLACEHOLDER_SUFFIX); _folderManager.reset(new FolderMan); @@ -503,7 +503,7 @@ void Application::parseOptions(const QStringList &options) _backgroundMode = true; } else if (option == QLatin1String("--version") || option == QLatin1String("-v")) { _versionOnly = true; - } else if (option.endsWith(QStringLiteral(OWNCLOUD_PLACEHOLDER_SUFFIX))) { + } else if (option.endsWith(QStringLiteral(APPLICATION_DOTPLACEHOLDER_SUFFIX))) { // placeholder file, open it after the Folder were created (if the app is not terminated) QTimer::singleShot(0, this, [this, option] { openPlaceholder(option); }); } else { @@ -683,7 +683,7 @@ void Application::slotGuiIsShowingSettings() void Application::openPlaceholder(const QString &filename) { - QString placeholderExt = QStringLiteral(OWNCLOUD_PLACEHOLDER_SUFFIX); + QString placeholderExt = QStringLiteral(APPLICATION_DOTPLACEHOLDER_SUFFIX); if (!filename.endsWith(placeholderExt)) { qWarning(lcApplication) << "Can only handle file ending in .owncloud. Unable to open" << filename; return; diff --git a/src/gui/folder.cpp b/src/gui/folder.cpp index f724a85c3..9fdc4cfaa 100644 --- a/src/gui/folder.cpp +++ b/src/gui/folder.cpp @@ -715,7 +715,7 @@ void Folder::setSyncOptions() opt._confirmExternalStorage = cfgFile.confirmExternalStorage(); opt._moveFilesToTrash = cfgFile.moveToTrash(); opt._newFilesArePlaceholders = _definition.usePlaceholders; - opt._placeholderSuffix = QStringLiteral(OWNCLOUD_PLACEHOLDER_SUFFIX); + opt._placeholderSuffix = QStringLiteral(APPLICATION_DOTPLACEHOLDER_SUFFIX); QByteArray chunkSizeEnv = qgetenv("OWNCLOUD_CHUNK_SIZE"); if (!chunkSizeEnv.isEmpty()) { diff --git a/src/gui/owncloud.xml.in b/src/gui/owncloud.xml.in index 5d1d06234..8bc9b48fe 100644 --- a/src/gui/owncloud.xml.in +++ b/src/gui/owncloud.xml.in @@ -2,6 +2,6 @@ @APPLICATION_NAME@ placeholders - + diff --git a/src/gui/socketapi.cpp b/src/gui/socketapi.cpp index 4ab9bead7..50ac868b0 100644 --- a/src/gui/socketapi.cpp +++ b/src/gui/socketapi.cpp @@ -689,7 +689,7 @@ void SocketApi::command_OPEN_PRIVATE_LINK(const QString &localFile, SocketListen void SocketApi::command_DOWNLOAD_PLACEHOLDER(const QString &filesArg, SocketListener *) { QStringList files = filesArg.split(QLatin1Char('\x1e')); // Record Separator - auto placeholderSuffix = QStringLiteral(OWNCLOUD_PLACEHOLDER_SUFFIX); + auto placeholderSuffix = QStringLiteral(APPLICATION_DOTPLACEHOLDER_SUFFIX); for (const auto &file : files) { if (!file.endsWith(placeholderSuffix)) @@ -974,7 +974,7 @@ void SocketApi::command_GET_MENU_ITEMS(const QString &argument, OCC::SocketListe // Placeholder download action if (syncFolder) { - auto placeholderSuffix = QStringLiteral(OWNCLOUD_PLACEHOLDER_SUFFIX); + auto placeholderSuffix = QStringLiteral(APPLICATION_DOTPLACEHOLDER_SUFFIX); bool hasPlaceholderFile = false; for (const auto &file : files) { if (file.endsWith(placeholderSuffix))