Use different icon for a sync folder on Windows depending on zoom level.
authoralex-z <blackslayer4@gmail.com>
Wed, 24 Nov 2021 14:09:41 +0000 (16:09 +0200)
committerMatthieu Gallien (Rebase PR Action) <matthieu_gallien@yahoo.fr>
Tue, 7 Dec 2021 15:48:16 +0000 (15:48 +0000)
Signed-off-by: alex-z <blackslayer4@gmail.com>
.gitignore
cmake/modules/ECMAddAppIcon.cmake
src/common/utility_win.cpp
src/gui/CMakeLists.txt
src/gui/configgui.h.in [new file with mode: 0644]
theme/colored/icons/Nextcloud-icon-win-folder.svg [new file with mode: 0644]

index 15a7371a0437f273a803ce4ec4158fdac07990ec..dcd25d421c3a362655729f7da786cac129dfd5cc 100644 (file)
@@ -184,6 +184,7 @@ compile_commands.json
 convert.exe
 .dir-locals.el
 *-icon.png
+*-icon-win-folder.png
 *-sidebar.png
 *-w10startmenu.png
 theme.qrc
index 3934491bd9cb791e0971da7880180f95f015b82e..61dba6c425a7109a1a059bf4314bbf964d84f68c 100644 (file)
@@ -41,7 +41,7 @@
 #      target does not have the ``WIN32_EXECUTABLE`` property set.
 #    * One of the tools png2ico (See :find-module:`FindPng2Ico`) or
 #      icotool (see :find-module:`FindIcoTool`) is required.
-#    * Supported sizes: 16, 24, 32, 48, 64, 128, 256, 512 and 1024.
+#    * Supported sizes: 16, 20, 24, 32, 40, 48, 64, 128, 256, 512 and 1024.
 #
 # Mac OS X notes
 #    * The executable target must have the ``MACOSX_BUNDLE`` property set.
@@ -102,9 +102,12 @@ include(CMakeParseArguments)
 
 function(ecm_add_app_icon appsources)
     set(options)
-    set(oneValueArgs OUTFILE_BASENAME)
-    set(multiValueArgs ICONS SIDEBAR_ICONS)
+    set(oneValueArgs OUTFILE_BASENAME ICON_INDEX)
+    set(multiValueArgs ICONS SIDEBAR_ICONS RC_DEPENDENCIES)
     cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+    if (NOT ARG_ICON_INDEX)
+        set(ARG_ICON_INDEX 1)
+    endif()
 
     if(NOT ARG_ICONS)
         message(FATAL_ERROR "No ICONS argument given to ecm_add_app_icon")
@@ -138,8 +141,11 @@ function(ecm_add_app_icon appsources)
         endforeach()
     endif()
 
-
-    _ecm_add_app_icon_categorize_icons("${ARG_ICONS}" "icons" "16;24;32;48;64;128;256;512;1024")
+    if (WIN32)
+        _ecm_add_app_icon_categorize_icons("${ARG_ICONS}" "icons" "16;20;24;32;40;48;64;128;256;512;1024")
+    else()
+        _ecm_add_app_icon_categorize_icons("${ARG_ICONS}" "icons" "16;24;32;48;64;128;256;512;1024")
+    endif()
     if(ARG_SIDEBAR_ICONS)
         _ecm_add_app_icon_categorize_icons("${ARG_SIDEBAR_ICONS}" "sidebar_icons" "16;32;64;128;256")
     endif()
@@ -168,8 +174,10 @@ function(ecm_add_app_icon appsources)
 
 
     set(windows_icons   ${icons_at_16px}
+                        ${icons_at_20px}
                         ${icons_at_24px}
                         ${icons_at_32px}
+                        ${icons_at_40px}
                         ${icons_at_48px}
                         ${icons_at_64px}
                         ${icons_at_128px}
@@ -204,12 +212,12 @@ function(ecm_add_app_icon appsources)
                     WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
                 )
                 # this bit's a little hacky to make the dependency stuff work
-                file(WRITE "${_outfilename}.rc.in" "IDI_ICON1        ICON        DISCARDABLE    \"${_outfilename}.ico\"\n")
+                file(WRITE "${_outfilename}.rc.in" "IDI_ICON${ARG_ICON_INDEX}        ICON        DISCARDABLE    \"${_outfilename}.ico\"\n")
                 add_custom_command(
                     OUTPUT "${_outfilename}.rc"
                     COMMAND ${CMAKE_COMMAND}
                     ARGS -E copy "${_outfilename}.rc.in" "${_outfilename}.rc"
-                    DEPENDS "${_outfilename}.ico"
+                    DEPENDS ${ARG_RC_DEPENDENCIES} "${_outfilename}.ico"
                     WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
                 )
         endfunction()
@@ -226,7 +234,7 @@ function(ecm_add_app_icon appsources)
                 endif()
             endforeach()
 
-            foreach(size 16 24 32 48 64 128 ${maxSize})
+            foreach(size 16 20 24 32 40 48 64 128 ${maxSize})
                 if(NOT icons_at_${size}px)
                     continue()
                 endif()
index 5637a023e4d5a022b893d0691c8338a4c8b6adcd..80907ea5d8a6eec5060eb242c1935600d3aaf044 100644 (file)
@@ -18,6 +18,7 @@
 
 #include "asserts.h"
 #include "utility.h"
+#include "gui/configgui.h"
 
 #include <comdef.h>
 #include <Lmcons.h>
@@ -48,7 +49,14 @@ static void setupFavLink_private(const QString &folder)
         desktopIni.open(QFile::WriteOnly);
         desktopIni.write("[.ShellClassInfo]\r\nIconResource=");
         desktopIni.write(QDir::toNativeSeparators(qApp->applicationFilePath()).toUtf8());
-        desktopIni.write(",0\r\n");
+#ifdef APPLICATION_FOLDER_ICON_INDEX
+        const auto iconIndex = APPLICATION_FOLDER_ICON_INDEX;
+#else
+        const auto iconIndex = "0";
+#endif
+        desktopIni.write(",");
+        desktopIni.write(iconIndex);
+        desktopIni.write("\r\n");
         desktopIni.close();
 
         // Set the folder as system and Desktop.ini as hidden+system for explorer to pick it.
index 794f44f275bfa553789d904d2691c2d956433a65..abf2a190a64000fccadf99fc9feba5603918a3a3 100644 (file)
@@ -258,6 +258,10 @@ if (NOT DEFINED APPLICATION_ICON_NAME)
     set(APPLICATION_ICON_NAME ${APPLICATION_SHORTNAME})
 endif()
 
+if(NOT DEFINED APPLICATION_FOLDER_ICON_INDEX)
+    set(APPLICATION_FOLDER_ICON_INDEX 0)
+endif()
+
 # Generate png icons from svg
 find_program(SVG_CONVERTER
   NAMES inkscape inkscape.exe rsvg-convert
@@ -269,9 +273,24 @@ if (NOT SVG_CONVERTER)
 endif()
 
 function(generate_sized_png_from_svg icon_path size)
+  set(options)
+  set(oneValueArgs OUTPUT_ICON_NAME OUTPUT_ICON_PATH)
+  set(multiValueArgs)
+
+  cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
   get_filename_component(icon_name_dir ${icon_path} DIRECTORY)
   get_filename_component(icon_name_wle ${icon_path} NAME_WLE)
 
+  if (ARG_OUTPUT_ICON_NAME)
+    set(icon_name_wle ${ARG_OUTPUT_ICON_NAME})
+  endif ()
+
+  if (ARG_OUTPUT_ICON_PATH)
+    set(icon_name_dir ${ARG_OUTPUT_ICON_PATH})
+  endif ()
+  
+
   if (EXISTS "${icon_name_dir}/${size}-${icon_name_wle}.png")
     return()
   endif()
@@ -317,22 +336,84 @@ if(WIN32)
 endif()
 
 set(APP_ICON_SVG "${theme_dir}/colored/${APPLICATION_ICON_NAME}-icon.svg")
-generate_sized_png_from_svg(${APP_ICON_SVG} 16)
-generate_sized_png_from_svg(${APP_ICON_SVG} 24)
-generate_sized_png_from_svg(${APP_ICON_SVG} 32)
-generate_sized_png_from_svg(${APP_ICON_SVG} 48)
-generate_sized_png_from_svg(${APP_ICON_SVG} 64)
-generate_sized_png_from_svg(${APP_ICON_SVG} 128)
-generate_sized_png_from_svg(${APP_ICON_SVG} 256)
-generate_sized_png_from_svg(${APP_ICON_SVG} 512)
-generate_sized_png_from_svg(${APP_ICON_SVG} 1024)
+
+# generate secondary icon if available (currently for Windows only)--------------------------------------
+set(APP_SECONDARY_ICONS "${theme_dir}/colored/icons")
+set(APP_ICON_WIN_FOLDER_SVG "${APP_SECONDARY_ICONS}/${APPLICATION_ICON_NAME}-icon-win-folder.svg")
+
+set(RC_DEPENDENCIES "")
+
+if (EXISTS ${APP_ICON_WIN_FOLDER_SVG})
+    get_filename_component(output_icon_name_win ${APP_ICON_WIN_FOLDER_SVG} NAME_WLE)
+    # Product icon (for smallest size)
+    foreach(size IN ITEMS 16;20)
+        generate_sized_png_from_svg(${APP_ICON_SVG} ${size} OUTPUT_ICON_NAME ${output_icon_name_win} OUTPUT_ICON_PATH "${APP_SECONDARY_ICONS}/")
+    endforeach()
+
+    # Product icon with Windows folder (for sizes larger than 20)
+    foreach(size IN ITEMS 24;32;40;48;64;128;256;512;1024)
+        generate_sized_png_from_svg(${APP_ICON_WIN_FOLDER_SVG} ${size} OUTPUT_ICON_NAME ${output_icon_name_win} OUTPUT_ICON_PATH "${APP_SECONDARY_ICONS}/")
+    endforeach()
+
+    file(GLOB_RECURSE OWNCLOUD_ICONS_WIN_FOLDER "${APP_SECONDARY_ICONS}/*-${APPLICATION_ICON_NAME}-icon*")
+    set(APP_ICON_WIN_FOLDER_ICO_NAME "${APPLICATION_ICON_NAME}-win-folder")
+    set(RC_DEPENDENCIES "${RC_DEPENDENCIES} ${APP_ICON_WIN_FOLDER_ICO_NAME}.ico")
+    ecm_add_app_icon(APP_ICON_WIN_FOLDER ICONS "${OWNCLOUD_ICONS_WIN_FOLDER}" SIDEBAR_ICONS "${OWNCLOUD_SIDEBAR_ICONS}" OUTFILE_BASENAME "${APP_ICON_WIN_FOLDER_ICO_NAME}" ICON_INDEX 2)
+endif()
+# --------------------------------------
+
+if (NOT ${RC_DEPENDENCIES} STREQUAL "")
+    string(STRIP ${RC_DEPENDENCIES} RC_DEPENDENCIES)
+endif()
+
+# generate primary icon from SVG (due to Win .ico vs .rc dependency issues, primary icon must always be generated last)--------------------------------------
+if(WIN32)
+    foreach(size IN ITEMS 16;20;24;32;40;48;64;128;256;512;1024)
+        generate_sized_png_from_svg(${APP_ICON_SVG} ${size})
+    endforeach()
+else()
+    foreach(size IN ITEMS 16;24;32;48;64;128;256;512;1024)
+        generate_sized_png_from_svg(${APP_ICON_SVG} ${size})
+    endforeach()
+endif()
 
 file(GLOB_RECURSE OWNCLOUD_ICONS "${theme_dir}/colored/*-${APPLICATION_ICON_NAME}-icon*")
+
 if(APPLE)
     file(GLOB_RECURSE OWNCLOUD_SIDEBAR_ICONS "${theme_dir}/colored/*-${APPLICATION_ICON_NAME}-sidebar*")
     MESSAGE(STATUS "OWNCLOUD_SIDEBAR_ICONS: ${APPLICATION_ICON_NAME}: ${OWNCLOUD_SIDEBAR_ICONS}")
 endif()
-ecm_add_app_icon(APP_ICON ICONS "${OWNCLOUD_ICONS}" SIDEBAR_ICONS "${OWNCLOUD_SIDEBAR_ICONS}" OUTFILE_BASENAME "${APPLICATION_ICON_NAME}")
+
+ecm_add_app_icon(APP_ICON RC_DEPENDENCIES ${RC_DEPENDENCIES} ICONS "${OWNCLOUD_ICONS}" SIDEBAR_ICONS "${OWNCLOUD_SIDEBAR_ICONS}" OUTFILE_BASENAME "${APPLICATION_ICON_NAME}" ICON_INDEX 1)
+# --------------------------------------
+
+if(WIN32)
+# merge *.rc.in files for Windows (multiple ICON resources must be placed in a single file, otherwise, this won't work de to a bug in Windows compiler https://developercommunity.visualstudio.com/t/visual-studio-2017-prof-1557-cvt1100-duplicate-res/363156)
+    function(merge_files IN_FILE OUT_FILE)
+        file(READ ${IN_FILE} CONTENTS)
+        message("Merging ${IN_FILE} into ${OUT_FILE}")
+        file(APPEND ${OUT_FILE} "${CONTENTS}")
+    endfunction()
+    message("APP_ICON is: ${APP_ICON}")
+    if(APP_ICON)
+        get_filename_component(RC_IN_FOLDER ${APP_ICON}} DIRECTORY)
+
+        file(GLOB_RECURSE RC_IN_FILES "${RC_IN_FOLDER}/*rc.in")
+
+        foreach(rc_in_file IN ITEMS ${RC_IN_FILES})
+          get_filename_component(rc_in_file_name ${rc_in_file} NAME)
+          get_filename_component(app_icon_name "${APP_ICON}.in" NAME)
+          if(NOT "${rc_in_file_name}" STREQUAL "${app_icon_name}")
+              merge_files(${rc_in_file} "${APP_ICON}.in")
+              if (DEFINED APPLICATION_FOLDER_ICON_INDEX)
+                  MATH(EXPR APPLICATION_FOLDER_ICON_INDEX "${APPLICATION_FOLDER_ICON_INDEX}+1")
+                  message("APPLICATION_FOLDER_ICON_INDEX is now set to: ${APPLICATION_FOLDER_ICON_INDEX}")
+              endif()
+          endif()
+        endforeach()
+    endif()
+endif()
+# --------------------------------------
 
 if(UNIX AND NOT APPLE)
   set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE")
@@ -545,3 +626,5 @@ if(NOT BUILD_OWNCLOUD_OSX_BUNDLE AND NOT WIN32)
         update_xdg_mimetypes( ${CMAKE_INSTALL_DATADIR}/mime/packages )
     endif(SharedMimeInfo_FOUND)
 endif()
+
+configure_file(configgui.h.in ${CMAKE_CURRENT_BINARY_DIR}/configgui.h)
diff --git a/src/gui/configgui.h.in b/src/gui/configgui.h.in
new file mode 100644 (file)
index 0000000..36bc6fb
--- /dev/null
@@ -0,0 +1,4 @@
+#ifndef CONFIG_GUI_H
+#define CONFIG_GUI_H
+#cmakedefine APPLICATION_FOLDER_ICON_INDEX "@APPLICATION_FOLDER_ICON_INDEX@"
+#endif
diff --git a/theme/colored/icons/Nextcloud-icon-win-folder.svg b/theme/colored/icons/Nextcloud-icon-win-folder.svg
new file mode 100644 (file)
index 0000000..2fbba0b
--- /dev/null
@@ -0,0 +1,278 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   version="1.1"
+   id="Ebene_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 300 300"
+   style="enable-background:new 0 0 300 300;"
+   xml:space="preserve"
+   sodipodi:docname="Windows_Folder.svg"
+   inkscape:version="1.1.1 (1:1.1+202109281949+c3084ef5ed)"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:svg="http://www.w3.org/2000/svg"><defs
+   id="defs74">
+               
+       
+                       
+                               <linearGradient
+   id="Pfad_499_00000161620552563728473090000003454445015337385602_"
+   gradientUnits="userSpaceOnUse"
+   x1="3.5778999"
+   y1="299.08331"
+   x2="3.5778999"
+   y2="297.29568"
+   gradientTransform="matrix(72,0,0,-72,49,21673)">
+                               <stop
+   offset="0"
+   style="stop-color:#FE319A"
+   id="stop59" />
+                               <stop
+   offset="1"
+   style="stop-color:#E20074"
+   id="stop61" />
+                       </linearGradient>
+                       
+                               
+                       
+                       
+               <linearGradient
+   gradientTransform="matrix(0.9909162,0,0,0.99091623,283.08824,126.10294)"
+   inkscape:collect="always"
+   xlink:href="#linearGradient857"
+   id="linearGradient1192"
+   gradientUnits="userSpaceOnUse"
+   x1="18.230097"
+   y1="150"
+   x2="150.00002"
+   y2="-7.6293945e-06" /><linearGradient
+   inkscape:collect="always"
+   id="linearGradient857"><stop
+     style="stop-color:#0082c9;stop-opacity:1;"
+     offset="0"
+     id="stop853" /><stop
+     style="stop-color:#1cafff;stop-opacity:1"
+     offset="1"
+     id="stop855" /></linearGradient></defs><sodipodi:namedview
+   id="namedview72"
+   pagecolor="#ffffff"
+   bordercolor="#666666"
+   borderopacity="1.0"
+   inkscape:pageshadow="2"
+   inkscape:pageopacity="0.0"
+   inkscape:pagecheckerboard="0"
+   showgrid="false"
+   inkscape:zoom="1.9233304"
+   inkscape:cx="123.48372"
+   inkscape:cy="174.17704"
+   inkscape:window-width="1920"
+   inkscape:window-height="1046"
+   inkscape:window-x="0"
+   inkscape:window-y="34"
+   inkscape:window-maximized="1"
+   inkscape:current-layer="Ebene_1" />
+<style
+   type="text/css"
+   id="style2">
+       .st0{fill:url(#SVGID_1_);}
+       .st1{fill:url(#SVGID_00000073698049827524260440000006626317865822427277_);}
+       .st2{fill:url(#SVGID_00000058549202148666045310000006535695705354523308_);}
+       .st3{fill:url(#SVGID_00000135661076229880923210000014324535628046543800_);}
+       .st4{fill:url(#SVGID_00000090993352524005697930000005123350809455339168_);}
+       .st5{fill:#FDE07F;}
+       .st6{fill:#FFEEB6;}
+       .st7{clip-path:url(#SVGID_00000027581996385575992730000014613207578918336175_);}
+       .st8{fill:url(#Pfad_499_00000154407742523961947240000000935762443450757262_);}
+       .st9{fill:#FFFFFF;}
+       .st10{fill:#F2F2F2;}
+</style>
+<g
+   id="g51">
+       <linearGradient
+   id="SVGID_1_"
+   gradientUnits="userSpaceOnUse"
+   x1="224.238"
+   y1="251.2621"
+   x2="235.5521"
+   y2="229.8477">
+               <stop
+   offset="0"
+   style="stop-color:#E5E5E5"
+   id="stop4" />
+               <stop
+   offset="1"
+   style="stop-color:#F2F2F2;stop-opacity:0"
+   id="stop6" />
+       </linearGradient>
+       <polygon
+   class="st0"
+   points="221,245 251,236 221,222  "
+   id="polygon9" />
+       
+               <linearGradient
+   id="SVGID_00000168800218275837730680000003462325949068373151_"
+   gradientUnits="userSpaceOnUse"
+   x1="108.238"
+   y1="292.2621"
+   x2="119.5521"
+   y2="270.8477">
+               <stop
+   offset="0"
+   style="stop-color:#E5E5E5"
+   id="stop11" />
+               <stop
+   offset="1"
+   style="stop-color:#F2F2F2;stop-opacity:0"
+   id="stop13" />
+       </linearGradient>
+       <polygon
+   style="fill:url(#SVGID_00000168800218275837730680000003462325949068373151_);"
+   points="105,286 135,277 105,263  "
+   id="polygon16" />
+       
+               <linearGradient
+   id="SVGID_00000003802560936691988940000016049607085827979708_"
+   gradientUnits="userSpaceOnUse"
+   x1="51.9582"
+   y1="185.0925"
+   x2="200.6586"
+   y2="104.7857">
+               <stop
+   offset="0.3193"
+   style="stop-color:#EBC863"
+   id="stop18" />
+               <stop
+   offset="1"
+   style="stop-color:#FEE182"
+   id="stop20" />
+       </linearGradient>
+       <path
+   style="fill:url(#SVGID_00000003802560936691988940000016049607085827979708_);"
+   d="M219,246H56c-1.7,0-3-1.3-3-3V33h151   c1.7,0,3,1.3,3,3v125.2c0,0.8,0.3,1.5,0.9,2.1l13.3,13.6c0.5,0.6,0.9,1.3,0.9,2.1V243C222,244.7,220.7,246,219,246z"
+   id="path23" />
+       <g
+   id="g39">
+               
+                       <linearGradient
+   id="SVGID_00000088830071281327557650000012927193665735863469_"
+   gradientUnits="userSpaceOnUse"
+   x1="81.921"
+   y1="116.6131"
+   x2="83.1607"
+   y2="222.7924">
+                       <stop
+   offset="0"
+   style="stop-color:#FFEFBC"
+   id="stop25" />
+                       <stop
+   offset="1"
+   style="stop-color:#FFE495"
+   id="stop27" />
+               </linearGradient>
+               <path
+   style="fill:url(#SVGID_00000088830071281327557650000012927193665735863469_);"
+   d="M103.5,286L54,246V33l55.9,44.1    c0.7,0.6,1.1,1.4,1.1,2.4V211l-5,7v66.9C106,286.1,104.5,286.8,103.5,286z"
+   id="path30" />
+               
+                       <linearGradient
+   id="SVGID_00000075125985038499810010000013334681634146325900_"
+   gradientUnits="userSpaceOnUse"
+   x1="58.9558"
+   y1="126.3097"
+   x2="117.1869"
+   y2="218.9498">
+                       <stop
+   offset="0"
+   style="stop-color:#FFEAA5"
+   id="stop32" />
+                       <stop
+   offset="1"
+   style="stop-color:#FFE086"
+   id="stop34" />
+               </linearGradient>
+               <path
+   style="fill:url(#SVGID_00000075125985038499810010000013334681634146325900_);"
+   d="M102.5,285.7l-49.5-40V33l55.8,44    c0.7,0.6,1.1,1.4,1.1,2.4v131.4l-5,7v66.8C104.9,285.8,103.5,286.5,102.5,285.7z"
+   id="path37" />
+       </g>
+       <g
+   id="g49">
+               <rect
+   x="60"
+   y="46"
+   class="st5"
+   width="1"
+   height="200"
+   id="rect41" />
+               <rect
+   x="56.5"
+   y="46"
+   class="st5"
+   width="1"
+   height="200"
+   id="rect43" />
+               <rect
+   x="57.5"
+   y="46"
+   class="st6"
+   width="1"
+   height="200"
+   id="rect45" />
+               <rect
+   x="61"
+   y="46"
+   class="st6"
+   width="1"
+   height="200"
+   id="rect47" />
+       </g>
+</g>
+<g
+   id="g69"
+   transform="translate(0,-100)">
+       <defs
+   id="defs54">
+               <rect
+   id="SVGID_00000093176395783954265780000012512996052019405743_"
+   x="122.3"
+   y="139"
+   width="128.7"
+   height="128.7" />
+       </defs>
+       <clipPath
+   id="SVGID_00000106127748250350940740000017471206982484828042_">
+               <use
+   xlink:href="#SVGID_00000093176395783954265780000012512996052019405743_"
+   style="overflow:visible"
+   id="use56"
+   x="0"
+   y="0"
+   width="100%"
+   height="100%" />
+       </clipPath>
+       
+               <g
+   id="g925"
+   transform="matrix(0.81518987,0,0,0.81518987,-44.170655,200.60216)"><circle
+     r="79"
+     cy="126.10294"
+     cx="283.08823"
+     id="circle1050"
+     style="fill:url(#linearGradient1192);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.0990916;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     inkscape:export-filename="nextcloud-icon.png"
+     inkscape:export-xdpi="300"
+     inkscape:export-ydpi="300" /><path
+     inkscape:connector-curvature="0"
+     id="path1052"
+     d="m 283.18965,95.813064 c -13.79313,0 -25.48394,9.350826 -29.10731,22.020146 -3.14909,-6.72 -9.97328,-11.42792 -17.83356,-11.42792 -10.80973,0 -19.69562,8.88589 -19.69562,19.69562 0,10.80972 8.88589,19.69967 19.69562,19.69967 7.86028,0 14.68447,-4.7108 17.83356,-11.43198 3.62337,12.67028 15.31418,22.02422 29.10731,22.02422 13.69111,0 25.32232,-9.21286 29.03837,-21.74023 3.20726,6.56859 9.94698,11.14799 17.69562,11.14799 10.80974,0 19.69967,-8.88995 19.69967,-19.69967 0,-10.80973 -8.88993,-19.69562 -19.69967,-19.69562 -7.74864,0 -14.48836,4.57653 -17.69562,11.14395 -3.71605,-12.5264 -15.34726,-21.736176 -29.03837,-21.736176 z m 0,11.561796 c 10.41225,0 18.73011,8.31383 18.73011,18.72605 0,10.41221 -8.31786,18.73011 -18.73011,18.73011 -10.41219,0 -18.72603,-8.3179 -18.72603,-18.73011 0,-10.41222 8.31384,-18.72605 18.72603,-18.72605 z m -46.94087,10.59222 c 4.56183,0 8.13788,3.57198 8.13788,8.13383 0,4.56184 -3.57605,8.13787 -8.13788,8.13787 -4.56183,0 -8.13385,-3.57603 -8.13385,-8.13787 0,-4.56185 3.57202,-8.13383 8.13385,-8.13383 z m 93.67486,0 c 4.56187,0 8.1379,3.57198 8.1379,8.13383 0,4.56184 -3.57605,8.13787 -8.1379,8.13787 -4.56181,0 -8.13381,-3.57603 -8.13381,-8.13787 0,-4.56185 3.57201,-8.13383 8.13381,-8.13383 z"
+     style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6.50314;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+     inkscape:export-filename="Nextcloud Hub logo variants.png"
+     inkscape:export-xdpi="300"
+     inkscape:export-ydpi="300" /></g>
+</g>
+</svg>