Skip to content
This repository has been archived by the owner on Sep 6, 2019. It is now read-only.

Commit

Permalink
#3: Experimental overlay icons on Windows (#64)
Browse files Browse the repository at this point in the history
Only for the Goobox folder only, but not its files and subfolders.
  • Loading branch information
kaloyan-raev authored Dec 15, 2017
1 parent 5a4e317 commit 5cfda24
Show file tree
Hide file tree
Showing 5 changed files with 219 additions and 0 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,12 @@ The app uses an embedded Nitrine database for storing the current sync state of
- `~/Library/Application Support/Goobox` for macOS

The `list-db.bat` script can be used to dump the content of the database. This might be useful for debugging.

### Overlay icons on Windows

Setting up the overlay icons on Windows required the following steps:

1. Open a Command Prompt as Administrator
1. Execute the `register-dlls.bat` file
1. Restart Windows
1. Run the app as usual
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@
<artifactId>libstorj-java</artifactId>
<version>0.4</version>
</dependency>
<dependency>
<groupId>com.liferay</groupId>
<artifactId>com.liferay.nativity</artifactId>
<version>1.0.5</version>
</dependency>
<dependency>
<groupId>org.dizitart</groupId>
<artifactId>nitrite</artifactId>
Expand Down
52 changes: 52 additions & 0 deletions src/main/java/io/goobox/sync/storj/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,17 @@
import java.nio.file.Path;
import java.util.concurrent.CountDownLatch;

import com.liferay.nativity.control.NativityControl;
import com.liferay.nativity.control.NativityControlUtil;
import com.liferay.nativity.modules.fileicon.FileIconControl;
import com.liferay.nativity.modules.fileicon.FileIconControlCallback;
import com.liferay.nativity.modules.fileicon.FileIconControlUtil;
import com.liferay.nativity.util.OSDetector;

import io.goobox.sync.common.Utils;
import io.goobox.sync.common.systemtray.ShutdownListener;
import io.goobox.sync.common.systemtray.SystemTrayHelper;
import io.goobox.sync.storj.overlay.OverlayHelper;
import io.storj.libstorj.Bucket;
import io.storj.libstorj.CreateBucketCallback;
import io.storj.libstorj.GetBucketsCallback;
Expand All @@ -42,6 +50,49 @@ public class App implements ShutdownListener {
public static void main(String[] args) {
instance = new App();
instance.init();

NativityControl nativityControl = NativityControlUtil.getNativityControl();
nativityControl.connect();

// Setting filter folders is required for Mac's Finder Sync plugin
// nativityControl.setFilterFolder(Utils.getSyncDir().toString());

/* File Icons */

int testIconId = 1;

// FileIconControlCallback used by Windows and Mac
FileIconControlCallback fileIconControlCallback = new FileIconControlCallback() {
@Override
public int getIconForFile(String path) {
return 1; // testIconId;
}
};

FileIconControl fileIconControl = FileIconControlUtil.getFileIconControl(nativityControl,
fileIconControlCallback);

fileIconControl.enableFileIcons();

String testFilePath = Utils.getSyncDir().toString();

if (OSDetector.isWindows()) {
// This id is determined when building the DLL
testIconId = 1;
} else if (OSDetector.isMinimumAppleVersion(OSDetector.MAC_YOSEMITE_10_10)) {
// Used by Mac Finder Sync. This unique id can be set at runtime.
testIconId = 1;

fileIconControl.registerIconWithId("/tmp/goobox.icns",
"test label", "" + testIconId);
} else if (OSDetector.isLinux()) {
// Used by Mac Injector and Linux
testIconId = fileIconControl.registerIcon("/tmp/git-clean.png");
}

// FileIconControl.setFileIcon() method only used by Linux
fileIconControl.setFileIcon(testFilePath, testIconId);
nativityControl.disconnect();
}

public static App getInstance() {
Expand Down Expand Up @@ -97,6 +148,7 @@ private void init() {
@Override
public void shutdown() {
// TODO graceful shutdown
OverlayHelper.getInstance().shutdown();
System.exit(0);
}

Expand Down
3 changes: 3 additions & 0 deletions src/main/java/io/goobox/sync/storj/CheckStateTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import io.goobox.sync.storj.db.DB;
import io.goobox.sync.storj.db.SyncFile;
import io.goobox.sync.storj.db.SyncState;
import io.goobox.sync.storj.overlay.OverlayHelper;
import io.storj.libstorj.Bucket;
import io.storj.libstorj.File;
import io.storj.libstorj.ListFilesCallback;
Expand All @@ -56,6 +57,7 @@ public void run() {

System.out.println("Checking for changes...");
SystemTrayHelper.setSynchronizing();
OverlayHelper.getInstance().setSynchronizing();

Storj.getInstance().listFiles(gooboxBucket, new ListFilesCallback() {
@Override
Expand All @@ -68,6 +70,7 @@ public void onFilesReceived(File[] files) {
// Sleep some time to avoid overloading the bridge
tasks.add(new SleepTask());
SystemTrayHelper.setIdle();
OverlayHelper.getInstance().setOK();
}
// Add itself to the queueAdd itself to the queue
tasks.add(CheckStateTask.this);
Expand Down
150 changes: 150 additions & 0 deletions src/main/java/io/goobox/sync/storj/overlay/OverlayHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/*
* Copyright (C) 2017 Kaloyan Raev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.goobox.sync.storj.overlay;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.attribute.DosFileAttributeView;
import java.util.ArrayList;
import java.util.List;

import com.liferay.nativity.control.NativityControl;
import com.liferay.nativity.control.NativityControlUtil;
import com.liferay.nativity.modules.contextmenu.ContextMenuControlCallback;
import com.liferay.nativity.modules.contextmenu.ContextMenuControlUtil;
import com.liferay.nativity.modules.contextmenu.model.ContextMenuAction;
import com.liferay.nativity.modules.contextmenu.model.ContextMenuItem;
import com.liferay.nativity.modules.fileicon.FileIconControl;
import com.liferay.nativity.modules.fileicon.FileIconControlCallback;
import com.liferay.nativity.modules.fileicon.FileIconControlUtil;
import com.liferay.nativity.util.OSDetector;

import io.goobox.sync.common.Utils;

public class OverlayHelper {

private NativityControl nativityControl;
private FileIconControl fileIconControl;

private int stateIconId = 0;

private static OverlayHelper instance;

public static OverlayHelper getInstance() {
if (instance == null) {
instance = new OverlayHelper();
}
return instance;
}

public OverlayHelper() {
init();
}

public void setOK() {
if (!OSDetector.isWindows()) {
return;
}

stateIconId = 1;
refresh();
}

public void setSynchronizing() {
if (!OSDetector.isWindows()) {
return;
}

stateIconId = 2;
refresh();
}

public void shutdown() {
if (!OSDetector.isWindows()) {
return;
}

stateIconId = 0;
refresh();
nativityControl.disconnect();
}

private void refresh() {
fileIconControl.refreshIcons(new String[] { Utils.getSyncDir().toString() });
}

private void init() {
if (!OSDetector.isWindows()) {
return;
}

nativityControl = NativityControlUtil.getNativityControl();
nativityControl.connect();

// Setting filter folders is required for Mac's Finder Sync plugin
nativityControl.setFilterFolder(Utils.getSyncDir().toString());

DosFileAttributeView attr = Files.getFileAttributeView(Utils.getSyncDir(), DosFileAttributeView.class);
try {
attr.setSystem(true);
} catch (IOException e) {
e.printStackTrace();
}

// FileIconControlCallback used by Windows and Mac
FileIconControlCallback fileIconControlCallback = new FileIconControlCallback() {
@Override
public int getIconForFile(String path) {
if (Utils.getSyncDir().toString().equals(path)) {
return stateIconId;
}
return 0;
}
};

fileIconControl = FileIconControlUtil.getFileIconControl(nativityControl, fileIconControlCallback);

fileIconControl.enableFileIcons();

/* Context Menus */

ContextMenuControlCallback contextMenuControlCallback = new ContextMenuControlCallback() {
@Override
public List<ContextMenuItem> getContextMenuItems(String[] paths) {
ContextMenuItem contextMenuItem = new ContextMenuItem("Goobox");

ContextMenuAction contextMenuAction = new ContextMenuAction() {
@Override
public void onSelection(String[] paths) {
System.out.println("Context menu selection: " + String.join("; ", paths));
}
};

contextMenuItem.setContextMenuAction(contextMenuAction);

List<ContextMenuItem> contextMenuItems = new ArrayList<ContextMenuItem>();
contextMenuItems.add(contextMenuItem);

// Mac Finder Sync will only show the parent level of context menus
return contextMenuItems;
}
};

ContextMenuControlUtil.getContextMenuControl(nativityControl, contextMenuControlCallback);
}

}

0 comments on commit 5cfda24

Please sign in to comment.