@Override
        public void changeEvent(DebuggerContextImpl newContext, DebuggerSession.Event event) {

          final DebuggerSession session = newContext.getDebuggerSession();
          if (event == DebuggerSession.Event.PAUSE
              && myDebuggerStateManager.myDebuggerSession != session) {
            // if paused in non-active session; switch current session
            myDebuggerStateManager.setState(
                newContext,
                session != null ? session.getState() : DebuggerSession.State.DISPOSED,
                event,
                null);
            return;
          }

          if (myDebuggerStateManager.myDebuggerSession == session) {
            myDebuggerStateManager.fireStateChanged(newContext, event);
          }
          if (event == DebuggerSession.Event.ATTACHED) {
            myDispatcher.getMulticaster().sessionAttached(session);
          } else if (event == DebuggerSession.Event.DETACHED) {
            myDispatcher.getMulticaster().sessionDetached(session);
          } else if (event == DebuggerSession.Event.DISPOSE) {
            dispose(session);
            if (myDebuggerStateManager.myDebuggerSession == session) {
              myDebuggerStateManager.setState(
                  DebuggerContextImpl.EMPTY_CONTEXT,
                  DebuggerSession.State.DISPOSED,
                  DebuggerSession.Event.DISPOSE,
                  null);
            }
          }
        }
  private void refreshPointers(@NotNull final Module module) {
    // todo[nik] refresh only pointers related to renamed module/facet?
    List<Pair<FacetPointerImpl, String>> changed = new ArrayList<Pair<FacetPointerImpl, String>>();

    for (FacetPointerImpl pointer : myPointers.values()) {
      final String oldId = pointer.getId();
      pointer.refresh();
      if (!oldId.equals(pointer.getId())) {
        changed.add(Pair.create(pointer, oldId));
      }
    }

    for (Pair<FacetPointerImpl, String> pair : changed) {
      FacetPointerImpl pointer = pair.getFirst();
      final Facet facet = pointer.getFacet();
      Class facetClass = facet != null ? facet.getClass() : Facet.class;
      while (facetClass != Object.class) {
        final EventDispatcher<FacetPointerListener> dispatcher = myDispatchers.get(facetClass);
        if (dispatcher != null) {
          //noinspection unchecked
          dispatcher.getMulticaster().pointerIdChanged(pointer, pair.getSecond());
        }
        facetClass = facetClass.getSuperclass();
      }
    }
  }
 @Override
 public <F extends Facet> void removeListener(
     final Class<F> facetClass, final FacetPointerListener<F> listener) {
   EventDispatcher<FacetPointerListener> dispatcher = myDispatchers.get(facetClass);
   if (dispatcher != null) {
     dispatcher.removeListener(listener);
   }
 }
 @Override
 public <F extends Facet> void addListener(
     final Class<F> facetClass, final FacetPointerListener<F> listener) {
   EventDispatcher<FacetPointerListener> dispatcher = myDispatchers.get(facetClass);
   if (dispatcher == null) {
     dispatcher = EventDispatcher.create(FacetPointerListener.class);
     myDispatchers.put(facetClass, dispatcher);
   }
   dispatcher.addListener(listener);
 }
  public final IdeFrameImpl allocateFrame(final Project project) {
    LOG.assertTrue(!myProject2Frame.containsKey(project));

    final IdeFrameImpl frame;
    if (myProject2Frame.containsKey(null)) {
      frame = myProject2Frame.get(null);
      myProject2Frame.remove(null);
      myProject2Frame.put(project, frame);
      frame.setProject(project);
    } else {
      frame =
          new IdeFrameImpl(
              (ApplicationInfoEx) ApplicationInfo.getInstance(),
              ActionManagerEx.getInstanceEx(),
              UISettings.getInstance(),
              DataManager.getInstance(),
              ApplicationManager.getApplication());
      final Rectangle bounds = ProjectFrameBounds.getInstance(project).getBounds();
      if (bounds != null) {
        frame.setBounds(bounds);
      } else if (myFrameBounds != null) {
        frame.setBounds(myFrameBounds);
      }
      frame.setExtendedState(myFrameExtendedState);
      frame.setProject(project);
      myProject2Frame.put(project, frame);
      frame.setVisible(true);
    }

    frame.addWindowListener(myActivationListener);

    myEventDispatcher.getMulticaster().frameCreated(frame);

    return frame;
  }
 private void moveSelectedRows(int increment) {
   if (increment == 0) {
     return;
   }
   if (myEntryTable.isEditing()) {
     myEntryTable.getCellEditor().stopCellEditing();
   }
   final ListSelectionModel selectionModel = myEntryTable.getSelectionModel();
   for (int row = increment < 0 ? 0 : myModel.getRowCount() - 1;
       increment < 0 ? row < myModel.getRowCount() : row >= 0;
       row += increment < 0 ? +1 : -1) {
     if (selectionModel.isSelectedIndex(row)) {
       final int newRow = moveRow(row, increment);
       selectionModel.removeSelectionInterval(row, row);
       selectionModel.addSelectionInterval(newRow, newRow);
     }
   }
   myModel.fireTableRowsUpdated(0, myModel.getRowCount() - 1);
   Rectangle cellRect = myEntryTable.getCellRect(selectionModel.getMinSelectionIndex(), 0, true);
   if (cellRect != null) {
     myEntryTable.scrollRectToVisible(cellRect);
   }
   myEntryTable.repaint();
   myListeners.getMulticaster().entryMoved();
 }
  private LocalTask doActivate(Task origin, boolean explicitly) {
    final LocalTaskImpl task =
        origin instanceof LocalTaskImpl ? (LocalTaskImpl) origin : new LocalTaskImpl(origin);
    if (explicitly) {
      task.setUpdated(new Date());
    }
    myActiveTask.setActive(false);
    task.setActive(true);
    addTask(task);
    if (task.isIssue()) {
      StartupManager.getInstance(myProject)
          .runWhenProjectIsInitialized(
              new Runnable() {
                public void run() {
                  ProgressManager.getInstance()
                      .run(
                          new com.intellij.openapi.progress.Task.Backgroundable(
                              myProject, "Updating " + task.getId()) {

                            public void run(@NotNull ProgressIndicator indicator) {
                              updateIssue(task.getId());
                            }
                          });
                }
              });
    }
    LocalTask oldActiveTask = myActiveTask;
    boolean isChanged = !task.equals(oldActiveTask);
    myActiveTask = task;
    if (isChanged) {
      myDispatcher.getMulticaster().taskDeactivated(oldActiveTask);
      myDispatcher.getMulticaster().taskActivated(task);
    }
    return task;
  }
/**
 * Created by IntelliJ IDEA. User: lex Date: Jun 4, 2003 Time: 12:45:56 PM To change this template
 * use Options | File Templates.
 */
public abstract class DebuggerStateManager {
  private final EventDispatcher<DebuggerContextListener> myEventDispatcher =
      EventDispatcher.create(DebuggerContextListener.class);

  public abstract DebuggerContextImpl getContext();

  public abstract void setState(
      DebuggerContextImpl context,
      DebuggerSession.State state,
      DebuggerSession.Event event,
      String description);

  // we allow add listeners inside DebuggerContextListener.changeEvent
  public void addListener(DebuggerContextListener listener) {
    myEventDispatcher.addListener(listener);
  }

  // we allow remove listeners inside DebuggerContextListener.changeEvent
  public void removeListener(DebuggerContextListener listener) {
    myEventDispatcher.removeListener(listener);
  }

  protected void fireStateChanged(DebuggerContextImpl newContext, DebuggerSession.Event event) {
    myEventDispatcher.getMulticaster().changeEvent(newContext, event);
  }
}
 public void setDefaultManifestFileLocation(@NotNull String defaultManifestFileLocation) {
   _defaultManifestFileLocation = defaultManifestFileLocation;
   if (_defaultManifestFileLocation.equals("META-INF")) {
     // we specify full names, so to work with older projects, we have to convert this
     _defaultManifestFileLocation = "META-INF/MANIFEST.MF";
   }
   dispatcher.getMulticaster().projectSettingsChanged();
 }
Example #10
0
 /** Notifies all registered listeners that UI settings has been changed. */
 public void fireUISettingsChanged() {
   incModificationCount();
   myDispatcher.getMulticaster().uiSettingsChanged(this);
   ApplicationManager.getApplication()
       .getMessageBus()
       .syncPublisher(UISettingsListener.TOPIC)
       .uiSettingsChanged(this);
 }
 private void dispose(DebuggerSession session) {
   ProcessHandler processHandler = session.getProcess().getProcessHandler();
   synchronized (mySessions) {
     DebuggerSession removed = mySessions.remove(processHandler);
     LOG.assertTrue(removed != null);
     myDispatcher.getMulticaster().sessionRemoved(session);
   }
 }
Example #12
0
 private void updateOrderEntriesInEditors() {
   if (getModule() != null) { // module with attached module libraries was deleted
     getPanel(); // init editor if needed
     for (final ModuleConfigurationEditor myEditor : myEditors) {
       myEditor.moduleStateChanged();
     }
     myEventDispatcher.getMulticaster().moduleStateChanged(getModifiableRootModelProxy());
   }
 }
 @Override
 public void removeTask(LocalTask task) {
   if (task.isDefault()) return;
   if (myActiveTask.equals(task)) {
     activateTask(myTasks.get(LocalTaskImpl.DEFAULT_TASK_ID), true);
   }
   myTasks.remove(task.getId());
   myDispatcher.getMulticaster().taskRemoved(task);
   myContextManager.removeContext(task);
 }
  public boolean tryToApplyActivationState(boolean active, Window window) {
    final Component frame = UIUtil.findUltimateParent(window);

    if (frame instanceof IdeFrame) {
      final IdeFrame ideFrame = (IdeFrame) frame;
      if (isActive() != active) {
        myActive = Boolean.valueOf(active);
        System.setProperty("idea.active", Boolean.valueOf(myActive).toString());
        if (active) {
          myDispatcher.getMulticaster().applicationActivated(ideFrame);
        } else {
          myDispatcher.getMulticaster().applicationDeactivated(ideFrame);
        }
        return true;
      }
    }

    return false;
  }
  public static void enterModal(@NotNull Object modalEntity) {
    LOG.assertTrue(isDispatchThread(), "enterModal() should be invoked in event-dispatch thread");

    if (LOG.isDebugEnabled()) {
      LOG.debug("enterModal:" + modalEntity);
    }

    ourModalityStateMulticaster.getMulticaster().beforeModalityStateChanged(true);

    ourModalEntities.add(modalEntity);
  }
Example #16
0
 /**
  * Notify single line
  *
  * @param line a line to notify
  * @param outputType output type
  */
 private void notifyLine(final String line, final Key outputType) {
   String trimmed = trimLineSeparator(line);
   // if line ends with return, then it is a progress line, ignore it
   if (myVcs != null && !"\r".equals(line.substring(trimmed.length()))) {
     if (outputType == ProcessOutputTypes.STDOUT && !isStdoutSuppressed()) {
       myVcs.showMessages(trimmed);
     } else if (outputType == ProcessOutputTypes.STDERR && !isStderrSuppressed()) {
       myVcs.showErrorMessages(trimmed);
     }
   }
   myLineListeners.getMulticaster().onLineAvailable(trimmed, outputType);
 }
 // used in Fabrique
 public synchronized void addBreakpoint(@NotNull Breakpoint breakpoint) {
   myBreakpoints.put(breakpoint.myXBreakpoint, breakpoint);
   myBreakpointsListForIteration = null;
   breakpoint.updateUI();
   RequestManagerImpl.createRequests(breakpoint);
   myDispatcher.getMulticaster().breakpointsChanged();
   if (breakpoint instanceof MethodBreakpoint || breakpoint instanceof WildcardMethodBreakpoint) {
     XDebugSessionImpl.NOTIFICATION_GROUP
         .createNotification(
             "Method breakpoints may dramatically slow down debugging", MessageType.WARNING)
         .notify(myProject);
   }
 }
  public boolean updateDescription(boolean modified) {
    EditorColorsScheme scheme = myOptions.getSelectedScheme();

    if (modified
        && (ColorAndFontOptions.isReadOnly(scheme) || ColorSettingsUtil.isSharedScheme(scheme))) {
      showReadOnlyMessage(this, ColorSettingsUtil.isSharedScheme(scheme));
      return false;
    }

    myDispatcher.getMulticaster().fontChanged();

    return true;
  }
  public void initComponent() {
    if (!ApplicationManager.getApplication().isUnitTestMode()) {
      myCacheRefreshTimer =
          UIUtil.createNamedTimer(
              "TaskManager refresh",
              myConfig.updateInterval * 60 * 1000,
              new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                  if (myConfig.updateEnabled && !myUpdating) {
                    updateIssues(null);
                  }
                }
              });
      myCacheRefreshTimer.setInitialDelay(0);
      StartupManager.getInstance(myProject)
          .registerPostStartupActivity(
              new Runnable() {
                public void run() {
                  myCacheRefreshTimer.start();
                }
              });
    }

    // make sure that the default task is exist
    LocalTask defaultTask = findTask(LocalTaskImpl.DEFAULT_TASK_ID);
    if (defaultTask == null) {
      defaultTask = createDefaultTask();
      addTask(defaultTask);
    }

    // search for active task
    LocalTask activeTask = null;
    final List<LocalTask> tasks = getLocalTasks();
    Collections.sort(tasks, TASK_UPDATE_COMPARATOR);
    for (LocalTask task : tasks) {
      if (activeTask == null) {
        if (task.isActive()) {
          activeTask = task;
        }
      } else {
        task.setActive(false);
      }
    }
    if (activeTask == null) {
      activeTask = defaultTask;
    }

    myActiveTask = activeTask;
    doActivate(myActiveTask, false);
    myDispatcher.getMulticaster().taskActivated(myActiveTask);
  }
  public void start() {
    synchronized (myLock) {
      checkNotStarted();

      try {
        myProcess = myCommandLine.createProcess();
        if (LOG.isDebugEnabled()) {
          LOG.debug(myCommandLine.toString());
        }
        myHandler = new OSProcessHandler(myProcess, myCommandLine.getCommandLineString());
        startHandlingStreams();
      } catch (Throwable t) {
        myListeners.getMulticaster().startFailed(t);
      }
    }
  }
  private boolean canExit() {
    for (ApplicationListener applicationListener : myDispatcher.getListeners()) {
      if (!applicationListener.canExitApplication()) {
        return false;
      }
    }

    ProjectManagerEx projectManager = (ProjectManagerEx) ProjectManager.getInstance();
    Project[] projects = projectManager.getOpenProjects();
    for (Project project : projects) {
      if (!projectManager.canClose(project)) {
        return false;
      }
    }

    return true;
  }
  private synchronized void onBreakpointRemoved(@Nullable final XBreakpoint xBreakpoint) {
    ApplicationManager.getApplication().assertIsDispatchThread();
    if (xBreakpoint == null) {
      return;
    }

    Breakpoint breakpoint = myBreakpoints.remove(xBreakpoint);
    if (breakpoint != null) {
      // updateBreakpointRules(breakpoint);
      myBreakpointsListForIteration = null;
      // we delete breakpoints inside release, so gutter will not fire events to deleted breakpoints
      breakpoint.delete();

      RequestManagerImpl.deleteRequests(breakpoint);
      myDispatcher.getMulticaster().breakpointsChanged();
    }
  }
  public static void leaveModal(@NotNull Object modalEntity) {
    LOG.assertTrue(isDispatchThread(), "leaveModal() should be invoked in event-dispatch thread");

    if (LOG.isDebugEnabled()) {
      LOG.debug("leaveModal:" + modalEntity);
    }

    //noinspection StatementWithEmptyBody
    while (ourFlushQueueRunnable.runNextEvent()) ;

    ourModalityStateMulticaster.getMulticaster().beforeModalityStateChanged(false);

    boolean removed = ourModalEntities.remove(modalEntity);
    LOG.assertTrue(removed, modalEntity);
    cleanupQueueForModal(modalEntity);
    ourQueueSkipCount = 0;
    requestFlush();
  }
  public final void releaseFrame(final IdeFrameImpl frame) {

    myEventDispatcher.getMulticaster().beforeFrameReleased(frame);

    final Project project = frame.getProject();
    LOG.assertTrue(project != null);

    frame.removeWindowListener(myActivationListener);
    proceedDialogDisposalQueue(project);

    frame.setProject(null);
    frame.setTitle(null);
    frame.setFileTitle(null, null);

    myProject2Frame.remove(project);
    Disposer.dispose(frame.getStatusBar());
    frame.dispose();
  }
public class ClasspathPanelImpl extends JPanel implements ClasspathPanel {
  private static final Logger LOG =
      Logger.getInstance(
          "#com.intellij.openapi.roots.ui.configuration.classpath.ClasspathPanelImpl");
  private final JBTable myEntryTable;
  private final ClasspathTableModel myModel;
  private final EventDispatcher<OrderPanelListener> myListeners =
      EventDispatcher.create(OrderPanelListener.class);
  private List<AddItemPopupAction<?>> myPopupActions = null;
  private AnActionButton myEditButton;
  private final ModuleConfigurationState myState;
  private AnActionButton myRemoveButton;

  public ClasspathPanelImpl(ModuleConfigurationState state) {
    super(new BorderLayout());

    myState = state;
    myModel = new ClasspathTableModel(state, getStructureConfigurableContext());
    myEntryTable =
        new JBTable(myModel) {
          @Override
          protected TableRowSorter<TableModel> createRowSorter(TableModel model) {
            return new DefaultColumnInfoBasedRowSorter(model) {
              @Override
              public void toggleSortOrder(int column) {
                if (isSortable(column)) {
                  SortKey oldKey = ContainerUtil.getFirstItem(getSortKeys());
                  SortOrder oldOrder;
                  if (oldKey == null || oldKey.getColumn() != column) {
                    oldOrder = SortOrder.UNSORTED;
                  } else {
                    oldOrder = oldKey.getSortOrder();
                  }
                  setSortKeys(
                      Collections.singletonList(new SortKey(column, getNextSortOrder(oldOrder))));
                }
              }
            };
          }
        };
    myEntryTable.setShowGrid(false);
    myEntryTable.setDragEnabled(false);
    myEntryTable.setIntercellSpacing(new Dimension(0, 0));

    myEntryTable.setDefaultRenderer(
        ClasspathTableItem.class, new TableItemRenderer(getStructureConfigurableContext()));
    myEntryTable.setDefaultRenderer(
        Boolean.class, new ExportFlagRenderer(myEntryTable.getDefaultRenderer(Boolean.class)));

    JComboBox scopeEditor =
        new ComboBox(new EnumComboBoxModel<DependencyScope>(DependencyScope.class));
    myEntryTable.setDefaultEditor(DependencyScope.class, new DefaultCellEditor(scopeEditor));
    myEntryTable.setDefaultRenderer(
        DependencyScope.class,
        new ComboBoxTableRenderer<DependencyScope>(DependencyScope.values()) {
          @Override
          protected String getTextFor(@NotNull final DependencyScope value) {
            return value.getDisplayName();
          }
        });

    myEntryTable.setTransferHandler(
        new TransferHandler() {
          @Nullable
          @Override
          protected Transferable createTransferable(JComponent c) {
            OrderEntry entry = getSelectedEntry();
            if (entry == null) return null;
            String text = entry.getPresentableName();
            return new TextTransferable(text);
          }

          @Override
          public int getSourceActions(JComponent c) {
            return COPY;
          }
        });

    myEntryTable
        .getSelectionModel()
        .setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

    new SpeedSearchBase<JBTable>(myEntryTable) {
      @Override
      public int getSelectedIndex() {
        return myEntryTable.getSelectedRow();
      }

      @Override
      protected int convertIndexToModel(int viewIndex) {
        return myEntryTable.convertRowIndexToModel(viewIndex);
      }

      @Override
      public Object[] getAllElements() {
        final int count = myModel.getRowCount();
        Object[] elements = new Object[count];
        for (int idx = 0; idx < count; idx++) {
          elements[idx] = myModel.getItem(idx);
        }
        return elements;
      }

      @Override
      public String getElementText(Object element) {
        return getCellAppearance(
                (ClasspathTableItem<?>) element, getStructureConfigurableContext(), false)
            .getText();
      }

      @Override
      public void selectElement(Object element, String selectedText) {
        final int count = myModel.getRowCount();
        for (int row = 0; row < count; row++) {
          if (element.equals(myModel.getItem(row))) {
            final int viewRow = myEntryTable.convertRowIndexToView(row);
            myEntryTable.getSelectionModel().setSelectionInterval(viewRow, viewRow);
            TableUtil.scrollSelectionToVisible(myEntryTable);
            break;
          }
        }
      }
    };
    setFixedColumnWidth(ClasspathTableModel.EXPORT_COLUMN);
    setFixedColumnWidth(ClasspathTableModel.SCOPE_COLUMN); // leave space for combobox border

    myEntryTable.registerKeyboardAction(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            final int[] selectedRows = myEntryTable.getSelectedRows();
            boolean currentlyMarked = true;
            for (final int selectedRow : selectedRows) {
              final ClasspathTableItem<?> item = getItemAt(selectedRow);
              if (selectedRow < 0 || !item.isExportable()) {
                return;
              }
              currentlyMarked &= item.isExported();
            }
            for (final int selectedRow : selectedRows) {
              getItemAt(selectedRow).setExported(!currentlyMarked);
            }
            myModel.fireTableDataChanged();
            TableUtil.selectRows(myEntryTable, selectedRows);
          }
        },
        KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0),
        WHEN_FOCUSED);

    myEditButton =
        new AnActionButton(
            ProjectBundle.message("module.classpath.button.edit"), null, IconUtil.getEditIcon()) {
          @Override
          public void actionPerformed(@NotNull AnActionEvent e) {
            doEdit();
          }

          @Override
          public boolean isEnabled() {
            ClasspathTableItem<?> selectedItem = getSelectedItem();
            return selectedItem != null && selectedItem.isEditable();
          }

          @Override
          public boolean isDumbAware() {
            return true;
          }
        };
    add(createTableWithButtons(), BorderLayout.CENTER);

    if (myEntryTable.getRowCount() > 0) {
      myEntryTable.getSelectionModel().setSelectionInterval(0, 0);
    }

    new DoubleClickListener() {
      @Override
      protected boolean onDoubleClick(MouseEvent e) {
        navigate(true);
        return true;
      }
    }.installOn(myEntryTable);

    DefaultActionGroup actionGroup = new DefaultActionGroup();
    final AnAction navigateAction =
        new AnAction(ProjectBundle.message("classpath.panel.navigate.action.text")) {
          @Override
          public void actionPerformed(@NotNull AnActionEvent e) {
            navigate(false);
          }

          @Override
          public void update(@NotNull AnActionEvent e) {
            final Presentation presentation = e.getPresentation();
            presentation.setEnabled(false);
            final OrderEntry entry = getSelectedEntry();
            if (entry != null && entry.isValid()) {
              if (!(entry instanceof ModuleSourceOrderEntry)) {
                presentation.setEnabled(true);
              }
            }
          }
        };
    navigateAction.registerCustomShortcutSet(
        ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE).getShortcutSet(),
        myEntryTable);
    actionGroup.add(myEditButton);
    actionGroup.add(myRemoveButton);
    actionGroup.add(navigateAction);
    actionGroup.add(new InlineModuleDependencyAction(this));
    actionGroup.add(new MyFindUsagesAction());
    actionGroup.add(new AnalyzeDependencyAction());
    addChangeLibraryLevelAction(actionGroup, LibraryTablesRegistrar.PROJECT_LEVEL);
    addChangeLibraryLevelAction(actionGroup, LibraryTablesRegistrar.APPLICATION_LEVEL);
    addChangeLibraryLevelAction(actionGroup, LibraryTableImplUtil.MODULE_LEVEL);
    PopupHandler.installPopupHandler(
        myEntryTable, actionGroup, ActionPlaces.UNKNOWN, ActionManager.getInstance());
  }

  @NotNull
  private static SortOrder getNextSortOrder(@NotNull SortOrder order) {
    switch (order) {
      case ASCENDING:
        return SortOrder.DESCENDING;
      case DESCENDING:
        return SortOrder.UNSORTED;
      case UNSORTED:
      default:
        return SortOrder.ASCENDING;
    }
  }

  private ClasspathTableItem<?> getItemAt(int selectedRow) {
    return myModel.getItem(myEntryTable.convertRowIndexToModel(selectedRow));
  }

  private void addChangeLibraryLevelAction(DefaultActionGroup actionGroup, String tableLevel) {
    final LibraryTablePresentation presentation =
        LibraryEditingUtil.getLibraryTablePresentation(getProject(), tableLevel);
    actionGroup.add(
        new ChangeLibraryLevelInClasspathAction(
            this, presentation.getDisplayName(true), tableLevel));
  }

  @Override
  @Nullable
  public OrderEntry getSelectedEntry() {
    ClasspathTableItem<?> item = getSelectedItem();
    return item != null ? item.getEntry() : null;
  }

  @Nullable
  private ClasspathTableItem<?> getSelectedItem() {
    if (myEntryTable.getSelectedRowCount() != 1) return null;
    return getItemAt(myEntryTable.getSelectedRow());
  }

  private void setFixedColumnWidth(final int columnIndex) {
    final TableColumn column =
        myEntryTable.getTableHeader().getColumnModel().getColumn(columnIndex);
    column.setResizable(false);
    column.setMaxWidth(column.getPreferredWidth());
  }

  @Override
  public void navigate(boolean openLibraryEditor) {
    final OrderEntry entry = getSelectedEntry();
    final ProjectStructureConfigurable rootConfigurable =
        ProjectStructureConfigurable.getInstance(myState.getProject());
    if (entry instanceof ModuleOrderEntry) {
      Module module = ((ModuleOrderEntry) entry).getModule();
      if (module != null) {
        rootConfigurable.select(module.getName(), null, true);
      }
    } else if (entry instanceof LibraryOrderEntry) {
      if (!openLibraryEditor
          && !((LibraryOrderEntry) entry)
              .getLibraryLevel()
              .equals(LibraryTableImplUtil.MODULE_LEVEL)) {
        rootConfigurable.select((LibraryOrderEntry) entry, true);
      } else {
        doEdit();
      }
    } else if (entry instanceof JdkOrderEntry) {
      Sdk jdk = ((JdkOrderEntry) entry).getJdk();
      if (jdk != null) {
        rootConfigurable.select(jdk, true);
      }
    }
  }

  private JComponent createTableWithButtons() {
    final boolean isAnalyzeShown = false;

    final ClasspathPanelAction removeAction =
        new ClasspathPanelAction(this) {
          @Override
          public void run() {
            removeSelectedItems(TableUtil.removeSelectedItems(myEntryTable));
          }
        };

    final AnActionButton analyzeButton =
        new AnActionButton(
            ProjectBundle.message("classpath.panel.analyze"), null, IconUtil.getAnalyzeIcon()) {
          @Override
          public void actionPerformed(@NotNull AnActionEvent e) {
            AnalyzeDependenciesDialog.show(getRootModel().getModule());
          }
        };

    // addButton.setShortcut(CustomShortcutSet.fromString("alt A", "INSERT"));
    // removeButton.setShortcut(CustomShortcutSet.fromString("alt DELETE"));
    // upButton.setShortcut(CustomShortcutSet.fromString("alt UP"));
    // downButton.setShortcut(CustomShortcutSet.fromString("alt DOWN"));

    final ToolbarDecorator decorator = ToolbarDecorator.createDecorator(myEntryTable);
    AnActionButtonUpdater moveUpDownUpdater =
        new AnActionButtonUpdater() {
          @Override
          public boolean isEnabled(AnActionEvent e) {
            for (RowSorter.SortKey key : myEntryTable.getRowSorter().getSortKeys()) {
              if (key.getSortOrder() != SortOrder.UNSORTED) {
                return false;
              }
            }
            return true;
          }
        };
    decorator
        .setAddAction(
            new AnActionButtonRunnable() {
              @Override
              public void run(AnActionButton button) {
                initPopupActions();
                final JBPopup popup =
                    JBPopupFactory.getInstance()
                        .createListPopup(
                            new BaseListPopupStep<AddItemPopupAction<?>>(null, myPopupActions) {
                              @Override
                              public Icon getIconFor(AddItemPopupAction<?> aValue) {
                                return aValue.getIcon();
                              }

                              @Override
                              public boolean hasSubstep(AddItemPopupAction<?> selectedValue) {
                                return selectedValue.hasSubStep();
                              }

                              @Override
                              public boolean isMnemonicsNavigationEnabled() {
                                return true;
                              }

                              @Override
                              public PopupStep onChosen(
                                  final AddItemPopupAction<?> selectedValue,
                                  final boolean finalChoice) {
                                if (selectedValue.hasSubStep()) {
                                  return selectedValue.createSubStep();
                                }
                                return doFinalStep(
                                    new Runnable() {
                                      @Override
                                      public void run() {
                                        selectedValue.execute();
                                      }
                                    });
                              }

                              @Override
                              @NotNull
                              public String getTextFor(AddItemPopupAction<?> value) {
                                return "&" + value.getIndex() + "  " + value.getTitle();
                              }
                            });
                popup.show(button.getPreferredPopupPoint());
              }
            })
        .setRemoveAction(
            new AnActionButtonRunnable() {
              @Override
              public void run(AnActionButton button) {
                removeAction.actionPerformed(null);
              }
            })
        .setRemoveActionUpdater(
            new AnActionButtonUpdater() {
              @Override
              public boolean isEnabled(AnActionEvent e) {
                final int[] selectedRows = myEntryTable.getSelectedRows();
                for (final int selectedRow : selectedRows) {
                  if (!getItemAt(selectedRow).isRemovable()) {
                    return false;
                  }
                }
                return selectedRows.length > 0;
              }
            })
        .setMoveUpAction(
            new AnActionButtonRunnable() {
              @Override
              public void run(AnActionButton button) {
                moveSelectedRows(-1);
              }
            })
        .setMoveUpActionUpdater(moveUpDownUpdater)
        .setMoveUpActionName("Move Up (disabled if items are shown in sorted order)")
        .setMoveDownAction(
            new AnActionButtonRunnable() {
              @Override
              public void run(AnActionButton button) {
                moveSelectedRows(+1);
              }
            })
        .setMoveDownActionUpdater(moveUpDownUpdater)
        .setMoveDownActionName("Move Down (disabled if items are shown in sorted order)")
        .addExtraAction(myEditButton);
    if (isAnalyzeShown) {
      decorator.addExtraAction(analyzeButton);
    }

    final JPanel panel = decorator.createPanel();
    myRemoveButton = ToolbarDecorator.findRemoveButton(panel);
    return panel;
  }

  private void doEdit() {
    final OrderEntry entry = getSelectedEntry();
    if (!(entry instanceof LibraryOrderEntry)) return;

    final Library library = ((LibraryOrderEntry) entry).getLibrary();
    if (library == null) {
      return;
    }
    final LibraryTable table = library.getTable();
    final String tableLevel =
        table != null ? table.getTableLevel() : LibraryTableImplUtil.MODULE_LEVEL;
    final LibraryTablePresentation presentation =
        LibraryEditingUtil.getLibraryTablePresentation(getProject(), tableLevel);
    final LibraryTableModifiableModelProvider provider = getModifiableModelProvider(tableLevel);
    EditExistingLibraryDialog dialog =
        EditExistingLibraryDialog.createDialog(
            this,
            provider,
            library,
            myState.getProject(),
            presentation,
            getStructureConfigurableContext());
    dialog.setContextModule(getRootModel().getModule());
    dialog.show();
    myEntryTable.repaint();
    ModuleStructureConfigurable.getInstance(myState.getProject()).getTree().repaint();
  }

  private void removeSelectedItems(final List removedRows) {
    if (removedRows.isEmpty()) {
      return;
    }
    for (final Object removedRow : removedRows) {
      final ClasspathTableItem<?> item =
          (ClasspathTableItem<?>) ((Object[]) removedRow)[ClasspathTableModel.ITEM_COLUMN];
      final OrderEntry orderEntry = item.getEntry();
      if (orderEntry == null) {
        continue;
      }

      getRootModel().removeOrderEntry(orderEntry);
    }
    final int[] selectedRows = myEntryTable.getSelectedRows();
    myModel.fireTableDataChanged();
    TableUtil.selectRows(myEntryTable, selectedRows);
    final StructureConfigurableContext context =
        ModuleStructureConfigurable.getInstance(myState.getProject()).getContext();
    context
        .getDaemonAnalyzer()
        .queueUpdate(new ModuleProjectStructureElement(context, getRootModel().getModule()));
  }

  @Override
  @NotNull
  public LibraryTableModifiableModelProvider getModifiableModelProvider(
      @NotNull String tableLevel) {
    if (LibraryTableImplUtil.MODULE_LEVEL.equals(tableLevel)) {
      final LibraryTable moduleLibraryTable = getRootModel().getModuleLibraryTable();
      return new LibraryTableModifiableModelProvider() {
        @Override
        public LibraryTable.ModifiableModel getModifiableModel() {
          return moduleLibraryTable.getModifiableModel();
        }
      };
    } else {
      return getStructureConfigurableContext().createModifiableModelProvider(tableLevel);
    }
  }

  @Override
  public void runClasspathPanelAction(Runnable action) {
    try {
      disableModelUpdate();
      action.run();
    } finally {
      enableModelUpdate();
      myEntryTable.requestFocus();
    }
  }

  @Override
  public void addItems(List<ClasspathTableItem<?>> toAdd) {
    for (ClasspathTableItem<?> item : toAdd) {
      myModel.addRow(item);
    }
    TIntArrayList toSelect = new TIntArrayList();
    for (int i = myModel.getRowCount() - toAdd.size(); i < myModel.getRowCount(); i++) {
      toSelect.add(myEntryTable.convertRowIndexToView(i));
    }
    TableUtil.selectRows(myEntryTable, toSelect.toNativeArray());
    TableUtil.scrollSelectionToVisible(myEntryTable);

    final StructureConfigurableContext context =
        ModuleStructureConfigurable.getInstance(myState.getProject()).getContext();
    context
        .getDaemonAnalyzer()
        .queueUpdate(new ModuleProjectStructureElement(context, getRootModel().getModule()));
  }

  @Override
  public ModifiableRootModel getRootModel() {
    return myState.getRootModel();
  }

  @Override
  public Project getProject() {
    return myState.getProject();
  }

  @Override
  public ModuleConfigurationState getModuleConfigurationState() {
    return myState;
  }

  @Override
  public JComponent getComponent() {
    return this;
  }

  public void rootsChanged() {
    forceInitFromModel();
  }

  private void initPopupActions() {
    if (myPopupActions == null) {
      int actionIndex = 1;
      final List<AddItemPopupAction<?>> actions = new ArrayList<AddItemPopupAction<?>>();
      final StructureConfigurableContext context = getStructureConfigurableContext();
      actions.add(new AddNewModuleLibraryAction(this, actionIndex++, context));
      actions.add(
          new AddLibraryDependencyAction(
              this, actionIndex++, ProjectBundle.message("classpath.add.library.action"), context));
      actions.add(new AddModuleDependencyAction(this, actionIndex, context));

      myPopupActions = actions;
    }
  }

  private StructureConfigurableContext getStructureConfigurableContext() {
    return ProjectStructureConfigurable.getInstance(myState.getProject()).getContext();
  }

  private void enableModelUpdate() {
    myInsideChange--;
  }

  private void disableModelUpdate() {
    myInsideChange++;
  }

  public void addListener(OrderPanelListener listener) {
    myListeners.addListener(listener);
  }

  public void removeListener(OrderPanelListener listener) {
    myListeners.removeListener(listener);
  }

  private void moveSelectedRows(int increment) {
    LOG.assertTrue(increment == -1 || increment == 1);
    if (myEntryTable.isEditing()) {
      myEntryTable.getCellEditor().stopCellEditing();
    }
    final ListSelectionModel selectionModel = myEntryTable.getSelectionModel();
    for (int row = increment < 0 ? 0 : myModel.getRowCount() - 1;
        increment < 0 ? row < myModel.getRowCount() : row >= 0;
        row += increment < 0 ? +1 : -1) {
      if (selectionModel.isSelectedIndex(row)) {
        final int newRow = moveRow(row, increment);
        selectionModel.removeSelectionInterval(row, row);
        selectionModel.addSelectionInterval(newRow, newRow);
      }
    }
    Rectangle cellRect = myEntryTable.getCellRect(selectionModel.getMinSelectionIndex(), 0, true);
    myEntryTable.scrollRectToVisible(cellRect);
    myEntryTable.repaint();
  }

  public void selectOrderEntry(@NotNull OrderEntry entry) {
    for (int row = 0; row < myModel.getRowCount(); row++) {
      final OrderEntry orderEntry = getItemAt(row).getEntry();
      if (orderEntry != null
          && entry.getPresentableName().equals(orderEntry.getPresentableName())) {
        myEntryTable.getSelectionModel().setSelectionInterval(row, row);
        TableUtil.scrollSelectionToVisible(myEntryTable);
      }
    }
    IdeFocusManager.getInstance(myState.getProject()).requestFocus(myEntryTable, true);
  }

  private int moveRow(final int row, final int increment) {
    int newIndex = Math.abs(row + increment) % myModel.getRowCount();
    myModel.exchangeRows(row, newIndex);
    return newIndex;
  }

  public void stopEditing() {
    TableUtil.stopEditing(myEntryTable);
  }

  private int myInsideChange = 0;

  public void initFromModel() {
    if (myInsideChange == 0) {
      forceInitFromModel();
    }
  }

  public void forceInitFromModel() {
    Set<ClasspathTableItem<?>> oldSelection = new HashSet<ClasspathTableItem<?>>();
    for (int i : myEntryTable.getSelectedRows()) {
      ContainerUtil.addIfNotNull(getItemAt(i), oldSelection);
    }
    myModel.clear();
    myModel.init();
    myModel.fireTableDataChanged();
    TIntArrayList newSelection = new TIntArrayList();
    for (int i = 0; i < myModel.getRowCount(); i++) {
      if (oldSelection.contains(getItemAt(i))) {
        newSelection.add(i);
      }
    }
    TableUtil.selectRows(myEntryTable, newSelection.toNativeArray());
  }

  static CellAppearanceEx getCellAppearance(
      final ClasspathTableItem<?> item,
      final StructureConfigurableContext context,
      final boolean selected) {
    final OrderEntryAppearanceService service = OrderEntryAppearanceService.getInstance();
    if (item instanceof InvalidJdkItem) {
      return service.forJdk(null, false, selected, true);
    } else {
      final OrderEntry entry = item.getEntry();
      assert entry != null : item;
      return service.forOrderEntry(context.getProject(), entry, selected);
    }
  }

  private static class TableItemRenderer extends ColoredTableCellRenderer {
    private final Border NO_FOCUS_BORDER = BorderFactory.createEmptyBorder(1, 1, 1, 1);
    private StructureConfigurableContext myContext;

    public TableItemRenderer(StructureConfigurableContext context) {
      myContext = context;
    }

    @Override
    protected void customizeCellRenderer(
        JTable table, Object value, boolean selected, boolean hasFocus, int row, int column) {
      setPaintFocusBorder(false);
      setFocusBorderAroundIcon(true);
      setBorder(NO_FOCUS_BORDER);
      if (value instanceof ClasspathTableItem<?>) {
        final ClasspathTableItem<?> tableItem = (ClasspathTableItem<?>) value;
        getCellAppearance(tableItem, myContext, selected).customize(this);
        setToolTipText(tableItem.getTooltipText());
      }
    }
  }

  private static class ExportFlagRenderer implements TableCellRenderer {
    private final TableCellRenderer myDelegate;
    private final JPanel myBlankPanel;

    public ExportFlagRenderer(TableCellRenderer delegate) {
      myDelegate = delegate;
      myBlankPanel = new JPanel();
    }

    @Override
    public Component getTableCellRendererComponent(
        JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
      if (!table.isCellEditable(row, column)) {
        myBlankPanel.setBackground(
            isSelected ? table.getSelectionBackground() : table.getBackground());
        return myBlankPanel;
      }
      return myDelegate.getTableCellRendererComponent(
          table, value, isSelected, hasFocus, row, column);
    }
  }

  private class MyFindUsagesAction extends FindUsagesInProjectStructureActionBase {
    private MyFindUsagesAction() {
      super(myEntryTable, myState.getProject());
    }

    @Override
    protected boolean isEnabled() {
      return getSelectedElement() != null;
    }

    @Override
    protected ProjectStructureElement getSelectedElement() {
      final OrderEntry entry = getSelectedEntry();
      if (entry instanceof LibraryOrderEntry) {
        final Library library = ((LibraryOrderEntry) entry).getLibrary();
        if (library != null) {
          return new LibraryProjectStructureElement(getContext(), library);
        }
      } else if (entry instanceof ModuleOrderEntry) {
        final Module module = ((ModuleOrderEntry) entry).getModule();
        if (module != null) {
          return new ModuleProjectStructureElement(getContext(), module);
        }
      } else if (entry instanceof JdkOrderEntry) {
        final Sdk jdk = ((JdkOrderEntry) entry).getJdk();
        if (jdk != null) {
          return new SdkProjectStructureElement(getContext(), jdk);
        }
      }
      return null;
    }

    @Override
    protected RelativePoint getPointToShowResults() {
      Rectangle rect = myEntryTable.getCellRect(myEntryTable.getSelectedRow(), 1, false);
      Point location = rect.getLocation();
      location.y += rect.height;
      return new RelativePoint(myEntryTable, location);
    }
  }

  private class AnalyzeDependencyAction extends AnAction {
    private AnalyzeDependencyAction() {
      super("Analyze This Dependency");
    }

    @Override
    public void actionPerformed(@NotNull AnActionEvent e) {
      final OrderEntry selectedEntry = getSelectedEntry();
      GlobalSearchScope targetScope;
      if (selectedEntry instanceof ModuleOrderEntry) {
        final Module module = ((ModuleOrderEntry) selectedEntry).getModule();
        LOG.assertTrue(module != null);
        targetScope = GlobalSearchScope.moduleScope(module);
      } else {
        Library library = ((LibraryOrderEntry) selectedEntry).getLibrary();
        LOG.assertTrue(library != null);
        targetScope = new LibraryScope(getProject(), library);
      }
      new AnalyzeDependenciesOnSpecifiedTargetHandler(
          getProject(), new AnalysisScope(myState.getRootModel().getModule()), targetScope) {
        @Override
        protected boolean shouldShowDependenciesPanel(List<DependenciesBuilder> builders) {
          for (DependenciesBuilder builder : builders) {
            for (Set<PsiFile> files : builder.getDependencies().values()) {
              if (!files.isEmpty()) {
                Messages.showInfoMessage(
                    myProject,
                    "Dependencies were successfully collected in \""
                        + ToolWindowId.DEPENDENCIES
                        + "\" toolwindow",
                    FindBundle.message("find.pointcut.applications.not.found.title"));
                return true;
              }
            }
          }
          if (Messages.showOkCancelDialog(
                  myProject,
                  "No code dependencies were found. Would you like to remove the dependency?",
                  CommonBundle.getWarningTitle(),
                  Messages.getWarningIcon())
              == Messages.OK) {
            removeSelectedItems(TableUtil.removeSelectedItems(myEntryTable));
          }
          return false;
        }
      }.analyze();
    }

    @Override
    public void update(@NotNull AnActionEvent e) {
      final OrderEntry entry = getSelectedEntry();
      e.getPresentation()
          .setVisible(
              entry instanceof ModuleOrderEntry && ((ModuleOrderEntry) entry).getModule() != null
                  || entry instanceof LibraryOrderEntry
                      && ((LibraryOrderEntry) entry).getLibrary() != null);
    }
  }
}
 public void removeListener(OrderPanelListener listener) {
   myListeners.removeListener(listener);
 }
 public void addListener(OrderPanelListener listener) {
   myListeners.addListener(listener);
 }
 public void fireUpdate() {
   myEventDispatcher.getMulticaster().stateChanged(new ChangeEvent(this));
   update();
 }
 public void removeListener(ChangeListener changeListener) {
   myEventDispatcher.removeListener(changeListener);
 }
 public void addListener(ChangeListener changeListener) {
   myEventDispatcher.addListener(changeListener);
 }