/*
* Syncany, www.syncany.org
* Copyright (C) 2011-2015 Philipp C. Heckel <philipp.heckel@gmail.com>
*
* 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 org.syncany.gui.tray;
import java.io.File;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicBoolean;
import org.syncany.util.LimitedSortedSet;
import org.syncany.operations.ChangeSet;
import org.syncany.operations.log.LightweightDatabaseVersion;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
/**
* @author Philipp C. Heckel <philipp.heckel@gmail.com>
*/
public class RecentFileChanges {
public static final int RECENT_CHANGES_COUNT = 15;
private TrayIcon trayIcon;
private Timer recentFileChangesUpdateTimer;
private AtomicBoolean recentFileChangesUpdated;
private LimitedSortedSet<RecentFileEntry> recentFileChanges;
public RecentFileChanges(TrayIcon trayIcon) {
this.trayIcon = trayIcon;
this.recentFileChangesUpdateTimer = new Timer();
this.recentFileChangesUpdated = new AtomicBoolean(false);
this.recentFileChanges = new LimitedSortedSet<>(RECENT_CHANGES_COUNT);
initTimer();
}
private void initTimer() {
recentFileChangesUpdateTimer.schedule(new TimerTask() {
@Override
public void run() {
if (recentFileChangesUpdated.get()) {
trayIcon.setRecentChanges(getRecentFiles());
recentFileChangesUpdated.set(false);
}
}
}, 6000, 3000);
}
public void updateRecentFiles(String root, List<LightweightDatabaseVersion> databaseVersions) {
for (LightweightDatabaseVersion databaseVersion : databaseVersions) {
updateRecentFiles(root, databaseVersion.getDate(), databaseVersion.getChangeSet());
}
}
public void updateRecentFiles(String root, Date date, ChangeSet changeSet) {
// Update recent file entries (list only)
for (String newFile : changeSet.getNewFiles()) {
replaceEntry(new RecentFileEntry(new File(root, newFile), date));
}
for (String changedFile : changeSet.getChangedFiles()) {
replaceEntry(new RecentFileEntry(new File(root, changedFile), date));
}
// Trigger update thread
if (changeSet.getNewFiles().size() > 0 || changeSet.getChangedFiles().size() > 0) {
recentFileChangesUpdated.set(true);
}
}
private synchronized void replaceEntry(final RecentFileEntry recentFileEntry) {
// Remove old entry
Iterables.removeIf(recentFileChanges, new Predicate<RecentFileEntry>() {
@Override
public boolean apply(RecentFileEntry aRecentFileEntry) {
return aRecentFileEntry.file.equals(recentFileEntry.file);
}
});
// Add new entry
recentFileChanges.add(recentFileEntry);
}
public synchronized List<File> getRecentFiles() {
List<File> recentChanges = Lists.newArrayList();
Iterator<RecentFileEntry> recentChangeEntryIterator = recentFileChanges.iterator();
while (recentChangeEntryIterator.hasNext()) {
recentChanges.add(recentChangeEntryIterator.next().file);
}
return recentChanges;
}
public synchronized void clear() {
recentFileChanges.clear();
}
public synchronized int size() {
return recentFileChanges.size();
}
private static class RecentFileEntry implements Comparable<RecentFileEntry> {
private File file;
private Date date;
public RecentFileEntry(File file, Date date) {
this.file = file;
this.date = date;
}
@Override
public int compareTo(RecentFileEntry other) {
int dateCompare = other.date.compareTo(date);
if (dateCompare == 0) {
return other.file.compareTo(file);
}
else {
return dateCompare;
}
}
}
}