Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.app / org.gvsig.app.mainplugin / src / main / java / org / gvsig / app / gui / command / CommandStackDialog.java @ 44196

History | View | Annotate | Download (13.7 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.app.gui.command;
25

    
26
import java.awt.BorderLayout;
27
import java.awt.Color;
28
import java.awt.Component;
29
import java.awt.Dimension;
30

    
31
import javax.swing.ImageIcon;
32
import javax.swing.JLabel;
33
import javax.swing.JPanel;
34
import javax.swing.JScrollBar;
35
import javax.swing.JScrollPane;
36
import javax.swing.JSlider;
37
import javax.swing.JTable;
38
import javax.swing.ListSelectionModel;
39
import javax.swing.SwingUtilities;
40
import javax.swing.table.DefaultTableCellRenderer;
41
import javax.swing.table.TableColumn;
42

    
43
import org.gvsig.andami.IconThemeHelper;
44
import org.gvsig.andami.PluginServices;
45
import org.gvsig.andami.ui.mdiManager.IWindowListener;
46
import org.gvsig.andami.ui.mdiManager.SingletonWindow;
47
import org.gvsig.andami.ui.mdiManager.WindowInfo;
48
import org.gvsig.app.ApplicationLocator;
49
import org.gvsig.app.project.documents.Document;
50
import org.gvsig.app.project.documents.view.ViewDocument;
51
import org.gvsig.app.project.documents.view.ViewManager;
52
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
53
import org.gvsig.gui.beans.DefaultBean;
54
import org.gvsig.tools.observer.Observable;
55
import org.gvsig.tools.observer.Observer;
56
import org.gvsig.tools.undo.UndoRedoInfo;
57
import org.gvsig.tools.undo.UndoRedoStack;
58

    
59

    
60
@SuppressWarnings("serial")
61
public class CommandStackDialog extends DefaultBean implements SingletonWindow, IWindowListener, Observer{
62

    
63
        private JTable commandTable = null;
64
        private JPanel topPanel = null;
65
        private UndoRedoStack undoRedoStack;
66
        private JSlider commandSlider = null;
67
        
68
        private int lowLimit;
69
        private int currentValue = -1;
70
        private int currentSliderValue = -1;
71
        private JPanel sliderPanel = null;
72
        protected boolean refreshing;
73
        private JPanel centerPanel = null;
74
        private JScrollPane jScrollPane = null;
75
        private JPanel tablePanel = null;
76
        
77
        private static final ImageIcon imodify = IconThemeHelper.getImageIcon("edit-undo-redo-actions-modify"); 
78
        private static final ImageIcon iadd = IconThemeHelper.getImageIcon("edit-undo-redo-actions-add");
79
        private static final ImageIcon idel = IconThemeHelper.getImageIcon("edit-undo-redo-actions-delete");
80

    
81
        private CommandTableModel commandTableModel = null;
82
        /**
83
         * This is the default constructor
84
         */
85
        public CommandStackDialog() {
86
                super();
87
                initialize();
88
        }
89
        
90
        public void setModel(UndoRedoStack cr1) {
91
        if (this.undoRedoStack != null) {
92
            if (this.undoRedoStack.equals(cr1)) {
93
                return;
94
            } else {
95
                this.undoRedoStack.deleteObserver(this);
96
            }
97
                }
98
                this.undoRedoStack = cr1;
99
                this.undoRedoStack.addObserver(this);
100
                initTable();
101
                initSlider();
102
                currentValue = commandTableModel.getPos();
103
            refreshControls();
104
                refreshSliderSize();
105
        }
106
        
107
        /**
108
         * This method initializes this
109
         *
110
         * @return void
111
         */
112
        private void initialize() {
113
                this.setLayout(new BorderLayout());
114
                this.setSize(328, 229);                
115
                this.add(getJScrollPane(), java.awt.BorderLayout.CENTER);
116
        }
117

    
118
        /**
119
         * This method initializes jList
120
         *
121
         * @return javax.swing.JList
122
         */
123
        private JTable getTable() {
124
                if (commandTable == null) {
125
                        commandTable = new JTable();
126
                }
127
                return commandTable;
128
        }
129
        
130
        private void initTable(){
131
                commandTableModel = new CommandTableModel(undoRedoStack);
132
                commandTable.setModel(commandTableModel);
133
                commandTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
134
                commandTable.setSelectionBackground(Color.orange);
135
                commandTable.setSelectionForeground(Color.black);
136
                commandTable.setShowGrid(false);
137
                commandTable.getTableHeader().setBackground(Color.white);
138
                TableColumn tc = commandTable.getColumnModel().getColumn(0);
139
                tc.setCellRenderer(new DefaultTableCellRenderer() {
140
                           public Component getTableCellRendererComponent(JTable table,
141
                                                                       Object value,
142
                                                                       boolean isSelected,
143
                                                                       boolean hasFocus,
144
                                                                       int row,
145
                                                                       int column)
146
                              {
147
                                 JLabel label = (JLabel)
148
                                    super.getTableCellRendererComponent
149
                                       (table, value, isSelected, hasFocus, row, column);
150
                                    UndoRedoInfo info = (UndoRedoInfo) value;
151
                                    switch (info.getType()) {
152
                            case UndoRedoInfo.INSERT:
153
                                label.setIcon(iadd);
154
                                break;
155
                            case UndoRedoInfo.DELETE:
156
                                label.setIcon(idel);
157
                                break;
158
                            default:
159
                                label.setIcon(imodify);
160
                        }
161
                                 if (commandTableModel.getPos()<row){
162
                                         label.setBackground(Color.lightGray);
163
                                 }else {
164
                                                label.setBackground(Color.orange);
165
                                 }
166
                                    return label;
167
                              }
168
                        });
169

    
170
                commandTable.addMouseListener(new java.awt.event.MouseAdapter() {
171
                        public void mousePressed(java.awt.event.MouseEvent e) {
172
                                int newpos = commandTable.getSelectedRow();        
173
                                if (newpos >= 0){
174
                                    commandTableModel.setPos(newpos);                                
175
                                    ApplicationLocator.getManager().refreshMenusAndToolBars();
176
                                }
177
                        }
178
                });
179
        }
180
        /**
181
         * This method initializes jPanel
182
         *
183
         * @return javax.swing.JPanel
184
         */
185
        private JPanel getTopPanel() {
186
                if (topPanel == null) {
187
                        topPanel = new JPanel();        
188
                }
189
                return topPanel;
190
        }
191

    
192
        @Override
193
        public WindowInfo getWindowInfo() {
194
                WindowInfo m_viewinfo = new WindowInfo(WindowInfo.ICONIFIABLE |
195
                                WindowInfo.MODELESSDIALOG | WindowInfo.RESIZABLE | WindowInfo.PALETTE);
196
                m_viewinfo.setTitle(PluginServices.getText(this,
197
                                "pila_de_comandos"));
198
                return m_viewinfo;
199
        }
200

    
201
        public Object getWindowModel() {
202
                return commandTableModel.getClass().getName();
203
        }
204

    
205
        public void windowActivated() {
206
                this.validate();
207
        }
208

    
209
        public void windowClosed() {
210
                
211
        }
212

    
213
        public void commandRepaint() {
214
                setValue(commandTableModel.getPos(), true);
215
                refreshSliderSize();
216
        }
217

    
218
    /**
219
     * Refreshes all the mutable controls in this component.
220
     */
221
    private void refreshControls() {
222
        int normalizedValue = (int) (((commandTableModel.getRowCount() - (currentValue + 1)) / (float)commandTableModel.getRowCount()) * 100);
223
        //Adding the 50% od the interval
224
        if (commandTableModel.getRowCount() > 0){
225
            normalizedValue = normalizedValue + (100 / (commandTableModel.getRowCount() * 2));
226
        }
227
        refreshSlider(normalizedValue);
228
        commandTable.repaint();
229
    }
230
    
231
    /**
232
     * Sets the slider to the correct (scaled) position.
233
     * @param normalizedValue
234
     */
235
    private void refreshSlider(int normalizedValue) {
236
        if (!refreshing){
237
            refreshing = true;
238
            getJSlider().setValue(normalizedValue);
239
            refreshing = false; 
240
        }
241
    }    
242
    
243
    private void refreshSliderSize(){
244
        if (!refreshing){
245
            Dimension size = new Dimension(commandSlider.getPreferredSize().width,
246
                ((commandTableModel.getRowCount() + 1) * getTable().getRowHeight()));
247
            JScrollBar verticalScrollBar = getJScrollPane().getVerticalScrollBar();
248
            verticalScrollBar.setValue(commandTableModel.getPos()*getTable().getRowHeight());
249
            commandSlider.setPreferredSize(size);
250
            commandSlider.setSize(size);
251
            validate();
252
        }
253
    }
254
    
255
        
256
        /**
257
         * This method initializes jSlider
258
         *
259
         * @return javax.swing.JSlider
260
         */
261
        private JSlider getJSlider() {
262
                if (commandSlider == null) {
263
                        commandSlider = new JSlider(JSlider.VERTICAL, 0, 100, 0);        
264
                }
265
                return commandSlider;
266
        }
267
        
268
        private void initSlider(){                
269
                commandSlider.setPreferredSize(
270
                    new Dimension(commandSlider.getPreferredSize().width,
271
                        ((getTable().getRowCount())*getTable().getRowHeight())));
272

    
273
                commandSlider.addChangeListener(new javax.swing.event.ChangeListener() {
274
                                public synchronized void stateChanged(javax.swing.event.ChangeEvent e) {
275
                                    if (!refreshing){
276
                                        int value = getTablePosFromSlider();  
277
                                        //currentSliderValue controls the same event thrown by the
278
                                        //slider. currentValue controls the event thrown by the table
279
                                        if (currentSliderValue != value){
280
                                            refreshing = true;        
281
                                            currentSliderValue = value;
282
                                            commandTableModel.setPos(value);
283
                                            ApplicationLocator.getManager().refreshMenusAndToolBars();
284

    
285
                                            SwingUtilities.invokeLater(new Runnable() {
286
                                                @Override
287
                                                public void run() {
288
                                                    ViewDocument view = (ViewDocument) ApplicationLocator.getManager().getActiveDocument(ViewManager.TYPENAME);
289
                                                    if (view != null) {
290
                                                        view.getMapContext().invalidate();
291
                                                    }
292
                                                }
293
                                            }
294
                                            );
295

    
296

    
297
                                            refreshing = false;    
298
                                        }
299
                                    }
300
                            }
301
                    });
302
            setValue(commandTableModel.getRowCount() - 1 - commandTableModel.getPos(),true);
303
        }
304
        
305
        private int getTablePosFromSlider(){          
306
            if (commandTableModel.getRowCount() == 0){
307
                return -1;
308
            }
309
            
310
            int value = getJSlider().getValue();
311
            value = (int) ((value * 0.01) * commandTableModel.getRowCount());
312

    
313
            //The bottom part of the slider starts in 100: take the reverse value
314
            value = (commandTableModel.getRowCount() - 1) - value;
315
            
316
            if (value == -1){
317
                return 0;
318
            }
319
            return value;
320
        }
321
        
322
    public void setValue(int number, boolean fireEvent) {
323
        int rowCount = commandTableModel.getRowCount();
324
               
325
        if (number < lowLimit) {
326
                        number = lowLimit;
327
                }
328
        if (number > (rowCount - 1)) {
329
                        number = rowCount;
330
                }
331
        if (number != currentValue) {
332
                currentValue = number;
333
                if (fireEvent) {
334
                                callValueChanged(new Integer(currentValue));
335
                        }
336
        }
337
        /*
338
         * This needs to be refreshed also when same number is set
339
         * Example: select one feature and click 'delete' key
340
         */
341
        refreshControls();
342
    }
343

    
344
        /**
345
         * This method initializes jPanel1
346
         *
347
         * @return javax.swing.JPanel
348
         */
349
        private JPanel getSliderPanel() {
350
                if (sliderPanel == null) {
351
                        sliderPanel = new JPanel();
352
                        sliderPanel.add(getJSlider());
353
                }
354
                return sliderPanel;
355
        }
356

    
357
        /**
358
         * This method initializes pCenter
359
         *
360
         * @return javax.swing.JPanel
361
         */
362
        private JPanel getCenterPanel() {
363
                if (centerPanel == null) {
364
                        centerPanel = new JPanel();
365
                        centerPanel.setLayout(new BorderLayout());                        
366
                        centerPanel.add(getTablePanel(), java.awt.BorderLayout.CENTER);
367
                        centerPanel.add(getSliderPanel(), java.awt.BorderLayout.WEST);
368
                }
369
                return centerPanel;
370
        }
371
        
372
        private JPanel getTablePanel() {
373
            if (tablePanel == null) {
374
                tablePanel = new JPanel();
375
                tablePanel.setLayout(new BorderLayout());
376
                tablePanel.add(getTable(), java.awt.BorderLayout.CENTER);                
377
                tablePanel.add(getTopPanel(), java.awt.BorderLayout.NORTH);
378
            }
379
            return tablePanel;
380
        }
381

    
382
        /**
383
         * This method initializes jScrollPane
384
         *
385
         * @return javax.swing.JScrollPane
386
         */
387
        private JScrollPane getJScrollPane() {
388
                if (jScrollPane == null) {
389
                        jScrollPane = new JScrollPane();
390
                        jScrollPane.setViewportView(getCenterPanel());
391
                }
392
                return jScrollPane;
393
        }
394
        
395
        public void update(Observable observable, Object notification) {
396
                if (notification instanceof FeatureStoreNotification){
397
                        FeatureStoreNotification featureStoreNotification =
398
                                        (FeatureStoreNotification) notification;
399
                        //If the edition finish the command stack disappears
400
                        String type = featureStoreNotification.getType();
401
                        if (FeatureStoreNotification.AFTER_FINISHEDITING.equals(type) ||
402
                                        FeatureStoreNotification.AFTER_CANCELEDITING.equals(type)){                                                        
403
                                ApplicationLocator.getManager().getUIManager().closeWindow(this);                                
404
                                featureStoreNotification.getSource().deleteObserver(this);
405
                                return;
406
                        }
407
                        //Only repaint if the event is a selection event or an edition event
408
                        if (FeatureStoreNotification.AFTER_INSERT.equals(type) ||
409
                FeatureStoreNotification.AFTER_DELETE.equals(type) ||
410
                FeatureStoreNotification.AFTER_UPDATE.equals(type) ||
411
                FeatureStoreNotification.SELECTION_CHANGE.equals(type) ||
412
                FeatureStoreNotification.AFTER_REDO.equals(type) ||
413
                FeatureStoreNotification.AFTER_UNDO.equals(type)) {                   
414
                            commandRepaint();
415
                        }                        
416
                }
417
        }
418

    
419
        public Object getWindowProfile() {
420
                return WindowInfo.DIALOG_PROFILE;
421
        }
422
}