Merge remote-tracking branch 'oc/master' into master-oc

This commit is contained in:
Roeland Jago Douma 2017-08-23 15:40:35 +02:00
commit cdc5c1db43
No known key found for this signature in database
GPG Key ID: F941078878347C0C
238 changed files with 3903 additions and 7096 deletions

View File

@ -2,7 +2,7 @@
Please try to only report a bug if it happens with the latest version
The latest version can be seen by checking the ChangeLog: https://owncloud.org/changelog/desktop/
For support try: https://central.owncloud.org/c/help/desktop-file-sync
For support try: https://central.owncloud.org/c/desktop-client
--->

3
.gitmodules vendored
View File

@ -1,6 +1,3 @@
[submodule "doc/ocdoc"]
path = doc/ocdoc
url = https://github.com/nextcloud/documentation
[submodule "src/3rdparty/qtmacgoodies"]
path = src/3rdparty/qtmacgoodies
url = https://github.com/guruz/qtmacgoodies.git

View File

@ -191,6 +191,24 @@ add_definitions( -D__USE_MINGW_ANSI_STDIO=1 )
add_definitions( -DNOMINMAX )
endif( WIN32 )
include(QtVersionAbstraction)
setup_qt()
if (${Qt5Core_VERSION_MAJOR} EQUAL "5")
if (${Qt5Core_VERSION_MINOR} EQUAL "6" OR ${Qt5Core_VERSION_MINOR} GREATER 6)
else()
message(STATUS "If possible compile me with Qt 5.6 or higher.")
endif()
if (${Qt5Core_VERSION_MINOR} EQUAL "9" OR ${Qt5Core_VERSION_MINOR} GREATER 9)
else()
message(STATUS "For HTTP2 use Qt 5.9.2 or higher.")
endif()
endif()
message("Qt ${Qt5Core_VERSION} at ${Qt5Core_INCLUDE_DIRS}")
if (APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
endif()
# Handle Translations, pick all client_* files from trans directory.
file( GLOB TRANS_FILES ${CMAKE_SOURCE_DIR}/translations/client_*.ts)
set(TRANSLATIONS ${TRANS_FILES})

View File

@ -4,32 +4,62 @@ ChangeLog
version 2.4.0 (2017-0X-XX)
* OAuth2 authentication support
* Sharing: Add support for multiple public link shares (#5655)
* Sharing: Add option to copy/email direct links (#5627)
* Sharing: Add option to copy/email direct links (#5627, #5023)
* Sharing: Add option "show file listing" (#5837)
* Sharing: Show warning that links are public
* Sharing: Many UI improvements
* Sharing: Make "can edit" partially checked sometimes #5642
* Wizards: Never propose an existing folder for syncing (#5597)
* Wizard: Don't show last page anymore, go to settings directly (#5726)
* Settings Dialog: Display the user server avatar
* Selective Sync: Open sub folder context menu (#5596)
* Selective Sync: Skip excluded folders when reading db
* Selective Sync: SelectiveSync: Remove local files of unselected folder despite other modified files (#5783)
* Exclude list: remove .htaccess
* Detect maintenance mode (#4485)
* Selective Sync: Remove local files of unselected folder despite other modified files (#5783)
* Exclude list: remove .htaccess form list of excluded files
* Sync Issues: More functional error view including filters and conflicts #5516
* Discovery: Increase the MAX_DEPTH and show deep folders as ignored
* Downloads: Remove empty temporary if disk space full (#5746)
* Downloads: Re-trigger folder discovery on 404
* When creating explorer favorite use more specific windows functions (#5690)
* AccountSettings: Triggering log in re-ask about previously rejected certificates #5819
* Added owncloudcmd bandwidth limit parameter (#5707)
* AccountSettings: Sync with clean discovery on Ctrl-F6 (#5666)
* Dynamic size of chunks in chunked uploads for improved big file upload performance
* ShareDialog: Make "can edit" partially checked sometimes #5642
* Require Qt5
* Switch 3rdparty/json usage to Qt5's QJson (#5710)
* Sync: Dynamic sizing of chunks in chunked uploads for improved big file upload performance
* Sync: Introduce overall errors that are not tied to a file #5746
* Sync: Better messaging for 507 Insufficient Storage #5537
* Sync: Create conflicts by comparing the hash of files with identical mtime/size #5589
* Sync: Blacklist: Don't let errors become warnings #5516
* macOS: Finder sidebar icon #296
* Reduce memory usage
* Fix at least one memory leak
* Documentation improvements
* Logging improvements (with Qt logging categories), new --logdebug parameter
* Harmonize source code style with clang-format
* Crash fixes
* Test improvements
* Windows Overlays: Potential hang fixes
* Small UI layout fixes
* Maintenance Mode: Detect maintenance mode (#4485)
* Maintenance Mode: Add a 1 to 5 min reconnection delay #5872
* HTTP: Send a unique X-Request-ID with each request #5853
* HTTP: Support HTTP2 when built and running with Qt 5.9.x (Official packages still on Qt 5.6.x)
* owncloudcmd: Don't start if connection or auth fails #5692
* Overlays: Consider also the "shared by me" as shared (#4788)
* Switch 3rdparty/json usage to Qt5's QJson (#5710)
* OpenSSL: Don't require directly, only via Qt
* Remove iconv dependency, use Qt for file system locale encoding/decoding (emoji filename support on macOS)
version 2.3.3 (2017-07-XX)
* Chunking NG: Don't use old chunking on new DAV endpoint (#5855)
* Selective Sync: Skip excluded folders when reading DB, don't let them show errors (#5772)
* Settings: Make window bigger so Qt version is always visible (#5760)
* Share links: Show warning that public link shares are public (#5786)
* Downloads: Re-trigger folder discovery on HTTP 404 (#5799)
* Overlay Icons: Fix potential hangs on Windows
* SyncJournalDB: Don't use ._ as filename pattern if that does not work because of SMB storage settings (#5844)
* SyncJournalDB: Log reason for sqlite3 opening errors
* Switch Linux build also to Qt 5.6.2 (#5470)
* Stopped maintaining Qt 4 buildability
version 2.3.2 (2017-05-08)
* Fix more crashes (thanks to everyone submitting to our crash reporter!)

View File

@ -506,536 +506,6 @@
<key>UUID</key>
<string>7D7219B7-1897-48C3-8533-842BDEC46F71</string>
</dict>
<dict>
<key>PACKAGE_FILES</key>
<dict>
<key>DEFAULT_INSTALL_LOCATION</key>
<string>/</string>
<key>HIERARCHY</key>
<dict>
<key>CHILDREN</key>
<array>
<dict>
<key>CHILDREN</key>
<array>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>80</integer>
<key>PATH</key>
<string>Utilities</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
</array>
<key>GID</key>
<integer>80</integer>
<key>PATH</key>
<string>Applications</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>509</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>80</integer>
<key>PATH</key>
<string>Application Support</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Documentation</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Filesystems</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Frameworks</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Input Methods</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Internet Plug-Ins</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>LaunchAgents</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>LaunchDaemons</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>PreferencePanes</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Preferences</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>80</integer>
<key>PATH</key>
<string>Printers</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>PrivilegedHelperTools</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>QuickLook</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>QuickTime</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Screen Savers</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array>
<dict>
<key>CHILDREN</key>
<array>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Library/ScriptingAdditions/SyncStateFinder.osax/Contents</string>
<key>PATH_TYPE</key>
<integer>3</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>3</integer>
<key>UID</key>
<integer>0</integer>
</dict>
</array>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>SyncStateFinder.osax</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>2</integer>
<key>UID</key>
<integer>0</integer>
</dict>
</array>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>ScriptingAdditions</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>2</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Scripts</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Services</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Widgets</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
</array>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Library</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array>
<dict>
<key>CHILDREN</key>
<array>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Extensions</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
</array>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Library</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
</array>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>System</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<dict>
<key>CHILDREN</key>
<array>
<dict>
<key>CHILDREN</key>
<array/>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>Shared</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>1023</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
</array>
<key>GID</key>
<integer>80</integer>
<key>PATH</key>
<string>Users</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
</array>
<key>GID</key>
<integer>0</integer>
<key>PATH</key>
<string>/</string>
<key>PATH_TYPE</key>
<integer>0</integer>
<key>PERMISSIONS</key>
<integer>493</integer>
<key>TYPE</key>
<integer>1</integer>
<key>UID</key>
<integer>0</integer>
</dict>
<key>PAYLOAD_TYPE</key>
<integer>0</integer>
<key>VERSION</key>
<integer>2</integer>
</dict>
<key>PACKAGE_SCRIPTS</key>
<dict>
<key>POSTINSTALL_PATH</key>
<dict/>
<key>PREINSTALL_PATH</key>
<dict/>
<key>RESOURCES</key>
<array/>
</dict>
<key>PACKAGE_SETTINGS</key>
<dict>
<key>AUTHENTICATION</key>
<integer>1</integer>
<key>CONCLUSION_ACTION</key>
<integer>0</integer>
<key>IDENTIFIER</key>
<string>com.ownCloud.finderPlugin</string>
<key>LOCATION</key>
<integer>0</integer>
<key>NAME</key>
<string>Legacy Finder Plugin (OS X 10.9 or older)</string>
<key>OVERWRITE_PERMISSIONS</key>
<false/>
<key>VERSION</key>
<string>@MIRALL_VERSION_FULL@</string>
</dict>
<key>TYPE</key>
<integer>0</integer>
<key>UUID</key>
<string>39F61FCD-6EAA-4F3A-81C6-25E3F667DFB5</string>
</dict>
</array>
<key>PROJECT</key>
<dict>
@ -1103,49 +573,6 @@
<key>UUID</key>
<string>9647ADC0-BD53-4D7D-A561-73D383AACDE1</string>
</dict>
<dict>
<key>DESCRIPTION</key>
<array/>
<key>OPTIONS</key>
<dict>
<key>HIDDEN</key>
<false/>
<key>STATE</key>
<integer>1</integer>
</dict>
<key>PACKAGE_UUID</key>
<string>39F61FCD-6EAA-4F3A-81C6-25E3F667DFB5</string>
<key>REQUIREMENTS</key>
<array>
<dict>
<key>BEHAVIOR</key>
<integer>1</integer>
<key>DICTIONARY</key>
<dict>
<key>IC_REQUIREMENT_JAVASCRIPT_FUNCTION</key>
<string>olderOsx</string>
<key>IC_REQUIREMENT_JAVASCRIPT_PARAMETERS</key>
<array/>
</dict>
<key>IDENTIFIER</key>
<string>fr.whitebox.Packages.requirement.javascript</string>
<key>MESSAGE</key>
<array/>
<key>NAME</key>
<string>JavaScript</string>
<key>STATE</key>
<true/>
</dict>
</array>
<key>TITLE</key>
<array/>
<key>TOOLTIP</key>
<array/>
<key>TYPE</key>
<integer>0</integer>
<key>UUID</key>
<string>1D2C47E0-5FD3-4623-B934-1347C66782D0</string>
</dict>
</array>
<key>REMOVED</key>
<dict/>
@ -1450,18 +877,6 @@
<string>@CMAKE_INSTALL_DIR@</string>
</dict>
</dict>
<key>SHARED_GLOBAL_DATA</key>
<dict>
<key>IC_REQUIREMENT_JAVASCRIPT_SHARED_SOURCE_CODE</key>
<string>
function olderOsx() {
if(system.compareVersions(system.version.ProductVersion, '10.10') == -1) {
return true;
}
return false;
}
</string>
</dict>
<key>TYPE</key>
<integer>0</integer>
<key>VERSION</key>

View File

@ -3,7 +3,4 @@
# kill the old version. see issue #2044
killall @APPLICATION_EXECUTABLE@
# Unload the Finder plugin. see issue #2105
killall Finder
exit 0

View File

@ -8,7 +8,7 @@ ENV HOME /root
ENV REFRESHED_AT 20160421
RUN zypper --non-interactive --gpg-auto-import-keys refresh
RUN zypper --non-interactive --gpg-auto-import-keys ar http://download.opensuse.org/repositories/windows:/mingw/openSUSE_42.1/windows:mingw.repo
RUN zypper --non-interactive --gpg-auto-import-keys ar http://download.opensuse.org/repositories/windows:/mingw/openSUSE_Leap_42.1/windows:mingw.repo
RUN zypper --non-interactive --gpg-auto-import-keys ar http://download.opensuse.org/repositories/isv:ownCloud:toolchains:mingw:win32:2.3/openSUSE_Leap_42.1/isv:ownCloud:toolchains:mingw:win32:2.3.repo
RUN zypper --non-interactive --gpg-auto-import-keys install cmake make mingw32-cross-binutils mingw32-cross-cpp mingw32-cross-gcc \
mingw32-cross-gcc-c++ mingw32-cross-pkg-config mingw32-filesystem \

View File

@ -18,7 +18,7 @@ StrCpy $SEC_APPLICATION_DETAILS "A instalar o essencial de ${APPLICATION_NAME}."
StrCpy $OPTION_SECTION_SC_SHELL_EXT_SECTION "Integração para Windows Explorer"
StrCpy $OPTION_SECTION_SC_SHELL_EXT_DetailPrint "A instalar integração para Windows Explorer"
StrCpy $OPTION_SECTION_SC_START_MENU_SECTION "Atalho do progama no Menu Iniciar"
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "A adicionar o atalho de ${APPLICATION_NAME} ao Menu Inicial."
StrCpy $OPTION_SECTION_SC_START_MENU_DetailPrint "A adicionar o atalho de ${APPLICATION_NAME} no Menu Iniciar."
StrCpy $OPTION_SECTION_SC_DESKTOP_SECTION "Atalho da área de trabalho"
StrCpy $OPTION_SECTION_SC_DESKTOP_DetailPrint "A criar atalhos na área de trabalho"
StrCpy $OPTION_SECTION_SC_QUICK_LAUNCH_SECTION "Atalho de início rápido"

2
binary

@ -1 +1 @@
Subproject commit 1818b48380f4fc50d482b980e5ec0d347f896a70
Subproject commit 3425fab2c66118ffae3e3b16751e636ca71ee450

View File

@ -70,45 +70,64 @@ macro (KDE4_ADD_APP_ICON appsources pattern)
endif(PNG2ICO_EXECUTABLE AND WINDRES_EXECUTABLE)
endif(WIN32)
if (APPLE)
# first convert image to a tiff using the Mac OS X "sips" utility,
# then use tiff2icns to convert to an icon
find_program(SIPS_EXECUTABLE NAMES sips)
find_program(TIFF2ICNS_EXECUTABLE NAMES tiff2icns)
if (SIPS_EXECUTABLE AND TIFF2ICNS_EXECUTABLE)
file(GLOB_RECURSE files "${pattern}")
# we can only test for the 128-icon like that - we don't use patterns anymore
foreach (it ${files})
if (it MATCHES ".*128.*" )
set (_icon ${it})
endif (it MATCHES ".*128.*")
endforeach (it)
file(GLOB_RECURSE files "${pattern}")
file(MAKE_DIRECTORY ${appsources}.iconset)
if (_icon)
# first, get the basename of our app icon
add_custom_command(OUTPUT ${_outfilename}.icns ${outfilename}.tiff
COMMAND ${SIPS_EXECUTABLE} -s format tiff ${_icon} --out ${outfilename}.tiff
COMMAND ${TIFF2ICNS_EXECUTABLE} ${outfilename}.tiff ${_outfilename}.icns
DEPENDS ${_icon}
)
# List from:
# https://developer.apple.com/library/content/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Optimizing/Optimizing.html#//apple_ref/doc/uid/TP40012302-CH7-SW4
foreach (it ${files})
if (it MATCHES ".*icon-16.*")
configure_file(${it} ${appsources}.iconset/icon_16x16.png COPYONLY)
elseif (it MATCHES ".*icon-32.*")
configure_file(${it} ${appsources}.iconset/icon_16x16@2x.png COPYONLY)
configure_file(${it} ${appsources}.iconset/icon_32x32.png COPYONLY)
elseif (it MATCHES ".*icon-64.*")
configure_file(${it} ${appsources}.iconset/icon_32x32@2x.png COPYONLY)
elseif (it MATCHES ".*icon-128.*")
configure_file(${it} ${appsources}.iconset/icon_128x128.png COPYONLY)
elseif (it MATCHES ".*icon-256.*")
configure_file(${it} ${appsources}.iconset/icon_128x128@2x.png COPYONLY)
configure_file(${it} ${appsources}.iconset/icon_256x256.png COPYONLY)
elseif (it MATCHES ".*icon-512.*")
configure_file(${it} ${appsources}.iconset/icon_256x256@2x.png COPYONLY)
configure_file(${it} ${appsources}.iconset/icon_512x512.png COPYONLY)
elseif (it MATCHES ".*icon-1024.*")
configure_file(${it} ${appsources}.iconset/icon_512x512@2x.png COPYONLY)
endif()
endforeach (it)
# This will register the icon into the bundle
set(MACOSX_BUNDLE_ICON_FILE ${appsources}.icns)
# Copy the sidebar icons in the main app bundle for the FinderSync extension to pick.
# https://developer.apple.com/library/content/documentation/General/Conceptual/ExtensibilityPG/Finder.html#//apple_ref/doc/uid/TP40014214-CH15-SW15
foreach (it ${files})
if (it MATCHES ".*sidebar-16.*")
configure_file(${it} ${appsources}.iconset/sidebar_16x16.png COPYONLY)
elseif (it MATCHES ".*sidebar-18.*")
configure_file(${it} ${appsources}.iconset/sidebar_18x18.png COPYONLY)
elseif (it MATCHES ".*sidebar-32.*")
configure_file(${it} ${appsources}.iconset/sidebar_16x16@2x.png COPYONLY)
configure_file(${it} ${appsources}.iconset/sidebar_32x32.png COPYONLY)
elseif (it MATCHES ".*sidebar-36.*")
configure_file(${it} ${appsources}.iconset/sidebar_18x18@2x.png COPYONLY)
elseif (it MATCHES ".*sidebar-64.*")
configure_file(${it} ${appsources}.iconset/sidebar_32x32@2x.png COPYONLY)
endif()
endforeach (it)
# Append the icns file to the sources list so it will be a dependency to the
# main target
list(APPEND ${appsources} ${_outfilename}.icns)
add_custom_command(OUTPUT ${_outfilename}.icns
COMMAND echo === Building bundle icns with iconset:
COMMAND ls -1 ${appsources}.iconset
COMMAND iconutil -c icns -o ${_outfilename}.icns ${appsources}.iconset
DEPENDS ${files}
)
# Install the icon into the Resources dir in the bundle
set_source_files_properties(${_outfilename}.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
# This will register the icon into the bundle
set(MACOSX_BUNDLE_ICON_FILE ${appsources}.icns)
else(_icon)
# TODO - try to scale a non-128 icon...? Try to convert an SVG on the fly?
message(STATUS "Unable to find an 128x128 icon that matches pattern ${pattern} for variable ${appsources} - application will not have an application icon!")
endif(_icon)
# Append the icns file to the sources list so it will be a dependency to the
# main target
list(APPEND ${appsources} ${_outfilename}.icns)
else(SIPS_EXECUTABLE AND TIFF2ICNS_EXECUTABLE)
message(STATUS "Unable to find the sips and tiff2icns utilities - application will not have an application icon!")
endif(SIPS_EXECUTABLE AND TIFF2ICNS_EXECUTABLE)
# Install the icon into the Resources dir in the bundle
set_source_files_properties(${_outfilename}.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
endif(APPLE)
endmacro (KDE4_ADD_APP_ICON)

View File

@ -1,82 +0,0 @@
# - Try to find Iconv
# Once done this will define
#
# ICONV_FOUND - system has Iconv
# ICONV_INCLUDE_DIRS - the Iconv include directory
# ICONV_LIBRARIES - Link these to use Iconv
# ICONV_DEFINITIONS - Compiler switches required for using Iconv
#
# Copyright (c) 2013 Andreas Schneider <asn@cryptomilk.org>
#
# Redistribution and use is allowed according to the terms of the New
# BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
include(CheckIncludeFile)
include(CheckFunctionExists)
include(CheckLibraryExists)
include(CheckPrototypeDefinition)
find_path(ICONV_INCLUDE_DIR
NAMES
iconv.h sys/iconv.h
)
set(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR})
check_include_file(iconv.h HAVE_ICONV_H)
check_include_file(sys/iconv.h HAVE_SYS_ICONV_H)
set(CMAKE_REQUIRED_INCLUDES)
find_library(ICONV_LIBRARY
NAMES
iconv
libiconv
PATHS
)
if (ICONV_LIBRARY)
get_filename_component(_ICONV_NAME ${ICONV_LIBRARY} NAME)
get_filename_component(_ICONV_PATH ${ICONV_LIBRARY} PATH)
check_library_exists(${_ICONV_NAME} iconv ${_ICONV_PATH} HAVE_ICONV)
else()
check_function_exists(iconv HAVE_ICONV)
endif()
if (HAVE_ICONV_H OR HAVE_SYS_ICONV_H)
if (HAVE_ICONV_H)
set(_ICONV_PROTO_INCLUDE "iconv.h")
endif (HAVE_ICONV_H)
if (HAVE_SYS_ICONV_H)
set(_ICONV_PROTO_INCLUDE "sys/iconv.h")
endif (HAVE_SYS_ICONV_H)
set(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR})
check_prototype_definition(iconv
"size_t iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)"
"-1"
${_ICONV_PROTO_INCLUDE}
HAVE_ICONV_CONST)
set(CMAKE_REQUIRED_INCLUDES)
endif (HAVE_ICONV_H OR HAVE_SYS_ICONV_H)
set(ICONV_INCLUDE_DIRS
${ICONV_INCLUDE_DIR}
)
if (ICONV_LIBRARY)
set(ICONV_LIBRARIES
${ICONV_LIBRARIES}
${ICONV_LIBRARY}
)
endif (ICONV_LIBRARY)
include(FindPackageHandleStandardArgs)
if (ICONV_LIBRARIES)
find_package_handle_standard_args(Iconv DEFAULT_MSG ICONV_LIBRARIES ICONV_INCLUDE_DIRS)
else()
find_package_handle_standard_args(Iconv DEFAULT_MSG ICONV_INCLUDE_DIRS)
endif()
# show the ICONV_INCLUDE_DIRS and ICONV_LIBRARIES variables only in the advanced view
mark_as_advanced(ICONV_INCLUDE_DIRS ICONV_LIBRARIES)

View File

@ -18,10 +18,6 @@ include(DefineInstallationPaths)
include(MacroAddPlugin)
include(MacroCopyFile)
if (NOT WIN32)
find_package(Iconv)
endif (NOT WIN32)
find_package(SQLite3 3.8.0 REQUIRED)
include(ConfigureChecks.cmake)

View File

@ -1,5 +1,2 @@
if ( NOT WIN32 )
option(WITH_ICONV "Build csync with iconv support" ON)
endif()
option(UNIT_TESTING "Build with unit tests" OFF)
option(MEM_NULL_TESTS "Enable NULL memory testing" OFF)

View File

@ -9,19 +9,14 @@
#cmakedefine HAVE_CLOCK_GETTIME
#cmakedefine WITH_LOG4C 1
#cmakedefine WITH_ICONV 1
#cmakedefine HAVE_ARGP_H 1
#cmakedefine HAVE_ICONV_H 1
#cmakedefine HAVE_SYS_ICONV_H 1
#cmakedefine HAVE_TIMEGM 1
#cmakedefine HAVE_STRERROR_R 1
#cmakedefine HAVE_UTIMES 1
#cmakedefine HAVE_LSTAT 1
#cmakedefine HAVE_FNMATCH 1
#cmakedefine HAVE_ICONV 1
#cmakedefine HAVE_ICONV_CONST 1
#cmakedefine HAVE___MINGW_ASPRINTF 1
#cmakedefine HAVE_ASPRINTF 1

View File

@ -28,11 +28,6 @@ set(CSYNC_LINK_LIBRARIES
${SQLITE3_LIBRARIES}
)
if(HAVE_ICONV AND WITH_ICONV)
list(APPEND CSYNC_PRIVATE_INCLUDE_DIRS ${ICONV_INCLUDE_DIR})
list(APPEND CSYNC_LINK_LIBRARIES ${ICONV_LIBRARIES})
endif()
# Specific option for builds tied to servers that do not support renaming extensions
set(NO_RENAME_EXTENSION 0 CACHE BOOL "Do not issue rename if the extension changes")
if(NO_RENAME_EXTENSION)

View File

@ -33,13 +33,6 @@
#include <sys/types.h>
#include <stdbool.h>
#ifdef HAVE_ICONV_H
#include <iconv.h>
#endif
#ifdef HAVE_SYS_ICONV_H
#include <sys/iconv.h>
#endif
#include "c_lib.h"
#include "csync_private.h"
#include "csync_exclude.h"
@ -569,10 +562,6 @@ int csync_destroy(CSYNC *ctx) {
SAFE_FREE(ctx->local.uri);
SAFE_FREE(ctx->error_string);
#ifdef WITH_ICONV
c_close_iconv();
#endif
SAFE_FREE(ctx);
return rc;
@ -626,19 +615,6 @@ const char *csync_get_status_string(CSYNC *ctx)
return csync_vio_get_status_string(ctx);
}
#ifdef WITH_ICONV
int csync_set_iconv_codec(const char *from)
{
c_close_iconv();
if (from != NULL) {
c_setup_iconv(from);
}
return 0;
}
#endif
void csync_request_abort(CSYNC *ctx)
{
if (ctx != NULL) {

View File

@ -100,7 +100,8 @@ enum csync_status_codes_e {
CSYNC_STATUS_INVALID_CHARACTERS,
CSYNC_STATUS_INDIVIDUAL_STAT_FAILED,
CSYNC_STATUS_FORBIDDEN,
CSYNC_STATUS_INDIVIDUAL_TOO_DEEP
CSYNC_STATUS_INDIVIDUAL_TOO_DEEP,
CSYNC_STATUS_INDIVIDUAL_IS_CONFLICT_FILE
};
typedef enum csync_status_codes_e CSYNC_STATUS;
@ -479,17 +480,6 @@ int OCSYNC_EXPORT csync_walk_remote_tree(CSYNC *ctx, csync_treewalk_visit_func *
*/
const char OCSYNC_EXPORT *csync_get_status_string(CSYNC *ctx);
#ifdef WITH_ICONV
/**
* @brief Set iconv source codec for filenames.
*
* @param from Source codec.
*
* @return 0 on success, or an iconv error number.
*/
int OCSYNC_EXPORT csync_set_iconv_codec(const char *from);
#endif
/**
* @brief Aborts the current sync run as soon as possible. Can be called from another thread.
*

View File

@ -293,6 +293,13 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const ch
}
#endif
/* We create a desktop.ini on Windows for the sidebar icon, make sure we don't sync them. */
rc = csync_fnmatch("Desktop.ini", bname, 0);
if (rc == 0) {
match = CSYNC_FILE_SILENTLY_EXCLUDED;
goto out;
}
rc = csync_fnmatch(".owncloudsync.log*", bname, 0);
if (rc == 0) {
match = CSYNC_FILE_SILENTLY_EXCLUDED;
@ -302,7 +309,7 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const ch
/* Always ignore conflict files, not only via the exclude list */
rc = csync_fnmatch("*_conflict-*", bname, 0);
if (rc == 0) {
match = CSYNC_FILE_SILENTLY_EXCLUDED;
match = CSYNC_FILE_EXCLUDE_CONFLICT;
goto out;
}
@ -313,7 +320,7 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(c_strlist_t *excludes, const ch
}
rc = csync_fnmatch(conflict, path, 0);
if (rc == 0) {
match = CSYNC_FILE_SILENTLY_EXCLUDED;
match = CSYNC_FILE_EXCLUDE_CONFLICT;
SAFE_FREE(conflict);
goto out;
}

View File

@ -32,7 +32,8 @@ enum csync_exclude_type_e {
CSYNC_FILE_EXCLUDE_TRAILING_SPACE,
CSYNC_FILE_EXCLUDE_LONG_FILENAME,
CSYNC_FILE_EXCLUDE_HIDDEN,
CSYNC_FILE_EXCLUDE_STAT_FAILED
CSYNC_FILE_EXCLUDE_STAT_FAILED,
CSYNC_FILE_EXCLUDE_CONFLICT
};
typedef enum csync_exclude_type_e CSYNC_EXCLUDE_TYPE;

View File

@ -42,17 +42,6 @@
#include "csync.h"
#include "csync_misc.h"
#ifdef WITH_ICONV
#include <iconv.h>
#endif
#ifdef HAVE_ICONV_H
#include <iconv.h>
#endif
#ifdef HAVE_SYS_ICONV_H
#include <sys/iconv.h>
#endif
#include "csync_macros.h"
/**
@ -130,12 +119,6 @@ struct csync_s {
} remote;
#if defined(HAVE_ICONV) && defined(WITH_ICONV)
struct {
iconv_t iconv_cd;
} options;
#endif
/* replica we are currently walking */
enum csync_replica_e current;

View File

@ -469,6 +469,8 @@ out:
st->error_status = CSYNC_STATUS_INDIVIDUAL_EXCLUDE_HIDDEN;
} else if (excluded == CSYNC_FILE_EXCLUDE_STAT_FAILED) {
st->error_status = CSYNC_STATUS_INDIVIDUAL_STAT_FAILED;
} else if (excluded == CSYNC_FILE_EXCLUDE_CONFLICT) {
st->error_status = CSYNC_STATUS_INDIVIDUAL_IS_CONFLICT_FILE;
}
}
}

View File

@ -1,14 +1,10 @@
project(cstdlib C)
project(cstdlib)
set(CSTDLIB_PUBLIC_INCLUDE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}
CACHE INTERNAL "cstdlib public include directories"
)
set(CSTDLIB_PRIVATE_INCLUDE_DIRS
${ICONV_INCLUDE_DIR}
)
set(CSTDLIB_LIBRARY
cstdlib
CACHE INTERNAL "cstdlib library"
@ -24,6 +20,7 @@ set(cstdlib_SRCS
c_rbtree.c
c_string.c
c_time.c
c_utf8.cc
)
if(NOT HAVE_ASPRINTF AND NOT HAVE___MINGW_ASPRINTF)
@ -34,12 +31,12 @@ endif()
include_directories(
${CSTDLIB_PUBLIC_INCLUDE_DIRS}
${CSTDLIB_PRIVATE_INCLUDE_DIRS}
)
add_library(${CSTDLIB_LIBRARY} STATIC ${cstdlib_SRCS})
if(NOT WIN32)
add_definitions( -fPIC )
qt5_use_modules(${CSTDLIB_LIBRARY} Core)
endif()
if(NOT HAVE_FNMATCH AND WIN32)
# needed for PathMatchSpec for our fnmatch replacement

View File

@ -159,13 +159,6 @@ typedef char mbchar_t;
#define _tgetcwd getcwd
#endif
#ifdef WITH_ICONV
/** @internal */
int c_setup_iconv(const char* to);
/** @internal */
int c_close_iconv(void);
#endif
/* FIXME: Implement TLS for OS X */
#if defined(__GNUC__) && !defined(__APPLE__)
# define CSYNC_THREAD __thread

View File

@ -40,97 +40,6 @@
#include <windows.h>
#endif
#if defined(HAVE_ICONV) && defined(WITH_ICONV)
# ifdef HAVE_ICONV_H
# include <iconv.h>
# endif
# ifdef HAVE_SYS_ICONV_H
# include <sys/iconv.h>
# endif
typedef struct {
iconv_t to;
iconv_t from;
} iconv_conversions;
CSYNC_THREAD iconv_conversions _iconvs = { NULL, NULL };
int c_setup_iconv(const char* to) {
_iconvs.to = iconv_open(to, "UTF-8");
_iconvs.from = iconv_open("UTF-8", to);
if (_iconvs.to == (iconv_t)-1 || _iconvs.from == (iconv_t)-1)
return -1;
return 0;
}
int c_close_iconv() {
int ret_to = 0;
int ret_from = 0;
if( _iconvs.to != (iconv_t) NULL ) {
ret_to = iconv_close(_iconvs.to);
}
if( _iconvs.from != (iconv_t) NULL ) {
ret_from = iconv_close(_iconvs.from);
}
if (ret_to == -1 || ret_from == -1)
return -1;
_iconvs.to = (iconv_t) 0;
_iconvs.from = (iconv_t) 0;
return 0;
}
enum iconv_direction { iconv_from_native, iconv_to_native };
static char *c_iconv(const char* str, enum iconv_direction dir)
{
#ifdef HAVE_ICONV_CONST
const char *in = str;
#else
char *in = discard_const(str);
#endif
size_t size;
size_t outsize;
char *out;
char *out_in;
size_t ret;
if (str == NULL) {
return NULL;
}
if(_iconvs.from == NULL && _iconvs.to == NULL) {
#ifdef __APPLE__
c_setup_iconv("UTF-8-MAC");
#else
return c_strdup(str);
#endif
}
size = strlen(in);
outsize = size*2;
out = c_malloc(outsize);
out_in = out;
if (dir == iconv_to_native) {
ret = iconv(_iconvs.to, &in, &size, &out, &outsize);
} else {
ret = iconv(_iconvs.from, &in, &size, &out, &outsize);
}
if (ret == (size_t)-1) {
SAFE_FREE(out_in);
return NULL;
}
return out_in;
}
#endif /* defined(HAVE_ICONV) && defined(WITH_ICONV) */
int c_strncasecmp(const char *a, const char *b, size_t n) {
#ifdef _WIN32
return _strnicmp(a, b, n);
@ -258,70 +167,3 @@ void c_strlist_destroy(c_strlist_t *strlist) {
SAFE_FREE(strlist->vector);
SAFE_FREE(strlist);
}
/* Convert a wide multibyte String to UTF8 */
char* c_utf8_from_locale(const mbchar_t *wstr)
{
char *dst = NULL;
#ifdef _WIN32
char *mdst = NULL;
int size_needed;
size_t len;
#endif
if (wstr == NULL) {
return NULL;
}
#ifdef _WIN32
len = wcslen(wstr);
/* Call once to get the required size. */
size_needed = WideCharToMultiByte(CP_UTF8, 0, wstr, len, NULL, 0, NULL, NULL);
if (size_needed > 0) {
mdst = c_malloc(size_needed + 1);
memset(mdst, 0, size_needed + 1);
WideCharToMultiByte(CP_UTF8, 0, wstr, len, mdst, size_needed, NULL, NULL);
dst = mdst;
}
#else
#ifdef WITH_ICONV
dst = c_iconv(wstr, iconv_from_native);
#else
dst = (char*) wstr;
#endif
#endif
return dst;
}
/* Convert a an UTF8 string to multibyte */
mbchar_t* c_utf8_string_to_locale(const char *str)
{
mbchar_t *dst = NULL;
#ifdef _WIN32
size_t len;
int size_needed;
#endif
if (str == NULL ) {
return NULL;
}
#ifdef _WIN32
len = strlen(str);
size_needed = MultiByteToWideChar(CP_UTF8, 0, str, len, NULL, 0);
if (size_needed > 0) {
int size_char = (size_needed + 1) * sizeof(mbchar_t);
dst = c_malloc(size_char);
memset((void*)dst, 0, size_char);
MultiByteToWideChar(CP_UTF8, 0, str, -1, dst, size_needed);
}
#else
#ifdef WITH_ICONV
dst = c_iconv(str, iconv_to_native);
#else
dst = (_TCHAR*) str;
#endif
#endif
return dst;
}

View File

@ -194,8 +194,6 @@ void c_strlist_destroy(c_strlist_t *strlist);
*/
mbchar_t* c_utf8_string_to_locale(const char *wstr);
#if defined(_WIN32) || defined(WITH_ICONV)
/**
* @brief Free buffer malloced by c_utf8_from_locale or c_utf8_to_locale().
*
@ -214,9 +212,7 @@ mbchar_t* c_utf8_string_to_locale(const char *wstr);
*
*/
#define c_free_locale_string(x) SAFE_FREE(x)
#else
#define c_free_locale_string(x) (void)x
#endif
/**
* }@

104
csync/src/std/c_utf8.cc Normal file
View File

@ -0,0 +1,104 @@
/*
* cynapses libc functions
*
* Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
* Copyright (c) 2012-2013 by Klaas Freitag <freitag@owncloud.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config_csync.h"
#ifdef _WIN32
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <sys/types.h>
#include <wchar.h>
#include <windows.h>
#else
#include <QtCore/QTextCodec>
#include <QtCore/QFile>
#endif
extern "C" {
#include "c_alloc.h"
#include "c_string.h"
/* Convert a locale String to UTF8 */
char* c_utf8_from_locale(const mbchar_t *wstr)
{
if (wstr == NULL) {
return NULL;
}
#ifdef _WIN32
char *dst = NULL;
char *mdst = NULL;
int size_needed;
size_t len;
len = wcslen(wstr);
/* Call once to get the required size. */
size_needed = WideCharToMultiByte(CP_UTF8, 0, wstr, len, NULL, 0, NULL, NULL);
if (size_needed > 0) {
mdst = (char*)c_malloc(size_needed + 1);
memset(mdst, 0, size_needed + 1);
WideCharToMultiByte(CP_UTF8, 0, wstr, len, mdst, size_needed, NULL, NULL);
dst = mdst;
}
return dst;
#else
QTextDecoder dec(QTextCodec::codecForLocale());
QString s = dec.toUnicode(wstr, qstrlen(wstr));
if (s.isEmpty() || dec.hasFailure()) {
/* Conversion error: since we can't report error from this function, just return the original
string. We take care of invalid utf-8 in SyncEngine::treewalkFile */
return c_strdup(wstr);
}
#ifdef __APPLE__
s = s.normalized(QString::NormalizationForm_C);
#endif
return c_strdup(std::move(s).toUtf8().constData());
#endif
}
/* Convert a an UTF8 string to locale */
mbchar_t* c_utf8_string_to_locale(const char *str)
{
if (str == NULL ) {
return NULL;
}
#ifdef _WIN32
mbchar_t *dst = NULL;
size_t len;
int size_needed;
len = strlen(str);
size_needed = MultiByteToWideChar(CP_UTF8, 0, str, len, NULL, 0);
if (size_needed > 0) {
int size_char = (size_needed + 1) * sizeof(mbchar_t);
dst = (mbchar_t*)c_malloc(size_char);
memset((void*)dst, 0, size_char);
MultiByteToWideChar(CP_UTF8, 0, str, -1, dst, size_needed);
}
return dst;
#else
return c_strdup(QFile::encodeName(QString::fromUtf8(str)));
#endif
}
}

View File

@ -115,7 +115,7 @@ int csync_vio_stat(CSYNC *ctx, const char *uri, csync_vio_file_stat_t *buf) {
case LOCAL_REPLICA:
rc = csync_vio_local_stat(uri, buf);
if (rc < 0) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Local stat failed, errno %d", errno);
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Local stat failed, errno %d for %s", errno, uri);
}
break;
default:

View File

@ -113,9 +113,9 @@ static void check_csync_excluded(void **state)
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
rc = csync_excluded_no_ctx(csync->excludes, ".kde/share/config/kwin.eventsrc", CSYNC_FTW_TYPE_FILE);
assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
rc = csync_excluded_no_ctx(csync->excludes, ".htaccess/cache-maximegalon/cache1.txt", CSYNC_FTW_TYPE_FILE);
rc = csync_excluded_no_ctx(csync->excludes, ".directory/cache-maximegalon/cache1.txt", CSYNC_FTW_TYPE_FILE);
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
rc = csync_excluded_no_ctx(csync->excludes, "mozilla/.htaccess", CSYNC_FTW_TYPE_DIR);
rc = csync_excluded_no_ctx(csync->excludes, "mozilla/.directory", CSYNC_FTW_TYPE_DIR);
assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
/*

View File

@ -52,6 +52,13 @@ static void statedb_create_metadata_table(sqlite3 *db)
rc = sqlite3_exec(db, sql, NULL, NULL, NULL);
//const char *msg = sqlite3_errmsg(db);
assert_int_equal( rc, SQLITE_OK );
sql = "CREATE TABLE IF NOT EXISTS checksumtype("
"id INTEGER PRIMARY KEY,"
"name TEXT UNIQUE"
");";
rc = sqlite3_exec(db, sql, NULL, NULL, NULL);
assert_int_equal( rc, SQLITE_OK );
}
}

View File

@ -29,30 +29,12 @@
static void setup(void **state)
{
int rc = 0;
(void) state; /* unused */
#ifdef HAVE_ICONV
#ifdef __APPLE__
/* this test only works on apple because linux does not know the
* UTF-8-MAC encoding that we use here. */
rc = c_setup_iconv("UTF-8-MAC");
#endif
#endif
assert_int_equal(rc, 0);
}
static void teardown(void **state)
{
int rc = 0;
(void) state; /* unused */
#ifdef HAVE_ICONV
// this must never crash
rc = c_close_iconv();
#endif
assert_int_equal(rc, 0);
}
static void check_iconv_to_native_normalization(void **state)

View File

@ -294,15 +294,12 @@ sub localCleanup($)
system( "rm -rf $dir" );
}
# parameter: An optional full url to the owncloud sync dir.
# parameter: the expected return code
sub csync( ;$ )
{
my ($aurl) = @_;
my $expected = $_[0] // 0;
my $url = testDirUrl();
if( $aurl ) {
$url = $aurl;
}
if( $url =~ /^https:/ ) {
$url =~ s#^https://##; # Remove the leading http://
$url = "ownclouds://$user:$passwd@". $url;
@ -317,7 +314,8 @@ sub csync( ;$ )
my $cmd = "LD_LIBRARY_PATH=$ld_libpath $csync $args $localDir $url";
print "Starting: $cmd\n";
system( $cmd ) == 0 or die("CSync died!\n");
my $result = system( $cmd );
$result == ($expected << 8) or die("Wrong csync return code or crash! $result\n");
}
#

View File

@ -79,7 +79,8 @@ printInfo("Add a file in a read only directory");
system( "echo \"Hello World\" >> /tmp/kernelcrash.txt" );
put_to_dir( '/tmp/kernelcrash.txt', 'test_stat' );
csync();
# Sync failed, can't download file to readonly dir
csync(1);
assert( ! -e localDir().'test_stat/kernelcrash' );

View File

@ -102,10 +102,6 @@ system("echo '__modified' > ". localDir() . "normalDirectory_PERM_CKDNV_/canBeMo
system("echo '__modified_' > ". localDir() . "readonlyDirectory_PERM_M_/canBeModified_PERM_W_.data");
#5. Create a new file in a read only folder
# (they should not be uploaded)
createLocalFile( localDir() . "readonlyDirectory_PERM_M_/newFile_PERM_WDNV_.data", 105 );
#6. Create a new file in a read only folder
# (should be uploaded)
createLocalFile( localDir() . "normalDirectory_PERM_CKDNV_/newFile_PERM_WDNV_.data", 106 );
@ -113,7 +109,6 @@ createLocalFile( localDir() . "normalDirectory_PERM_CKDNV_/newFile_PERM_WDNV_.da
csync();
assertCsyncJournalOk(localDir());
#1.
# File should be recovered
assert( -e localDir(). 'normalDirectory_PERM_CKDNV_/cannotBeRemoved_PERM_WVN_.data' );
@ -139,6 +134,23 @@ system("rm " . localDir().'readonlyDirectory_PERM_M_/canotBeModified_PERM_DVN__c
#4. File should be updated, that's tested by assertLocalAndRemoteDir
#5.
# the file should be in the server and local
assert( -e localDir() . "normalDirectory_PERM_CKDNV_/newFile_PERM_WDNV_.data" );
### Both side should still be the same
assertLocalAndRemoteDir( '', 0);
# Next test
#6. Create a new file in a read only folder
# (they should not be uploaded)
createLocalFile( localDir() . "readonlyDirectory_PERM_M_/newFile_PERM_WDNV_.data", 105 );
# error: can't upload to readonly
csync(1);
assertCsyncJournalOk(localDir());
#6.
# The file should not exist on the remote
# TODO: test that the file is NOT on the server
# but still be there
@ -146,11 +158,6 @@ assert( -e localDir() . "readonlyDirectory_PERM_M_/newFile_PERM_WDNV_.data" );
# remove it so assertLocalAndRemoteDir succeed.
unlink(localDir() . "readonlyDirectory_PERM_M_/newFile_PERM_WDNV_.data");
#6.
# the file should be in the server and local
assert( -e localDir() . "normalDirectory_PERM_CKDNV_/newFile_PERM_WDNV_.data" );
### Both side should still be the same
assertLocalAndRemoteDir( '', 0);
@ -207,7 +214,8 @@ system("mv " . localDir().'readonlyDirectory_PERM_M_/subdir_PERM_CK_ ' . localDi
#2. move a directory from read to read only (move the directory from previous step)
system("mv " . localDir().'normalDirectory_PERM_CKDNV_/subdir_PERM_CKDNV_ ' . localDir().'readonlyDirectory_PERM_M_/moved_PERM_CK_' );
csync();
# error: can't upload to readonly!
csync(1);
assertCsyncJournalOk(localDir());
#1.

View File

@ -54,7 +54,8 @@ createLocalFile( $tmpdir . "test.dat", 170 );
createRemoteDir( "dir" );
glob_put( "$tmpdir/*", "dir" );
csync();
# can't download these
csync(1);
# Check that only one of the two file was synced.
# The one that exist here is undefined, the current implementation will take the
@ -76,7 +77,8 @@ printInfo( "Renaming one file to the same name as another one with different cas
moveRemoteFile( 'dir/Hello.dat', 'dir/NORMAL.dat');
moveRemoteFile( 'dir/test.dat', 'dir/TEST.dat');
csync();
# can't download these
csync(1);
# Hello -> NORMAL should not have do the move since the case conflict
assert( -e localDir() . 'dir/Hello.dat' );
@ -87,13 +89,16 @@ assert( -e localDir() . 'dir/Normal.dat' );
assert( -e localDir() . 'dir/TEST.dat' );
assert( !-e localDir() . 'dir/test.dat' );
# undo the change that causes the sync fail
moveRemoteFile( 'dir/NORMAL.dat', 'dir/Hello.dat');
printInfo( "Another directory with the same name but different casing is created" );
createRemoteDir( "DIR" );
glob_put( "$tmpdir/*", "DIR" );
glob_put( "$tmpdir/HELLO.dat", "DIR" );
csync();
# can't download dirs
csync(1);
assert( !-e localDir() . 'DIR' );
@ -107,7 +112,6 @@ csync();
# now DIR was fetched
assert( -e localDir() . 'DIR' );
assert( -e localDir() . 'DIR/HELLO.dat' );
assert( !-e localDir() . 'DIR/Hello.dat' );
assert( !-e localDir() . 'dir' );
# dir/NORMAL.dat is still on the server
@ -125,7 +129,8 @@ createLocalFile( $tmpdir2 . "file.dat", 33 );
createRemoteDir( "parallel" );
glob_put( "$tmpdir2/*", "parallel" );
csync();
# again, can't download both
csync(1);
# only one file must exist
assert( (!-e localDir() . 'parallel/FILE.dat' ) or (!-e localDir() . 'parallel/file.dat') );

View File

@ -434,7 +434,7 @@ static void check_readdir_bigunicode(void **state)
assert_int_equal(rc, 0);
SAFE_FREE(p);
const char *t1 = "goodone/ugly\xEF\xBB\xBF\x32" ".txt";
const char *t1 = "goodone/ugly\xEF\xBB\xBF\x32" ".txt"; // file with encoding error
asprintf( &p, "%s/%s", CSYNC_TEST_DIR, t1 );
rc = _tmkdir(p, MKDIR_MASK);
SAFE_FREE(p);
@ -444,18 +444,10 @@ static void check_readdir_bigunicode(void **state)
int files_cnt = 0;
traverse_dir(state, CSYNC_TEST_DIR, &files_cnt);
const char *expected_result = "<DIR> C:/tmp/csync_test/goodone"
#ifndef __APPLE__
// On Mac, iconv will not return some files with fancy unicode.
// Linux is not so picky about it and return everything and let the sync engine deal with it.
"<DIR> C:/tmp/csync_test/goodone/ugly\xEF\xBB\xBF\x32" ".txt"
#endif
;
assert_string_equal( sv->result, expected_result);
#ifdef __APPLE__
// Bad one is recognized though.. !
assert_string_equal( sv->ignored_dir, CSYNC_TEST_DIR "/goodone/" "ugly\xEF\xBB\xBF\x32" ".txt");
#endif
assert_int_equal(files_cnt, 0);
}

View File

@ -30,10 +30,10 @@ you the exact sources from which the binary packages are built. These are
hosted on the `ownCloud repository from OBS`_. Go to the `Index of
repositories`_ to see all the Linux client repos.
1. At the `bottom of the page for each distribution
1. The source RPMs for CentOS, RHEL, Fedora, SLES, and openSUSE are at the `bottom of the page for each distribution
<https://software.opensuse.org/download/package?project=isv:ownCloud:desktop&
package=owncloud-client>`_ is a "Grab binary packages directly" section.
These contain source RPMs for CentOS, RHEL, Fedora, SLES, and openSUSE.
package=owncloud-client>`
the sources for DEB and Ubuntu based distributions are at e.g. http://download.opensuse.org/repositories/isv:/ownCloud:/desktop/Ubuntu_16.04/
To get the .deb source packages add the source
repo for your Debian or Ubuntu version, like this example for Debian 8
@ -120,6 +120,7 @@ follow `Windows Installer Build (Cross-Compile)`_ instead.
* Make sure that you have CMake_ and Git_.
* Download the Qt_ MinGW package. You will use the MinGW version bundled with it.
* Download an `OpenSSL Windows Build`_ (the non-"Light" version)
2. Get the QtKeychain_ sources as well as the latest versions of the ownCloud client
from Git as follows::
@ -129,10 +130,11 @@ follow `Windows Installer Build (Cross-Compile)`_ instead.
3. Open the Qt MinGW shortcut console from the Start Menu
4. Make sure that your qtkeychain source directories are in your PATH. This will
allow CMake to find the library and headers, as well as allow the ownCloud
client to find the DLLs at runtime::
4. Make sure that OpenSSL's ``bin`` directory as well as your qtkeychain source
directories are in your PATH. This will allow CMake to find the library and
headers, as well as allow the ownCloud client to find the DLLs at runtime::
set PATH=C:\<OpenSSL Install Dir>\bin;%PATH%
set PATH=C:\<qtkeychain Clone Dir>;%PATH%
5. Build qtkeychain **directly in the source directory** so that the DLL is built
@ -277,6 +279,7 @@ The following are known cmake parameters:
.. _Git: http://git-scm.com
.. _MacPorts: http://www.macports.org
.. _Homebrew: http://mxcl.github.com/homebrew/
.. _OpenSSL Windows Build: http://slproweb.com/products/Win32OpenSSL.html
.. _Qt: http://www.qt.io/download
.. _Microsoft Authenticode: https://msdn.microsoft.com/en-us/library/ie/ms537361%28v=vs.85%29.aspx
.. _QtKeychain: https://github.com/frankosterfeld/qtkeychain

View File

@ -48,9 +48,9 @@ copyright = u'2013-2016, The ownCloud developers'
# built documents.
#
# The short X.Y version.
version = '2.3.0'
version = '2.4.0'
# The full version, including alpha/beta/rc tags.
release = '2.3.0'
release = '2.4.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@ -190,7 +190,9 @@ The Activity window contains the log of your recent activities, organized over
three tabs: **Server Activities**, which includes new shares and files
downloaded and deleted, **Sync Protocol**, which displays local activities such
as which local folders your files went into, and **Not Synced** shows errors
such as files not synced.
such as files not synced. Double clicking an entry pointing to an existing
file in **Server Activities** or **Sync Protocol** will open the folder containing
the file and highlight it.
.. figure:: images/client-8.png
:alt: Activity windows logs all server and client activities.

@ -1 +0,0 @@
Subproject commit 2fdd8b2833ea1db7da08a61afda665eb6ecaa017

View File

@ -1,34 +0,0 @@
:orphan:
owncloud(1)
-----------
SYNOPSIS
========
*owncloud* [`OPTIONS`...]
DESCRIPTION
===========
The ownCloud Client is a file synchronization desktop utility. It synchronizes files on your local computer, tablet, or handheld device with an ownCloud Server. If you make a change to the files on one device, the change is propagated to all other synchronized devices using the desktop synchronization clients.
Normally, you start the client by clicking on the desktop icon or by starting it from the client application menu. After starting, an ownCloud icon appears in the computer system tray or on your tablet or handheld device.
Options
=======
.. include:: options.rst
Config File
===========
.. include:: conffile.rst
BUGS
====
Please report bugs at https://github.com/owncloud/client/issues.
SEE ALSO
========
:manpage:`owncloudcmd(1)`

View File

@ -1,98 +0,0 @@
:orphan:
owncloudcmd(1)
--------------
SYNOPSIS
========
*owncloudcmd* [`OPTIONS`...] sourcedir owncloudurl
DESCRIPTION
===========
owncloudcmd is the command line tool used for the ownCloud file synchronization
desktop utility.
Contrary to the :manpage:`owncloud(1)` GUI client, `owncloudcmd` only performs
a single sync run and then exits. In so doing, `owncloudcmd` replaces the
`ocsync` binary used for the same purpose in earlier releases.
A *sync run* synchronizes a single local directory using a WebDAV share on a
remote ownCloud server.
To invoke the command line client, provide the local and the remote repository:
The first parameter is the local directory. The second parameter is
the server URL.
.. note:: Prior to the 1.6 release of owncloudcmd, the tool only accepted
``owncloud://`` or ``ownclouds://`` in place of ``http://`` and ``https://`` as
a scheme. See ``Examples`` for details.
OPTIONS
=======
``--user``, ``-u`` ``[user]``
Use ``user`` as the login name.
``--password``, ``-p`` ``[password]``
Use ``password`` as the password.
``-n``
Use ``netrc (5)`` for login.
``--non-interactive``
Do not prompt for questions.
``--silent``, ``--s``
Inhibits verbose log output.
``--trust``
Trust any SSL certificate, including invalid ones.
``--httpproxy http://[user@pass:]<server>:<port>``
Uses ``server`` as HTTP proxy.
``--nonshib``
Uses Non Shibboleth WebDAV Authentication
``--davpath [path]``
Overrides the WebDAV Path with ``path``
``--exclude [file]``
Exclude list file
``--unsyncedfolders [file]``
File containing the list of un-synced folders (selective sync)
``--max-sync-retries [n]``
Retries maximum n times (defaults to 3)
``-h``
Sync hidden files,do not ignore them
Example
=======
To synchronize the ownCloud directory ``Music`` to the local directory ``media/music``
through a proxy listening on port ``8080`` on the gateway machine ``192.168.178.1``,
the command line would be::
$ owncloudcmd --httpproxy http://192.168.178.1:8080 \
$HOME/media/music \
https://server/owncloud/remote.php/webdav/Music
``owncloudcmd`` will enquire user name and password, unless they have
been specified on the command line or ``-n`` (see `netrc(5)`) has been passed.
Using the legacy scheme, it would be::
$ owncloudcmd --httpproxy http://192.168.178.1:8080 \
$HOME/media/music \
ownclouds://server/owncloud/remote.php/webdav/Music
BUGS
====
Please report bugs at https://github.com/owncloud/client/issues.
SEE ALSO
========
:manpage:`owncloud(1)`

View File

@ -48,6 +48,66 @@ X-GNOME-Autostart-Delay=3
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
# Translations
Comment[oc]=@APPLICATION_NAME@ sincronizacion del client
GenericName[oc]=Dorsièr de Sincronizacion
@ -187,6 +247,7 @@ Comment[zh_CN]=@APPLICATION_NAME@ 桌面同步客户端
GenericName[zh_CN]=
Name[zh_CN]=@APPLICATION_NAME@
Icon[zh_CN]=@APPLICATION_EXECUTABLE@
Comment[zh_HK]=
GenericName[zh_TW]=
Comment[es_AR]=Cliente de sincronización para escritorio @APPLICATION_NAME@
GenericName[es_AR]=Sincronización de directorio

View File

@ -1,12 +1,4 @@
if(APPLE)
add_custom_target( legacy_mac_overlayplugin ALL
xcodebuild -workspace ${CMAKE_SOURCE_DIR}/shell_integration/MacOSX/OwnCloud.xcworkspace
-scheme SyncStateFinder.osax -configuration Release SYMROOT=${CMAKE_CURRENT_BINARY_DIR}
OC_APPLICATION_REV_DOMAIN=${APPLICATION_REV_DOMAIN}
OC_SOCKETAPI_TEAM_IDENTIFIER_PREFIX=${SOCKETAPI_TEAM_IDENTIFIER_PREFIX}
COMMENT building Legacy Mac Overlay icons)
# Contrary to popular belief, this is called like this no matter what theme/OEM.
set(OC_OEM_SHARE_ICNS "${CMAKE_BINARY_DIR}/src/gui/ownCloud.icns")
@ -25,12 +17,6 @@ add_custom_target( mac_overlayplugin ALL
VERBATIM)
add_dependencies(mac_overlayplugin ${APPLICATION_EXECUTABLE}) # for the ownCloud.icns to be generated
# legacy
INSTALL( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Release/SyncStateFinder.osax/Contents
DESTINATION ${CMAKE_INSTALL_PREFIX}/Library/ScriptingAdditions/SyncStateFinder.osax/ )
# >= 10.10.x
INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Release/FinderSyncExt.appex
DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/PlugIns
USE_SOURCE_PERMISSIONS)

View File

@ -4,10 +4,4 @@
<FileRef
location = "group:OwnCloudFinderSync/OwnCloudFinderSync.xcodeproj">
</FileRef>
<FileRef
location = "group:OwnCloudFinder/OwnCloudFinder.xcodeproj">
</FileRef>
<FileRef
location = "group:OwnCloudInjector/OwnCloudInjector.xcodeproj">
</FileRef>
</Workspace>

View File

@ -1,47 +0,0 @@
/**
* Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
#import <Foundation/Foundation.h>
@interface OwnCloudFinderContentManager : NSObject
{
NSMutableDictionary* _fileNamesCache;
NSMutableDictionary* _oldFileNamesCache;
BOOL _fileIconsEnabled;
BOOL _hasChangedContent;
NSNumber *_icnOk;
NSNumber *_icnSync;
NSNumber *_icnWarn;
NSNumber *_icnErr;
NSNumber *_icnOkSwm;
NSNumber *_icnSyncSwm;
NSNumber *_icnWarnSwm;
NSNumber *_icnErrSwm;
}
+ (OwnCloudFinderContentManager*)sharedInstance;
- (void)enableFileIcons:(BOOL)enable;
- (NSNumber*)iconByPath:(NSString*)path isDirectory:(BOOL)isDir;
- (void)removeAllIcons;
- (void)setIcons:(NSDictionary*)iconDictionary filterByFolder:(NSString*)filterFolder;
- (void)setResultForPath:(NSString*)path result:(NSString*)result;
- (void)clearFileNameCache;
- (void)reFetchFileNameCacheForPath:(NSString*)path;
- (void)repaintAllWindows;
- (void)loadIconResources;
@end

View File

@ -1,358 +0,0 @@
/**
* Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
#import <AppKit/NSApplication.h>
#import <AppKit/NSWindow.h>
#import <objc/runtime.h>
#import "ContentManager.h"
#import "MenuManager.h"
#import "RequestManager.h"
#import "IconCache.h"
static OwnCloudFinderContentManager* sharedInstance = nil;
@implementation OwnCloudFinderContentManager
- init
{
self = [super init];
if (self)
{
_fileNamesCache = [[NSMutableDictionary alloc] init];
_oldFileNamesCache = [[NSMutableDictionary alloc] init];
_fileIconsEnabled = TRUE;
_hasChangedContent = TRUE;
[self loadIconResources];
}
return self;
}
- (void)dealloc
{
[self removeAllIcons];
[_fileNamesCache release];
[_oldFileNamesCache release];
sharedInstance = nil;
[super dealloc];
}
+ (OwnCloudFinderContentManager*)sharedInstance
{
@synchronized(self)
{
if (sharedInstance == nil)
{
sharedInstance = [[self alloc] init];
}
}
return sharedInstance;
}
- (void)loadIconResources
{
NSBundle *extBundle = [NSBundle bundleForClass:[self class]];
_icnOk = [[IconCache sharedInstance] registerIcon:[extBundle imageForResource:@"ok.icns"]];
_icnSync = [[IconCache sharedInstance] registerIcon:[extBundle imageForResource:@"sync.icns"]];
_icnWarn = [[IconCache sharedInstance] registerIcon:[extBundle imageForResource:@"warning.icns"]];
_icnErr = [[IconCache sharedInstance] registerIcon:[extBundle imageForResource:@"error.icns"]];
_icnOkSwm = [[IconCache sharedInstance] registerIcon:[extBundle imageForResource:@"ok_swm.icns"]];
_icnSyncSwm = [[IconCache sharedInstance] registerIcon:[extBundle imageForResource:@"sync_swm.icns"]];
_icnWarnSwm = [[IconCache sharedInstance] registerIcon:[extBundle imageForResource:@"warning_swm.icns"]];
_icnErrSwm = [[IconCache sharedInstance] registerIcon:[extBundle imageForResource:@"error_swm.icns"]];
// NSLog(@"Icon ok: %@ identifier: %d from bundle %@", [extBundle imageForResource:@"ok.icns"], [_icnOk intValue], extBundle);
}
- (void)enableFileIcons:(BOOL)enable
{
_fileIconsEnabled = enable;
[self repaintAllWindows];
}
- (void)setResultForPath:(NSString*)path result:(NSString*)result
{
if (_icnOk == nil) {
// no icon resource path registered yet
return;
}
NSNumber *res;
res = [NSNumber numberWithInt:0];
if( [result isEqualToString:@"OK"] ) {
res = _icnOk;
} else if( [result isEqualToString:@"SYNC"] || [result isEqualToString:@"NEW"] ) {
res = _icnSync;
} else if( [result isEqualToString:@"IGNORE"]) {
res = _icnWarn;
} else if( [result isEqualToString:@"ERROR"]) {
res = _icnErr;
} else if( [result isEqualToString:@"OK+SWM"] ) {
res = _icnOkSwm;
} else if( [result isEqualToString:@"SYNC+SWM"] || [result isEqualToString:@"NEW+SWM"] ) {
res = _icnSyncSwm;
} else if( [result isEqualToString:@"IGNORE+SWM"]) {
res = _icnWarnSwm;
} else if( [result isEqualToString:@"ERROR+SWM"]) {
res = _icnErrSwm;
}else if( [result isEqualToString:@"NOP"]) {
// Nothing.
} else {
NSLog(@"SyncState: Unknown status code %@", result);
}
NSString* normalizedPath = [path decomposedStringWithCanonicalMapping];
if (![_fileNamesCache objectForKey:normalizedPath] || ![[_fileNamesCache objectForKey:normalizedPath] isEqualTo:res]) {
[_fileNamesCache setObject:res forKey:normalizedPath];
//NSLog(@"SET value %d %@", [res intValue], normalizedPath);
_hasChangedContent = YES;
[self performSelector:@selector(repaintAllWindowsIfNeeded) withObject:0 afterDelay:1.0]; // 1 sec
}
}
- (NSNumber*)iconByPath:(NSString*)path isDirectory:(BOOL)isDir
{
//NSLog(@"%@ %@", NSStringFromSelector(_cmd), path);
if (!_fileIconsEnabled)
{
NSLog(@"SyncState: Icons are NOT ENABLED!");
// return nil;
}
if( path == nil ) {
NSNumber *res = [NSNumber numberWithInt:0];
return res;
}
NSString* normalizedPath = [path decomposedStringWithCanonicalMapping];
if (![[OwnCloudFinderRequestManager sharedInstance] isRegisteredPath:normalizedPath isDirectory:isDir]) {
return [NSNumber numberWithInt:0];
}
NSNumber* result = [_fileNamesCache objectForKey:normalizedPath];
// NSLog(@"XXXXXXX Asking for icon for path %@ = %d",normalizedPath, [result intValue]);
if( result == nil ) {
result = [NSNumber numberWithInt:0];
// Set 0 into the cache, meaning "don't have an icon, but already requested it"
[_fileNamesCache setObject:result forKey:normalizedPath];
// start the async call
[[OwnCloudFinderRequestManager sharedInstance] askForIcon:normalizedPath isDirectory:isDir];
}
if ([result intValue] == 0) {
// Show the old state while we wait for the new one
NSNumber* oldResult = [_oldFileNamesCache objectForKey:normalizedPath];
if (oldResult)
result = oldResult;
}
// NSLog(@"iconByPath return value %d", [result intValue]);
return result;
}
// Clears the entries from the hash to make it call again home to the desktop client.
- (void)clearFileNameCache
{
[_fileNamesCache release];
_fileNamesCache = [[NSMutableDictionary alloc] init];
[_oldFileNamesCache removeAllObjects];
}
- (void)reFetchFileNameCacheForPath:(NSString*)path
{
//NSLog(@"%@", NSStringFromSelector(_cmd));
// We won't request the new state if it finds the path in _fileNamesCache
// Move all entries to _oldFileNamesCache so that they get re-requested, but
// still available while we refill the cache
[_oldFileNamesCache addEntriesFromDictionary:_fileNamesCache];
[_fileNamesCache removeAllObjects];
[self repaintAllWindows];
}
- (void)removeAllIcons
{
[_fileNamesCache removeAllObjects];
[_oldFileNamesCache removeAllObjects];
[self repaintAllWindows];
}
- (void)repaintAllWindowsIfNeeded
{
if (!_hasChangedContent) {
//NSLog(@"%@ Repaint scheduled but not needed", NSStringFromSelector(_cmd));
return;
}
_hasChangedContent = NO;
[self repaintAllWindows];
}
- (void)repaintAllWindows
{
//NSLog(@"%@", NSStringFromSelector(_cmd));
NSArray* windows = [[NSApplication sharedApplication] windows];
for (int i = 0; i < [windows count]; i++)
{
NSWindow* window = [windows objectAtIndex:i];
if (![window isVisible])
{
continue;
}
MenuManager* menuManager = [MenuManager sharedInstance];
OwnCloudFinderRequestManager* requestManager = [OwnCloudFinderRequestManager sharedInstance];
if ([[window className] isEqualToString:@"TBrowserWindow"])
{
NSObject* browserWindowController = [window browserWindowController];
BOOL repaintWindow = YES;
NSString* filterFolder = [requestManager filterFolder];
if (filterFolder)
{
repaintWindow = NO;
struct TFENodeVector* targetPath;
if ([browserWindowController respondsToSelector:@selector(targetPath)])
{
// 10.7 & 10.8
targetPath = [browserWindowController targetPath];
}
else if ([browserWindowController respondsToSelector:@selector(activeContainer)])
{
// 10.9
targetPath = [[browserWindowController activeContainer] targetPath];
}
else
{
NSLog(@"SyncState: refreshing icon badges failed");
return;
}
NSArray* folderPaths = [menuManager pathsForNodes:targetPath];
for (NSString* folderPath in folderPaths)
{
if ([folderPath hasPrefix:filterFolder] || [filterFolder hasPrefix:folderPath])
{
repaintWindow = YES;
break;
}
}
}
if (repaintWindow)
{
if ([browserWindowController respondsToSelector:@selector(browserViewController)])
{
// 10.7 & 10.8
NSObject* browserViewController = [browserWindowController browserViewController];
NSObject* browserView = [browserViewController browserView];
dispatch_async(dispatch_get_main_queue(), ^{[browserView setNeedsDisplay:YES];});
}
else if ([browserWindowController respondsToSelector:@selector(activeBrowserViewController)])
{
// 10.9
NSObject* browserViewController = [browserWindowController activeBrowserViewController];
NSObject* browserView = [browserViewController browserView];
if ([browserView isKindOfClass:(id)objc_getClass("TListView")])
{
// List or Coverflow View
[self setNeedsDisplayForListView:browserView];
}
else
{
// Icon or Column View
dispatch_async(dispatch_get_main_queue(), ^{[browserView setNeedsDisplay:YES];});
}
}
else
{
NSLog(@"SyncState: refreshing icon badges failed");
return;
}
}
}
}
}
- (void)setIcons:(NSDictionary*)iconDictionary filterByFolder:(NSString*)filterFolder
{
NSLog(@"%@", NSStringFromSelector(_cmd));
for (NSString* path in iconDictionary)
{
if (filterFolder && ![path hasPrefix:filterFolder])
{
continue;
}
NSString* normalizedPath = [path decomposedStringWithCanonicalMapping];
NSNumber* iconId = [iconDictionary objectForKey:path];
if ([iconId intValue] == -1)
{
[_fileNamesCache removeObjectForKey:normalizedPath];
}
else
{
[_oldFileNamesCache removeObjectForKey:normalizedPath];
[_fileNamesCache setObject:iconId forKey:normalizedPath];
}
}
[self repaintAllWindows];
}
- (void)setNeedsDisplayForListView:(NSView*)view
{
NSArray* subviews = [view subviews];
for (int i = 0; i < [subviews count]; i++)
{
NSView* subview = [subviews objectAtIndex:i];
if ([subview isKindOfClass:(id)objc_getClass("TListRowView")])
{
[self setNeedsDisplayForListView:subview];
}
else if ([subview isKindOfClass:(id)objc_getClass("TListNameCellView")])
{
dispatch_async(dispatch_get_main_queue(), ^{[subview setNeedsDisplay:YES];});
}
}
}
@end

View File

@ -1,28 +0,0 @@
/**
* Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
#import <Foundation/Foundation.h>
@interface NSObject (ContextMenuHandlers)
struct TFENodeVector;
+ (void)OCContextMenuHandlers_handleContextMenuCommon:(unsigned int)arg1 nodes:(const struct TFENodeVector*)arg2 event:(id)arg3 view:(id)arg4 browserController:(id)arg5 addPlugIns:(BOOL)arg6;
+ (void)OCContextMenuHandlers_handleContextMenuCommon:(unsigned int)arg1 nodes:(const struct TFENodeVector*)arg2 event:(id)arg3 view:(id)arg4 windowController:(id)arg5 addPlugIns:(BOOL)arg6;
+ (void)OCContextMenuHandlers_addViewSpecificStuffToMenu:(id)arg1 browserViewController:(id)arg2 context:(unsigned int)arg3;
- (void)OCContextMenuHandlers_configureWithNodes:(const struct TFENodeVector*)arg1 browserController:(id)arg2 container:(BOOL)arg3;
- (void)OCContextMenuHandlers_configureWithNodes:(const struct TFENodeVector*)arg1 windowController:(id)arg2 container:(BOOL)arg3;
@end

View File

@ -1,101 +0,0 @@
/**
* Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
#import "ContextMenuHandlers.h"
#import "MenuManager.h"
@class TIconViewController;
@implementation NSObject (ContextMenuHandlers)
+ (void)OCContextMenuHandlers_addViewSpecificStuffToMenu:(id)arg1 browserViewController:(id)arg2 context:(unsigned int)arg3 // 10.7 & 10.8
{
[self OCContextMenuHandlers_addViewSpecificStuffToMenu:arg1 browserViewController:arg2 context:arg3];
NSLog(@"OCContextMenuHandlers_addViewSpecificStuffToMenu 10.7/10.8 %@ %@ %d", arg1, arg2, arg3);
MenuManager* menuManager = [MenuManager sharedInstance];
if (menuManager.menuItems.count > 0)
{
[menuManager addItemsToMenu:arg1 forFiles:menuManager.menuItems];
[menuManager.menuItems removeAllObjects];
}
}
+ (void)OCContextMenuHandlers_addViewSpecificStuffToMenu:(id)arg1 clickedView:(id)arg2 browserViewController:(id)arg3 context:(unsigned int)arg4 // 10.9
{
[self OCContextMenuHandlers_addViewSpecificStuffToMenu:arg1 clickedView:arg2 browserViewController:arg3 context:arg4];
NSLog(@"OCContextMenuHandlers_addViewSpecificStuffToMenu 10.9 %@ %@ %@ %d", arg1, arg2, arg3, arg4);
MenuManager* menuManager = [MenuManager sharedInstance];
if (menuManager.menuItems.count > 0)
{
[menuManager addItemsToMenu:arg1 forFiles:menuManager.menuItems];
[menuManager.menuItems removeAllObjects];
}
}
+ (void)OCContextMenuHandlers_handleContextMenuCommon:(unsigned int)arg1 nodes:(const struct TFENodeVector*)arg2 event:(id)arg3 view:(id)arg4 windowController:(id)arg5 addPlugIns:(BOOL)arg6 // 10.7
{
MenuManager* menuManager = [MenuManager sharedInstance];
NSLog(@"ContextMenuHandlers_handleContextMenuCommon");
menuManager.menuItems = (NSMutableArray*)[menuManager pathsForNodes:arg2];
[self OCContextMenuHandlers_handleContextMenuCommon:arg1 nodes:arg2 event:arg3 view:arg4 windowController:arg5 addPlugIns:arg6];
}
+ (void)OCContextMenuHandlers_handleContextMenuCommon:(unsigned int)arg1 nodes:(const struct TFENodeVector*)arg2 event:(id)arg3 view:(id)arg4 browserController:(id)arg5 addPlugIns:(BOOL)arg6 // 10.8
{
MenuManager* menuManager = [MenuManager sharedInstance];
NSLog(@"ContextMenuHandlers_handleContextMenuCommon");
menuManager.menuItems = (NSMutableArray*)[menuManager pathsForNodes:arg2];
[self OCContextMenuHandlers_handleContextMenuCommon:arg1 nodes:arg2 event:arg3 view:arg4 browserController:arg5 addPlugIns:arg6];
}
+ (void)OCContextMenuHandlers_handleContextMenuCommon:(unsigned int)arg1 nodes:(const struct TFENodeVector*)arg2 event:(id)arg3 clickedView:(id)arg4 browserViewController:(id)arg5 addPlugIns:(BOOL)arg6 // 10.9
{
MenuManager* menuManager = [MenuManager sharedInstance];
NSLog(@"ContextMenuHandlers_handleContextMenuCommon");
menuManager.menuItems = (NSMutableArray*)[menuManager pathsForNodes:arg2];
[self OCContextMenuHandlers_handleContextMenuCommon:arg1 nodes:arg2 event:arg3 clickedView:arg4 browserViewController:arg5 addPlugIns:arg6];
}
- (void)OCContextMenuHandlers_configureWithNodes:(const struct TFENodeVector*)arg1 windowController:(id)arg2 container:(BOOL)arg3 // 10.7
{
[self OCContextMenuHandlers_configureWithNodes:arg1 windowController:arg2 container:arg3];
NSLog(@"ContextMenuHandlers_configureWithNodes");
TContextMenu* realSelf = (TContextMenu*)self;
MenuManager* menuManager = [MenuManager sharedInstance];
NSArray* selectedItems = [menuManager pathsForNodes:arg1];
[menuManager addItemsToMenu:realSelf forFiles:selectedItems];
}
- (void)OCContextMenuHandlers_configureWithNodes:(const struct TFENodeVector*)arg1 browserController:(id)arg2 container:(BOOL)arg3 // 10.8
{
[self OCContextMenuHandlers_configureWithNodes:arg1 browserController:arg2 container:arg3];
NSLog(@"ContextMenuHandlers_configureWithNodes");
TContextMenu* realSelf = (TContextMenu*)self;
MenuManager* menuManager = [MenuManager sharedInstance];
NSArray* selectedItems = [menuManager pathsForNodes:arg1];
[menuManager addItemsToMenu:realSelf forFiles:selectedItems];
}
- (void)OCContextMenuHandlers_configureFromMenuNeedsUpdate:(id)arg1 clickedView:(id)arg2 container:(BOOL)arg3 event:(id)arg4 selectedNodes:(const struct TFENodeVector *)arg5 // 10.9
{
[self OCContextMenuHandlers_configureFromMenuNeedsUpdate:arg1 clickedView:arg2 container:arg3 event:arg4 selectedNodes:arg5]; // 10.8
NSLog(@"ContextMenuHandlers_configureFromMenuNeedsUpdate");
TContextMenu* realSelf = (TContextMenu*)self;
MenuManager* menuManager = [MenuManager sharedInstance];
NSArray* selectedItems = [menuManager pathsForNodes:arg5];
[menuManager addItemsToMenu:realSelf forFiles:selectedItems];
}
@end

View File

@ -1,74 +0,0 @@
/**
* Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
#import "ContextMenuHandlers.h"
#import "Finder/Finder.h"
#import "MenuManager.h"
@implementation NSObject (ContextMenuHandlers)
+ (void) ContextMenuHandlers_handleContextMenuCommon:(unsigned int)arg1 nodes:(const struct TFENodeVector*)arg2 event:(id)arg3 view:(id)arg4 windowController:(id)arg5 addPlugIns:(BOOL)arg6 // Lion
{
MenuManager* contextMenuUtils = [MenuManager sharedInstance];
contextMenuUtils.menuItems = (NSMutableArray*)[contextMenuUtils pathsForNodes:arg2];
[self ContextMenuHandlers_handleContextMenuCommon:arg1 nodes:arg2 event:arg3 view:arg4 windowController:arg5 addPlugIns:arg6];
}
+ (void) ContextMenuHandlers_handleContextMenuCommon:(unsigned int)arg1 nodes:(const struct TFENodeVector*)arg2 event:(id)arg3 view:(id)arg4 browserController:(id)arg5 addPlugIns:(BOOL)arg6 // Mountain Lion
{
MenuManager* contextMenuUtils = [MenuManager sharedInstance];
contextMenuUtils.menuItems = (NSMutableArray*)[contextMenuUtils pathsForNodes:arg2];
[self ContextMenuHandlers_handleContextMenuCommon:arg1 nodes:arg2 event:arg3 view:arg4 browserController:arg5 addPlugIns:arg6];
}
+ (void) ContextMenuHandlers_addViewSpecificStuffToMenu:(id)arg1 browserViewController:(id)arg2 context:(unsigned int)arg3
{
[self ContextMenuHandlers_addViewSpecificStuffToMenu:arg1 browserViewController:arg2 context:arg3];
if ([MenuManager sharedInstance].menuItems.count > 0)
{
MenuManager* contextMenuUtils = [MenuManager sharedInstance];
[contextMenuUtils addItemsToMenu:arg1 forPaths:contextMenuUtils.menuItems];
[contextMenuUtils.menuItems removeAllObjects];
}
}
- (void) ContextMenuHandlers_configureWithNodes:(const struct TFENodeVector*)arg1 windowController:(id)arg2 container:(BOOL)arg3 // Lion
{
[self ContextMenuHandlers_configureWithNodes:arg1 windowController:arg2 container:arg3];
TContextMenu* realSelf = (TContextMenu*)self;
MenuManager* contextMenuUtils = [MenuManager sharedInstance];
NSArray* selectedItems = [contextMenuUtils pathsForNodes:arg1];
[contextMenuUtils addItemsToMenu:realSelf forPaths:selectedItems];
}
- (void) ContextMenuHandlers_configureWithNodes:(const struct TFENodeVector*)arg1 browserController:(id)arg2 container:(BOOL)arg3 // Mountain Lion
{
[self ContextMenuHandlers_configureWithNodes:arg1 browserController:arg2 container:arg3];
TContextMenu* realSelf = (TContextMenu*)self;
MenuManager* contextMenuUtils = [MenuManager sharedInstance];
NSArray* selectedItems = [contextMenuUtils pathsForNodes:arg1];
[contextMenuUtils addItemsToMenu:realSelf forPaths:selectedItems];
}
@end

View File

@ -1,2 +0,0 @@
/* Localized versions of Info.plist keys */

File diff suppressed because it is too large Load Diff

View File

@ -1,22 +0,0 @@
/**
* Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
#import <Cocoa/Cocoa.h>
@interface FinderHook : NSObject
+ (void)hookClassMethod:(SEL)oldSelector inClass:(NSString*)className toCallToTheNewMethod:(SEL)newSelector;
+ (void)hookMethod:(SEL)oldSelector inClass:(NSString*)className toCallToTheNewMethod:(SEL)newSelector;
@end

View File

@ -1,125 +0,0 @@
/**
* Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
#import "ContentManager.h"
#import "FinderHook.h"
#import "IconCache.h"
#import "objc/objc-class.h"
#import "RequestManager.h"
static BOOL installed = NO;
@implementation FinderHook
+ (void)hookClassMethod:(SEL)oldSelector inClass:(NSString*)className toCallToTheNewMethod:(SEL)newSelector
{
Class hookedClass = NSClassFromString(className);
Method oldMethod = class_getClassMethod(hookedClass, oldSelector);
Method newMethod = class_getClassMethod(hookedClass, newSelector);
method_exchangeImplementations(newMethod, oldMethod);
}
+ (void)hookMethod:(SEL)oldSelector inClass:(NSString*)className toCallToTheNewMethod:(SEL)newSelector
{
Class hookedClass = NSClassFromString(className);
Method oldMethod = class_getInstanceMethod(hookedClass, oldSelector);
Method newMethod = class_getInstanceMethod(hookedClass, newSelector);
method_exchangeImplementations(newMethod, oldMethod);
}
+ (void)install
{
if (installed)
{
// NSLog(@"SyncStateFinder: already installed");
return;
}
// NSLog(@"SyncStateFinder: installing SyncState Shell extension");
[OwnCloudFinderRequestManager sharedInstance];
// Icons
[self hookMethod:@selector(drawImage:) inClass:@"IKImageBrowserCell" toCallToTheNewMethod:@selector(OCIconOverlayHandlers_IKImageBrowserCell_drawImage:)]; // 10.7 & 10.8 & 10.9 (Icon View arrange by name)
[self hookMethod:@selector(drawImage:) inClass:@"IKFinderReflectiveIconCell" toCallToTheNewMethod:@selector(OCIconOverlayHandlers_IKFinderReflectiveIconCell_drawImage:)]; // 10.7 & 10.8 & 10.9 (Icon View arrange by everything else)
[self hookMethod:@selector(drawIconWithFrame:) inClass:@"TColumnCell" toCallToTheNewMethod:@selector(OCIconOverlayHandlers_drawIconWithFrame:)]; // 10.7 & 10.8 & 10.9 Column View
[self hookMethod:@selector(drawRect:) inClass:@"TDimmableIconImageView" toCallToTheNewMethod:@selector(OCIconOverlayHandlers_drawRect:)]; // 10.9 (List and Coverflow Views)
// Context Menus
[self hookClassMethod:@selector(addViewSpecificStuffToMenu:browserViewController:context:) inClass:@"TContextMenu" toCallToTheNewMethod:@selector(OCContextMenuHandlers_addViewSpecificStuffToMenu:browserViewController:context:)]; // 10.7 & 10.8
[self hookClassMethod:@selector(addViewSpecificStuffToMenu:clickedView:browserViewController:context:) inClass:@"TContextMenu" toCallToTheNewMethod:@selector(OCContextMenuHandlers_addViewSpecificStuffToMenu:clickedView:browserViewController:context:)]; // 10.9
[self hookClassMethod:@selector(handleContextMenuCommon:nodes:event:view:windowController:addPlugIns:) inClass:@"TContextMenu" toCallToTheNewMethod:@selector(OCContextMenuHandlers_handleContextMenuCommon:nodes:event:view:windowController:addPlugIns:)]; // 10.7
[self hookClassMethod:@selector(handleContextMenuCommon:nodes:event:view:browserController:addPlugIns:) inClass:@"TContextMenu" toCallToTheNewMethod:@selector(OCContextMenuHandlers_handleContextMenuCommon:nodes:event:view:browserController:addPlugIns:)]; // 10.8
[self hookClassMethod:@selector(handleContextMenuCommon:nodes:event:clickedView:browserViewController:addPlugIns:) inClass:@"TContextMenu" toCallToTheNewMethod:@selector(OCContextMenuHandlers_handleContextMenuCommon:nodes:event:clickedView:browserViewController:addPlugIns:)]; // 10.9
[self hookMethod:@selector(configureWithNodes:windowController:container:) inClass:@"TContextMenu" toCallToTheNewMethod:@selector(OCContextMenuHandlers_configureWithNodes:windowController:container:)]; // 10.7
[self hookMethod:@selector(configureWithNodes:browserController:container:) inClass:@"TContextMenu" toCallToTheNewMethod:@selector(OCContextMenuHandlers_configureWithNodes:browserController:container:)]; // 10.8
[self hookMethod:@selector(configureFromMenuNeedsUpdate:clickedView:container:event:selectedNodes:) inClass:@"TContextMenu" toCallToTheNewMethod:@selector(OCContextMenuHandlers_configureFromMenuNeedsUpdate:clickedView:container:event:selectedNodes:)]; // 10.9
installed = YES;
// NSLog(@"SyncStateFinder: installed");
}
+ (void)uninstall
{
if (!installed)
{
// NSLog(@"SyncStateFinder: not installed");
return;
}
// NSLog(@"SyncStateFinder: uninstalling");
[[OwnCloudFinderContentManager sharedInstance] dealloc];
[[IconCache sharedInstance] dealloc];
[[OwnCloudFinderRequestManager sharedInstance] dealloc];
// Icons
[self hookMethod:@selector(OCIconOverlayHandlers_drawImage:) inClass:@"TIconViewCell" toCallToTheNewMethod:@selector(drawImage:)]; // 10.7 & 10.8 & 10.9
[self hookMethod:@selector(OCIconOverlayHandlers_drawIconWithFrame:) inClass:@"TListViewIconAndTextCell" toCallToTheNewMethod:@selector(drawIconWithFrame:)]; // 10.7 & 10.8 & 10.9
// Context Menus
[self hookClassMethod:@selector(OCContextMenuHandlers_addViewSpecificStuffToMenu:browserViewController:context:) inClass:@"TContextMenu" toCallToTheNewMethod:@selector(addViewSpecificStuffToMenu:browserViewController:context:)]; // 10.7 & 10.8
[self hookClassMethod:@selector(OCContextMenuHandlers_handleContextMenuCommon:nodes:event:view:windowController:addPlugIns:) inClass:@"TContextMenu" toCallToTheNewMethod:@selector(handleContextMenuCommon:nodes:event:view:windowController:addPlugIns:)]; // 10.7
[self hookMethod:@selector(OCContextMenuHandlers_configureWithNodes:windowController:container:) inClass:@"TContextMenu" toCallToTheNewMethod:@selector(configureWithNodes:windowController:container:)]; // 10.7
[self hookClassMethod:@selector(OCContextMenuHandlers_handleContextMenuCommon:nodes:event:view:browserController:addPlugIns:) inClass:@"TContextMenu" toCallToTheNewMethod:@selector(handleContextMenuCommon:nodes:event:view:browserController:addPlugIns:)]; // 10.8
[self hookMethod:@selector(OCContextMenuHandlers_configureWithNodes:browserController:container:) inClass:@"TContextMenu" toCallToTheNewMethod:@selector(configureWithNodes:browserController:container:)]; // 10.8
installed = NO;
// NSLog(@"SyncStateFinder: uninstalled");
}
@end

View File

@ -1,24 +0,0 @@
//
// FinishedIconCache.h
// OwnCloudFinder
//
// Created by Markus Goetz on 01/10/14.
//
//
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
@interface FinishedIconCache : NSObject {
NSCache *_cache;
long long _hits;
long long _misses;
}
+ (FinishedIconCache*)sharedInstance;
- (NSImage*)getIcon:(NSString*)fileName overlayIconIndex:(int)idx width:(float)w height:(float)h;
- (void)registerIcon:(NSImage*)icon withFileName:(NSString*)fileName overlayIconIndex:(int)idx width:(float)w height:(float)h;
@end

View File

@ -1,91 +0,0 @@
//
// FinishedIconCache.m
// OwnCloudFinder
//
// Created by Markus Goetz on 01/10/14.
//
//
#import "FinishedIconCache.h"
@interface FinishedIconCacheItem : NSObject
@property (nonatomic, strong) NSImage *icon;
@property (nonatomic) NSTimeInterval maxAge;
@end
@implementation FinishedIconCacheItem
@synthesize icon;
@synthesize maxAge;
- (void)dealloc {
//NSLog(@"RELEASE %@ %@", self, self.icon);
if (self.icon) {
[self->icon release];
}
[super dealloc];
}
@end
@implementation FinishedIconCache
static FinishedIconCache* sharedInstance = nil;
- init
{
self = [super init];
if (self)
{
_cache = [[NSCache alloc] init];
_cache.totalCostLimit = (2880 * 1800); // mbp15 screen size
_hits = 0;
_misses = 0;
}
return self;
}
- (void)dealloc
{
[_cache dealloc];
[super dealloc];
}
+ (FinishedIconCache*)sharedInstance
{
@synchronized(self)
{
if (sharedInstance == nil)
{
sharedInstance = [[self alloc] init];
}
}
return sharedInstance;
}
- (NSImage*)getIcon:(NSString*)fileName overlayIconIndex:(int)idx width:(float)w height:(float)h
{
NSString *cacheKey = [NSString stringWithFormat:@"%@--%d--%f%f", fileName, idx, w,h];
FinishedIconCacheItem *item = [_cache objectForKey:cacheKey];
if (item) {
if (item.maxAge > [[NSDate date] timeIntervalSinceReferenceDate]) {
_hits++;
return item.icon;
}
}
_misses++;
return NULL;
}
- (void)registerIcon:(NSImage*)icon withFileName:(NSString*)fileName overlayIconIndex:(int)idx width:(float)w height:(float)h
{
NSString *cacheKey = [NSString stringWithFormat:@"%@--%d--%f%f", fileName, idx, w, h];
FinishedIconCacheItem *item = [[FinishedIconCacheItem alloc] init];
item.icon = icon;
// max age between 1 sec and 5 sec
item.maxAge = [[NSDate date] timeIntervalSinceReferenceDate] + 1.0 + 4.0*((double)arc4random() / 0x100000000);
[_cache setObject:item forKey:cacheKey cost:w*h];
[item release];
//NSLog(@"CACHE hit/miss ratio: %f", (float)_hits/(float)_misses);
}
@end

View File

@ -1,27 +0,0 @@
/**
* Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
#import <Cocoa/Cocoa.h>
@interface IconCache : NSObject {
int _currentIconId;
NSMutableDictionary* _iconIdDictionary;
}
+ (IconCache*)sharedInstance;
- (NSImage*)getIcon:(NSNumber*)iconId;
- (NSNumber*)registerIcon:(NSImage*)image;
@end

View File

@ -1,72 +0,0 @@
/**
* Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
#import "IconCache.h"
@implementation IconCache
static IconCache* sharedInstance = nil;
- init
{
self = [super init];
if (self)
{
_iconIdDictionary = [[NSMutableDictionary alloc] init];
_currentIconId = 0;
}
return self;
}
- (void)dealloc
{
[_iconIdDictionary release];
sharedInstance = nil;
[super dealloc];
}
+ (IconCache*)sharedInstance
{
@synchronized(self)
{
if (sharedInstance == nil)
{
sharedInstance = [[self alloc] init];
}
}
return sharedInstance;
}
- (NSImage*)getIcon:(NSNumber*)iconId
{
NSImage* image = [_iconIdDictionary objectForKey:iconId];
return image;
}
- (NSNumber*)registerIcon:(NSImage*)image
{
_currentIconId++;
NSNumber* iconId = [NSNumber numberWithInt:_currentIconId];
[_iconIdDictionary setObject:image forKey:iconId];
return iconId;
}
@end

View File

@ -1,23 +0,0 @@
/**
* Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
#import <Foundation/Foundation.h>
@interface NSObject (IconOverlayHandlers)
- (void)OCIconOverlayHandlers_drawIconWithFrame:(struct CGRect)arg1;
- (void)OCIconOverlayHandlers_drawImage:(id)arg1;
- (void)OCIconOverlayHandlers_drawRect:(struct CGRect)arg1;
@end

View File

@ -1,176 +0,0 @@
/**
* Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
#import <objc/runtime.h>
#import "ContentManager.h"
#import "IconCache.h"
#import "FinishedIconCache.h"
#import "IconOverlayHandlers.h"
#import "Finder/Finder.h"
@implementation NSObject (IconOverlayHandlers)
- (void)OCIconOverlayHandlers_drawIconWithFrame:(struct CGRect)arg1
{
[self OCIconOverlayHandlers_drawIconWithFrame:arg1];
NSURL* url = [[NSClassFromString(@"FINode") nodeFromNodeRef:[(TIconAndTextCell*)self node]->fNodeRef] previewItemURL];
BOOL isDir;
if ([[NSFileManager defaultManager] fileExistsAtPath: [url path] isDirectory:&isDir] == NO) {
NSLog(@"ERROR: Could not determine file type of %@", [url path]);
isDir = NO;
}
NSNumber* imageIndex = [[OwnCloudFinderContentManager sharedInstance] iconByPath:[url path] isDirectory:isDir];
//NSLog(@"1 The icon index is %d", [imageIndex intValue]);
if ([imageIndex intValue] > 0)
{
NSImage* image = [[IconCache sharedInstance] getIcon:imageIndex];
if (image != nil)
{
struct CGRect arg2 = [(TIconViewCell*)self imageRectForBounds:arg1];
[image drawInRect:NSMakeRect(arg2.origin.x, arg2.origin.y, arg2.size.width, arg2.size.height) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0 respectFlipped:TRUE hints:nil];
}
}
}
- (void)OCIconOverlayHandlers_IKImageBrowserCell_drawImage:(id)arg1
{
IKImageWrapper*imageWrapper = [self OCIconOverlayHandlers_imageWrapper:arg1];
[self OCIconOverlayHandlers_IKImageBrowserCell_drawImage:imageWrapper];
}
- (void)OCIconOverlayHandlers_IKFinderReflectiveIconCell_drawImage:(id)arg1
{
IKImageWrapper*imageWrapper = [self OCIconOverlayHandlers_imageWrapper:arg1];
[self OCIconOverlayHandlers_IKFinderReflectiveIconCell_drawImage:imageWrapper];
}
- (IKImageWrapper*)OCIconOverlayHandlers_imageWrapper:(id)arg1
{
TIconViewCell* realSelf = (TIconViewCell*)self;
FINode* node = (FINode*)[realSelf representedItem];
NSURL* url = [node previewItemURL];
BOOL isDir;
if ([[NSFileManager defaultManager] fileExistsAtPath:[url path] isDirectory:&isDir] == NO) {
NSLog(@"ERROR: Could not determine file type of %@", [url path]);
isDir = NO;
}
NSNumber* imageIndex = [[OwnCloudFinderContentManager sharedInstance] iconByPath:[url path] isDirectory:isDir];
//NSLog(@"2 The icon index is %d %@ %@", [imageIndex intValue], [url path], isDir ? @"isDir" : @"");
if ([imageIndex intValue] > 0)
{
NSImage* icon = [arg1 _nsImage];
// Use the short term icon cache that possibly has the finished icon
FinishedIconCache *finishedIconCache = [FinishedIconCache sharedInstance];
NSImage *finishedImage = [finishedIconCache getIcon:[url path] overlayIconIndex:imageIndex width:[icon size].width height:[icon size].height];
if (finishedImage) {
//NSLog(@"X Got finished image from cache %@ %@", finishedImage, [url path]);
return [[[IKImageWrapper alloc] initWithNSImage:finishedImage] autorelease];;
} else {
//NSLog(@"X Need to redraw %@", [url path]);
}
NSImage* iconimage = [[IconCache sharedInstance] getIcon:[NSNumber numberWithInt:[imageIndex intValue]]];
if (iconimage != nil)
{
[icon lockFocus];
CGContextRef myContext = [[NSGraphicsContext currentContext] graphicsPort];
CGRect destRect = CGRectMake(0, 0, [icon size].width, [icon size].height);
CGImageRef cgImage = [iconimage CGImageForProposedRect:&destRect
context:[NSGraphicsContext currentContext]
hints:nil];
if (cgImage) {
CGContextDrawImage(myContext, destRect, cgImage);
//CGImageRelease(cgImage); // leak here? if we leave this code in, Finder crashes
// But actually i'm not seeing a leak in Activity Monitor.. maybe it is not really leaking?
} else {
NSLog(@"No image given!!!!!11 %@", [url path]);
}
[icon unlockFocus];
}
// Insert into cache
[finishedIconCache registerIcon:icon withFileName:[url path] overlayIconIndex:imageIndex width:[icon size].width height:[icon size].height];
return [[[IKImageWrapper alloc] initWithNSImage:icon] autorelease];
}
else
{
return arg1;
}
}
- (void)OCIconOverlayHandlers_drawRect:(struct CGRect)arg1
{
[self OCIconOverlayHandlers_drawRect:arg1];
NSView* supersuperview = [[(NSView*)self superview] superview];
if ([supersuperview isKindOfClass:(id)objc_getClass("TListRowView")])
{
TListRowView *listRowView = (TListRowView*) supersuperview;
FINode *fiNode;
object_getInstanceVariable(listRowView, "_node", (void**)&fiNode);
NSURL *url;
if ([fiNode respondsToSelector:@selector(previewItemURL)])
{
url = [fiNode previewItemURL];
}
else {
return;
}
BOOL isDir;
if ([[NSFileManager defaultManager] fileExistsAtPath:[url path] isDirectory: &isDir] == NO) {
NSLog(@"ERROR: Could not determine file type of %@", [url path]);
isDir = NO;
}
NSNumber* imageIndex = [[OwnCloudFinderContentManager sharedInstance] iconByPath:[url path] isDirectory:isDir];
//NSLog(@"3 The icon index is %d", [imageIndex intValue]);
if ([imageIndex intValue] > 0)
{
NSImage* image = [[IconCache sharedInstance] getIcon:imageIndex];
if (image != nil)
{
[image drawInRect:NSMakeRect(arg1.origin.x, arg1.origin.y, arg1.size.width, arg1.size.height) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0 respectFlipped:TRUE hints:nil];
}
}
}
}
@end

View File

@ -1,48 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SocketApiPrefix</key>
<string>$(OC_SOCKETAPI_TEAM_IDENTIFIER_PREFIX)$(OC_APPLICATION_REV_DOMAIN)</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>com.owncloud.finder</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>OWNC</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>CFPlugInDynamicRegisterFunction</key>
<string></string>
<key>CFPlugInDynamicRegistration</key>
<string>NO</string>
<key>CFPlugInFactories</key>
<dict>
<key>00000000-0000-0000-0000-000000000000</key>
<string>MyFactoryFunction</string>
</dict>
<key>CFPlugInTypes</key>
<dict>
<key>00000000-0000-0000-0000-000000000000</key>
<array>
<string>00000000-0000-0000-0000-000000000000</string>
</array>
</dict>
<key>CFPlugInUnloadFunction</key>
<string></string>
<key>NSPrincipalClass</key>
<string>FinderHook</string>
</dict>
</plist>

View File

@ -1,29 +0,0 @@
/**
* Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
#import <Foundation/Foundation.h>
@class TContextMenu;
struct TFENodeVector;
@interface MenuManager : NSObject
@property (nonatomic, strong) NSMutableArray* menuItems;
+ (MenuManager*)sharedInstance;
- (void)addItemsToMenu:(TContextMenu*)menu forFiles:(NSArray*)files;
- (NSArray*)pathsForNodes:(const struct TFENodeVector*)nodes;
@end

View File

@ -1,188 +0,0 @@
/**
* Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
#import "MenuManager.h"
#import "Finder/Finder.h"
#import "RequestManager.h"
@implementation MenuManager
static MenuManager* sharedInstance = nil;
+ (MenuManager*)sharedInstance
{
@synchronized(self)
{
if (sharedInstance == nil)
{
sharedInstance = [[self alloc] init];
}
}
return sharedInstance;
}
- init
{
return [super init];
}
- (void)addChildrenSubMenuItems:(NSMenuItem*)parentMenuItem withChildren:(NSArray*)menuItemsDictionaries forFiles:(NSArray*)files
{
NSMenu* menu = [[NSMenu alloc] init];
for (int i = 0; i < [menuItemsDictionaries count]; ++i)
{
NSDictionary* menuItemDictionary = [menuItemsDictionaries objectAtIndex:i];
NSString* submenuTitle = [menuItemDictionary objectForKey:@"title"];
BOOL enabled = [[menuItemDictionary objectForKey:@"enabled"] boolValue];
NSString* uuid = [menuItemDictionary objectForKey:@"uuid"];
NSArray* childrenSubMenuItems = (NSArray*)[menuItemDictionary objectForKey:@"contextMenuItems"];
if ([submenuTitle isEqualToString:@"_SEPARATOR_"])
{
[menu addItem:[NSMenuItem separatorItem]];
}
else if (childrenSubMenuItems != nil && [childrenSubMenuItems count] != 0)
{
NSMenuItem* submenuItem = [menu addItemWithTitle:submenuTitle action:nil keyEquivalent:@""];
[self addChildrenSubMenuItems:submenuItem withChildren:childrenSubMenuItems forFiles:files];
}
else
{
[self createActionMenuItemIn:menu withTitle:submenuTitle withIndex:i enabled:enabled withUuid:uuid forFiles:files];
}
}
[parentMenuItem setSubmenu:menu];
[menu release];
}
- (void)addItemsToMenu:(TContextMenu*)menu forFiles:(NSArray*)files
{
OwnCloudFinderRequestManager *requestManager = [OwnCloudFinderRequestManager sharedInstance];
NSString *shareItemTitle = [requestManager shareItemTitle];
if (!shareItemTitle || shareItemTitle.length == 0) {
return;
}
for (int i = 0; i < files.count; i++) {
NSString *fn = [files objectAtIndex:i];
BOOL isDir = false;
if ([[NSFileManager defaultManager] fileExistsAtPath:fn isDirectory:&isDir]) {
if (![requestManager isRegisteredPath:fn isDirectory:isDir]) {
return;
}
}
}
NSMutableArray* menuItemsArray = [[[NSMutableArray alloc] init] autorelease];
NSMutableDictionary *firstEntry = [[[NSMutableDictionary alloc] init] autorelease];
[firstEntry setValue:[NSNumber numberWithBool:YES] forKey:@"enabled"];
[firstEntry setValue:shareItemTitle forKey:@"title"];
[menuItemsArray addObject:firstEntry];
// Find the menu with a submenu which should be the share menu position
NSInteger menuIndex = MIN(4, menu.itemArray.count);
for (int i = menuIndex; i < menu.itemArray.count; i++) {
if ([[menu itemAtIndex:i] hasSubmenu]) {
menuIndex = i;
//NSLog(@"addItemsToMenu: menuIndex --> %lu (count=%lu)", menuIndex, (unsigned long)menu.itemArray.count);
break;
}
}
for (int i = 0; i < [menuItemsArray count]; ++i)
{
NSDictionary* menuItemDictionary = [menuItemsArray objectAtIndex:i];
NSString* mainMenuTitle = [menuItemDictionary objectForKey:@"title"];
if ([mainMenuTitle isEqualToString:@""])
{
continue;
}
menuIndex++;
BOOL enabled = [[menuItemDictionary objectForKey:@"enabled"] boolValue];
NSString* uuid = [menuItemDictionary objectForKey:@"uuid"];
NSArray* childrenSubMenuItems = (NSArray*)[menuItemDictionary objectForKey:@"contextMenuItems"];
if (childrenSubMenuItems != nil && [childrenSubMenuItems count] != 0)
{
NSMenuItem* mainMenuItem = [menu insertItemWithTitle:mainMenuTitle action:nil keyEquivalent:@"" atIndex:menuIndex];
[self addChildrenSubMenuItems:mainMenuItem withChildren:childrenSubMenuItems forFiles:files];
}
else
{
[self createActionMenuItemIn:menu withTitle:mainMenuTitle withIndex:menuIndex enabled:enabled withUuid:uuid forFiles:files];
}
}
}
- (void)createActionMenuItemIn:(NSMenu*)menu withTitle:(NSString*)title withIndex:(NSInteger*)index enabled:(BOOL)enabled withUuid:(NSString*)uuid forFiles:(NSArray*)files
{
NSMenuItem* mainMenuItem = [menu insertItemWithTitle:title action:@selector(menuItemClicked:) keyEquivalent:@"" atIndex:index];
if (enabled)
{
[mainMenuItem setTarget:self];
}
NSDictionary* menuActionDictionary = [[NSMutableDictionary alloc] init];
[menuActionDictionary setValue:uuid forKey:@"uuid"];
NSMutableArray* filesArray = [files copy];
[menuActionDictionary setValue:filesArray forKey:@"files"];
[mainMenuItem setRepresentedObject:menuActionDictionary];
[filesArray release];
[menuActionDictionary release];
}
- (void)menuItemClicked:(id)param
{
[[OwnCloudFinderRequestManager sharedInstance] menuItemClicked:[param representedObject]];
}
- (NSArray*)pathsForNodes:(const struct TFENodeVector*)nodes
{
struct TFENode* start = nodes->_M_impl._M_start;
struct TFENode* end = nodes->_M_impl._M_finish;
int count = end - start;
NSMutableArray* selectedItems = [[NSMutableArray alloc] initWithCapacity:count];
struct TFENode* current;
for (current = start; current < end; ++current)
{
FINode* node = (FINode*)[NSClassFromString(@"FINode") nodeFromNodeRef:current->fNodeRef];
NSString* path = [[node previewItemURL] path];
if (path)
{
[selectedItems addObject:path];
}
}
return [selectedItems autorelease];
}
@end

View File

@ -1,369 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
0B13ECAF173C687900548DA1 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BFC9ACB173C57E400CDD329 /* Security.framework */; };
5BB74A8719DBF9BB001BAAAC /* FinishedIconCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 5BB74A8619DBF9BB001BAAAC /* FinishedIconCache.m */; };
692C18A516660C4700BF6A53 /* ContextMenuHandlers.m in Sources */ = {isa = PBXBuildFile; fileRef = 692C18A416660C4600BF6A53 /* ContextMenuHandlers.m */; };
692C18A9166617F500BF6A53 /* IconOverlayHandlers.m in Sources */ = {isa = PBXBuildFile; fileRef = 692C18A8166617F500BF6A53 /* IconOverlayHandlers.m */; };
692C18AC1666392700BF6A53 /* MenuManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 692C18AB1666392700BF6A53 /* MenuManager.m */; };
6993878616494C000044E4DF /* RequestManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 6993878516494C000044E4DF /* RequestManager.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
69948B361636D50E0093B6CE /* ContentManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 69948B351636D50E0093B6CE /* ContentManager.m */; };
8C37DD9F161593BD00016A95 /* FinderHook.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C37DD9A161593BD00016A95 /* FinderHook.m */; };
8C37DDB2161593FF00016A95 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C37DDB1161593FF00016A95 /* Cocoa.framework */; };
8C37DDBA161594B400016A95 /* Quartz.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C37DDB9161594B400016A95 /* Quartz.framework */; };
8C99F6941622D145002D2135 /* IconCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C99F6931622D145002D2135 /* IconCache.m */; };
8D576314048677EA00EA77CD /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */; };
8D5B49A804867FD3000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8D5B49A704867FD3000E48DA /* InfoPlist.strings */; };
C220057B1B31B04C00A4FB37 /* error_swm.icns in Resources */ = {isa = PBXBuildFile; fileRef = C22005731B31B04C00A4FB37 /* error_swm.icns */; };
C220057C1B31B04C00A4FB37 /* error.icns in Resources */ = {isa = PBXBuildFile; fileRef = C22005741B31B04C00A4FB37 /* error.icns */; };
C220057D1B31B04C00A4FB37 /* ok_swm.icns in Resources */ = {isa = PBXBuildFile; fileRef = C22005751B31B04C00A4FB37 /* ok_swm.icns */; };
C220057E1B31B04C00A4FB37 /* ok.icns in Resources */ = {isa = PBXBuildFile; fileRef = C22005761B31B04C00A4FB37 /* ok.icns */; };
C220057F1B31B04C00A4FB37 /* sync_swm.icns in Resources */ = {isa = PBXBuildFile; fileRef = C22005771B31B04C00A4FB37 /* sync_swm.icns */; };
C22005801B31B04C00A4FB37 /* sync.icns in Resources */ = {isa = PBXBuildFile; fileRef = C22005781B31B04C00A4FB37 /* sync.icns */; };
C22005811B31B04C00A4FB37 /* warning_swm.icns in Resources */ = {isa = PBXBuildFile; fileRef = C22005791B31B04C00A4FB37 /* warning_swm.icns */; };
C22005821B31B04C00A4FB37 /* warning.icns in Resources */ = {isa = PBXBuildFile; fileRef = C220057A1B31B04C00A4FB37 /* warning.icns */; };
C2B573831B1CD5AE00303B36 /* SyncClientProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = C2B573821B1CD5AE00303B36 /* SyncClientProxy.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
0B2BF60B176A43DB001246CD /* Finder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Finder.h; sourceTree = "<group>"; };
0BFC9ACB173C57E400CDD329 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
5BB74A8519DBF9BB001BAAAC /* FinishedIconCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FinishedIconCache.h; sourceTree = "<group>"; };
5BB74A8619DBF9BB001BAAAC /* FinishedIconCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FinishedIconCache.m; sourceTree = "<group>"; };
692C18A316660C4600BF6A53 /* ContextMenuHandlers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContextMenuHandlers.h; sourceTree = "<group>"; };
692C18A416660C4600BF6A53 /* ContextMenuHandlers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContextMenuHandlers.m; sourceTree = "<group>"; };
692C18A7166617F500BF6A53 /* IconOverlayHandlers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IconOverlayHandlers.h; sourceTree = "<group>"; };
692C18A8166617F500BF6A53 /* IconOverlayHandlers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IconOverlayHandlers.m; sourceTree = "<group>"; };
692C18AA1666392700BF6A53 /* MenuManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MenuManager.h; sourceTree = "<group>"; };
692C18AB1666392700BF6A53 /* MenuManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MenuManager.m; sourceTree = "<group>"; };
6993878416494C000044E4DF /* RequestManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RequestManager.h; sourceTree = "<group>"; };
6993878516494C000044E4DF /* RequestManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RequestManager.m; sourceTree = "<group>"; usesTabs = 1; };
69948B341636D50E0093B6CE /* ContentManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContentManager.h; sourceTree = "<group>"; };
69948B351636D50E0093B6CE /* ContentManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContentManager.m; sourceTree = "<group>"; };
8C37DD99161593BD00016A95 /* FinderHook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FinderHook.h; sourceTree = "<group>"; };
8C37DD9A161593BD00016A95 /* FinderHook.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FinderHook.m; sourceTree = "<group>"; };
8C37DDB1161593FF00016A95 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
8C37DDB9161594B400016A95 /* Quartz.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quartz.framework; path = System/Library/Frameworks/Quartz.framework; sourceTree = SDKROOT; };
8C99F6921622D145002D2135 /* IconCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IconCache.h; sourceTree = "<group>"; };
8C99F6931622D145002D2135 /* IconCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IconCache.m; sourceTree = "<group>"; };
8D576316048677EA00EA77CD /* SyncStateFinder.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SyncStateFinder.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
8D576317048677EA00EA77CD /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
C22005731B31B04C00A4FB37 /* error_swm.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = error_swm.icns; path = ../../icons/icns/error_swm.icns; sourceTree = "<group>"; };
C22005741B31B04C00A4FB37 /* error.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = error.icns; path = ../../icons/icns/error.icns; sourceTree = "<group>"; };
C22005751B31B04C00A4FB37 /* ok_swm.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = ok_swm.icns; path = ../../icons/icns/ok_swm.icns; sourceTree = "<group>"; };
C22005761B31B04C00A4FB37 /* ok.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = ok.icns; path = ../../icons/icns/ok.icns; sourceTree = "<group>"; };
C22005771B31B04C00A4FB37 /* sync_swm.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = sync_swm.icns; path = ../../icons/icns/sync_swm.icns; sourceTree = "<group>"; };
C22005781B31B04C00A4FB37 /* sync.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = sync.icns; path = ../../icons/icns/sync.icns; sourceTree = "<group>"; };
C22005791B31B04C00A4FB37 /* warning_swm.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = warning_swm.icns; path = ../../icons/icns/warning_swm.icns; sourceTree = "<group>"; };
C220057A1B31B04C00A4FB37 /* warning.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = warning.icns; path = ../../icons/icns/warning.icns; sourceTree = "<group>"; };
C2B573811B1CD5AE00303B36 /* SyncClientProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SyncClientProxy.h; sourceTree = "<group>"; };
C2B573821B1CD5AE00303B36 /* SyncClientProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SyncClientProxy.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
8D576313048677EA00EA77CD /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
0B13ECAF173C687900548DA1 /* Security.framework in Frameworks */,
8D576314048677EA00EA77CD /* CoreFoundation.framework in Frameworks */,
8C37DDB2161593FF00016A95 /* Cocoa.framework in Frameworks */,
8C37DDBA161594B400016A95 /* Quartz.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
089C166AFE841209C02AAC07 /* SyncStateFinder */ = {
isa = PBXGroup;
children = (
C2B573801B1CD5AE00303B36 /* common */,
08FB77AFFE84173DC02AAC07 /* Source */,
089C167CFE841241C02AAC07 /* Resources */,
089C1671FE841209C02AAC07 /* External Frameworks and Libraries */,
19C28FB6FE9D52B211CA2CBB /* Products */,
);
name = SyncStateFinder;
sourceTree = "<group>";
usesTabs = 1;
};
089C1671FE841209C02AAC07 /* External Frameworks and Libraries */ = {
isa = PBXGroup;
children = (
0BFC9ACB173C57E400CDD329 /* Security.framework */,
8C37DDB9161594B400016A95 /* Quartz.framework */,
0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */,
8C37DDB1161593FF00016A95 /* Cocoa.framework */,
);
name = "External Frameworks and Libraries";
sourceTree = "<group>";
};
089C167CFE841241C02AAC07 /* Resources */ = {
isa = PBXGroup;
children = (
C22005731B31B04C00A4FB37 /* error_swm.icns */,
C22005741B31B04C00A4FB37 /* error.icns */,
C22005751B31B04C00A4FB37 /* ok_swm.icns */,
C22005761B31B04C00A4FB37 /* ok.icns */,
C22005771B31B04C00A4FB37 /* sync_swm.icns */,
C22005781B31B04C00A4FB37 /* sync.icns */,
C22005791B31B04C00A4FB37 /* warning_swm.icns */,
C220057A1B31B04C00A4FB37 /* warning.icns */,
8D576317048677EA00EA77CD /* Info.plist */,
8D5B49A704867FD3000E48DA /* InfoPlist.strings */,
);
name = Resources;
sourceTree = "<group>";
};
08FB77AFFE84173DC02AAC07 /* Source */ = {
isa = PBXGroup;
children = (
0B2BF60A176A43DB001246CD /* Finder */,
8C37DD99161593BD00016A95 /* FinderHook.h */,
8C37DD9A161593BD00016A95 /* FinderHook.m */,
692C18A316660C4600BF6A53 /* ContextMenuHandlers.h */,
692C18A416660C4600BF6A53 /* ContextMenuHandlers.m */,
692C18A7166617F500BF6A53 /* IconOverlayHandlers.h */,
692C18A8166617F500BF6A53 /* IconOverlayHandlers.m */,
6993878416494C000044E4DF /* RequestManager.h */,
6993878516494C000044E4DF /* RequestManager.m */,
69948B341636D50E0093B6CE /* ContentManager.h */,
69948B351636D50E0093B6CE /* ContentManager.m */,
8C99F6921622D145002D2135 /* IconCache.h */,
8C99F6931622D145002D2135 /* IconCache.m */,
5BB74A8519DBF9BB001BAAAC /* FinishedIconCache.h */,
5BB74A8619DBF9BB001BAAAC /* FinishedIconCache.m */,
692C18AA1666392700BF6A53 /* MenuManager.h */,
692C18AB1666392700BF6A53 /* MenuManager.m */,
);
name = Source;
sourceTree = "<group>";
};
0B2BF60A176A43DB001246CD /* Finder */ = {
isa = PBXGroup;
children = (
0B2BF60B176A43DB001246CD /* Finder.h */,
);
path = Finder;
sourceTree = "<group>";
};
19C28FB6FE9D52B211CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
8D576316048677EA00EA77CD /* SyncStateFinder.bundle */,
);
name = Products;
sourceTree = "<group>";
};
C2B573801B1CD5AE00303B36 /* common */ = {
isa = PBXGroup;
children = (
C2B573811B1CD5AE00303B36 /* SyncClientProxy.h */,
C2B573821B1CD5AE00303B36 /* SyncClientProxy.m */,
);
name = common;
path = ../common;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
8D57630D048677EA00EA77CD /* SyncStateFinder */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1DEB911A08733D790010E9CD /* Build configuration list for PBXNativeTarget "SyncStateFinder" */;
buildPhases = (
8D57630F048677EA00EA77CD /* Resources */,
8D576311048677EA00EA77CD /* Sources */,
8D576313048677EA00EA77CD /* Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = SyncStateFinder;
productInstallPath = "$(HOME)/Library/Bundles";
productName = SyncStateFinder;
productReference = 8D576316048677EA00EA77CD /* SyncStateFinder.bundle */;
productType = "com.apple.product-type.bundle";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
089C1669FE841209C02AAC07 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0460;
};
buildConfigurationList = 1DEB911E08733D790010E9CD /* Build configuration list for PBXProject "OwnCloudFinder" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
English,
Japanese,
French,
German,
);
mainGroup = 089C166AFE841209C02AAC07 /* SyncStateFinder */;
projectDirPath = "";
projectRoot = "";
targets = (
8D57630D048677EA00EA77CD /* SyncStateFinder */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
8D57630F048677EA00EA77CD /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C220057E1B31B04C00A4FB37 /* ok.icns in Resources */,
C22005821B31B04C00A4FB37 /* warning.icns in Resources */,
C220057F1B31B04C00A4FB37 /* sync_swm.icns in Resources */,
C220057C1B31B04C00A4FB37 /* error.icns in Resources */,
8D5B49A804867FD3000E48DA /* InfoPlist.strings in Resources */,
C22005801B31B04C00A4FB37 /* sync.icns in Resources */,
C220057D1B31B04C00A4FB37 /* ok_swm.icns in Resources */,
C220057B1B31B04C00A4FB37 /* error_swm.icns in Resources */,
C22005811B31B04C00A4FB37 /* warning_swm.icns in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
8D576311048677EA00EA77CD /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8C37DD9F161593BD00016A95 /* FinderHook.m in Sources */,
8C99F6941622D145002D2135 /* IconCache.m in Sources */,
69948B361636D50E0093B6CE /* ContentManager.m in Sources */,
C2B573831B1CD5AE00303B36 /* SyncClientProxy.m in Sources */,
6993878616494C000044E4DF /* RequestManager.m in Sources */,
5BB74A8719DBF9BB001BAAAC /* FinishedIconCache.m in Sources */,
692C18A516660C4700BF6A53 /* ContextMenuHandlers.m in Sources */,
692C18A9166617F500BF6A53 /* IconOverlayHandlers.m in Sources */,
692C18AC1666392700BF6A53 /* MenuManager.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
8D5B49A704867FD3000E48DA /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
089C167EFE841241C02AAC07 /* English */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
1DEB911B08733D790010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_LINK_OBJC_RUNTIME = NO;
COMBINE_HIDPI_IMAGES = YES;
CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_MODEL_TUNING = G5;
GCC_OPTIMIZATION_LEVEL = 0;
INFOPLIST_FILE = Info.plist;
INSTALL_PATH = "$(HOME)/Library/Bundles";
OC_APPLICATION_REV_DOMAIN = com.owncloud.desktopclient;
OC_SOCKETAPI_TEAM_IDENTIFIER_PREFIX = "";
PRODUCT_NAME = SyncStateFinder;
WRAPPER_EXTENSION = bundle;
};
name = Debug;
};
1DEB911C08733D790010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_LINK_OBJC_RUNTIME = NO;
COMBINE_HIDPI_IMAGES = YES;
CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_MODEL_TUNING = G5;
INFOPLIST_FILE = Info.plist;
INSTALL_PATH = "$(HOME)/Library/Bundles";
OC_APPLICATION_REV_DOMAIN = com.owncloud.desktopclient;
OC_SOCKETAPI_TEAM_IDENTIFIER_PREFIX = "";
PRODUCT_NAME = SyncStateFinder;
WRAPPER_EXTENSION = bundle;
};
name = Release;
};
1DEB911F08733D790010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
COPY_PHASE_STRIP = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = _DEBUG_LOG;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.7;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
name = Debug;
};
1DEB912008733D790010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
COPY_PHASE_STRIP = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.7;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB911A08733D790010E9CD /* Build configuration list for PBXNativeTarget "SyncStateFinder" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB911B08733D790010E9CD /* Debug */,
1DEB911C08733D790010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
1DEB911E08733D790010E9CD /* Build configuration list for PBXProject "OwnCloudFinder" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB911F08733D790010E9CD /* Debug */,
1DEB912008733D790010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 089C1669FE841209C02AAC07 /* Project object */;
}

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:OwnCloudFinder.xcodeproj">
</FileRef>
</Workspace>

View File

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>8D57630D048677EA00EA77CD</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>

View File

@ -1,40 +0,0 @@
/**
* Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
#import <Foundation/Foundation.h>
#import "RequestManager.h"
#import "SyncClientProxy.h"
@interface OwnCloudFinderRequestManager : NSObject <SyncClientProxyDelegate>
{
SyncClientProxy *_syncClientProxy;
NSMutableArray* _requestQueue;
NSMutableDictionary* _registeredPathes;
NSMutableSet* _requestedPaths;
NSString *_shareMenuTitle;
}
@property (nonatomic, retain) NSString* filterFolder;
+ (OwnCloudFinderRequestManager*)sharedInstance;
- (BOOL)isRegisteredPath:(NSString*)path isDirectory:(BOOL)isDir;
- (void)askForIcon:(NSString*)path isDirectory:(BOOL)isDir;
- (void)menuItemClicked:(NSDictionary*)actionDictionary;
- (NSString*) shareItemTitle;
@end

View File

@ -1,159 +0,0 @@
/**
* Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
#import "ContentManager.h"
#import "IconCache.h"
#import "RequestManager.h"
static OwnCloudFinderRequestManager* sharedInstance = nil;
@implementation OwnCloudFinderRequestManager
- (id)init
{
if ((self = [super init]))
{
// For the sake of allowing both the legacy and the FinderSync extensions to work with the same
// client build, use the same server name including the Team ID even though we won't be sandboxed.
NSBundle *extBundle = [NSBundle bundleForClass:[self class]];
// This was added to the bundle's Info.plist to get it from the build system
NSString *socketApiPrefix = [extBundle objectForInfoDictionaryKey:@"SocketApiPrefix"];
NSString *serverName = [socketApiPrefix stringByAppendingString:@".socketApi"];
// NSLog(@"OwnCloudFinderRequestManager serverName %@", serverName);
_syncClientProxy = [[SyncClientProxy alloc] initWithDelegate:self serverName:serverName];
_registeredPathes = [[NSMutableDictionary alloc] init];
_requestedPaths = [[NSMutableSet alloc] init];
_shareMenuTitle = nil;
// The NSConnection will block until the distant object came back and this creates a loop hanging Finder.
// Start from a timer to have time to unwind the stack first.
[NSTimer scheduledTimerWithTimeInterval:0 target:_syncClientProxy selector:@selector(start) userInfo:nil repeats:NO];
}
return self;
}
- (void)dealloc
{
sharedInstance = nil;
}
+ (OwnCloudFinderRequestManager*)sharedInstance
{
@synchronized(self)
{
if (sharedInstance == nil)
{
sharedInstance = [[self alloc] init];
}
}
return sharedInstance;
}
- (BOOL)isRegisteredPath:(NSString*)path isDirectory:(BOOL)isDir
{
// check if the file in question is underneath a registered directory
NSArray *regPathes = [_registeredPathes allKeys];
BOOL registered = NO;
NSString* checkPath = [NSString stringWithString:path];
if (isDir && ![checkPath hasSuffix:@"/"]) {
// append a slash
checkPath = [path stringByAppendingString:@"/"];
}
for( NSString *regPath in regPathes ) {
if( [checkPath hasPrefix:regPath]) {
// the path was registered
registered = YES;
break;
}
}
return registered;
}
- (void)askForIcon:(NSString*)path isDirectory:(BOOL)isDir
{
if( [self isRegisteredPath:path isDirectory:isDir] ) {
[_requestedPaths addObject:path];
[_syncClientProxy askForIcon:path isDirectory:isDir];
}
}
- (void)setResultForPath:(NSString*)path result:(NSString*)result
{
// The client will broadcast all changes, do not fill the cache for paths that Finder didn't ask for.
if ([_requestedPaths containsObject:path]) {
[[OwnCloudFinderContentManager sharedInstance] setResultForPath:path result:result];
}
}
- (void)reFetchFileNameCacheForPath:(NSString*)path
{
[_requestedPaths removeAllObjects];
[[OwnCloudFinderContentManager sharedInstance] reFetchFileNameCacheForPath:path];
}
- (void)registerPath:(NSString*)path
{
NSNumber *one = [NSNumber numberWithInt:1];
[_registeredPathes setObject:one forKey:path];
[[OwnCloudFinderContentManager sharedInstance] repaintAllWindows];
}
- (void)unregisterPath:(NSString*)path
{
[_registeredPathes removeObjectForKey:path];
[[OwnCloudFinderContentManager sharedInstance] repaintAllWindows];
}
- (void)setShareMenuTitle:(NSString*)title
{
_shareMenuTitle = title;
}
- (void)connectionDidDie
{
// NSLog(@"Socket DISconnected! %@", [err localizedDescription]);
// clear the registered paths.
_registeredPathes = [[NSMutableDictionary alloc] init];
[_requestedPaths removeAllObjects];
// clear the caches in content manager
OwnCloudFinderContentManager *contentman = [OwnCloudFinderContentManager sharedInstance];
[contentman clearFileNameCache];
[contentman repaintAllWindows];
}
- (void)menuItemClicked:(NSDictionary*)actionDictionary
{
// NSLog(@"RequestManager menuItemClicked %@", actionDictionary);
NSArray *filePaths = [actionDictionary valueForKey:@"files"];
for (int i = 0; i < filePaths.count; i++) {
[_syncClientProxy askOnSocket:[filePaths objectAtIndex:i] query:@"SHARE"];
}
}
- (NSString*) shareItemTitle
{
return _shareMenuTitle;
}
@end

View File

@ -22,6 +22,7 @@
SyncClientProxy *_syncClientProxy;
NSMutableSet *_registeredDirectories;
NSString *_shareMenuTitle;
NSMutableDictionary *_strings;
}
@end

View File

@ -59,7 +59,7 @@
_syncClientProxy = [[SyncClientProxy alloc] initWithDelegate:self serverName:serverName];
_registeredDirectories = [[NSMutableSet alloc] init];
_shareMenuTitle = nil;
_strings = [[NSMutableDictionary alloc] init];
[_syncClientProxy start];
return self;
@ -101,11 +101,21 @@
}
}];
if (_shareMenuTitle && !onlyRootsSelected) {
NSMenu *menu = [[NSMenu alloc] initWithTitle:@""];
NSMenuItem *item = [menu addItemWithTitle:_shareMenuTitle action:@selector(shareMenuAction:) keyEquivalent:@"title"];
item.image = [[NSBundle mainBundle] imageForResource:@"app.icns"];
id contextMenuTitle = [_strings objectForKey:@"CONTEXT_MENU_TITLE"];
id shareTitle = [_strings objectForKey:@"SHARE_MENU_TITLE"];
id copyLinkTitle = [_strings objectForKey:@"COPY_PRIVATE_LINK_MENU_TITLE"];
id emailLinkTitle = [_strings objectForKey:@"EMAIL_PRIVATE_LINK_MENU_TITLE"];
if (contextMenuTitle && !onlyRootsSelected) {
NSMenu *menu = [[NSMenu alloc] initWithTitle:@""];
NSMenu *subMenu = [[NSMenu alloc] initWithTitle:@""];
NSMenuItem *subMenuItem = [menu addItemWithTitle:contextMenuTitle action:nil keyEquivalent:@""];
subMenuItem.submenu = subMenu;
subMenuItem.image = [[NSBundle mainBundle] imageForResource:@"app.icns"];
[subMenu addItemWithTitle:shareTitle action:@selector(shareMenuAction:) keyEquivalent:@""];
[subMenu addItemWithTitle:copyLinkTitle action:@selector(copyLinkMenuAction:) keyEquivalent:@""];
[subMenu addItemWithTitle:emailLinkTitle action:@selector(emailLinkMenuAction:) keyEquivalent:@""];
return menu;
}
return nil;
@ -114,13 +124,33 @@
- (IBAction)shareMenuAction:(id)sender
{
NSArray* items = [[FIFinderSyncController defaultController] selectedItemURLs];
[items enumerateObjectsUsingBlock: ^(id obj, NSUInteger idx, BOOL *stop) {
NSString* normalizedPath = [[obj path] decomposedStringWithCanonicalMapping];
[_syncClientProxy askOnSocket:normalizedPath query:@"SHARE"];
}];
}
- (IBAction)copyLinkMenuAction:(id)sender
{
NSArray* items = [[FIFinderSyncController defaultController] selectedItemURLs];
[items enumerateObjectsUsingBlock: ^(id obj, NSUInteger idx, BOOL *stop) {
NSString* normalizedPath = [[obj path] decomposedStringWithCanonicalMapping];
[_syncClientProxy askOnSocket:normalizedPath query:@"COPY_PRIVATE_LINK"];
}];
}
- (IBAction)emailLinkMenuAction:(id)sender
{
NSArray* items = [[FIFinderSyncController defaultController] selectedItemURLs];
[items enumerateObjectsUsingBlock: ^(id obj, NSUInteger idx, BOOL *stop) {
NSString* normalizedPath = [[obj path] decomposedStringWithCanonicalMapping];
[_syncClientProxy askOnSocket:normalizedPath query:@"EMAIL_PRIVATE_LINK"];
}];
}
#pragma mark - SyncClientProxyDelegate implementation
- (void)setResultForPath:(NSString*)path result:(NSString*)result
@ -146,15 +176,14 @@
[FIFinderSyncController defaultController].directoryURLs = _registeredDirectories;
}
- (void)setShareMenuTitle:(NSString*)title
- (void)setString:(NSString*)key value:(NSString*)value
{
_shareMenuTitle = title;
[_strings setObject:value forKey:key];
}
- (void)connectionDidDie
{
_shareMenuTitle = nil;
[_strings removeAllObjects];
[_registeredDirectories removeAllObjects];
// For some reason the FIFinderSync cache doesn't seem to be cleared for the root item when
// we reset the directoryURLs (seen on macOS 10.12 at least).

View File

@ -20,7 +20,7 @@
- (void)reFetchFileNameCacheForPath:(NSString*)path;
- (void)registerPath:(NSString*)path;
- (void)unregisterPath:(NSString*)path;
- (void)setShareMenuTitle:(NSString*)title;
- (void)setString:(NSString*)key value:(NSString*)value;
- (void)connectionDidDie;
@end

View File

@ -73,7 +73,7 @@
[_remoteEnd setProtocolForProxy:@protocol(ChannelProtocol)];
// Everything is set up, start querying
[self askOnSocket:@"" query:@"SHARE_MENU_TITLE"];
[self askOnSocket:@"" query:@"GET_STRINGS"];
}
- (void)scheduleRetry
@ -119,8 +119,10 @@
} else if( [[chunks objectAtIndex:0 ] isEqualToString:@"UNREGISTER_PATH"] ) {
NSString *path = [chunks objectAtIndex:1];
[_delegate unregisterPath:path];
} else if( [[chunks objectAtIndex:0 ] isEqualToString:@"SHARE_MENU_TITLE"] ) {
[_delegate setShareMenuTitle:[chunks objectAtIndex:1]];
} else if( [[chunks objectAtIndex:0 ] isEqualToString:@"GET_STRINGS"] ) {
// BEGIN and END messages, do nothing.
} else if( [[chunks objectAtIndex:0 ] isEqualToString:@"STRING"] ) {
[_delegate setString:[chunks objectAtIndex:1] value:[chunks objectAtIndex:2]];
} else {
NSLog(@"SyncState: Unknown command %@", [chunks objectAtIndex:0]);
}

View File

@ -11,12 +11,12 @@
C2B573D21B1CD94B00303B36 /* main.m in Resources */ = {isa = PBXBuildFile; fileRef = C2B573B91B1CD91E00303B36 /* main.m */; };
C2B573DE1B1CD9CE00303B36 /* FinderSync.m in Sources */ = {isa = PBXBuildFile; fileRef = C2B573DD1B1CD9CE00303B36 /* FinderSync.m */; };
C2B573E21B1CD9CE00303B36 /* FinderSyncExt.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = C2B573D71B1CD9CE00303B36 /* FinderSyncExt.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
C2B573E91B1DA1FB00303B36 /* SyncClientProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = C2B573E81B1DA1FB00303B36 /* SyncClientProxy.m */; };
C2B573F31B1DAD6400303B36 /* error.iconset in Resources */ = {isa = PBXBuildFile; fileRef = C2B573EB1B1DAD6400303B36 /* error.iconset */; };
C2B573F41B1DAD6400303B36 /* ok_swm.iconset in Resources */ = {isa = PBXBuildFile; fileRef = C2B573EC1B1DAD6400303B36 /* ok_swm.iconset */; };
C2B573F51B1DAD6400303B36 /* ok.iconset in Resources */ = {isa = PBXBuildFile; fileRef = C2B573ED1B1DAD6400303B36 /* ok.iconset */; };
C2B573F71B1DAD6400303B36 /* sync.iconset in Resources */ = {isa = PBXBuildFile; fileRef = C2B573EF1B1DAD6400303B36 /* sync.iconset */; };
C2B573F91B1DAD6400303B36 /* warning.iconset in Resources */ = {isa = PBXBuildFile; fileRef = C2B573F11B1DAD6400303B36 /* warning.iconset */; };
C2C932F01F0BFC6700C8BCB3 /* SyncClientProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = C2C932EF1F0BFC6700C8BCB3 /* SyncClientProxy.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -52,13 +52,13 @@
C2B573DB1B1CD9CE00303B36 /* FinderSyncExt.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = FinderSyncExt.entitlements; sourceTree = "<group>"; };
C2B573DC1B1CD9CE00303B36 /* FinderSync.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FinderSync.h; sourceTree = "<group>"; };
C2B573DD1B1CD9CE00303B36 /* FinderSync.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FinderSync.m; sourceTree = "<group>"; };
C2B573E71B1DA1FB00303B36 /* SyncClientProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SyncClientProxy.h; sourceTree = "<group>"; };
C2B573E81B1DA1FB00303B36 /* SyncClientProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SyncClientProxy.m; sourceTree = "<group>"; };
C2B573EB1B1DAD6400303B36 /* error.iconset */ = {isa = PBXFileReference; lastKnownFileType = folder.iconset; name = error.iconset; path = ../../icons/nopadding/error.iconset; sourceTree = SOURCE_ROOT; };
C2B573EC1B1DAD6400303B36 /* ok_swm.iconset */ = {isa = PBXFileReference; lastKnownFileType = folder.iconset; name = ok_swm.iconset; path = ../../icons/nopadding/ok_swm.iconset; sourceTree = SOURCE_ROOT; };
C2B573ED1B1DAD6400303B36 /* ok.iconset */ = {isa = PBXFileReference; lastKnownFileType = folder.iconset; name = ok.iconset; path = ../../icons/nopadding/ok.iconset; sourceTree = SOURCE_ROOT; };
C2B573EF1B1DAD6400303B36 /* sync.iconset */ = {isa = PBXFileReference; lastKnownFileType = folder.iconset; name = sync.iconset; path = ../../icons/nopadding/sync.iconset; sourceTree = SOURCE_ROOT; };
C2B573F11B1DAD6400303B36 /* warning.iconset */ = {isa = PBXFileReference; lastKnownFileType = folder.iconset; name = warning.iconset; path = ../../icons/nopadding/warning.iconset; sourceTree = SOURCE_ROOT; };
C2C932EE1F0BFC6700C8BCB3 /* SyncClientProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SyncClientProxy.h; sourceTree = "<group>"; };
C2C932EF1F0BFC6700C8BCB3 /* SyncClientProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SyncClientProxy.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -82,7 +82,6 @@
C2B573941B1CD88000303B36 = {
isa = PBXGroup;
children = (
C2B573E61B1DA1FB00303B36 /* common */,
C2B573B31B1CD91E00303B36 /* desktopclient */,
C2B573D81B1CD9CE00303B36 /* FinderSyncExt */,
C2B573B21B1CD91E00303B36 /* Products */,
@ -118,6 +117,8 @@
C2B573D81B1CD9CE00303B36 /* FinderSyncExt */ = {
isa = PBXGroup;
children = (
C2C932EE1F0BFC6700C8BCB3 /* SyncClientProxy.h */,
C2C932EF1F0BFC6700C8BCB3 /* SyncClientProxy.m */,
C2B573DC1B1CD9CE00303B36 /* FinderSync.h */,
C2B573DD1B1CD9CE00303B36 /* FinderSync.m */,
C2B573D91B1CD9CE00303B36 /* Supporting Files */,
@ -139,16 +140,6 @@
name = "Supporting Files";
sourceTree = "<group>";
};
C2B573E61B1DA1FB00303B36 /* common */ = {
isa = PBXGroup;
children = (
C2B573E71B1DA1FB00303B36 /* SyncClientProxy.h */,
C2B573E81B1DA1FB00303B36 /* SyncClientProxy.m */,
);
name = common;
path = ../common;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -284,7 +275,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C2B573E91B1DA1FB00303B36 /* SyncClientProxy.m in Sources */,
C2C932F01F0BFC6700C8BCB3 /* SyncClientProxy.m in Sources */,
C2B573DE1B1CD9CE00303B36 /* FinderSync.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;

View File

@ -1,2 +0,0 @@
/* Localized versions of Info.plist keys */

View File

@ -1,59 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>com.owncloud.injector</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>OwnCloudInjector</string>
<key>CFBundlePackageType</key>
<string>osax</string>
<key>CFBundleShortVersionString</key>
<string>1.0.2</string>
<key>CFBundleSignature</key>
<string>OWNC</string>
<key>CFBundleVersion</key>
<string>1.0.2</string>
<key>OSAScriptingDefinition</key>
<string>OwnCloudInjector.sdef</string>
<key>OSAXHandlers</key>
<dict>
<key>Events</key>
<dict>
<key>OWNClded</key>
<dict>
<key>Context</key>
<string>Process</string>
<key>Handler</key>
<string>HandleLoadedEvent</string>
<key>ThreadSafe</key>
<false/>
</dict>
<key>OWNCload</key>
<dict>
<key>Context</key>
<string>Process</string>
<key>Handler</key>
<string>HandleLoadEvent</string>
<key>ThreadSafe</key>
<false/>
</dict>
<key>OWNCunld</key>
<dict>
<key>Context</key>
<string>Process</string>
<key>Handler</key>
<string>HandleUnloadEvent</string>
<key>ThreadSafe</key>
<false/>
</dict>
</dict>
</dict>
</dict>
</plist>

View File

@ -1,35 +0,0 @@
//
// LNStandardVersionComparator.h
// Sparkle
//
// Created by Andy Matuschak on 12/21/07.
// Copyright 2007 Andy Matuschak. All rights reserved.
//
#ifndef LNSTANDARDVERSIONCOMPARATOR_H
#define LNSTANDARDVERSIONCOMPARATOR_H
#import "LNVersionComparisonProtocol.h"
/*!
@class
@abstract Sparkle's default version comparator.
@discussion This comparator is adapted from MacPAD, by Kevin Ballard. It's "dumb" in that it does essentially string comparison, in components split by character type.
*/
@interface LNStandardVersionComparator : NSObject<LNVersionComparison> { }
/*!
@method
@abstract Returns a singleton instance of the comparator.
*/
+(LNStandardVersionComparator*)defaultComparator;
/*!
@method
@abstract Compares version strings through textual analysis.
@discussion See the implementation for more details.
*/
-(NSComparisonResult)compareVersion:(NSString*)versionA toVersion:(NSString*)versionB;
@end
#endif

View File

@ -1,158 +0,0 @@
//
// LNStandardVersionComparator.m
// Sparkle
//
// Created by Andy Matuschak on 12/21/07.
// Copyright 2007 Andy Matuschak. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "LNStandardVersionComparator.h"
@implementation LNStandardVersionComparator
+(LNStandardVersionComparator*) defaultComparator {
static LNStandardVersionComparator* defaultComparator = nil;
if (defaultComparator == nil) defaultComparator = [[LNStandardVersionComparator alloc] init];
return defaultComparator;
}
typedef enum {
kNumberType,
kStringType,
kPeriodType
} SUCharacterType;
-(SUCharacterType) typeOfCharacter:(NSString*)character {
if ([character isEqualToString:@"."]) {
return kPeriodType;
} else if ([[NSCharacterSet decimalDigitCharacterSet] characterIsMember:[character characterAtIndex:0]]) {
return kNumberType;
} else {
return kStringType;
}
}
-(NSArray*) splitVersionString:(NSString*)version {
NSString* character;
NSMutableString* s;
NSUInteger i, n;
SUCharacterType oldType, newType;
NSMutableArray* parts = [NSMutableArray array];
if ([version length] == 0) {
// Nothing to do here
return parts;
}
s = [[[version substringToIndex:1] mutableCopy] autorelease];
oldType = [self typeOfCharacter:s];
n = [version length] - 1;
for (i = 1; i <= n; ++i) {
character = [version substringWithRange:NSMakeRange(i, 1)];
newType = [self typeOfCharacter:character];
if ((oldType != newType) || (oldType == kPeriodType)) {
// We've reached a new segment
NSString* aPart = [[[NSString alloc] initWithString:s] autorelease];
[parts addObject:aPart];
[s setString:character];
} else {
// Add character to string and continue
[s appendString:character];
}
oldType = newType;
}
// Add the last part onto the array
[parts addObject:[NSString stringWithString:s]];
return parts;
}
-(NSComparisonResult) compareVersion:(NSString*)versionA toVersion:(NSString*)versionB;
{
NSArray* partsA = [self splitVersionString:versionA];
NSArray* partsB = [self splitVersionString:versionB];
NSString* partA, * partB;
NSUInteger i, n;
int intA, intB;
SUCharacterType typeA, typeB;
n = MIN([partsA count], [partsB count]);
for (i = 0; i < n; ++i) {
partA = [partsA objectAtIndex:i];
partB = [partsB objectAtIndex:i];
typeA = [self typeOfCharacter:partA];
typeB = [self typeOfCharacter:partB];
// Compare types
if (typeA == typeB) {
// Same type; we can compare
if (typeA == kNumberType) {
intA = [partA intValue];
intB = [partB intValue];
if (intA > intB) {
return NSOrderedDescending;
} else if (intA < intB) {
return NSOrderedAscending;
}
} else if (typeA == kStringType) {
NSComparisonResult result = [partA compare:partB];
if (result != NSOrderedSame) {
return result;
}
}
} else {
// Not the same type? Now we have to do some validity checking
if ((typeA != kStringType) && (typeB == kStringType)) {
// typeA wins
return NSOrderedDescending;
} else if ((typeA == kStringType) && (typeB != kStringType)) {
// typeB wins
return NSOrderedAscending;
} else {
// One is a number and the other is a period. The period is invalid
if (typeA == kNumberType) {
return NSOrderedDescending;
} else {
return NSOrderedAscending;
}
}
}
}
// The versions are equal up to the point where they both still have parts
// Lets check to see if one is larger than the other
if ([partsA count] != [partsB count]) {
// Yep. Lets get the next part of the larger
// n holds the index of the part we want.
NSString* missingPart;
SUCharacterType missingType;
NSComparisonResult shorterResult, largerResult;
if ([partsA count] > [partsB count]) {
missingPart = [partsA objectAtIndex:n];
shorterResult = NSOrderedAscending;
largerResult = NSOrderedDescending;
} else {
missingPart = [partsB objectAtIndex:n];
shorterResult = NSOrderedDescending;
largerResult = NSOrderedAscending;
}
missingType = [self typeOfCharacter:missingPart];
// Check the type
if (missingType == kStringType) {
// It's a string. Shorter version wins
return shorterResult;
} else {
// It's a number/period. Larger version wins
return largerResult;
}
}
// The 2 strings are identical
return NSOrderedSame;
}
@end

View File

@ -1,27 +0,0 @@
//
// LNVersionComparisonProtocol.h
// Sparkle
//
// Created by Andy Matuschak on 12/21/07.
// Copyright 2007 Andy Matuschak. All rights reserved.
//
#ifndef LNVERSIONCOMPARISONPROTOCOL_H
#define LNVERSIONCOMPARISONPROTOCOL_H
/*!
@protocol
@abstract Implement this protocol to provide version comparison facilities for Sparkle.
*/
@protocol LNVersionComparison
/*!
@method
@abstract An abstract method to compare two version strings.
@discussion Should return NSOrderedAscending if b > a, NSOrderedDescending if b < a, and NSOrderedSame if they are equivalent.
*/
-(NSComparisonResult)compareVersion:(NSString*)versionA toVersion:(NSString*)versionB;
@end
#endif

View File

@ -1,270 +0,0 @@
#import <Cocoa/Cocoa.h>
#import "LNStandardVersionComparator.h"
#define EXPORT __attribute__((visibility("default")))
#define WAIT_FOR_APPLE_EVENT_TO_ENTER_HANDLER_IN_SECONDS 1.0
#define FINDER_MIN_TESTED_VERSION @"10.7"
#define FINDER_MAX_TESTED_VERSION @"10.8.5"
#define LIFERAYNATIVITY_INJECTED_NOTIFICATION @"SyncStateInjectedNotification"
EXPORT OSErr HandleLoadEvent(const AppleEvent* ev, AppleEvent* reply, long refcon);
static NSString* globalLock = @"I'm the global lock to prevent concurrent handler executions";
// SIMBL-compatible interface
@interface OwnCloudShell : NSObject { }
-(void) install;
-(void) uninstall;
@end
// just a dummy class for locating our bundle
@interface OwnCloudInjector : NSObject { }
@end
@implementation OwnCloudInjector { }
@end
static bool liferayNativityLoaded = false;
static NSString* liferayNativityBundleName = @"SyncStateFinder";
typedef struct {
NSString* location;
} configuration;
static OSErr AEPutParamString(AppleEvent* event, AEKeyword keyword, NSString* string) {
UInt8* textBuf;
CFIndex length, maxBytes, actualBytes;
length = CFStringGetLength((CFStringRef)string);
maxBytes = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8);
textBuf = malloc(maxBytes);
if (textBuf) {
CFStringGetBytes((CFStringRef)string, CFRangeMake(0, length), kCFStringEncodingUTF8, 0, true, (UInt8*)textBuf, maxBytes, &actualBytes);
OSErr err = AEPutParamPtr(event, keyword, typeUTF8Text, textBuf, actualBytes);
free(textBuf);
return err;
} else {
return memFullErr;
}
}
static void reportError(AppleEvent* reply, NSString* msg) {
NSLog(@"LiferayNativityInjector: %@", msg);
AEPutParamString(reply, keyErrorString, msg);
}
typedef enum {
InvalidBundleType,
LiferayNativityBundleType,
} LNBundleType;
static OSErr loadBundle(LNBundleType type, AppleEvent* reply, long refcon) {
bool isLoaded = false;
NSString* bundleName = nil;
NSString* targetAppName = nil;
NSString* versionCheckKey = nil;
NSString* maxVersion = nil;
NSString* minVersion = nil;
switch (type) {
case LiferayNativityBundleType:
isLoaded = liferayNativityLoaded;
bundleName = liferayNativityBundleName;
targetAppName = @"Finder";
versionCheckKey = @"LiferayNativityFinderVersionCheck";
maxVersion = FINDER_MAX_TESTED_VERSION;
minVersion = FINDER_MIN_TESTED_VERSION;
break;
default:
NSLog(@"SyncStateInjector: Failed to load bundle for type %d", type);
return 8;
break;
}
if (isLoaded) {
// NSLog(@"SyncStateInjector: %@ already loaded.", bundleName);
return noErr;
}
@try {
NSBundle* mainBundle = [NSBundle mainBundle];
if (!mainBundle) {
reportError(reply, [NSString stringWithFormat:@"Unable to locate main %@ bundle!", targetAppName]);
return 4;
}
NSString* mainVersion = [mainBundle objectForInfoDictionaryKey:@"CFBundleVersion"];
if (!mainVersion || ![mainVersion isKindOfClass:[NSString class]]) {
reportError(reply, [NSString stringWithFormat:@"Unable to determine %@ version!", targetAppName]);
return 5;
}
// future compatibility check
if (type == LiferayNativityBundleType) {
// in Dock we cannot use NSAlert and similar UI stuff - this would hang the Dock process and cause 100% CPU load
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
if ([defaults boolForKey:versionCheckKey]) {
LNStandardVersionComparator* comparator = [LNStandardVersionComparator defaultComparator];
if (([comparator compareVersion:mainVersion toVersion:maxVersion] == NSOrderedDescending) ||
([comparator compareVersion:mainVersion toVersion:minVersion] == NSOrderedAscending)) {
NSAlert* alert = [NSAlert new];
[alert setMessageText:[NSString stringWithFormat:@"You have %@ version %@", targetAppName, mainVersion]];
[alert setInformativeText:[NSString stringWithFormat:@"But %@ was properly tested only with %@ versions in range %@ - %@\n\nYou have probably updated your system and %@ version got bumped by Apple developers.\n\nYou may expect a new LiferayNativity release soon.", bundleName, targetAppName, targetAppName, minVersion, maxVersion]];
[alert setShowsSuppressionButton:YES];
[alert addButtonWithTitle:@"Launch LiferayNativity anyway"];
[alert addButtonWithTitle:@"Cancel"];
NSInteger res = [alert runModal];
if ([[alert suppressionButton] state] == NSOnState) {
[defaults setBool:NO forKey:versionCheckKey];
}
if (res != NSAlertFirstButtonReturn) {
// cancel
return noErr;
}
}
}
}
NSBundle* liferayNativityInjectorBundle = [NSBundle bundleForClass:[OwnCloudInjector class]];
NSString* liferayNativityLocation = [liferayNativityInjectorBundle pathForResource:bundleName ofType:@"bundle"];
NSBundle* pluginBundle = [NSBundle bundleWithPath:liferayNativityLocation];
if (!pluginBundle) {
reportError(reply, [NSString stringWithFormat:@"Unable to create bundle from path: %@ [%@]", liferayNativityLocation, liferayNativityInjectorBundle]);
return 2;
}
NSError* error;
if (![pluginBundle loadAndReturnError:&error]) {
reportError(reply, [NSString stringWithFormat:@"Unable to load bundle from path: %@ error: %@", liferayNativityLocation, [error localizedDescription]]);
return 6;
}
Class principalClass = [pluginBundle principalClass];
if (!principalClass) {
reportError(reply, [NSString stringWithFormat:@"Unable to retrieve principalClass for bundle: %@", pluginBundle]);
return 3;
}
id principalClassObject = NSClassFromString(NSStringFromClass(principalClass));
if ([principalClassObject respondsToSelector:@selector(install)]) {
// NSLog(@"SyncStateInjector: Installing %@ ...", bundleName);
[principalClassObject install];
}
return noErr;
} @catch (NSException* exception) {
reportError(reply, [NSString stringWithFormat:@"Failed to load %@ with exception: %@", bundleName, exception]);
}
return 1;
}
static LNBundleType mainBundleType(AppleEvent* reply) {
@try {
NSBundle* mainBundle = [NSBundle mainBundle];
if (!mainBundle) {
reportError(reply, [NSString stringWithFormat:@"Unable to locate main bundle!"]);
return InvalidBundleType;
}
if ([[mainBundle bundleIdentifier] isEqualToString:@"com.apple.finder"]) {
return LiferayNativityBundleType;
}
} @catch (NSException* exception) {
reportError(reply, [NSString stringWithFormat:@"Failed to load main bundle with exception: %@", exception]);
}
return InvalidBundleType;
}
EXPORT OSErr HandleLoadEvent(const AppleEvent* ev, AppleEvent* reply, long refcon) {
@synchronized(globalLock) {
@autoreleasepool {
NSBundle* injectorBundle = [NSBundle bundleForClass:[OwnCloudInjector class]];
NSString* injectorVersion = [injectorBundle objectForInfoDictionaryKey:@"CFBundleVersion"];
if (!injectorVersion || ![injectorVersion isKindOfClass:[NSString class]]) {
reportError(reply, [NSString stringWithFormat:@"Unable to determine SyncStateInjector version!"]);
return 7;
}
@try {
OSErr err = loadBundle(mainBundleType(reply), reply, refcon);
if (err != noErr)
{
return err;
}
pid_t pid = [[NSProcessInfo processInfo] processIdentifier];
[[NSDistributedNotificationCenter defaultCenter]postNotificationName:LIFERAYNATIVITY_INJECTED_NOTIFICATION object:[[NSBundle mainBundle]bundleIdentifier] userInfo:@{@"pid": @(pid)}];
liferayNativityLoaded = true;
return noErr;
} @catch (NSException* exception) {
reportError(reply, [NSString stringWithFormat:@"Failed to load OwnCloudFinder with exception: %@", exception]);
}
return 1;
}
}
}
EXPORT OSErr HandleLoadedEvent(const AppleEvent* ev, AppleEvent* reply, long refcon) {
@synchronized(globalLock) {
@autoreleasepool {
LNBundleType type = mainBundleType(reply);
if ((type == LiferayNativityBundleType) && liferayNativityLoaded) {
return noErr;
}
reportError(reply, @"LiferayNativity not loaded");
return 1;
}
}
}
EXPORT OSErr HandleUnloadEvent(const AppleEvent* ev, AppleEvent* reply, long refcon) {
@synchronized(globalLock) {
@autoreleasepool {
@try {
if (!liferayNativityLoaded) {
// NSLog(@"SyncStateInjector: not loaded.");
return noErr;
}
NSString* bundleName = liferayNativityBundleName;
NSBundle* liferayNativityInjectorBundle = [NSBundle bundleForClass:[OwnCloudInjector class]];
NSString* liferayNativityLocation = [liferayNativityInjectorBundle pathForResource:bundleName ofType:@"bundle"];
NSBundle* pluginBundle = [NSBundle bundleWithPath:liferayNativityLocation];
if (!pluginBundle) {
reportError(reply, [NSString stringWithFormat:@"Unable to create bundle from path: %@ [%@]", liferayNativityLocation, liferayNativityInjectorBundle]);
return 2;
}
Class principalClass = [pluginBundle principalClass];
if (!principalClass) {
reportError(reply, [NSString stringWithFormat:@"Unable to retrieve principalClass for bundle: %@", pluginBundle]);
return 3;
}
id principalClassObject = NSClassFromString(NSStringFromClass(principalClass));
if ([principalClassObject respondsToSelector:@selector(uninstall)]) {
// NSLog(@"SyncStateInjector: Uninstalling %@ ...", bundleName);
[principalClassObject uninstall];
}
liferayNativityLoaded = false;
return noErr;
} @catch (NSException* exception) {
reportError(reply, [NSString stringWithFormat:@"Failed to unload OwnCloudFinder with exception: %@", exception]);
}
return 1;
}
}
}

View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dictionary SYSTEM "file://localhost/System/Library/DTDs/sdef.dtd">
<dictionary title="OwnCloudInjector Terminology">
<suite name="OwnCloudInjector Suite" code="OWNC" description="OwnCloud Injector commands">
<command name="install OwnCloud" code="OWNCload" description="Loads OwnCloud into the Finder process"/>
<command name="uninstall OwnCloud" code="OWNCunld" description="Unloads OwnCloud from the Finder process"/>
<command name="check OwnCloud" code="OWNClded" description="Checks if OwnCloud is loaded in Finder process"/>
</suite>
</dictionary>

View File

@ -1,269 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
0B36CB92182461A10039B237 /* SyncStateFinder.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 0B36CB91182461A10039B237 /* SyncStateFinder.bundle */; };
0BD9C38E1778EF450094CF5D /* license.txt in Resources */ = {isa = PBXBuildFile; fileRef = 0BD9C38D1778EF450094CF5D /* license.txt */; };
8D576314048677EA00EA77CD /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */; };
8D5B49A804867FD3000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8D5B49A704867FD3000E48DA /* InfoPlist.strings */; };
D6ACBEA2117B7D5600F6691C /* OwnCloudInjector.m in Sources */ = {isa = PBXBuildFile; fileRef = D6ACBE9E117B7D5600F6691C /* OwnCloudInjector.m */; };
D6ACBEA3117B7D5600F6691C /* LNStandardVersionComparator.m in Sources */ = {isa = PBXBuildFile; fileRef = D6ACBEA0117B7D5600F6691C /* LNStandardVersionComparator.m */; };
D6ACBEA5117B7D6100F6691C /* OwnCloudInjector.sdef in Resources */ = {isa = PBXBuildFile; fileRef = D6ACBEA4117B7D6100F6691C /* OwnCloudInjector.sdef */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
0B36CB91182461A10039B237 /* SyncStateFinder.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; path = SyncStateFinder.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
0BD9C38D1778EF450094CF5D /* license.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = license.txt; sourceTree = "<group>"; };
8D576317048677EA00EA77CD /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
D60A992314CE37030061AD6D /* SyncStateFinder.osax */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SyncStateFinder.osax; sourceTree = BUILT_PRODUCTS_DIR; };
D6ACBE9E117B7D5600F6691C /* OwnCloudInjector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OwnCloudInjector.m; sourceTree = "<group>"; };
D6ACBE9F117B7D5600F6691C /* LNVersionComparisonProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LNVersionComparisonProtocol.h; sourceTree = "<group>"; };
D6ACBEA0117B7D5600F6691C /* LNStandardVersionComparator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LNStandardVersionComparator.m; sourceTree = "<group>"; };
D6ACBEA1117B7D5600F6691C /* LNStandardVersionComparator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LNStandardVersionComparator.h; sourceTree = "<group>"; };
D6ACBEA4117B7D6100F6691C /* OwnCloudInjector.sdef */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = OwnCloudInjector.sdef; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
8D576313048677EA00EA77CD /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
8D576314048677EA00EA77CD /* CoreFoundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
089C166AFE841209C02AAC07 /* TotalFinder-osax */ = {
isa = PBXGroup;
children = (
08FB77AFFE84173DC02AAC07 /* Source */,
089C167CFE841241C02AAC07 /* Resources */,
089C1671FE841209C02AAC07 /* Dependencies */,
D60A992414CE37030061AD6D /* Products */,
);
indentWidth = 2;
name = "SyncStateFinder-osax";
sourceTree = "<group>";
tabWidth = 2;
usesTabs = 0;
};
089C1671FE841209C02AAC07 /* Dependencies */ = {
isa = PBXGroup;
children = (
0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */,
);
name = Dependencies;
sourceTree = "<group>";
};
089C167CFE841241C02AAC07 /* Resources */ = {
isa = PBXGroup;
children = (
0B36CB91182461A10039B237 /* SyncStateFinder.bundle */,
D6ACBEA4117B7D6100F6691C /* OwnCloudInjector.sdef */,
8D576317048677EA00EA77CD /* Info.plist */,
8D5B49A704867FD3000E48DA /* InfoPlist.strings */,
0BD9C38D1778EF450094CF5D /* license.txt */,
);
name = Resources;
sourceTree = "<group>";
};
08FB77AFFE84173DC02AAC07 /* Source */ = {
isa = PBXGroup;
children = (
D6ACBE9E117B7D5600F6691C /* OwnCloudInjector.m */,
D6ACBE9F117B7D5600F6691C /* LNVersionComparisonProtocol.h */,
D6ACBEA0117B7D5600F6691C /* LNStandardVersionComparator.m */,
D6ACBEA1117B7D5600F6691C /* LNStandardVersionComparator.h */,
);
name = Source;
sourceTree = "<group>";
};
D60A992414CE37030061AD6D /* Products */ = {
isa = PBXGroup;
children = (
D60A992314CE37030061AD6D /* SyncStateFinder.osax */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
8D57630D048677EA00EA77CD /* SyncStateFinder.osax */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1DEB911A08733D790010E9CD /* Build configuration list for PBXNativeTarget "SyncStateFinder.osax" */;
buildPhases = (
8D57630F048677EA00EA77CD /* Resources */,
8D576311048677EA00EA77CD /* Sources */,
8D576313048677EA00EA77CD /* Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = SyncStateFinder.osax;
productInstallPath = "$(HOME)/Library/Bundles";
productName = "SyncStateFinder-osax";
productReference = D60A992314CE37030061AD6D /* SyncStateFinder.osax */;
productType = "com.apple.product-type.bundle";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
089C1669FE841209C02AAC07 /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
LastUpgradeCheck = 0460;
ORGANIZATIONNAME = BinaryAge;
};
buildConfigurationList = 1DEB911E08733D790010E9CD /* Build configuration list for PBXProject "OwnCloudInjector" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
en,
English,
);
mainGroup = 089C166AFE841209C02AAC07 /* TotalFinder-osax */;
productRefGroup = D60A992414CE37030061AD6D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
8D57630D048677EA00EA77CD /* SyncStateFinder.osax */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
8D57630F048677EA00EA77CD /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0B36CB92182461A10039B237 /* SyncStateFinder.bundle in Resources */,
8D5B49A804867FD3000E48DA /* InfoPlist.strings in Resources */,
D6ACBEA5117B7D6100F6691C /* OwnCloudInjector.sdef in Resources */,
0BD9C38E1778EF450094CF5D /* license.txt in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
8D576311048677EA00EA77CD /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
D6ACBEA2117B7D5600F6691C /* OwnCloudInjector.m in Sources */,
D6ACBEA3117B7D5600F6691C /* LNStandardVersionComparator.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
8D5B49A704867FD3000E48DA /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
089C167EFE841241C02AAC07 /* English */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
1DEB911B08733D790010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
COMBINE_HIDPI_IMAGES = YES;
GCC_DYNAMIC_NO_PIC = NO;
INFOPLIST_FILE = Info.plist;
OTHER_LDFLAGS = (
"-framework",
Foundation,
"-framework",
AppKit,
);
PRODUCT_NAME = SyncStateFinder;
SKIP_INSTALL = YES;
WRAPPER_EXTENSION = osax;
};
name = Debug;
};
1DEB911C08733D790010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
COMBINE_HIDPI_IMAGES = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
INFOPLIST_FILE = Info.plist;
OTHER_LDFLAGS = (
"-framework",
Foundation,
"-framework",
AppKit,
);
PRODUCT_NAME = SyncStateFinder;
WRAPPER_EXTENSION = osax;
};
name = Release;
};
1DEB911F08733D790010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CONFIGURATION_TEMP_DIR = "$(PROJECT_TEMP_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
COPY_PHASE_STRIP = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.7;
SDKROOT = macosx;
};
name = Debug;
};
1DEB912008733D790010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.7;
SDKROOT = macosx;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB911A08733D790010E9CD /* Build configuration list for PBXNativeTarget "SyncStateFinder.osax" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB911B08733D790010E9CD /* Debug */,
1DEB911C08733D790010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
1DEB911E08733D790010E9CD /* Build configuration list for PBXProject "OwnCloudInjector" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB911F08733D790010E9CD /* Debug */,
1DEB912008733D790010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 089C1669FE841209C02AAC07 /* Project object */;
}

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:OwnCloudFinder.xcodeproj">
</FileRef>
</Workspace>

View File

@ -1,73 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0500"
version = "1.3">
<BuildAction
parallelizeBuildables = "NO"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8D57630D048677EA00EA77CD"
BuildableName = "SyncStateFinder.bundle"
BlueprintName = "SyncStateFinder"
ReferencedContainer = "container:../OwnCloudFinder/OwnCloudFinder.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8D57630D048677EA00EA77CD"
BuildableName = "SyncStateFinder.osax"
BlueprintName = "SyncStateFinder.osax"
ReferencedContainer = "container:OwnCloudInjector.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>8D57630D048677EA00EA77CD</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>

View File

@ -1,25 +0,0 @@
Copyright (c) 2010-2013, BinaryAge Limited
Contributors: https://github.com/binaryage/totalfinder-osax/contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Antonin Hildebrand nor the
names of other contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY BINARYAGE LIMITED ``AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL Antonin Hildebrand BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,9 +0,0 @@
tell application "Finder"
try
«event OWNClded»
set the result to 0
on error msg number code
set the result to code
end try
end tell

View File

@ -1,24 +0,0 @@
#!/bin/sh
echo "Not used anymore, please do (from build dir) (this is <= 10.9 only)"
echo sudo cp -r ./shell_integration/MacOSX/Release/SyncStateFinder.osax /Library/ScriptingAdditions/
echo killall Finder
exit 1
SELFPATH=`dirname $0`
# osascript $SELFPATH/unload.scpt
sudo rm -rf /Library/ScriptingAdditions/SyncStateFinder.osax
# Klaas' machine
OSAXDIR=$HOME/Library/Developer/Xcode/DerivedData/OwnCloud-*/Build/Products/Debug/SyncStateFinder.osax
[ -d $OSAXDIR ] ||OSAXDIR=$HOME/Library/Developer/Xcode/DerivedData/OwnCloud-*/Build/Intermediates/ArchiveIntermediates/SyncStateFinder.osax/IntermediateBuildFilesPath/UninstalledProducts/SyncStateFinder.osax
# Markus' machine
[ -d $OSAXDIR ] || echo "OSAX does not exist"
[ -d $OSAXDIR ] && sudo cp -rv $OSAXDIR /Library/ScriptingAdditions/
sudo killall Finder
sleep 1
osascript $SELFPATH/load.scpt
osascript $SELFPATH/check.scpt

View File

@ -1,6 +0,0 @@
tell application "Finder"
try
«event OWNCload»
end try
end tell

View File

@ -1,8 +0,0 @@
#!/bin/sh
osascript -e 'tell application "Finder" \
try \
«event OWNCload» \
end try \
end tell'

View File

@ -1,6 +0,0 @@
tell application "Finder"
try
«event OWNCunld»
end try
end tell

View File

@ -24,6 +24,7 @@
#include <KIOCore/kfileitem.h>
#include <KIOCore/KFileItemListProperties>
#include <QtWidgets/QAction>
#include <QtWidgets/QMenu>
#include <QtCore/QDir>
#include <QtCore/QTimer>
#include "ownclouddolphinpluginhelper.h"
@ -53,12 +54,31 @@ public:
} ))
return {};
auto act = new QAction(parentWidget);
act->setText(helper->shareActionString());
connect(act, &QAction::triggered, this, [localFile, helper] {
auto menuaction = new QAction(parentWidget);
menuaction->setText(helper->contextMenuTitle());
auto menu = new QMenu(parentWidget);
menuaction->setMenu(menu);
auto shareAction = menu->addAction(helper->shareActionTitle());
connect(shareAction, &QAction::triggered, this, [localFile, helper] {
helper->sendCommand(QByteArray("SHARE:"+localFile.toUtf8()+"\n"));
} );
return { act };
if (!helper->copyPrivateLinkTitle().isEmpty()) {
auto copyPrivateLinkAction = menu->addAction(helper->copyPrivateLinkTitle());
connect(copyPrivateLinkAction, &QAction::triggered, this, [localFile, helper] {
helper->sendCommand(QByteArray("COPY_PRIVATE_LINK:" + localFile.toUtf8() + "\n"));
});
}
if (!helper->emailPrivateLinkTitle().isEmpty()) {
auto emailPrivateLinkAction = menu->addAction(helper->emailPrivateLinkTitle());
connect(emailPrivateLinkAction, &QAction::triggered, this, [localFile, helper] {
helper->sendCommand(QByteArray("EMAIL_PRIVATE_LINK:" + localFile.toUtf8() + "\n"));
});
}
return { menuaction };
}
};

View File

@ -59,7 +59,7 @@ void OwncloudDolphinPluginHelper::sendCommand(const char* data)
void OwncloudDolphinPluginHelper::slotConnected()
{
sendCommand("SHARE_MENU_TITLE:\n");
sendCommand("GET_STRINGS:\n");
}
void OwncloudDolphinPluginHelper::tryConnect()
@ -92,9 +92,11 @@ void OwncloudDolphinPluginHelper::slotReadyRead()
QString file = QString::fromUtf8(line.constData() + col + 1, line.size() - col - 1);
_paths.append(file);
continue;
} else if (line.startsWith("SHARE_MENU_TITLE:")) {
auto col = line.indexOf(':');
_shareActionString = QString::fromUtf8(line.constData() + col + 1, line.size() - col - 1);
} else if (line.startsWith("STRING:")) {
auto args = QString::fromUtf8(line).split(QLatin1Char(':'));
if (args.size() >= 3) {
_strings[args[1]] = args.mid(2).join(QLatin1Char(':'));
}
continue;
}
emit commandRecieved(line);

View File

@ -28,11 +28,22 @@ class OWNCLOUDDOLPHINPLUGINHELPER_EXPORT OwncloudDolphinPluginHelper : public QO
public:
static OwncloudDolphinPluginHelper *instance();
QString shareActionString() const { return _shareActionString; }
bool isConnected() const;
void sendCommand(const char *data);
QVector<QString> paths() const { return _paths; }
QString contextMenuTitle() const
{
return _strings.value("CONTEXT_MENU_TITLE", "ownCloud");
}
QString shareActionTitle() const
{
return _strings.value("SHARE_MENU_TITLE", "Share...");
}
QString copyPrivateLinkTitle() const { return _strings["COPY_PRIVATE_LINK_MENU_TITLE"]; }
QString emailPrivateLinkTitle() const { return _strings["EMAIL_PRIVATE_LINK_MENU_TITLE"]; }
signals:
void commandRecieved(const QByteArray &cmd);
@ -47,6 +58,7 @@ private:
QLocalSocket _socket;
QByteArray _line;
QVector<QString> _paths;
QString _shareActionString;
QBasicTimer _connectTimer;
QMap<QString, QString> _strings;
};

View File

@ -95,6 +95,9 @@ class SocketConnect(GObject.GObject):
print("Setting connected to %r." % self.connected )
self._watch_id = GObject.io_add_watch(self._sock, GObject.IO_IN, self._handle_notify)
print("Socket watch id: " + str(self._watch_id))
self.sendCommand('GET_STRINGS:\n')
return False # Don't run again
except Exception as e:
print("Could not connect to unix socket. " + str(e))
@ -153,6 +156,13 @@ class MenuExtension(GObject.GObject, Nautilus.MenuProvider):
def __init__(self):
GObject.GObject.__init__(self)
self.strings = {}
socketConnect.addListener(self.handle_commands)
def handle_commands(self, action, args):
if action == 'STRING':
self.strings[args[0]] = ':'.join(args[1:])
def check_registered_paths(self, filename):
topLevelFolder = False
internalFile = False
@ -178,7 +188,6 @@ class MenuExtension(GObject.GObject, Nautilus.MenuProvider):
if len(files) != 1:
return
file = files[0]
items = []
filename = get_local_path(file.get_uri())
# Check if its a folder (ends with an /), if yes add a "/"
@ -190,12 +199,14 @@ class MenuExtension(GObject.GObject, Nautilus.MenuProvider):
# Check if toplevel folder, we need to ignore those as they cannot be shared
topLevelFolder, internalFile = self.check_registered_paths(filename)
if topLevelFolder or not internalFile:
return items
return []
entry = socketConnect.nautilusVFSFile_table.get(filename)
if not entry:
return items
return []
# Currently 'sharable' also controls access to private link actions,
# and we definitely don't want to show them for IGNORED.
shareable = False
state = entry['state']
state_ok = state.startswith('OK')
@ -212,22 +223,42 @@ class MenuExtension(GObject.GObject, Nautilus.MenuProvider):
break
if not shareable:
return items
return []
# Create a menu item
labelStr = "Share with " + appname + "..."
item = Nautilus.MenuItem(name='NautilusPython::ShareItem', label=labelStr,
tip='Share file {} through {}'.format(file.get_name(), appname) )
item.connect("activate", self.menu_share, file)
items.append(item)
# Set up the 'ownCloud...' submenu
item_owncloud = Nautilus.MenuItem(
name='IntegrationMenu', label=self.strings.get('CONTEXT_MENU_TITLE', appname))
menu = Nautilus.Menu()
item_owncloud.set_submenu(menu)
return items
# Add share menu option
item = Nautilus.MenuItem(
name='NautilusPython::ShareItem',
label=self.strings.get('SHARE_MENU_TITLE', 'Share...'))
item.connect("activate", self.context_menu_action, 'SHARE', file)
menu.append_item(item)
# Add permalink menu options, but hide these options for older clients
# that don't have these actions.
if 'COPY_PRIVATE_LINK_MENU_TITLE' in self.strings:
item_copyprivatelink = Nautilus.MenuItem(
name='CopyPrivateLink', label=self.strings.get('COPY_PRIVATE_LINK_MENU_TITLE', 'Copy private link to clipboard'))
item_copyprivatelink.connect("activate", self.context_menu_action, 'COPY_PRIVATE_LINK', file)
menu.append_item(item_copyprivatelink)
if 'EMAIL_PRIVATE_LINK_MENU_TITLE' in self.strings:
item_emailprivatelink = Nautilus.MenuItem(
name='EmailPrivateLink', label=self.strings.get('EMAIL_PRIVATE_LINK_MENU_TITLE', 'Send private link by email...'))
item_emailprivatelink.connect("activate", self.context_menu_action, 'EMAIL_PRIVATE_LINK', file)
menu.append_item(item_emailprivatelink)
return [item_owncloud]
def menu_share(self, menu, file):
def context_menu_action(self, menu, action, file):
filename = get_local_path(file.get_uri())
print("Share file " + filename)
socketConnect.sendCommand("SHARE:" + filename + "\n")
print("Context menu: " + action + ' ' + filename)
socketConnect.sendCommand(action + ":" + filename + "\n")
class SyncStateExtension(GObject.GObject, Nautilus.ColumnProvider, Nautilus.InfoProvider):

View File

@ -45,7 +45,7 @@ OCClientInterface::ContextMenuInfo OCClientInterface::FetchInfo()
if (!socket.Connect(pipename)) {
return {};
}
socket.SendMsg(L"SHARE_MENU_TITLE\n");
socket.SendMsg(L"GET_STRINGS\n");
ContextMenuInfo info;
std::wstring response;
@ -56,9 +56,21 @@ OCClientInterface::ContextMenuInfo OCClientInterface::FetchInfo()
wstring responsePath = response.substr(14); // length of REGISTER_PATH
info.watchedDirectories.push_back(responsePath);
}
else if (StringUtil::begins_with(response, wstring(L"SHARE_MENU_TITLE:"))) {
info.shareMenuTitle = response.substr(17); // length of SHARE_MENU_TITLE:
break; // Stop once we received the last sent request
else if (StringUtil::begins_with(response, wstring(L"STRING:"))) {
wstring stringName, stringValue;
if (!StringUtil::extractChunks(response, stringName, stringValue))
continue;
if (stringName == L"SHARE_MENU_TITLE")
info.shareMenuTitle = move(stringValue);
else if (stringName == L"CONTEXT_MENU_TITLE")
info.contextMenuTitle = move(stringValue);
else if (stringName == L"COPY_PRIVATE_LINK_MENU_TITLE")
info.copyLinkMenuTitle = move(stringValue);
else if (stringName == L"EMAIL_PRIVATE_LINK_MENU_TITLE")
info.emailLinkMenuTitle = move(stringValue);
}
else if (StringUtil::begins_with(response, wstring(L"GET_STRINGS:END"))) {
break; // Stop once we completely received the last sent request
}
}
else {
@ -69,7 +81,22 @@ OCClientInterface::ContextMenuInfo OCClientInterface::FetchInfo()
return info;
}
void OCClientInterface::ShareObject(const std::wstring &path)
void OCClientInterface::RequestShare(const std::wstring &path)
{
SendRequest(L"SHARE", path);
}
void OCClientInterface::RequestCopyLink(const std::wstring &path)
{
SendRequest(L"COPY_PRIVATE_LINK", path);
}
void OCClientInterface::RequestEmailLink(const std::wstring &path)
{
SendRequest(L"EMAIL_PRIVATE_LINK", path);
}
void OCClientInterface::SendRequest(wchar_t *verb, const std::wstring &path)
{
auto pipename = CommunicationSocket::DefaultPipePath();
@ -82,7 +109,7 @@ void OCClientInterface::ShareObject(const std::wstring &path)
}
wchar_t msg[SOCK_BUFFER] = { 0 };
if (SUCCEEDED(StringCchPrintf(msg, SOCK_BUFFER, L"SHARE:%s\n", path.c_str())))
if (SUCCEEDED(StringCchPrintf(msg, SOCK_BUFFER, L"%s:%s\n", verb, path.c_str())))
{
socket.SendMsg(msg);
}

View File

@ -45,10 +45,19 @@ class OCClientInterface
public:
struct ContextMenuInfo {
std::vector<std::wstring> watchedDirectories;
std::wstring contextMenuTitle;
std::wstring shareMenuTitle;
std::wstring copyLinkMenuTitle;
std::wstring emailLinkMenuTitle;
};
static ContextMenuInfo FetchInfo();
static void ShareObject(const std::wstring &path);
static void RequestShare(const std::wstring &path);
static void RequestCopyLink(const std::wstring &path);
static void RequestEmailLink(const std::wstring &path);
private:
static void SendRequest(wchar_t *verb, const std::wstring &path);
};
#endif //ABSTRACTSOCKETHANDLER_H

View File

@ -25,19 +25,12 @@
extern HINSTANCE g_hInst;
extern long g_cDllRef;
#define IDM_SHARE 0
#define IDM_SHARE 0
#define IDM_COPYLINK 1
#define IDM_EMAILLINK 2
OCContextMenu::OCContextMenu(void)
: m_cRef(1)
, m_pszMenuText(L"&Share")
, m_pszVerb("ocshare")
, m_pwszVerb(L"ocshare")
, m_pszVerbCanonicalName("OCShareViaOC")
, m_pwszVerbCanonicalName(L"OCShareViaOC")
, m_pszVerbHelpText("Share via ownCloud")
, m_pwszVerbHelpText(L"Share via ownCloud")
{
InterlockedIncrement(&g_cDllRef);
}
@ -48,9 +41,19 @@ OCContextMenu::~OCContextMenu(void)
}
void OCContextMenu::OnVerbDisplayFileName(HWND hWnd)
void OCContextMenu::OnVerbShare(HWND hWnd)
{
OCClientInterface::ShareObject(std::wstring(m_szSelectedFile));
OCClientInterface::RequestShare(std::wstring(m_szSelectedFile));
}
void OCContextMenu::OnVerbCopyLink(HWND hWnd)
{
OCClientInterface::RequestCopyLink(std::wstring(m_szSelectedFile));
}
void OCContextMenu::OnVerbEmailLink(HWND hWnd)
{
OCClientInterface::RequestEmailLink(std::wstring(m_szSelectedFile));
}
@ -164,29 +167,61 @@ IFACEMETHODIMP OCContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(0));
}
InsertSeperator(hMenu, indexMenu);
indexMenu++;
InsertSeperator(hMenu, indexMenu++);
assert(!info.shareMenuTitle.empty());
MENUITEMINFO mii = { sizeof(mii) };
mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID | MIIM_STATE;
mii.wID = idCmdFirst + IDM_SHARE;
mii.fType = MFT_STRING;
mii.dwTypeData = &info.shareMenuTitle[0];
mii.fState = MFS_ENABLED;
if (!InsertMenuItem(hMenu, indexMenu, TRUE, &mii))
HMENU hSubmenu = CreateMenu();
{
return HRESULT_FROM_WIN32(GetLastError());
}
MENUITEMINFO mii = { sizeof(mii) };
mii.fMask = MIIM_SUBMENU | MIIM_FTYPE | MIIM_STRING;
mii.hSubMenu = hSubmenu;
mii.fType = MFT_STRING;
mii.dwTypeData = &info.contextMenuTitle[0];
indexMenu++;
InsertSeperator(hMenu, indexMenu);
if (!InsertMenuItem(hMenu, indexMenu++, TRUE, &mii))
return HRESULT_FROM_WIN32(GetLastError());
}
InsertSeperator(hMenu, indexMenu++);
UINT indexSubMenu = 0;
{
assert(!info.shareMenuTitle.empty());
MENUITEMINFO mii = { sizeof(mii) };
mii.fMask = MIIM_ID | MIIM_FTYPE | MIIM_STRING;
mii.wID = idCmdFirst + IDM_SHARE;
mii.fType = MFT_STRING;
mii.dwTypeData = &info.shareMenuTitle[0];
if (!InsertMenuItem(hSubmenu, indexSubMenu++, TRUE, &mii))
return HRESULT_FROM_WIN32(GetLastError());
}
{
assert(!info.copyLinkMenuTitle.empty());
MENUITEMINFO mii = { sizeof(mii) };
mii.fMask = MIIM_ID | MIIM_FTYPE | MIIM_STRING;
mii.wID = idCmdFirst + IDM_COPYLINK;
mii.fType = MFT_STRING;
mii.dwTypeData = &info.copyLinkMenuTitle[0];
if (!InsertMenuItem(hSubmenu, indexSubMenu++, TRUE, &mii))
return HRESULT_FROM_WIN32(GetLastError());
}
{
assert(!info.emailLinkMenuTitle.empty());
MENUITEMINFO mii = { sizeof(mii) };
mii.fMask = MIIM_ID | MIIM_FTYPE | MIIM_STRING;
mii.wID = idCmdFirst + IDM_EMAILLINK;
mii.fType = MFT_STRING;
mii.dwTypeData = &info.emailLinkMenuTitle[0];
if (!InsertMenuItem(hSubmenu, indexSubMenu++, TRUE, &mii))
return HRESULT_FROM_WIN32(GetLastError());
}
// Return an HRESULT value with the severity set to SEVERITY_SUCCESS.
// Set the code value to the offset of the largest command identifier
// that was assigned, plus one (1).
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(IDM_SHARE + 1));
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(IDM_EMAILLINK + 1));
}
IFACEMETHODIMP OCContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO pici)
@ -197,12 +232,16 @@ IFACEMETHODIMP OCContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO pici)
if (HIWORD(((CMINVOKECOMMANDINFOEX*)pici)->lpVerbW))
{
// Is the verb supported by this context menu extension?
if (StrCmpIW(((CMINVOKECOMMANDINFOEX*)pici)->lpVerbW, m_pwszVerb) == 0)
{
OnVerbDisplayFileName(pici->hwnd);
if (StrCmpIW(((CMINVOKECOMMANDINFOEX*)pici)->lpVerbW, L"ocshare") == 0) {
OnVerbShare(pici->hwnd);
}
else
{
else if (StrCmpIW(((CMINVOKECOMMANDINFOEX*)pici)->lpVerbW, L"occopylink") == 0) {
OnVerbCopyLink(pici->hwnd);
}
else if (StrCmpIW(((CMINVOKECOMMANDINFOEX*)pici)->lpVerbW, L"ocemaillink") == 0) {
OnVerbEmailLink(pici->hwnd);
}
else {
// If the verb is not recognized by the context menu handler, it
// must return E_FAIL to allow it to be passed on to the other
// context menu handlers that might implement that verb.
@ -216,12 +255,16 @@ IFACEMETHODIMP OCContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO pici)
{
// Is the command identifier offset supported by this context menu
// extension?
if (LOWORD(pici->lpVerb) == IDM_SHARE)
{
OnVerbDisplayFileName(pici->hwnd);
if (LOWORD(pici->lpVerb) == IDM_SHARE) {
OnVerbShare(pici->hwnd);
}
else
{
else if (LOWORD(pici->lpVerb) == IDM_COPYLINK) {
OnVerbCopyLink(pici->hwnd);
}
else if (LOWORD(pici->lpVerb) == IDM_EMAILLINK) {
OnVerbEmailLink(pici->hwnd);
}
else {
// If the verb is not recognized by the context menu handler, it
// must return E_FAIL to allow it to be passed on to the other
// context menu handlers that might implement that verb.
@ -237,31 +280,33 @@ IFACEMETHODIMP OCContextMenu::GetCommandString(UINT_PTR idCommand,
{
HRESULT hr = E_INVALIDARG;
if (idCommand == IDM_SHARE)
{
switch (uFlags)
{
case GCS_HELPTEXTW:
// Only useful for pre-Vista versions of Windows that have a
// Status bar.
hr = StringCchCopy(reinterpret_cast<PWSTR>(pszName), cchMax,
m_pwszVerbHelpText);
break;
case GCS_VERBW:
// GCS_VERBW is an optional feature that enables a caller to
// discover the canonical name for the verb passed in through
switch (idCommand) {
case IDM_SHARE:
if (uFlags == GCS_VERBW) {
// GCS_VERBW is an optional feature that enables a caller to
// discover the canonical name for the verb passed in through
// idCommand.
hr = StringCchCopy(reinterpret_cast<PWSTR>(pszName), cchMax,
m_pwszVerbCanonicalName);
break;
default:
hr = S_OK;
L"OCShareViaOC");
}
break;
case IDM_COPYLINK:
if (uFlags == GCS_VERBW) {
hr = StringCchCopy(reinterpret_cast<PWSTR>(pszName), cchMax,
L"OCCopyLink");
}
break;
case IDM_EMAILLINK:
if (uFlags == GCS_VERBW) {
hr = StringCchCopy(reinterpret_cast<PWSTR>(pszName), cchMax,
L"OCEmailLink");
}
break;
default:
break;
}
// If the command (idCommand) is not supported by this context menu
// If the idCommand or uFlags is not supported by this context menu
// extension handler, return E_INVALIDARG.
return hr;

View File

@ -46,8 +46,10 @@ private:
// The name of the selected file.
wchar_t m_szSelectedFile[MAX_PATH];
// The method that handles the "display" verb.
void OnVerbDisplayFileName(HWND hWnd);
// The method that handles the "ocshare" verb.
void OnVerbShare(HWND hWnd);
void OnVerbCopyLink(HWND hWnd);
void OnVerbEmailLink(HWND hWnd);
PWSTR m_pszMenuText;
PCSTR m_pszVerb;

View File

@ -111,17 +111,10 @@ void RemotePathChecker::workerThreadLoop()
} else if (StringUtil::begins_with(response, wstring(L"STATUS:")) ||
StringUtil::begins_with(response, wstring(L"BROADCAST:"))) {
auto statusBegin = response.find(L':', 0);
assert(statusBegin != std::wstring::npos);
auto statusEnd = response.find(L':', statusBegin + 1);
if (statusEnd == std::wstring::npos) {
// the command do not contains two colon?
wstring responseStatus, responsePath;
if (!StringUtil::extractChunks(response, responseStatus, responsePath))
continue;
}
auto responseStatus = response.substr(statusBegin+1, statusEnd - statusBegin-1);
auto responsePath = response.substr(statusEnd+1);
auto state = _StrToFileState(responseStatus);
bool wasAsked = asked.erase(responsePath) > 0;

View File

@ -17,6 +17,7 @@
#pragma once
#include <string>
#include <cassert>
class __declspec(dllexport) StringUtil {
public:
@ -44,6 +45,22 @@ public:
return (childLength == parentLength || childLength > parentLength && (child[parentLength] == L'\\' || child[parentLength - 1] == L'\\'))
&& wcsncmp(child, parent, parentLength) == 0;
}
static bool extractChunks(const std::wstring &source, std::wstring &secondChunk, std::wstring &thirdChunk) {
auto statusBegin = source.find(L':', 0);
assert(statusBegin != std::wstring::npos);
auto statusEnd = source.find(L':', statusBegin + 1);
if (statusEnd == std::wstring::npos) {
// the command do not contains two colon?
return false;
}
// Assume the caller extracted the chunk before the first colon.
secondChunk = source.substr(statusBegin + 1, statusEnd - statusBegin - 1);
thirdChunk = source.substr(statusEnd + 1);
return true;
}
};
#endif // STRINGUTIL_H

View File

@ -2,7 +2,7 @@
// This is the number that will end up in the version window of the DLLs.
// Increment this version before committing a new build if you are today's shell_integration build master.
#define OCEXT_BUILD_NUM 45
#define OCEXT_BUILD_NUM 46
#define STRINGIZE2(s) #s
#define STRINGIZE(s) STRINGIZE2(s)

Some files were not shown because too many files have changed in this diff Show More