Initial commit

This commit is contained in:
Dmitry Peshehonov 2020-04-30 22:40:03 +03:00
commit 44a36e5927
4722 changed files with 603578 additions and 0 deletions

81
.gitattributes vendored Normal file
View File

@ -0,0 +1,81 @@
# Boilerplate .gitattributes
#
# If you add anything here that might be useful for other (new) projects,
# consider changing ssh://git/git/template.git
* text=auto !eol
.*ignore text
.gitignore text
.gitattributes text
*.txt text
*.java text diff=java
*.html text diff=html
*.css text
*.js text
*.ts text
*.sql text
*.properties text
*.ipr text
*.iml text
*.iws text
*.xml text
*.form text
*.dtd text
*.xsl text
*.xslt text
*.plist text
*.vm text
*.install4j text
*.cs text diff=csharp
*.csproj text merge=union
*.sln text merge=union eol=crlf
*.dsp text eol=crlf
*.dsw text eol=crlf
*.c text diff=cpp
*.cpp text diff=cpp
*.h text diff=cpp
*.php text diff=php
*.py text diff=python
*.sh text eol=lf
*.bat text eol=crlf
*.cmd text eol=crlf
*.lnk text eol=crlf
Makefile text
*.png binary
*.jpg binary
*.gif binary
*.license binary
*.jar binary
*.zip binary
*.exe binary
*.bin binary
*.dat binary
*.bmp binary
*.ico binary
*.pdf binary
*.json text
*.jsbe text eol=crlf
*.jsbp text eol=crlf
*.jsbn text eol=crlf
*.jsbh text eol=crlf
*.jsbf text eol=crlf
*.jsbc text eol=crlf
*.mp4 binary
*.soy text
*.groovy text
*.gant text
README text
*.pem text
*.gpg text

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
build/
build.idea/
ant/generated.xml

8
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

9
.idea/jiraclient.iml Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

10
.idea/misc.xml Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
<component name="PreferredVcsStorage">
<preferredVcsName>ApexVCS</preferredVcsName>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8_112" project-jdk-type="JavaSDK" />
</project>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/jiraclient.iml" filepath="$PROJECT_DIR$/.idea/jiraclient.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

13
AppInit/AppInit.iml Normal file
View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<module relativePaths="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/../build.idea/AppInit" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1,9 @@
package com.almworks.appinit;
import java.awt.*;
public interface AWTEventPreprocessor {
boolean preprocess(AWTEvent event, boolean alreadyConsumed);
boolean postProcess(AWTEvent event, boolean alreadyConsumed);
}

View File

@ -0,0 +1,117 @@
package com.almworks.appinit;
import javax.swing.*;
import java.awt.*;
import java.awt.event.InputEvent;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* @author dyoma
*/
public class EventQueueReplacement extends EventQueue {
// @Nullable
private static EventQueueReplacement INSTANCE;
private final java.util.List<AWTEventPreprocessor> myPreprocessors = new ArrayList();
private AWTEventPreprocessor[] myArray;
private EventQueueReplacement() {
}
// @ThreadSafe
public void addPreprocessor(final AWTEventPreprocessor preprocessor) {
synchronized (myPreprocessors) {
myPreprocessors.add(preprocessor);
resetArray();
}
}
private void resetArray() {
int size = myPreprocessors.size();
myArray = size == 0 ? null : myPreprocessors.toArray(new AWTEventPreprocessor[size]);
}
// @ThreadSafe
public boolean removePreprocessor(AWTEventPreprocessor preprocessor) {
synchronized (myPreprocessors) {
boolean result = myPreprocessors.remove(preprocessor);
resetArray();
return result;
}
}
protected void dispatchEvent(AWTEvent event) {
boolean consumed = false;
AWTEventPreprocessor[] array = myArray;
if (array != null) {
for (AWTEventPreprocessor preprocessor : array) {
consumed = preprocessor.preprocess(event, consumed);
if (consumed) {
break;
}
}
}
if (!consumed) {
super.dispatchEvent(event);
}
consumed = consumed || ((event instanceof InputEvent) && ((InputEvent) event).isConsumed());
if (array != null && !consumed) {
for (AWTEventPreprocessor processor : array) {
consumed = processor.postProcess(event, consumed);
if (consumed) break;
}
}
}
// @NotNull
public static EventQueueReplacement ensureInstalled() {
synchronized (EventQueueReplacement.class) {
if (INSTANCE != null) return INSTANCE;
}
Runnable runnable = new Runnable() {
@Override
public void run() {
synchronized (EventQueueReplacement.class) {
if (INSTANCE == null) {
EventQueueReplacement queue = new EventQueueReplacement();
Toolkit.getDefaultToolkit().getSystemEventQueue().push(queue);
INSTANCE = queue;
}
}
}
};
if (EventQueue.isDispatchThread()) {
// Install event queue in separate invocation event. Otherwise previous AWT thread become not-AWT, so AWT confined object may be accessed from two threads (old AWT and new AWT).
// Code in both threads may check the thread and get the confirmation.
// To avoid such problems:
// 1. Install event queue from current AWT thread. This ensures that no other code is executed in AWT thread, no AWT confined objects can be accessed right during event queue
// replacement.
// 2. Install event queue in separate invocation event. Avoid any activity before and especially after event queue replacement. Since this thread is not AWT thread any more.
// This check logs error if it can not control right event queue replacement.
Logger.getLogger("").log(Level.WARNING, "Install event queue from not dispatch thread", new Throwable());
runnable.run();
}
else try {
SwingUtilities.invokeAndWait(runnable);
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
synchronized (EventQueueReplacement.class) {
return INSTANCE;
}
}
public static void detachPreprocessor(AWTEventPreprocessor preprocessor) {
EventQueueReplacement instance;
synchronized (EventQueueReplacement.class) {
instance = INSTANCE;
if (instance == null)
return;
}
instance.removePreprocessor(preprocessor);
}
}

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<module relativePaths="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager">
<output url="file://$MODULE_DIR$/../build.idea/Application" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="junit" level="project" />
<orderEntry type="library" name="picocontainer" level="project" />
<orderEntry type="module" module-name="Utils" />
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="file://$MODULE_DIR$/rc" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module" module-name="CoreComponents" exported="" />
<orderEntry type="module" module-name="Engine" exported="" />
<orderEntry type="module" module-name="Launcher" />
<orderEntry type="library" name="jetbrains-annotations" level="project" />
<orderEntry type="module" module-name="Services" exported="" />
<orderEntry type="library" name="jgoodies-forms" level="project" />
<orderEntry type="module" module-name="CommonUtils" />
<orderEntry type="module" module-name="Screenshot" />
<orderEntry type="module" module-name="CommonUtils" />
<orderEntry type="library" name="itext" level="project" />
<orderEntry type="library" name="jna" level="project" />
<orderEntry type="module" module-name="ItemStorage" />
<orderEntry type="module" module-name="ItemSync" />
<orderEntry type="module" module-name="ItemGUI" />
<orderEntry type="module" module-name="widgets" />
</component>
<component name="RetroweaverPlugin">
<setting name="active" value="true" />
<setting name="verbose" value="false" />
<setting name="verifyrefs" value="true" />
<setting name="targetJDK" value="1.4" />
</component>
</module>

View File

@ -0,0 +1,81 @@
<!DOCTYPE ui [
<!ELEMENT viewer (id,presentation,componentFactory,componentBinding)>
<!ELEMENT componentBinding (actionBinding*, modelBinding*, sameNames?)>
<!ELEMENT sameNames (#PCDATA)>
<!ELEMENT actionBinding (componentName, browseWeb)>
<!ELEMENT modelBinding (componentName, key)>
<!ELEMENT browseWeb (#PCDATA)>
<!ELEMENT presentation (Name)>
<!ELEMENT sizePolicy (srinkable)>
<!ELEMENT prototype (property)+>
<!ELEMENT property (key,value)>
<!ELEMENT srinkable (#PCDATA)>
<!ELEMENT componentFactory (className,instanceFieldName)>
<!ELEMENT mainColumns (column)+>
<!ELEMENT column (key,sizePolicy?)>
<!ELEMENT ui (viewers,mainProperty,mainColumns,prototype)>
<!ELEMENT viewers (viewer)+>
<!ELEMENT id (#PCDATA)>
<!ELEMENT key (#PCDATA)>
<!ELEMENT componentName (#PCDATA)>
<!ELEMENT className (#PCDATA)>
<!ELEMENT instanceFieldName (#PCDATA)>
<!ELEMENT Name (#PCDATA)>
<!ELEMENT mainProperty (#PCDATA)>
<!ELEMENT value (#PCDATA)>
<!ELEMENT browseActionKey (#PCDATA)>
]>
<ui>
<viewers>
<viewer>
<id>system</id>
<presentation>
<Name>System</Name>
</presentation>
<componentFactory>
<className>com.almworks.explorer.view.SystemView</className>
<instanceFieldName>myWholePanel</instanceFieldName>
</componentFactory>
</viewer>
</viewers>
<mainProperty>name</mainProperty>
<mainColumns>
<column>
<key>name</key>
</column>
<column>
<key>type</key>
</column>
<column>
<key>description</key>
</column>
<column>
<key>key</key>
</column>
<column>
<key>ID</key>
</column>
</mainColumns>
<prototype>
<property>
<key>name</key>
<value>Array of references</value>
</property>
<property>
<key>type</key>
<value>Value Type</value>
</property>
<property>
<key>description</key>
<value>Values of this type are arrays of values of type Reference</value>
</property>
<property>
<key>key</key>
<value>2.3.4.5.6.7.</value>
</property>
<property>
<key>ID</key>
<value>tracker:whatever:address:could:be:here</value>
</property>
</prototype>
</ui>

View File

@ -0,0 +1,2 @@
sumtable.configurations.duplicateName.name={1}{0,choice,0#|0< {0}}
sumtable.configurations.duplicateName.applied=(.*)\\s(\\d+)

View File

@ -0,0 +1 @@
sysprop.window.seedoc.text=See system properties reference

View File

@ -0,0 +1,57 @@
package com.almworks.actions;
import com.almworks.api.application.tree.ConnectionNode;
import com.almworks.api.application.tree.GenericNode;
import com.almworks.api.engine.Connection;
import com.almworks.api.search.TextSearchUtils;
import com.almworks.util.commons.FunctionE;
import com.almworks.util.ui.actions.ActionContext;
import com.almworks.util.ui.actions.CantPerformException;
import com.almworks.util.ui.actions.SimpleAction;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.List;
public abstract class ConnectionAction extends SimpleAction {
public static final FunctionE<ActionContext, Connection, CantPerformException> SELECTED_NODE =
new FunctionE<ActionContext, Connection, CantPerformException>() {
@Override
public Connection invoke(ActionContext context) throws CantPerformException {
final List<GenericNode> nodes = context.getSourceCollection(GenericNode.NAVIGATION_NODE);
return getConnection(nodes);
}
};
public static final FunctionE<ActionContext, Connection, CantPerformException> PARENT_NODE =
new FunctionE<ActionContext, Connection, CantPerformException>() {
@Override
public Connection invoke(ActionContext context) throws CantPerformException {
final Collection<GenericNode>
nodes = TextSearchUtils.escalateToConnectionNodes(context.getSourceCollection(GenericNode.NAVIGATION_NODE));
return getConnection(nodes);
}
};
private static Connection getConnection(Collection<GenericNode> nodes) {
if(nodes == null || nodes.size() != 1) {
return null;
}
final GenericNode node = nodes.iterator().next();
if(node instanceof ConnectionNode) {
return node.getConnection();
}
return null;
}
private final FunctionE<ActionContext, Connection, CantPerformException> myConnectionExtractor;
protected ConnectionAction(@Nullable String name, FunctionE<ActionContext, Connection, CantPerformException> connectionExtractor) {
super(name);
myConnectionExtractor = connectionExtractor;
}
protected Connection extractConnection(ActionContext context) throws CantPerformException {
return myConnectionExtractor.invoke(context);
}
}

View File

@ -0,0 +1,117 @@
package com.almworks.actions;
import com.almworks.api.application.ItemWrapper;
import com.almworks.api.application.LoadedItemServices;
import com.almworks.api.engine.Connection;
import com.almworks.integers.LongArray;
import com.almworks.integers.LongList;
import com.almworks.integers.LongListIterator;
import com.almworks.integers.WritableLongList;
import com.almworks.items.api.DBReader;
import com.almworks.items.api.Database;
import com.almworks.items.api.ReadTransaction;
import com.almworks.items.sync.util.SyncUtils;
import com.almworks.util.Terms;
import com.almworks.util.commons.Procedure;
import com.almworks.util.exec.ThreadGate;
import com.almworks.util.i18n.Local;
import com.almworks.util.ui.UIUtil;
import com.almworks.util.ui.actions.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.List;
import java.util.Map;
import static org.almworks.util.Collections15.hashMap;
public class CopyIdAndSummaryAction extends SimpleAction {
public CopyIdAndSummaryAction() {
super("C&opy ID && Summary");
setDefaultPresentation(PresentationKey.SHORT_DESCRIPTION, "Copy ID and Summary of selected " + Terms.ref_artifacts + " to clipboard");
setDefaultPresentation(PresentationKey.ENABLE, EnableState.DISABLED);
setDefaultPresentation(PresentationKey.SHORTCUT,
KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.CTRL_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK));
watchRole(ItemWrapper.ITEM_WRAPPER);
}
public static Map<Connection, LongList> getItemsGroupedByConnection(ActionContext context) throws CantPerformException {
List<ItemWrapper> wrappers = context.getSourceCollection(ItemWrapper.ITEM_WRAPPER);
Map<Connection, LongList> result = hashMap();
for (ItemWrapper wrapper : wrappers) {
LoadedItemServices services = wrapper.services();
if (services.isDeleted())
continue;
Connection connection = wrapper.getConnection();
if (connection != null && !connection.getState().getValue().isDegrading()) {
WritableLongList target = (WritableLongList) result.get(connection);
if (target == null) {
target = new LongArray();
result.put(connection, target);
}
target.add(services.getItem());
}
}
return result;
}
protected void doPerform(ActionContext context) throws CantPerformException {
final Map<Connection, LongList> map = getItemsGroupedByConnection(context);
context.getSourceObject(Database.ROLE).readForeground(new ReadTransaction<StringBuilder>() {
public StringBuilder transaction(DBReader reader) {
StringBuilder result = new StringBuilder();
boolean multiple = false;
for (Map.Entry<Connection, LongList> e : map.entrySet()) {
Connection connection = e.getKey();
for (LongListIterator i = e.getValue().iterator(); i.hasNext();) {
String s = connection.getExternalIdSummaryString(SyncUtils.readTrunk(reader, i.nextValue()));
if (s != null && s.length() > 0) {
if (result.length() > 0) {
result.append('\n');
multiple = true;
}
result.append(s);
}
}
}
if (multiple)
result.append('\n');
return result;
}
}).onSuccess(ThreadGate.AWT, new Procedure<StringBuilder>() {
public void invoke(StringBuilder arg) {
if (arg.length() == 0)
return;
UIUtil.copyToClipboard(arg.toString());
Toolkit.getDefaultToolkit().beep();
}
});
}
protected void customUpdate(UpdateContext context) throws CantPerformException {
int count = 0;
try {
List<ItemWrapper> wrappers = context.getSourceCollection(ItemWrapper.ITEM_WRAPPER);
for (ItemWrapper wrapper : wrappers) {
if (wrapper.services().isDeleted())
return;
Connection connection = wrapper.getConnection();
if (connection == null || connection.getState().getValue().isDegrading())
return;
count++;
}
context.setEnabled(count > 0);
} finally {
if (count != 1) {
context.putPresentationProperty(PresentationKey.SHORT_DESCRIPTION,
Local.parse("Copy to clipboard IDs and summaries of the selected " + Terms
.ref_artifacts));
} else {
context.putPresentationProperty(PresentationKey.SHORT_DESCRIPTION,
Local.parse("Copy to clipboard ID and summary of the selected " + Terms
.ref_artifact));
}
}
}
}

View File

@ -0,0 +1,51 @@
package com.almworks.actions;
import com.almworks.api.application.tree.GenericNode;
import com.almworks.api.application.tree.TreeNodeFactory;
import com.almworks.util.components.ACollectionComponent;
import com.almworks.util.ui.actions.*;
import javax.swing.*;
/**
* @author dyoma
*/
class CreateChildNodeAction extends SimpleAction {
private final TreeNodeFactory.NodeType myNodeType;
private CreateChildNodeAction(Icon icon, TreeNodeFactory.NodeType type) {
super((String)null, icon);
myNodeType = type;
watchRole(GenericNode.NAVIGATION_NODE);
setDefaultPresentation(PresentationKey.ENABLE, EnableState.INVISIBLE);
}
protected void doPerform(ActionContext context) throws CantPerformException {
ComponentContext<ACollectionComponent> componentContext =
context.getComponentContext(ACollectionComponent.class, GenericNode.NAVIGATION_NODE);
TreeNodeFactory nodeFactory = context.getSourceObject(TreeNodeFactory.TREE_NODE_FACTORY);
GenericNode parent = getGenericNodeImpl(componentContext);
nodeFactory.createAndEditNode(parent, myNodeType, context);
}
protected void customUpdate(UpdateContext context) throws CantPerformException {
context.getSourceObject(TreeNodeFactory.TREE_NODE_FACTORY);
ComponentContext<ACollectionComponent> componentContext =
context.getComponentContext(ACollectionComponent.class, GenericNode.NAVIGATION_NODE);
GenericNode node = getGenericNodeImpl(componentContext);
if (node.allowsChildren(myNodeType))
context.setEnabled(EnableState.ENABLED);
}
public static CreateChildNodeAction create(TreeNodeFactory.NodeType type) {
return new CreateChildNodeAction(null, type);
}
public static CreateChildNodeAction create(Icon icon, TreeNodeFactory.NodeType type) {
return new CreateChildNodeAction(icon, type);
}
public static GenericNode getGenericNodeImpl(ComponentContext<?> context) throws CantPerformException {
return context.getSourceObject(GenericNode.NAVIGATION_NODE);
}
}

View File

@ -0,0 +1,247 @@
package com.almworks.actions;
import com.almworks.api.actions.ItemActionUtils;
import com.almworks.api.application.ItemWrapper;
import com.almworks.api.engine.Engine;
import com.almworks.api.engine.ItemSyncProblem;
import com.almworks.api.engine.Synchronizer;
import com.almworks.integers.LongArray;
import com.almworks.integers.LongList;
import com.almworks.integers.LongListIterator;
import com.almworks.integers.WritableLongListIterator;
import com.almworks.items.api.DBOperationCancelledException;
import com.almworks.items.api.DBReader;
import com.almworks.items.sync.*;
import com.almworks.items.sync.util.ItemValues;
import com.almworks.items.sync.util.SyncUtils;
import com.almworks.util.AppBook;
import com.almworks.util.Terms;
import com.almworks.util.commons.Condition;
import com.almworks.util.exec.ThreadGate;
import com.almworks.util.i18n.LText1;
import com.almworks.util.i18n.LText2;
import com.almworks.util.i18n.Local;
import com.almworks.util.images.Icons;
import com.almworks.util.ui.DialogsUtil;
import com.almworks.util.ui.actions.*;
import gnu.trove.TLongObjectHashMap;
import org.almworks.util.Log;
import util.concurrent.SynchronizedBoolean;
import javax.swing.*;
import java.awt.*;
import java.util.List;
/**
* @author dyoma
*/
public class DiscardLocalChangesAction extends SimpleAction {
private static final String PREFIX = "Application.Actions.";
private static final Condition<ItemWrapper> DISCARDABLE_ITEM = new Condition<ItemWrapper>() {
public boolean isAccepted(ItemWrapper wrapper) {
return wrapper.getDBStatus().isDiscardable();
}
};
public DiscardLocalChangesAction() {
super("Discard &Changes", Icons.ACTION_DISCARD);
}
protected void customUpdate(UpdateContext context) throws CantPerformException {
context.watchModifiableRole(SyncManager.MODIFIABLE);
ItemActionUtils.basicUpdate(context, true);
SyncManager syncMan = context.getSourceObject(SyncManager.ROLE);
List<ItemWrapper> items = getItemWrappers(context);
int count = items.size();
for (ItemWrapper item : items) {
if (syncMan.findLock(item.getItem()) != null || item.services().isLockedForUpload()) {
count--;
} else {
LongList slaves = item.getMetaInfo().getSlavesToDiscard(item);
if (syncMan.findAnyLock(slaves) != null) count--;
}
}
context.setEnabled(count > 0);
}
protected void doPerform(ActionContext context) throws CantPerformException {
final SyncManager syncMan = context.getSourceObject(SyncManager.ROLE);
final LongArray items = new LongArray();
int discarding = 0, removing = 0;
for(final ItemWrapper iw : getItemWrappers(context)) {
final long item = iw.getItem();
if(syncMan.findLock(item) == null) {
items.add(item);
if(iw.getDBStatus() == ItemWrapper.DBStatus.DB_NEW) {
removing++;
} else {
discarding++;
}
}
}
CantPerformException.ensure(!items.isEmpty());
final Component component = context.getComponent();
final String confirmationMsg = createConfirmationMessage(discarding, removing);
final Synchronizer sync = context.getSourceObject(Engine.ROLE).getSynchronizer();
CantPerformException.ensure(
CantPerformException.ensureNotNull(syncMan.prepareEdit(items)).start(new MyDiscardFactory(component, confirmationMsg, sync)));
}
private static EditCommit createDiscardCommit(final LongArray items, final Synchronizer sync, final SynchronizedBoolean alive) {
return new EditCommit() {
@Override
public void performCommit(EditDrain drain) {
for (WritableLongListIterator i = items.iterator(); i.hasNext();) {
long primary = i.nextValue();
boolean discardSucceeded = drain.discardChanges(primary);
if (!discardSucceeded) {
Log.warn("discard did not succeed for item " + primary);
}
}
}
@Override
public void onCommitFinished(boolean success) {
if(success) {
ThreadGate.AWT_QUEUED.execute(new Runnable() { public void run() {
for (WritableLongListIterator i = items.iterator(); i.hasNext();) {
removeProblem(i.nextValue(), sync);
}
}});
} else {
alive.set(false);
}
}
};
}
public String toString() {
return "DiscardLocalChangesAction";
}
private static boolean confirmDiscard(Component component, String message) {
Component c = component == null ? null : SwingUtilities.getWindowAncestor(component);
return (DialogsUtil.YES_OPTION == DialogsUtil.askUser(c, message, "Discard Changes", DialogsUtil.YES_NO_OPTION));
}
private static String createConfirmationMessage(int discardCount, int removeCount) {
final String message;
if(discardCount > 0 && removeCount == 0) {
message = DISCARD_CONFIRM().format(discardCount);
} else if (discardCount == 0 && removeCount > 0) {
message = REMOVE_CONFIRM().format(removeCount);
} else {
message = MIXED_CONFIRM().format(discardCount, removeCount);
}
return message;
}
private static LText1<Integer> REMOVE_CONFIRM() {
return AppBook.text(PREFIX + "REMOVE_CONFIRM", Local.parse(
"Are you sure you want to remove {0,choice,1#this $(" + Terms.key_artifact + ")|1<these {0,number} " +
Terms.ref_artifacts + "}?"), 0);
}
private static LText1<Integer> DISCARD_CONFIRM() {
return AppBook.text(PREFIX + "DISCARD_CONFIRM", Local.parse(
"Are you sure you want to discard {0,choice,1#changes|1<the changes to {0,number} " + Terms.ref_artifacts + "}?"),
0);
}
private static LText2<Integer, Integer> MIXED_CONFIRM() {
return AppBook.text(PREFIX + "MIXED_CONFIRM", Local.parse(
"Are you sure you want to discard the changes to {0,number} " + Terms.ref_artifacts + " and to remove " +
"{1, number} new " + Terms.ref_artifacts + "?"), 0, 0);
}
private static List<ItemWrapper> getItemWrappers(ActionContext context) throws CantPerformException {
List<ItemWrapper> wrappers = context.getSourceCollection(ItemWrapper.ITEM_WRAPPER);
return DISCARDABLE_ITEM.filterList(wrappers);
}
private static void removeProblem(long item, Synchronizer synchronizer) {
if (synchronizer != null) {
for (ItemSyncProblem problem : synchronizer.getItemProblems(item)) {
problem.disappear();
}
}
}
private static class DiscardEditor implements ItemEditor {
private final SynchronizedBoolean myAlive;
private final Component myComponent;
private final String myConfirmationMsg;
private final LongArray myItemsToDiscard;
private final Synchronizer mySync;
private final EditControl myEditControl;
public DiscardEditor(Component component, String confirmationMsg, LongArray itemsToDiscard, Synchronizer sync, EditControl editControl, SynchronizedBoolean aliveFlag) {
myComponent = component;
myConfirmationMsg = confirmationMsg;
myItemsToDiscard = itemsToDiscard;
mySync = sync;
myEditControl = editControl;
myAlive = aliveFlag;
}
@Override
public void showEditor() throws CantPerformException {
if (!confirmDiscard(myComponent, myConfirmationMsg)) throw new CantPerformExceptionSilently("Rejected");
ThreadGate.AWT_QUEUED.execute(new Runnable() { public void run() {
myEditControl.commit(createDiscardCommit(myItemsToDiscard, mySync, myAlive));
}});
}
@Override
public boolean isAlive() {
return myAlive.get();
}
@Override
public void activate() throws CantPerformException {}
@Override
public void onEditReleased() {}
@Override
public void onItemsChanged(TLongObjectHashMap<ItemValues> newValues) {}
}
private static class MyDiscardFactory implements EditorFactory {
private final Component myComponent;
private final String myConfirmationMsg;
private final Synchronizer mySync;
private final SynchronizedBoolean myAliveFlag = new SynchronizedBoolean(true);
public MyDiscardFactory(Component component, String confirmationMsg, Synchronizer sync) {
myComponent = component;
myConfirmationMsg = confirmationMsg;
mySync = sync;
}
@Override
public void editCancelled() {
myAliveFlag.set(false);
}
@Override
public ItemEditor prepareEdit(DBReader reader, final EditPrepare prepare) throws DBOperationCancelledException {
LongArray primaryItems = LongArray.copy(prepare.getItems());
final LongArray itemsToDiscard = new LongArray(primaryItems.size());
for (LongListIterator i = primaryItems.iterator(); i.hasNext();) {
long primary = i.nextValue();
LongList subtree = SyncUtils.getSlavesSubtree(reader, primary);
if (prepare.addItems(subtree)) {
itemsToDiscard.add(primary);
}
}
if (itemsToDiscard.isEmpty()) return null;
return new DiscardEditor(myComponent, myConfirmationMsg, itemsToDiscard, mySync, prepare.getControl(), myAliveFlag);
}
}
}

View File

@ -0,0 +1,145 @@
package com.almworks.actions;
import com.almworks.api.actions.ItemActionUtils;
import com.almworks.api.application.*;
import com.almworks.api.engine.Connection;
import com.almworks.api.engine.Engine;
import com.almworks.api.engine.SyncTask;
import com.almworks.api.engine.Synchronizer;
import com.almworks.integers.LongList;
import com.almworks.integers.LongListIterator;
import com.almworks.util.L;
import com.almworks.util.Terms;
import com.almworks.util.collections.MultiMap;
import com.almworks.util.collections.PrimitiveUtils;
import com.almworks.util.collections.SimpleModifiable;
import com.almworks.util.commons.Condition;
import com.almworks.util.images.Icons;
import com.almworks.util.ui.actions.*;
import java.util.List;
class DownloadItemAction extends SimpleAction {
private static final Condition<ItemWrapper> CAN_DOWNLOAD = new CanDownload();
private static final Condition<ItemWrapper> HAS_DETAILS = new HasDetails();
private static final String DOWNLOAD_SHORT = L.actionName("&Download All Details");
private static final String RELOAD_SHORT = L.actionName("Reload All &Details");
private static final String DOWNLOAD_LONG = L.tooltip("Download all details for selected " + Terms.ref_artifacts);
private static final String RELOAD_LONG = L.tooltip("Re-download all details for selected " + Terms.ref_artifacts);
private static final String DOWNLOADING = L.actionName("Downloading\u2026");
private static final String RELOADING = L.actionName("Reloading\u2026");
private final Synchronizer mySync;
private boolean myPreToggle;
private final SimpleModifiable myPreToggleModifiable = new SimpleModifiable();
public DownloadItemAction(Engine engine) {
super(L.actionName(DOWNLOAD_SHORT), Icons.ACTION_UPDATE_ARTIFACT);
setDefaultPresentation(PresentationKey.ENABLE, EnableState.DISABLED);
mySync = engine.getSynchronizer();
updateOnChange(mySync.getTasksModifiable());
updateOnChange(myPreToggleModifiable);
}
private static MultiMap<Connection, ItemWrapper> getItemWrappersGroupedByConnection(ActionContext context)
throws CantPerformException
{
List<ItemWrapper> wrappers = context.getSourceCollection(ItemWrapper.ITEM_WRAPPER);
MultiMap<Connection, ItemWrapper> result = MultiMap.create();
for (ItemWrapper wrapper : wrappers) {
if (wrapper.services().isRemoteDeleted())
continue;
Connection connection = wrapper.getConnection();
if (connection != null && !connection.getState().getValue().isDegrading()) {
result.add(connection, wrapper);
}
}
return result;
}
protected void doPerform(ActionContext context) throws CantPerformException {
MultiMap<Connection, ItemWrapper> map = getItemWrappersGroupedByConnection(context);
for (Connection connection : map.keySet()) {
LongList items = PrimitiveUtils.selectThenCollect(CAN_DOWNLOAD, ItemWrapper.GET_ITEM, map.getAll(connection));
if (!items.isEmpty()) {
connection.downloadItemDetails(items);
myPreToggle = true;
}
}
if (myPreToggle) myPreToggleModifiable.fireChanged();
}
protected void customUpdate(UpdateContext context) throws CantPerformException {
final List<ItemWrapper> wrappers = ItemActionUtils.basicUpdate(context, false);
boolean enabled = false;
String name = DOWNLOAD_SHORT;
String ongoing = DOWNLOADING;
String expl = DOWNLOAD_LONG;
final List<ItemWrapper> updatable = CAN_DOWNLOAD.filterList(wrappers);
if(!updatable.isEmpty()) {
enabled = true;
final List<ItemWrapper> reloadable = HAS_DETAILS.filterList(updatable);
if(reloadable.size() == updatable.size()) {
name = RELOAD_SHORT;
ongoing = RELOADING;
expl = RELOAD_LONG;
}
}
context.setEnabled(enabled);
if(areBeingDownloaded(wrappers) || getPreToggledAndClear()) {
context.putPresentationProperty(PresentationKey.NAME, ongoing);
context.putPresentationProperty(PresentationKey.SMALL_ICON, Icons.ACTION_UPDATING_ITEM.getIcon());
} else {
context.putPresentationProperty(PresentationKey.NAME, name);
context.putPresentationProperty(PresentationKey.SMALL_ICON, Icons.ACTION_UPDATE_ARTIFACT);
}
context.putPresentationProperty(PresentationKey.SHORT_DESCRIPTION, expl);
}
public boolean areBeingDownloaded(List<ItemWrapper> wrappers) {
LongList items = PrimitiveUtils.collect(UiItem.GET_ITEM, wrappers);
tasks:
for (SyncTask task : mySync.getTasks().copyCurrent()) {
if (SyncTask.State.isWorking(task.getState().getValue())) {
for (LongListIterator i = items.iterator(); i.hasNext();) {
if (task.getSpecificActivityForItem(i.nextValue(), null) != SyncTask.SpecificItemActivity.DOWNLOAD)
continue tasks;
}
return true;
}
}
return false;
}
public boolean getPreToggledAndClear() {
boolean ret = myPreToggle;
myPreToggle = false;
return ret;
}
private static class CanDownload extends Condition<ItemWrapper> {
public boolean isAccepted(ItemWrapper wrapper) {
if(wrapper == null) {
return false;
}
LoadedItem.DBStatus status = wrapper.getDBStatus();
return status != LoadedItem.DBStatus.DB_NEW && status != LoadedItem.DBStatus.DB_CONNECTION_NOT_READY;
}
}
private static class HasDetails extends Condition<ItemWrapper> {
@Override
public boolean isAccepted(ItemWrapper value) {
ItemDownloadStage stage = ItemDownloadStageKey.retrieveValue(value);
return stage == ItemDownloadStage.STALE || stage == ItemDownloadStage.FULL;
}
}
}

View File

@ -0,0 +1,38 @@
package com.almworks.actions;
import com.almworks.api.application.tree.GenericNode;
import com.almworks.api.engine.Connection;
import com.almworks.util.commons.FunctionE;
import com.almworks.util.ui.actions.*;
/**
* "Edit Connection" menu action.
*/
public class EditConnectionAction extends ConnectionAction {
public static final EditConnectionAction POPUP = new EditConnectionAction(SELECTED_NODE);
public static final EditConnectionAction MAIN = new EditConnectionAction(PARENT_NODE);
public EditConnectionAction(FunctionE<ActionContext, Connection, CantPerformException> connectionExtractor) {
super("&Edit Connection Settings\u2026", connectionExtractor);
setDefaultPresentation(PresentationKey.SHORT_DESCRIPTION, "Change connection configuration");
}
@Override
protected void customUpdate(UpdateContext context) throws CantPerformException {
context.watchRole(GenericNode.NAVIGATION_NODE);
final Connection connection = extractConnection(context);
if(connection == null || connection.getProvider().isEditingConnection(connection)) {
context.setEnabled(EnableState.INVISIBLE);
} else {
context.setEnabled(EnableState.ENABLED);
}
}
@Override
protected void doPerform(ActionContext context) throws CantPerformException {
final Connection connection = extractConnection(context);
if(connection != null) {
connection.getProvider().showEditConnectionWizard(connection);
}
}
}

View File

@ -0,0 +1,27 @@
package com.almworks.actions;
import com.almworks.api.application.tree.GenericNode;
import com.almworks.api.application.tree.LazyDistributionExpanderNode;
import com.almworks.util.L;
import com.almworks.util.ui.actions.*;
// todo remove
public class ExpandLazyDistributionAction extends SimpleAction {
public ExpandLazyDistributionAction() {
super("Expand Distribution");
setDefaultPresentation(PresentationKey.ENABLE, EnableState.INVISIBLE);
setDefaultPresentation(PresentationKey.SHORT_DESCRIPTION, L.tooltip("Fill distribution with values"));
watchRole(GenericNode.NAVIGATION_NODE);
}
protected void customUpdate(UpdateContext context) throws CantPerformException {
GenericNode node = context.getSourceObject(GenericNode.NAVIGATION_NODE);
context.setEnabled(node instanceof LazyDistributionExpanderNode ? EnableState.ENABLED : EnableState.INVISIBLE);
}
protected void doPerform(ActionContext context) throws CantPerformException {
GenericNode node = context.getSourceObject(GenericNode.NAVIGATION_NODE);
if (node instanceof LazyDistributionExpanderNode)
((LazyDistributionExpanderNode) node).expand();
}
}

View File

@ -0,0 +1,572 @@
package com.almworks.actions;
import com.almworks.actions.console.actionsource.ActionGroup;
import com.almworks.actions.console.actionsource.ConsoleActionsComponent;
import com.almworks.actions.distribution.CreateDistribution;
import com.almworks.api.application.ExplorerComponent;
import com.almworks.api.application.LifeMode;
import com.almworks.api.application.qb.FilterNode;
import com.almworks.api.application.qb.QueryBuilderComponent;
import com.almworks.api.application.tree.*;
import com.almworks.api.application.viewer.CommentsController;
import com.almworks.api.engine.Connection;
import com.almworks.api.engine.Engine;
import com.almworks.api.engine.QueryUrlInfo;
import com.almworks.api.explorer.TableController;
import com.almworks.api.gui.MainMenu;
import com.almworks.explorer.ExplorerComponentImpl;
import com.almworks.explorer.ShowHideDistributionTableAction;
import com.almworks.explorer.ShowHideNavigationAreaAction;
import com.almworks.explorer.qbuilder.filter.BinaryCommutative;
import com.almworks.explorer.tree.ExcludeDisributionNodeAction;
import com.almworks.explorer.tree.NavigationTree;
import com.almworks.explorer.tree.OutboxNode;
import com.almworks.explorer.tree.TemporaryQueriesNode;
import com.almworks.integers.LongList;
import com.almworks.sysprop.SystemPropertiesAction;
import com.almworks.tags.AddRemoveFavoritesAction;
import com.almworks.tags.ImportTagsAction;
import com.almworks.tags.NewTagAction;
import com.almworks.tags.TagItemsAction;
import com.almworks.util.*;
import com.almworks.util.commons.Condition;
import com.almworks.util.commons.Procedure;
import com.almworks.util.commons.Procedure2;
import com.almworks.util.components.TreeModelAdapter;
import com.almworks.util.components.tabs.TabActions;
import com.almworks.util.exec.ThreadGate;
import com.almworks.util.files.ExternalBrowser;
import com.almworks.util.i18n.Local;
import com.almworks.util.images.Icons;
import com.almworks.util.model.BasicScalarModel;
import com.almworks.util.threads.Bottleneck;
import com.almworks.util.threads.Threads;
import com.almworks.util.ui.actions.*;
import com.almworks.util.ui.swing.Shortcuts;
import org.almworks.util.Collections15;
import org.picocontainer.Startable;
import javax.swing.*;
import javax.swing.event.TreeModelEvent;
import javax.swing.tree.DefaultTreeModel;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* @author : Dyoma
*/
public class ExplorerActions implements Startable {
private final ActionRegistry myRegistry;
private final ConsoleActionsComponent myActionConsole;
private final Engine myEngine;
public ExplorerActions(ActionRegistry registry, Engine engine, ConsoleActionsComponent actionConsole) {
myRegistry = registry;
myActionConsole = actionConsole;
myEngine = engine;
}
public void start() {
// myRegistry.registerAction(MainMenu.Edit.EDIT_ITEM, new EditPrimaryItemAction()); replaced in JC3
myRegistry.registerAction(MainMenu.Edit.VIEW_PROBLEMS, new ShowItemProblemAction());
myRegistry.registerAction(MainMenu.Edit.DOWNLOAD, new DownloadItemAction(myEngine));
myRegistry.registerAction(MainMenu.Edit.UPLOAD, new UploadItemAction());
myRegistry.registerAction(MainMenu.Edit.DISCARD, new DiscardLocalChangesAction());
myRegistry.registerAction(MainMenu.Edit.RENAME, new RenameAction());
myRegistry.registerAction(MainMenu.Edit.NEW_FOLDER, createCreateFolderAction());
myRegistry.registerAction(MainMenu.Edit.ADD_TO_FAVORITES, new AddRemoveFavoritesAction(true));
myRegistry.registerAction(MainMenu.Edit.REMOVE_FROM_FAVORITES, new AddRemoveFavoritesAction(false));
myRegistry.registerAction(MainMenu.Edit.TAG, new TagItemsAction());
myRegistry.registerAction(MainMenu.Edit.NEW_TAG, new NewTagAction(false));
myRegistry.registerAction(MainMenu.Edit.COPY_ID_SUMMARY, new CopyIdAndSummaryAction());
myRegistry.registerAction(MainMenu.Search.NEW_QUERY, createCreateNewQueryAction());
myRegistry.registerAction(MainMenu.Search.NEW_DISTRIBUTION, CreateDistribution.createAction());
myRegistry.registerAction(MainMenu.Search.EXCLUDE_FROM_DISTRIBUTION, new ExcludeDisributionNodeAction());
myRegistry.registerAction(MainMenu.Search.EDIT_QUERY, new EditQueryAction());
myRegistry.registerAction(MainMenu.Search.RUN_QUERY, new RunQueryAction());
myRegistry.registerAction(MainMenu.Search.RUN_LOCALLY, new ShowCachedResultAction());
myRegistry.registerAction(MainMenu.Search.RELOAD_QUERY, new ReloadQueryFromServerAction());
myRegistry.registerAction(MainMenu.Search.RUN_QUERY_IN_BROWSER, new OpenQueryInBrowserAction());
myRegistry.registerAction(MainMenu.Search.STOP_QUERY, new StopQueryAction());
myRegistry.registerAction(MainMenu.Search.CLOSE_CURRENT_TAB, TabActions.createCloseTabAction(
ExplorerComponentImpl.MAIN_TABS_MANAGER, "Close Current Ta&b", MainMenu.Search.CLOSE_CURRENT_TAB));
myRegistry.registerAction(MainMenu.Search.SELECT_NEXT_TAB, TabActions.createForwardTabAction(
ExplorerComponentImpl.MAIN_TABS_MANAGER, "Select Next Tab", MainMenu.Search.SELECT_NEXT_TAB));
myRegistry.registerAction(MainMenu.Search.SELECT_PREV_TAB, TabActions.createBackwardTabAction(
ExplorerComponentImpl.MAIN_TABS_MANAGER, "Select Previous Tab", MainMenu.Search.SELECT_PREV_TAB));
myRegistry.registerAction(MainMenu.Search.OPEN_ITEM_IN_BROWSER, new ViewItemInBrowserAction());
myRegistry.registerAction(MainMenu.Search.OPEN_ITEM_IN_TAB, new OpenInNewTabAction());
myRegistry.registerAction(MainMenu.Search.OPEN_ITEM_IN_FRAME, new OpenInNewFrameAction());
myRegistry.registerAction(MainMenu.Edit.SORT_NODES, new SortNodesAction());
myRegistry.registerAction(MainMenu.File.SHOW_CONNECTION_INFO, ShowConnectionInfo.MAIN);
myRegistry.registerAction(MainMenu.File.EDIT_CONNECTION, EditConnectionAction.MAIN);
myRegistry.registerAction(MainMenu.File.RETRY_INITIALIZATION, RetryInitializationAction.MAIN);
myRegistry.registerAction(MainMenu.File.REMOVE_CONNECTION, RemoveConnectionsAction.create());
myRegistry.registerAction(MainMenu.File.UPLOAD_ALL_CHANGES, new UploadLocalChangesAction());
myRegistry.registerAction(MainMenu.Search.TOP_DUPLICATE_QUERY, new TemporaryDuplicateAction());
// myRegistry.registerAction(MainMenu.Search.EXPAND_DISTRIBUTION, new ExpandLazyDistributionAction());
// myRegistry.registerAction(MainMenu.Tools.VIEW_NOTE, new ViewNoteAction());
// myRegistry.registerAction(MainMenu.Edit.DOWNLOAD_DETAILS, new DownloadDetailsAction());
// myRegistry.registerAction(MainMenu.Edit.DOWNLOAD_ATTACHMENTS, new DownloadAttachmentsAction());
myRegistry.registerAction(MainMenu.Windows.FOCUS_NAVIGATION_TREE,
new FocusComponentRoleAction(NavigationTree.NAVIGATION_JTREE));
myRegistry.registerAction(MainMenu.Windows.FOCUS_TABLE,
new FocusComponentRoleAction(TableController.TABLE_COMPONENT));
myRegistry.registerAction(MainMenu.Windows.FOCUS_ITEM_VIEWER,
new FocusComponentRoleAction(TableController.ARTIFACT_VIWER_COMPONENT));
CycleFocusComponentRoleAction cycleFocusAction = new CycleFocusComponentRoleAction(NavigationTree.NAVIGATION_JTREE,
TableController.TABLE_COMPONENT, TableController.ARTIFACT_VIWER_COMPONENT);
myRegistry.registerAction(MainMenu.Windows.CYCLE_FOCUS, cycleFocusAction);
myRegistry.registerAction(MainMenu.Windows.CYCLE_FOCUS_BACK, cycleFocusAction.backwardAction());
myRegistry.registerAction(MainMenu.Windows.SHOW_DISTRIBUTION_TABLE, new ShowHideDistributionTableAction());
myRegistry.registerAction(MainMenu.Windows.SHOW_NAVIGATION_AREA, ShowHideNavigationAreaAction.INSTANCE);
myRegistry.registerAction(TabActions.EXPAND_SHRINK_TABS_ID, ShowHideNavigationAreaAction.INSTANCE);
myRegistry.registerAction(MainMenu.Tools.REMOVE_BAD_ISSUE, new RemovePrimaryItemAction(myEngine));
myRegistry.registerAction(MainMenu.Tools.IMPORT_TAGS, new ImportTagsAction());
myRegistry.registerAction(MainMenu.Tools.SYSTEM_PROPERTIES, new SystemPropertiesAction());
myRegistry.registerAction(MainMenu.Search.FIND, new ShowHighlightPanelAction());
if (Env.getBoolean(GlobalProperties.INTERNAL_ACTIONS)) {
myRegistry.registerAction(MainMenu.Edit.VIEW_CHANGES, new ViewChangesAction());
myRegistry.registerAction(MainMenu.Edit.VIEW_ATTRIBUTES, new ViewAttributesAction());
myRegistry.registerAction(MainMenu.Tools.VIEW_ITEM_ATTRIBUTES, ViewAttributesAction.createViewItem());
myRegistry.registerAction(MainMenu.Edit.VIEW_SHADOWS, new ViewShadowsAction());
myRegistry.registerAction(MainMenu.Tools.OPERATION_CONSOLE, ConsoleActionsComponent.OPEN_CONSOLE);
}
registerHideEmptyQueriesActions(myRegistry);
ToggleLiveModeAction.registerActions(myRegistry);
RefreshArtifactsTableAction.registerActions(myRegistry);
// CreateItemHelper.registerActions(myRegistry);
// MergePrimaryItemAction.registerActions(myRegistry);
CommentsController.registerActions(myRegistry);
// PrimaryItemEditor.registerActions(myRegistry);
// NewArtifactForm.registerActions(myRegistry);
// EditorContent.registerActions(myRegistry);
registerConsoleActions();
}
private void registerConsoleActions() {
// Navigation tree/connection related actions
myActionConsole.addGroup(new ActionGroup.InContext("Connection", GenericNode.NAVIGATION_NODE,
MainMenu.File.EDIT_CONNECTION, MainMenu.File.SHOW_CONNECTION_INFO, MainMenu.File.RETRY_INITIALIZATION, MainMenu.File.REMOVE_CONNECTION,
MainMenu.File.DOWNLOAD_CHANGES_QUICK_POPUP, MainMenu.File.RELOAD_CONFIGURATION_POPUP));
}
private void registerHideEmptyQueriesActions(ActionRegistry registry) {
registry.registerAction(MainMenu.Search.HIDE_EMPTY_QUERIES_ON, new HideEmptyQueriesChooserAction("Hide",
"Hide sub-queries that would show zero " + Terms.ref_artifacts, Boolean.TRUE));
registry.registerAction(MainMenu.Search.HIDE_EMPTY_QUERIES_OFF, new HideEmptyQueriesChooserAction("Show",
"Do not hide sub-queries that would show zero " + Terms.ref_artifacts, Boolean.FALSE));
}
private CreateChildNodeAction createCreateNewQueryAction() {
CreateChildNodeAction action =
CreateChildNodeAction.create(Icons.ACTION_CREATE_NEW_QUERY, TreeNodeFactory.NodeType.QUERY);
action.setDefaultPresentation(PresentationKey.NAME, L.actionName("New &" + Terms.Query));
action.setDefaultPresentation(PresentationKey.SHORT_DESCRIPTION, L.tooltip("Create a new " + Terms.query));
return action;
}
private CreateChildNodeAction createCreateFolderAction() {
CreateChildNodeAction action = CreateChildNodeAction.create(TreeNodeFactory.NodeType.FOLDER);
action.setDefaultPresentation(PresentationKey.NAME, L.actionName("&New " + Terms.Folder));
action.setDefaultPresentation(PresentationKey.SHORT_DESCRIPTION, L.tooltip("Create a new " + Terms.folder));
return action;
}
public static <T extends GenericNode> T getSingleNavigationNode(ActionContext context, DataRole<T> role)
throws CantPerformException
{
try {
return context.getSourceObject(role);
} catch (CantPerformException e) {
GenericNode node = context.getSourceObject(GenericNode.NAVIGATION_NODE);
if (role.matches(node))
return (T) node;
throw new CantPerformException("No role: " + role + " object: " + node);
}
}
public void stop() {
}
private static class HideEmptyQueriesChooserAction extends SimpleAction {
private Boolean myValue;
public HideEmptyQueriesChooserAction(String name, String description, Boolean value) {
super(name);
setDefaultPresentation(PresentationKey.ENABLE, EnableState.INVISIBLE);
setDefaultPresentation(PresentationKey.SHORT_DESCRIPTION, Local.parse(description));
watchRole(GenericNode.NAVIGATION_NODE);
myValue = value;
}
protected void customUpdate(UpdateContext context) throws CantPerformException {
final GenericNode node = context.getSourceObject(GenericNode.NAVIGATION_NODE);
context.putPresentationProperty(PresentationKey.TOGGLED_ON, Boolean.valueOf(node.getHideEmptyChildren()).equals(myValue));
context.putPresentationProperty(PresentationKey.ENABLE,
node.canHideEmptyChildren() ? EnableState.ENABLED : EnableState.INVISIBLE);
}