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 @ 46039

History | View | Annotate | Download (14.3 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
import org.apache.commons.lang3.StringUtils;
43

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

    
62

    
63
@SuppressWarnings("serial")
64
public class CommandStackDialog extends DefaultBean implements SingletonWindow, IWindowListener, Observer{
65

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

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

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

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

    
196
        @Override
197
        public WindowInfo getWindowInfo() {
198
                WindowInfo m_viewinfo = new WindowInfo(WindowInfo.ICONIFIABLE |
199
                                WindowInfo.MODELESSDIALOG | WindowInfo.RESIZABLE | WindowInfo.PALETTE);
200
                I18nManager i18n = ToolsLocator.getI18nManager();
201
                if(StringUtils.isBlank(this.labelModel)){
202
                    m_viewinfo.setTitle(i18n.getTranslation("pila_de_comandos"));
203
                } else {
204
                    m_viewinfo.setTitle(
205
                            i18n.getTranslation("pila_de_comandos")+
206
                                    " - "+this.labelModel
207
                    );
208
                }
209
                return m_viewinfo;
210
        }
211

    
212
        public Object getWindowModel() {
213
                return this.undoRedoStack;
214
        }
215

    
216
        public void windowActivated() {
217
                this.validate();
218
        }
219

    
220
        public void windowClosed() {
221
                
222
        }
223

    
224
        public void commandRepaint() {
225
                setValue(commandTableModel.getPos(), true);
226
                refreshSliderSize();
227
        }
228

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

    
284
                commandSlider.addChangeListener(new javax.swing.event.ChangeListener() {
285
                                public synchronized void stateChanged(javax.swing.event.ChangeEvent e) {
286
                                    if (!refreshing){
287
                                        int value = getTablePosFromSlider();  
288
                                        //currentSliderValue controls the same event thrown by the
289
                                        //slider. currentValue controls the event thrown by the table
290
                                        if (currentSliderValue != value){
291
                                            refreshing = true;        
292
                                            currentSliderValue = value;
293
                                            commandTableModel.setPos(value);
294
                                            ApplicationLocator.getManager().refreshMenusAndToolBars();
295

    
296
                                            SwingUtilities.invokeLater(new Runnable() {
297
                                                @Override
298
                                                public void run() {
299
                                                    ViewDocument view = (ViewDocument) ApplicationLocator.getManager().getActiveDocument(ViewManager.TYPENAME);
300
                                                    if (view != null) {
301
                                                        view.getMapContext().invalidate();
302
                                                    }
303
                                                }
304
                                            }
305
                                            );
306

    
307

    
308
                                            refreshing = false;    
309
                                        }
310
                                    }
311
                            }
312
                    });
313
            setValue(commandTableModel.getRowCount() - 1 - commandTableModel.getPos(),true);
314
        }
315
        
316
        private int getTablePosFromSlider(){          
317
            if (commandTableModel.getRowCount() == 0){
318
                return -1;
319
            }
320
            
321
            int value = getJSlider().getValue();
322
            value = (int) ((value * 0.01) * commandTableModel.getRowCount());
323

    
324
            //The bottom part of the slider starts in 100: take the reverse value
325
            value = (commandTableModel.getRowCount() - 1) - value;
326
            
327
            if (value == -1){
328
                return 0;
329
            }
330
            return value;
331
        }
332
        
333
    public void setValue(int number, boolean fireEvent) {
334
        int rowCount = commandTableModel.getRowCount();
335
               
336
        if (number < lowLimit) {
337
                        number = lowLimit;
338
                }
339
        if (number > (rowCount - 1)) {
340
                        number = rowCount;
341
                }
342
        if (number != currentValue) {
343
                currentValue = number;
344
                if (fireEvent) {
345
                                callValueChanged(new Integer(currentValue));
346
                        }
347
        }
348
        /*
349
         * This needs to be refreshed also when same number is set
350
         * Example: select one feature and click 'delete' key
351
         */
352
        refreshControls();
353
    }
354

    
355
        /**
356
         * This method initializes jPanel1
357
         *
358
         * @return javax.swing.JPanel
359
         */
360
        private JPanel getSliderPanel() {
361
                if (sliderPanel == null) {
362
                        sliderPanel = new JPanel();
363
                        sliderPanel.add(getJSlider());
364
                }
365
                return sliderPanel;
366
        }
367

    
368
        /**
369
         * This method initializes pCenter
370
         *
371
         * @return javax.swing.JPanel
372
         */
373
        private JPanel getCenterPanel() {
374
                if (centerPanel == null) {
375
                        centerPanel = new JPanel();
376
                        centerPanel.setLayout(new BorderLayout());                        
377
                        centerPanel.add(getTablePanel(), java.awt.BorderLayout.CENTER);
378
                        centerPanel.add(getSliderPanel(), java.awt.BorderLayout.WEST);
379
                }
380
                return centerPanel;
381
        }
382
        
383
        private JPanel getTablePanel() {
384
            if (tablePanel == null) {
385
                tablePanel = new JPanel();
386
                tablePanel.setLayout(new BorderLayout());
387
                tablePanel.add(getTable(), java.awt.BorderLayout.CENTER);                
388
                tablePanel.add(getTopPanel(), java.awt.BorderLayout.NORTH);
389
            }
390
            return tablePanel;
391
        }
392

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

    
430
        public Object getWindowProfile() {
431
                return WindowInfo.DIALOG_PROFILE;
432
        }
433
        
434
        public void setLabelModel (String labelModel) {
435
            this.labelModel = labelModel;
436
        }
437
}