Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Collaboration Tools #47

Closed
wants to merge 76 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
f6830be
Add classes to simplify the API for creating a Mastodon menu entry.
maarzt Sep 21, 2023
1bbf6cc
Add plugin for uploading a Mastodon project to github / gitlab
maarzt Sep 21, 2023
08dc647
Add basic command to clone repository and open dataset
maarzt Sep 21, 2023
b580eb6
BasicMamutPlugin: make WindowManager and MamutAppModel accessible
maarzt Sep 21, 2023
6d1a377
Add git commit plugin
maarzt Sep 21, 2023
4948ad9
Mastodon Git: move SciJava commands to a separate package
maarzt Sep 21, 2023
39cf789
MastodonGit: remove unnecessary MastodonGitCommit class
maarzt Sep 21, 2023
646d614
Mastodon Git: implement push on create branch commands
maarzt Sep 21, 2023
a289403
MastodonGitUtils: don't unnecessary save the project
maarzt Sep 21, 2023
3f9709a
Mastodon Git: add switch branch plugin
maarzt Sep 21, 2023
4f3f398
Simplify the computation of max non empty time point in the merge Dat…
maarzt Sep 22, 2023
866815d
Mastodon Git: implement merge command based on the exiting merge tool
maarzt Sep 22, 2023
a0a1113
Mastodon Git: add pull and reset commands
maarzt Sep 22, 2023
013b3df
Add TODO
maarzt Sep 22, 2023
340b07e
Mastodon Git: add commit graph example
maarzt Sep 27, 2023
d28a157
MastodonGitUtils: refactoring
maarzt Sep 27, 2023
dc39105
Mastodon Git: shuffle menu entries
maarzt Sep 27, 2023
409a558
Mastodon Git: allow to switch to remote only branch
maarzt Sep 27, 2023
f24f1dd
Add class that asks for username and password once
maarzt Sep 28, 2023
1f3388c
Rename MastodonGitUtils and MastodonGitPlugins
maarzt Oct 2, 2023
c63b699
Introduce a MastodonGitRepository object per Mastodon instance
maarzt Oct 2, 2023
abaa7a0
Mastodon Git: rename menu entries
maarzt Oct 2, 2023
c4a0b47
Mastodon Git share project / clone project: add checkbox create new s…
maarzt Oct 2, 2023
d14608b
MastodonGitNewBranch: better title
maarzt Oct 2, 2023
c665067
MastodonGit: fix title for the reset command
maarzt Oct 2, 2023
323203e
POM: remove duplicated dependency
maarzt Oct 2, 2023
13055ee
Mastodon Git: let the user know if credentials where wrong
maarzt Oct 2, 2023
d96f4ad
Example on using SSH certificate in non standard location.
maarzt Oct 6, 2023
9367de4
MastodonGitCloneRepository: Add descriptions
maarzt Oct 6, 2023
afd272f
Mastodon Git: fix merge for projects where the image data is not avai…
maarzt Oct 6, 2023
14f713f
MastodonGitRepository: small refactoring
maarzt Oct 6, 2023
ac351e2
MastodonGitController: make switch branch also perform a git fetch
maarzt Oct 6, 2023
ab3d7c3
MastodonGitRepository: fix exception message
maarzt Oct 6, 2023
c9d1a92
Mastodon Git: allow to specify author, email and message used in commits
maarzt Oct 10, 2023
884f43c
Mastodon Git: add a cancel button to the commands
maarzt Oct 10, 2023
bc27080
Mastodon Git: remove dead code
maarzt Oct 10, 2023
24daad7
Mastodon Git: ask for author name
maarzt Oct 17, 2023
ea80b28
Mastodon Git: disable git related commands if not in a git repository
maarzt Oct 17, 2023
a21b713
Mastodon Git: fix typo
maarzt Oct 17, 2023
e9ec343
Mastodon Git: don't initialize repository when sharing a project
maarzt Oct 17, 2023
ed8aaa1
Mastodon Git: use text area in the commit command
maarzt Oct 17, 2023
66376ab
Mastodon Git: fix reset command, to undo changes on disc
maarzt Oct 18, 2023
1e1dfd9
Mastodon Git: let the pull command perform an automatic merge if poss…
maarzt Oct 18, 2023
8c42548
Mastodon Git: reuse code for normal merge and pull merge
maarzt Oct 18, 2023
26dc173
Add plugin to fix graph inconsistencies
maarzt Oct 18, 2023
676f4a6
Mastodon Git: don't reset project.xml, gui.xml during merge abort
maarzt Oct 18, 2023
331e0d0
Mastodon Git: tweak UI texts
maarzt Oct 18, 2023
1effc68
Mastodon Git: use gitignore for gui.xml, project.xml etc.
maarzt Oct 18, 2023
5f6b9be
Mastodon Git: show a dialog if there is an exception
maarzt Oct 19, 2023
5965628
Mastodon Git: inform user about an failed push
maarzt Oct 19, 2023
60fcffc
Mastodon Git: make sure the repo is clean before, switch, pull & merge
maarzt Oct 19, 2023
b736536
Mastodon Git: let the SettingsService implement ImageJService
maarzt Oct 19, 2023
86366e7
Mastodon Git: use JGit version that still support Java8
maarzt Oct 19, 2023
ee362b0
Mastodon Git: show success notification on push
maarzt Oct 20, 2023
915ee0f
Mastodon Git: add show branch name command
maarzt Oct 22, 2023
ef14faf
Mastodon Git: add synchronize menu item
maarzt Oct 22, 2023
9efb1c9
MastodonGitController: fix code formatting
maarzt Oct 23, 2023
d6779be
PersistentCredentials: fix typo
maarzt Nov 9, 2023
1bec310
Refactor PersistentCredentials
maarzt Nov 9, 2023
6d773fd
Mastodon Git: clicking cancel on username, password dialog is handled…
maarzt Nov 10, 2023
ae511d1
Mastodon Git: improve error message in NewDirectoryUtils
maarzt Nov 10, 2023
cef6a52
Mastodon Git: fix typo
maarzt Nov 10, 2023
050375b
Mastodon Git: include stack traces in the error message dialog
maarzt Nov 10, 2023
b2c868a
MastodonGitRepository: improve exceptions
maarzt Nov 13, 2023
23462c7
MastodonGitRepository: remove unused code
maarzt Nov 13, 2023
3736a42
Mastodon Git: refactor the dialogues
maarzt Nov 13, 2023
3170f4d
MastodonGitController: move the TODO notes into a github issue
maarzt Nov 13, 2023
24f2994
MastodonGitController: make the command identifiers more user-friendly
maarzt Nov 13, 2023
09effdc
CommitMessageDialog: remove unused parameter
maarzt Nov 13, 2023
efc98a7
MastodonGitController: improve descriptions
maarzt Nov 13, 2023
baf318d
Remove MastodonGitCommitCommand
maarzt Nov 13, 2023
69f265a
Mastodon Git: rename Fiji menu entry for downloading a shared project
maarzt Nov 13, 2023
9c7cc4a
Mastodon Git: make parameter private and final if possible
maarzt Nov 13, 2023
136eeb1
Clean up BasicMamutPlugin and BasicDescriptionProvider
maarzt Nov 13, 2023
911d9fe
Mastodon Git: add javadoc
maarzt Nov 13, 2023
ff26e88
Mastodon Git: rename menu entry to "Collaborative (Git)"
maarzt Nov 14, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,22 @@
<artifactId>mpicbg</artifactId>
</dependency>

<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>5.13.2.202306221912-r</version>
</dependency>
<!-- SSH support for JGit based on Apache MINA sshd - not sure if this is needed -->
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.ssh.apache</artifactId>
<version>5.13.2.202306221912-r</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.ui</artifactId>
<version>5.13.2.202306221912-r</version>
</dependency>
<!-- Test dependencies -->
<dependency>
<groupId>junit</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package org.mastodon.mamut.tomancak.collaboration;

import java.awt.KeyboardFocusManager;

import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import net.miginfocom.swing.MigLayout;

/**
* A dialog that asks the user to enter a commit message.
* The dialog can be closed by using the mouse to clock OK or Cancel,
* by pressing CTRL-ENTER or ESCAPE, or by pressing TAB and ENTER.
*/
public class CommitMessageDialog
{

/**
* Show a dialog that asks the user to enter a commit message.
*
* @return The commit message as a String, or null if the dialog was cancelled.
*/
public static String showDialog()
{
JTextArea textArea = new JTextArea( 5, 40 );

// Make the tab key move focus to the next component and shift-tab to the previous.
textArea.setFocusTraversalKeys( KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null );
textArea.setFocusTraversalKeys( KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null );

JPanel panel = new JPanel();
panel.setLayout( new MigLayout( "insets dialog" ) );
panel.add( new JLabel( "Save point message:" ), "wrap" );
panel.add( new JScrollPane( textArea ), "wrap" );
panel.add( new JLabel( "Please describe briefly the changes since the last save point!" ) );

// Show a JOptionPane, where the TextArea has focus when the dialog is shown.
JOptionPane optionPane = new JOptionPane( panel, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION )
{
@Override
public void selectInitialValue()
{
super.selectInitialValue();
textArea.requestFocusInWindow();
}
};
JDialog dialog = optionPane.createDialog( "Add Save Point (commit)" );
dialog.setVisible( true );
dialog.dispose();
Object result = optionPane.getValue();
if ( result instanceof Integer && ( int ) result == JOptionPane.OK_OPTION )
return textArea.getText();
else
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package org.mastodon.mamut.tomancak.collaboration;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
import java.awt.event.ItemEvent;

import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

import org.apache.commons.lang3.exception.ExceptionUtils;

/**
* A dialog that shows an exception message and stack trace.
* The stack trace is hidden by default and can be shown by
* clicking on "details".
*/
public class ErrorDialog
{

public static void showErrorMessage( String title, Exception exception )
{
SwingUtilities.invokeLater( () -> showDialog( null, title + " (Error)", exception ) );
}

private static void showDialog( Frame parent, String title, Exception exception )
{
String message = "\nThere was a problem:\n\n " + exception.getMessage() + "\n\n";
final JScrollPane scrollPane = initScrollPane( exception );
final JCheckBox checkBox = new JCheckBox( "show details" );
checkBox.setForeground( Color.BLUE );
Object[] objects = { message, checkBox, scrollPane };
JOptionPane pane = new JOptionPane( objects, JOptionPane.ERROR_MESSAGE );
JDialog dialog = pane.createDialog( parent, title );
dialog.setResizable( true );
checkBox.addItemListener( event -> {
boolean visible = event.getStateChange() == ItemEvent.SELECTED;
scrollPane.setVisible( visible );
scrollPane.setPreferredSize( visible ? null : new Dimension( 0, 0 ) );
dialog.pack();
} );
dialog.setModal( true );
dialog.pack();
dialog.setVisible( true );
dialog.dispose();
}

private static JScrollPane initScrollPane( Exception exception )
{
String stackTrace = ExceptionUtils.getStackTrace( exception );
int lines = Math.min( 20, countLines( stackTrace ) );
JTextArea textArea = new JTextArea( stackTrace, lines, 70 );
textArea.setForeground( new Color( 0x880000 ) );
textArea.setEditable( false );
textArea.setFont( new Font( Font.MONOSPACED, Font.PLAIN, textArea.getFont().getSize() ) );
final JScrollPane scrollPane = new JScrollPane( textArea );
scrollPane.setVisible( false );
return scrollPane;
}

private static int countLines( String str )
{
String[] lines = str.split( "\r\n|\r|\n" );
return lines.length;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package org.mastodon.mamut.tomancak.collaboration;

import org.mastodon.collection.RefCollection;
import org.mastodon.collection.RefCollections;
import org.mastodon.collection.RefList;
import org.mastodon.collection.RefSet;
import org.mastodon.collection.ref.RefArrayList;
import org.mastodon.collection.ref.RefSetImp;
import org.mastodon.mamut.model.Link;
import org.mastodon.mamut.model.Model;
import org.mastodon.mamut.model.ModelGraph;
import org.mastodon.mamut.model.Spot;
import org.mastodon.mamut.plugin.MamutPlugin;
import org.mastodon.mamut.tomancak.collaboration.utils.ActionDescriptions;
import org.mastodon.mamut.tomancak.collaboration.utils.BasicDescriptionProvider;
import org.mastodon.mamut.tomancak.collaboration.utils.BasicMamutPlugin;
import org.mastodon.ui.keymap.CommandDescriptionProvider;
import org.mastodon.ui.keymap.KeyConfigContexts;
import org.scijava.plugin.Plugin;

@Plugin( type = MamutPlugin.class )
public class FixGraphInconsistenciesPlugin extends BasicMamutPlugin
{

private static final ActionDescriptions< FixGraphInconsistenciesPlugin > actionDescriptions = new ActionDescriptions<>( FixGraphInconsistenciesPlugin.class );

static
{
actionDescriptions.addActionDescription(
"[mastodon-tomancak] fix graph inconsistencies",
"Plugins > Trees Management > Fix Graph Inconsistencies",
"Flip reversed edges",
FixGraphInconsistenciesPlugin::fixGraphInconsistencies );
}

public < T > FixGraphInconsistenciesPlugin()
{
super( actionDescriptions );
}

private void fixGraphInconsistencies()
{
Model model = getAppModel().getModel();
ModelGraph graph = model.getGraph();
flipBackwardsEdges( graph );
removeDoubleEdges( graph );
removeSameTimepointEdge( graph );
printWarnings( graph );
}

private static void printWarnings( ModelGraph graph )
{
for ( Spot spot : graph.vertices() )
{
if ( spot.incomingEdges().size() > 1 )
System.out.println( "More than one parent: " + spot.getLabel() );

if ( spot.outgoingEdges().size() > 2 )
System.out.println( "More than two children: " + spot.getLabel() );
}
}

private static void removeSameTimepointEdge( ModelGraph graph )
{
RefCollection< Link > backwardEdge = RefCollections.createRefList( graph.edges() );
Spot sourceRef = graph.vertexRef();
Spot targetRef = graph.vertexRef();
for ( Link edge : graph.edges() )
{
Spot source = edge.getSource( sourceRef );
Spot target = edge.getTarget( targetRef );
if ( source.getTimepoint() == target.getTimepoint() )
backwardEdge.add( edge );
}
for ( Link edge : backwardEdge )
{
Spot source = edge.getSource( sourceRef );
Spot target = edge.getTarget( targetRef );
System.out.println( "Remove same timepoint edge " + source.getLabel() + " -> " + target.getLabel() );
graph.remove( edge );
}
}

private static void removeDoubleEdges( ModelGraph graph )
{
Spot ref1 = graph.vertexRef();
Spot ref2 = graph.vertexRef();
RefSet< Spot > sources = new RefSetImp<>( graph.vertices().getRefPool() );
RefList< Link > doubleEdge = new RefArrayList<>( graph.edges().getRefPool() );
for ( Spot spot : graph.vertices() )
{
if ( spot.incomingEdges().size() > 1 )
{
for ( Link link : spot.incomingEdges() )
{
Spot source = link.getSource( ref1 );
if ( sources.contains( source ) )
doubleEdge.add( link );
else
sources.add( source );
}
sources.clear();
}
}
for ( Link link : doubleEdge )
{
Spot source = link.getSource( ref1 );
Spot target = link.getTarget( ref2 );
System.out.println( "Remove duplicated edge: " + source.getLabel() + " -> " + target.getLabel() );
graph.remove( link );
}
}

private static void flipBackwardsEdges( ModelGraph graph )
{
RefCollection< Link > backwardEdge = RefCollections.createRefList( graph.edges() );
Spot sourceRef = graph.vertexRef();
Spot targetRef = graph.vertexRef();
for ( Link edge : graph.edges() )
{
Spot source = edge.getSource( sourceRef );
Spot target = edge.getTarget( targetRef );
if ( source.getTimepoint() > target.getTimepoint() )
backwardEdge.add( edge );
}
for ( Link edge : backwardEdge )
{
Spot source = edge.getSource( sourceRef );
Spot target = edge.getTarget( targetRef );
System.out.println( "Flip backwards edge " + source.getLabel() + " -> " + target.getLabel() );
graph.remove( edge );
graph.addEdge( source, target ).init();
}
}

@Plugin( type = CommandDescriptionProvider.class )
public static class DescriptionProvider extends BasicDescriptionProvider
{
public DescriptionProvider()
{
super( actionDescriptions, KeyConfigContexts.MASTODON, KeyConfigContexts.TRACKSCHEME );
}
}
}
Loading