1 package ch
.cyberduck
.ui
.cocoa
;
4 * Copyright (c) 2007 David Kocher. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * Bug fixes, suggestions and comments should be sent to:
18 * dkocher@cyberduck.ch
21 import ch
.cyberduck
.binding
.application
.NSCell
;
22 import ch
.cyberduck
.binding
.application
.NSTableColumn
;
23 import ch
.cyberduck
.binding
.application
.NSTableView
;
24 import ch
.cyberduck
.binding
.application
.NSView
;
25 import ch
.cyberduck
.binding
.application
.NSWindow
;
26 import ch
.cyberduck
.binding
.foundation
.NSNotification
;
27 import ch
.cyberduck
.binding
.foundation
.NSObject
;
28 import ch
.cyberduck
.core
.AbstractCollectionListener
;
29 import ch
.cyberduck
.core
.LocaleFactory
;
30 import ch
.cyberduck
.core
.threading
.BackgroundAction
;
31 import ch
.cyberduck
.core
.threading
.BackgroundActionRegistry
;
32 import ch
.cyberduck
.ui
.cocoa
.view
.ControllerCell
;
34 import org
.apache
.log4j
.Logger
;
35 import org
.rococoa
.ID
;
36 import org
.rococoa
.Rococoa
;
37 import org
.rococoa
.cocoa
.CGFloat
;
38 import org
.rococoa
.cocoa
.foundation
.NSInteger
;
40 import java
.util
.Collections
;
41 import java
.util
.LinkedHashMap
;
47 public final class ActivityController
extends WindowController
{
48 private static Logger log
= Logger
.getLogger(ActivityController
.class);
51 private BackgroundActionRegistry registry
52 = BackgroundActionRegistry
.global();
54 private final Map
<BackgroundAction
, TaskController
> tasks
55 = Collections
.synchronizedMap(new LinkedHashMap
<BackgroundAction
, TaskController
>());
57 public ActivityController() {
59 // Initialize to listen for background tasks
64 public void invalidate() {
65 registry
.removeListener(backgroundActionListener
);
66 table
.setDataSource(null);
67 table
.setDelegate(null);
71 private final AbstractCollectionListener
<BackgroundAction
> backgroundActionListener
72 = new AbstractCollectionListener
<BackgroundAction
>() {
75 public void collectionItemAdded(final BackgroundAction action
) {
76 if(log
.isDebugEnabled()) {
77 log
.debug(String
.format("Add background action %s", action
));
79 tasks
.put(action
, new TaskController(action
));
84 public void collectionItemRemoved(final BackgroundAction action
) {
85 log
.debug(String
.format("Remove background action %s", action
));
86 final TaskController controller
= tasks
.remove(action
);
87 if(null == controller
) {
88 log
.warn(String
.format("Failed to find controller for action %s", action
));
91 controller
.invalidate();
97 registry
.addListener(backgroundActionListener
);
98 // Add already running background actions
99 final BackgroundAction
[] actions
= registry
.toArray(
100 new BackgroundAction
[registry
.size()]);
101 for(final BackgroundAction action
: actions
) {
102 tasks
.put(action
, new TaskController(action
));
110 private void reload() {
111 while(table
.subviews().count().intValue() > 0) {
112 (Rococoa
.cast(table
.subviews().lastObject(), NSView
.class)).removeFromSuperviewWithoutNeedingDisplay();
118 public void setWindow(NSWindow window
) {
119 window
.setContentMinSize(window
.frame().size
);
120 window
.setTitle(LocaleFactory
.localizedString("Activity"));
121 super.setWindow(window
);
125 public boolean isSingleton() {
129 private final TableColumnFactory tableColumnsFactory
= new TableColumnFactory();
132 private NSTableView table
;
135 private ListDataSource model
;
138 private AbstractTableDelegate
<TaskController
> delegate
;
140 public void setTable(NSTableView table
) {
142 this.table
.setRowHeight(new CGFloat(42));
144 NSTableColumn c
= tableColumnsFactory
.create("Default");
147 c
.setResizingMask(NSTableColumn
.NSTableColumnAutoresizingMask
);
148 c
.setDataCell(prototype
);
149 this.table
.addTableColumn(c
);
151 this.table
.setDataSource((model
= new ListDataSource() {
153 public NSObject
tableView_objectValueForTableColumn_row(final NSTableView view
, final NSTableColumn tableColumn
, final NSInteger row
) {
158 public NSInteger
numberOfRowsInTableView(NSTableView view
) {
159 return new NSInteger(tasks
.size());
162 this.table
.setDelegate((delegate
= new AbstractTableDelegate
<TaskController
>(
163 table
.tableColumnWithIdentifier("Default")
166 public void enterKeyPressed(final ID sender
) {
170 public void deleteKeyPressed(final ID sender
) {
174 public String
tooltip(final TaskController c
) {
179 public boolean tableView_shouldSelectRow(final NSTableView view
, final NSInteger row
) {
184 public void tableColumnClicked(final NSTableView view
, final NSTableColumn tableColumn
) {
188 public void tableRowDoubleClicked(final ID sender
) {
192 public void selectionDidChange(final NSNotification notification
) {
196 protected boolean isTypeSelectSupported() {
200 public void tableView_willDisplayCell_forTableColumn_row(final NSTableView view
, final NSCell cell
,
201 final NSTableColumn column
, final NSInteger row
) {
202 final TaskController controller
= getController(row
);
203 Rococoa
.cast(cell
, ControllerCell
.class).setView(controller
.view());
206 // public NSView tableView_viewForTableColumn_row(final NSTableView view, final NSTableColumn tableColumn,
207 // final NSInteger row) {
208 // if(!Factory.Platform.osversion.matches("10\\.(5|6).*")) {
209 // // 10.7 or later supports view View-Based Table Views
210 // final TaskController controller = getController(row);
211 // return controller.view();
216 this.table
.sizeToFit();
219 protected TaskController
getController(final NSInteger row
) {
220 return tasks
.values().toArray(new TaskController
[tasks
.size()])[row
.intValue()];
223 private final NSCell prototype
= ControllerCell
.controllerCell();
226 protected String
getBundleName() {