ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/cmview/branches/CMView-jung/cmview/View.java
Revision: 249
Committed: Tue Dec 4 15:27:58 2007 UTC (11 years, 10 months ago) by lpetzo
File size: 126461 byte(s)
Log Message:
class Start:
- some changes in function preloadModel(...) due to the new loading scheme for models
- changed default settings for the contact type and the contact distance according to Michael's suggestions

class View:
- adapted new loading scheme for the models
- implemented chain code and model serial Getters for the retrieval of all present chain codes and model serials in the source
Line File contents
1 package cmview;
2 import javax.swing.*;
3
4 import java.awt.*;
5 import java.awt.event.*;
6 import java.io.File;
7 import java.io.FileNotFoundException;
8 import java.io.FileOutputStream;
9 import java.io.IOException;
10 import java.lang.reflect.Field;
11 import java.sql.SQLException;
12 import java.util.Collection;
13 import java.util.HashMap;
14 import java.util.HashSet;
15 import java.util.Iterator;
16 import java.util.Map;
17 import java.util.TreeMap;
18 import java.util.TreeSet;
19 import java.util.concurrent.ThreadPoolExecutor;
20 import java.awt.image.BufferedImage;
21 import javax.imageio.*;
22
23 import actionTools.Getter;
24 import actionTools.GetterError;
25
26 import cmview.datasources.*;
27 import cmview.sadpAdapter.SADPDialog;
28 import cmview.sadpAdapter.SADPDialogDoneNotifier;
29 import cmview.sadpAdapter.SADPResult;
30 import cmview.sadpAdapter.SADPRunner;
31 import cmview.toolUtils.ToolDialog;
32 import edu.uci.ics.jung.graph.util.Pair;
33 import proteinstructure.*;
34 import proteinstructure.PairwiseSequenceAlignment.PairwiseSequenceAlignmentException;
35
36 /**
37 * Main GUI window and associated event handling.
38 * Multiple instances of this will be shown in separate windows.
39 *
40 * Initialized with mod=null, an empty window with the menu bars is shown.
41 * Initialized with a valid model, the contact map is displayed in a ContactMapPane.
42 * Multiple instances of this class are created to show multiple contact maps.
43 */
44 public class View extends JFrame implements ActionListener {
45
46 // constants
47 static final long serialVersionUID = 1l;
48 protected static final int SQUARE_SEL = 1;
49 protected static final int FILL_SEL = 2;
50 protected static final int NODE_NBH_SEL = 3;
51 protected static final int SHOW_COMMON_NBH = 4;
52 protected static final int DIAG_SEL = 5;
53 protected static final int SEL_MODE_COLOR = 6;
54
55 private static final boolean FIRST_MODEL = false;
56 private static final boolean SECOND_MODEL = true;
57
58 // menu item labels
59 private static final String LABEL_FILE_INFO = "Info";
60 private static final String LABEL_FILE_PRINT = "Print...";
61 private static final String LABEL_FILE_QUIT = "Quit";
62 private static final String LABEL_DELETE_CONTACTS = "Delete selected contacts";
63 private static final String LABEL_SHOW_TRIANGLES_3D = "Show Common Neighbour Triangles in 3D";
64 private static final String LABEL_SHOW_COMMON_NBS_MODE = "Show Common Neighbours Mode";
65 private static final String LABEL_SHOW_CONTACTS_3D = "Show Selected Contacts in 3D";
66 private static final String LABEL_NODE_NBH_SELECTION_MODE = "Node Neighbourhood Selection Mode";
67 private static final String LABEL_DIAGONAL_SELECTION_MODE = "Diagonal Selection Mode";
68 private static final String LABEL_FILL_SELECTION_MODE = "Fill Selection Mode";
69 private static final String LABEL_SQUARE_SELECTION_MODE = "Square Selection Mode";
70 private static final String LABEL_SEL_MODE_COLOR = "Select by color mode";
71 private static final String LABEL_COMPARE_CM = "Load second structure from";
72 private static final String LABEL_SHOW_COMMON = "Show/hide common contacts";
73 private static final String LABEL_SHOW_FIRST = "Show/hide contacts unique to first structure";
74 private static final String LABEL_SHOW_SECOND = "Show/hide contacts unique to second structure";
75 protected static final String LABEL_SHOW_PAIR_DIST_3D = "Show residue pair (%s,%s) as edge in 3D"; // used in ContactMapPane.showPopup
76
77 // GUI components in the main frame
78 JPanel statusPane; // panel holding the status bar (currently not used)
79 JLabel statusBar; // TODO: Create a class StatusBar
80 JToolBar toolBar; // icon tool bar
81 JPanel cmp; // Main panel holding the Contact map pane
82 JPanel topRul; // Panel for top ruler // TODO: Move this to ContactMapPane?
83 JPanel leftRul; // Panel for left ruler // TODO: Move this to ContactMapPane?
84 JPopupMenu popup; // right-click context menu
85 JPanel tbPane; // tool bar panel holding toolBar and cmp (necessary if toolbar is floatable)
86 //JLayeredPane cmp2; // added for testing
87
88 // Tool bar buttons
89 JButton tbFileInfo, tbFilePrint, tbFileQuit, tbShowSel3D, tbShowComNbh3D, tbDelete;
90 JToggleButton tbSquareSel, tbFillSel, tbDiagSel, tbNbhSel, tbShowComNbh, tbSelModeColor;
91 JToggleButton tbViewPdbResSer, tbViewRuler, tbViewNbhSizeMap, tbViewDistanceMap, tbViewDensityMap, tbShowCommon, tbShowFirstStructure, tbShowSecondStructure;
92
93 // indices of the all main menus in the frame's menu bar
94 TreeMap<String, Integer> menu2idx;
95
96 // contains all types of component that shall not be
97 // considered for the right setting of the visibility
98 // mode of a menu
99 HashSet<Class<?>> disregardedTypes;
100
101 HashMap<JPopupMenu,JMenu> popupMenu2Parent;
102
103 TreeMap<String,JMenu> smFile;
104 TreeMap<String,JMenu> smCompare;
105
106 // Menu items
107 JMenuItem sendM, squareM, fillM, comNeiM, triangleM, nodeNbhSelM, rangeM, delEdgesM, mmSelModeColor;
108 JMenuItem sendP, squareP, fillP, comNeiP, triangleP, nodeNbhSelP, rangeP, delEdgesP, popupSendEdge, pmSelModeColor;
109 JMenuItem mmLoadGraph, mmLoadPdbase, mmLoadMsd, mmLoadCm, mmLoadPdb, mmLoadFtp;
110 JMenuItem mmLoadGraph2, mmLoadPdbase2, mmLoadMsd2, mmLoadCm2, mmLoadPdb2, mmLoadFtp2;
111 JMenuItem mmSaveGraphDb, mmSaveCmFile, mmSavePng, mmSaveAli;
112 JMenuItem mmViewShowPdbResSers, mmViewHighlightComNbh, mmViewShowDensity, mmViewRulers, mmViewIconBar, mmViewShowDistMatrix;
113 JMenuItem mmSelectAll, mmSelectByResNum, mmSelectHelixHelix, mmSelectBetaBeta, mmSelectInterSsContacts, mmSelectIntraSsContacts;
114 JMenuItem mmColorReset, mmColorPaint, mmColorChoose;
115 JMenuItem mmSelCommonContactsInComparedMode, mmSelFirstStrucInComparedMode, mmSelSecondStrucInComparedMode;
116 JMenuItem mmToggleDiffDistMap;
117 JMenuItem mmSuposition, mmShowAlignedResidues;
118 JMenuItem mmInfo, mmPrint, mmQuit, mmHelpAbout, mmHelpHelp, mmHelpWriteConfig;
119
120 // Data and status variables
121 private Model mod;
122 private Model mod2;
123 private Model alignedMod1;
124 private Model alignedMod2;
125 private Alignment ali;
126 public ContactMapPane cmPane;
127 public ResidueRuler topRuler;
128 public ResidueRuler leftRuler;
129 private int pymolSelSerial; // for incremental numbering // TODO: Move this to PymolAdaptor
130 private int pymolNbhSerial; // for incremental numbering // TODO: Move this to PymolAdaptor
131
132 private boolean common;
133 private boolean firstS;
134 private boolean secondS;
135
136 // current gui state
137 private int currentSelectionMode; // current selection mode (see constants above), modify using setSelectionMode
138 private boolean showPdbSers; // whether showing pdb serials is switched on
139 private boolean showRulers; // whether showing residue rulers is switched on
140 private boolean showIconBar; // whether showing the icon bar is switched on
141 private boolean showNbhSizeMap; // whether showing the common neighbourhood size map is switched on
142 private boolean showDensityMap; // whether showing the density map is switched on
143 private boolean showDistanceMap; // whether showing the distance map is switched on
144 private boolean compareStatus; // tells ContactMapPane to draw compared contact map if 2. structure is loaded
145 private Color currentPaintingColor; // current color for coloring contacts selected by the user
146 private boolean selCommonContactsInComparedMode; // when true, selection on compared contact map in both structures possible
147 private boolean selFirstStrucInComparedMode; // when true selection on compared contact map in first structure possible
148 private boolean selSecondStrucInComparedMode; // when true selection on compared contact map in second structure possible
149 private boolean showDiffDistMap; // whether showing the difference distance map is switched on
150 private boolean comparisonMode; // whether comparison functions are enabled
151
152 // global icons TODO: replace these by tickboxes?
153 ImageIcon icon_selected = new ImageIcon(this.getClass().getResource("/icons/tick.png"));
154 ImageIcon icon_deselected = new ImageIcon(this.getClass().getResource("/icons/bullet_blue.png"));
155
156 LoadDialog actLoadDialog;
157
158 // holds a pointer to Start's thread-pool
159 ThreadPoolExecutor threadPool = Start.threadPool;
160
161 // invisible notifiers
162 SADPDialogDoneNotifier sadpNotifier;
163
164 /*----------------------------- constructors ----------------------------*/
165
166 /** Create a new View object */
167 public View(Model mod, String title) {
168 super(title);
169 this.mod = mod;
170 if(mod == null) {
171 this.setPreferredSize(new Dimension(Start.INITIAL_SCREEN_SIZE,Start.INITIAL_SCREEN_SIZE));
172 }
173 this.currentSelectionMode = SQUARE_SEL;
174 this.pymolSelSerial = 1;
175 this.pymolNbhSerial = 1;
176 this.showPdbSers = false;
177 this.showNbhSizeMap = false;
178 this.showRulers=Start.SHOW_RULERS_ON_STARTUP;
179 this.showIconBar=Start.SHOW_ICON_BAR;
180 this.showDensityMap=false;
181 this.showDistanceMap=false;
182 this.currentPaintingColor = Color.blue;
183 this.selCommonContactsInComparedMode= true;
184 this.selFirstStrucInComparedMode= true;
185 this.selSecondStrucInComparedMode= true;
186 this.showDiffDistMap = false;
187 this.comparisonMode = false;
188
189 this.initGUI(); // build gui tree and show window
190 //this.toFront(); // bring window to front
191 this.compareStatus = false;
192 }
193
194 /*---------------------------- private methods --------------------------*/
195
196 /**
197 * Sets the current selection mode. This sets the internal state variable and changes some gui components.
198 * Use getSelectionMode to retrieve the current state.
199 */
200 private void setSelectionMode(int mode) {
201 switch(mode) {
202 case(SQUARE_SEL): tbSquareSel.setSelected(true); break;
203 case(FILL_SEL): tbFillSel.setSelected(true); break;
204 case(NODE_NBH_SEL): tbNbhSel.setSelected(true); break;
205 case(SHOW_COMMON_NBH): tbShowComNbh.setSelected(true); break;
206 case(DIAG_SEL): tbDiagSel.setSelected(true); break;
207 case(SEL_MODE_COLOR) : tbSelModeColor.setSelected(true); break;
208 default: System.err.println("Error in setSelectionMode. Unknown selection mode " + mode); return;
209 }
210 this.currentSelectionMode = mode;
211 }
212
213 /**
214 * Sets up and returns a new menu item with the given icon and label, adds it to the given JMenu and
215 * registers 'this' as the action listener.
216 */
217 private JMenuItem makeMenuItem(String label, Icon icon, JMenu menu) {
218 JMenuItem newItem = new JMenuItem(label, icon);
219 newItem.addActionListener(this);
220 menu.add(newItem);
221 return newItem;
222 }
223
224 /**
225 * Sets up and returns a new popup menu item with the given icon and label, adds it to the given JPopupMenu and
226 * registers 'this' as the action listener.
227 */
228 private JMenuItem makePopupMenuItem(String label, Icon icon, JPopupMenu menu) {
229 JMenuItem newItem = new JMenuItem(label, icon);
230 newItem.addActionListener(this);
231 menu.add(newItem);
232 return newItem;
233 }
234
235 /**
236 * Sets up and returns a new tool bar button
237 */
238 private JButton makeToolBarButton(ImageIcon icon, String toolTipText) {
239 JButton newButton = new JButton(icon);
240 newButton.setFocusPainted(false);
241 newButton.setToolTipText(toolTipText);
242 newButton.addActionListener(this);
243 toolBar.add(newButton);
244 return newButton;
245 }
246
247 /**
248 * Sets up and returns a new tool bar toggle button
249 */
250 private JToggleButton makeToolBarToggleButton(ImageIcon icon, String toolTipText, boolean selected, boolean enabled, boolean visible) {
251 JToggleButton newButton = new JToggleButton(icon, selected);
252 newButton.setFocusPainted(false);
253 newButton.setToolTipText(toolTipText);
254 newButton.addActionListener(this);
255 newButton.setVisible(visible);
256 newButton.setEnabled(enabled);
257 newButton.setSelected(selected);
258 toolBar.add(newButton);
259 return newButton;
260 }
261
262 /**
263 * Creates an icon which changes the color with the variable 'currentPaintingColor'.
264 * @return The 'magic' icon
265 */
266 private Icon getCurrentColorIcon() {
267 return new Icon() {
268 public void paintIcon(Component c, Graphics g, int x, int y) {
269 Color oldColor = c.getForeground();
270 g.setColor(currentPaintingColor);
271 g.translate(x, y);
272 g.fillRect(2,2,12,12);
273 g.translate(-x, -y); // Restore Graphics object
274 g.setColor(oldColor);
275 }
276 public int getIconHeight() {
277 return 16;
278 }
279 public int getIconWidth() {
280 return 16;
281 }
282 };
283 }
284
285 /**
286 * Creates a black-square icon.
287 * @return The black icon
288 */
289 private Icon getBlackSquareIcon() {
290 return new Icon() {
291 public void paintIcon(Component c, Graphics g, int x, int y) {
292 Color oldColor = c.getForeground();
293 g.setColor(Color.black);
294 g.translate(x, y);
295 g.fillRect(2,2,12,12);
296 g.translate(-x, -y); // Restore Graphics object
297 g.setColor(oldColor);
298 }
299 public int getIconHeight() {
300 return 16;
301 }
302 public int getIconWidth() {
303 return 16;
304 }
305 };
306 }
307
308 /** Initialize and show the main GUI window */
309 private void initGUI(){
310
311 // Setting the main layout
312 setLayout(new BorderLayout());
313 setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
314 setLocation(20,20);
315
316 // Creating the Panels
317 tbPane = new JPanel(new BorderLayout()); // toolbar pane, holding only toolbar and cmp (all the rest)
318 cmp = new JPanel(new BorderLayout()); // pane holding the cmPane and (optionally) the ruler panes
319 topRul = new JPanel(new BorderLayout()); // pane holding the top ruler
320 leftRul = new JPanel(new BorderLayout()); // pane holding the left ruler
321 statusPane = new JPanel(); // pane holding the status bar, TODO: Create a class StatusBar
322 statusBar = new JLabel(" "); // a primitive status bar for testing
323 //cmp2 = new JLayeredPane(); // for testing with layered panes
324
325 // Icons
326 ImageIcon icon_square_sel_mode = new ImageIcon(this.getClass().getResource("/icons/shape_square.png"));
327 ImageIcon icon_fill_sel_mode = new ImageIcon(this.getClass().getResource("/icons/paintcan.png"));
328 ImageIcon icon_diag_sel_mode = new ImageIcon(this.getClass().getResource("/icons/diagonals.png"));
329 ImageIcon icon_nbh_sel_mode = new ImageIcon(this.getClass().getResource("/icons/group.png"));
330 ImageIcon icon_show_sel_cont_3d = new ImageIcon(this.getClass().getResource("/icons/shape_square_go.png"));
331 ImageIcon icon_show_com_nbs_mode = new ImageIcon(this.getClass().getResource("/icons/shape_flip_horizontal.png"));
332 ImageIcon icon_show_triangles_3d = new ImageIcon(this.getClass().getResource("/icons/shape_rotate_clockwise.png"));
333 ImageIcon icon_del_contacts = new ImageIcon(this.getClass().getResource("/icons/cross.png"));
334 ImageIcon icon_show_pair_dist_3d = new ImageIcon(this.getClass().getResource("/icons/user_go.png"));
335 ImageIcon icon_colorwheel = new ImageIcon(this.getClass().getResource("/icons/color_wheel.png"));
336 ImageIcon icon_file_info = new ImageIcon(this.getClass().getResource("/icons/information.png"));
337 ImageIcon icon_file_print = new ImageIcon(this.getClass().getResource("/icons/printer.png"));
338 ImageIcon icon_file_quit = new ImageIcon(this.getClass().getResource("/icons/door_open.png"));
339 ImageIcon icon_show_common = new ImageIcon(this.getClass().getResource("/icons/page_copy.png"));
340 ImageIcon icon_show_first = new ImageIcon(this.getClass().getResource("/icons/page_delete.png"));
341 ImageIcon icon_show_second = new ImageIcon(this.getClass().getResource("/icons/page_add.png"));
342 ImageIcon icon_sel_mode_color = new ImageIcon(this.getClass().getResource("/icons/color_swatch.png"));
343 Icon icon_color = getCurrentColorIcon(); // magic icon with current painting color
344 Icon icon_black = getBlackSquareIcon(); // black square icon
345
346 // Tool bar
347 toolBar = new JToolBar();
348 toolBar.setVisible(Start.SHOW_ICON_BAR);
349
350 tbFileInfo = makeToolBarButton(icon_file_info, LABEL_FILE_INFO);
351 tbFilePrint = makeToolBarButton(icon_file_print, LABEL_FILE_PRINT);
352 tbFileQuit = makeToolBarButton(icon_file_quit, LABEL_FILE_QUIT);
353 toolBar.addSeparator();
354 tbSquareSel = makeToolBarToggleButton(icon_square_sel_mode, LABEL_SQUARE_SELECTION_MODE, true, true, true);
355 tbFillSel = makeToolBarToggleButton(icon_fill_sel_mode, LABEL_FILL_SELECTION_MODE, false, true, true);
356 tbDiagSel = makeToolBarToggleButton(icon_diag_sel_mode, LABEL_DIAGONAL_SELECTION_MODE, false, true, true);
357 if(Start.INCLUDE_GROUP_INTERNALS) {
358 tbNbhSel = makeToolBarToggleButton(icon_nbh_sel_mode, LABEL_NODE_NBH_SELECTION_MODE, false, true, true);
359 tbShowComNbh = makeToolBarToggleButton(icon_show_com_nbs_mode, LABEL_SHOW_COMMON_NBS_MODE, false, true, true);
360 }
361 tbSelModeColor = makeToolBarToggleButton(icon_sel_mode_color, LABEL_SEL_MODE_COLOR, false, true, true);
362 toolBar.addSeparator();
363 tbShowSel3D = makeToolBarButton(icon_show_sel_cont_3d, LABEL_SHOW_CONTACTS_3D);
364 if(Start.INCLUDE_GROUP_INTERNALS) {
365 tbShowComNbh3D = makeToolBarButton(icon_show_triangles_3d, LABEL_SHOW_TRIANGLES_3D);
366 }
367 tbDelete = makeToolBarButton(icon_del_contacts, LABEL_DELETE_CONTACTS);
368 toolBar.addSeparator(new Dimension(100, 10));
369 tbShowCommon = makeToolBarToggleButton(icon_show_common, LABEL_SHOW_COMMON, selCommonContactsInComparedMode, true, false);
370 tbShowFirstStructure = makeToolBarToggleButton(icon_show_first, LABEL_SHOW_FIRST, selFirstStrucInComparedMode, true, false);
371 tbShowSecondStructure = makeToolBarToggleButton(icon_show_second, LABEL_SHOW_SECOND, selSecondStrucInComparedMode, true, false);
372
373 // Toggle buttons in view menu (not being used yet)
374 tbViewPdbResSer = new JToggleButton();
375 tbViewRuler = new JToggleButton();
376 tbViewNbhSizeMap = new JToggleButton();
377 tbViewDistanceMap = new JToggleButton();
378 tbViewDensityMap = new JToggleButton();
379 toolBar.setFloatable(Start.ICON_BAR_FLOATABLE);
380
381 // ButtonGroup for selection modes (so upon selecting one, others are deselected automatically)
382 ButtonGroup selectionModeButtons = new ButtonGroup();
383 selectionModeButtons.add(tbSquareSel);
384 selectionModeButtons.add(tbFillSel);
385 selectionModeButtons.add(tbDiagSel);
386 selectionModeButtons.add(tbSelModeColor);
387 if(Start.INCLUDE_GROUP_INTERNALS) {
388 selectionModeButtons.add(tbNbhSel);
389 selectionModeButtons.add(tbShowComNbh);
390 }
391
392 // Popup menu
393 JPopupMenu.setDefaultLightWeightPopupEnabled(false);
394 popup = new JPopupMenu();
395
396 squareP = makePopupMenuItem(LABEL_SQUARE_SELECTION_MODE, icon_square_sel_mode, popup);
397 fillP = makePopupMenuItem(LABEL_FILL_SELECTION_MODE, icon_fill_sel_mode, popup);
398 rangeP = makePopupMenuItem(LABEL_DIAGONAL_SELECTION_MODE, icon_diag_sel_mode, popup);
399 if(Start.INCLUDE_GROUP_INTERNALS) {
400 nodeNbhSelP = makePopupMenuItem(LABEL_NODE_NBH_SELECTION_MODE, icon_nbh_sel_mode, popup);
401 comNeiP = makePopupMenuItem(LABEL_SHOW_COMMON_NBS_MODE, icon_show_com_nbs_mode, popup);
402 }
403 pmSelModeColor = makePopupMenuItem(LABEL_SEL_MODE_COLOR, icon_sel_mode_color, popup);
404 if (Start.USE_PYMOL) {
405 popup.addSeparator();
406 sendP = makePopupMenuItem(LABEL_SHOW_CONTACTS_3D, icon_show_sel_cont_3d, popup);
407 popupSendEdge = makePopupMenuItem(LABEL_SHOW_PAIR_DIST_3D, icon_show_pair_dist_3d, popup);
408 if(Start.INCLUDE_GROUP_INTERNALS) {
409 triangleP = makePopupMenuItem(LABEL_SHOW_TRIANGLES_3D, icon_show_triangles_3d, popup);
410 }
411 }
412 popup.addSeparator();
413 delEdgesP = makePopupMenuItem(LABEL_DELETE_CONTACTS, icon_del_contacts, popup);
414
415 // Main menu
416 JMenuBar menuBar;
417 JMenu menu, submenu;
418 menuBar = new JMenuBar();
419 this.setJMenuBar(menuBar);
420 menu2idx = new TreeMap<String, Integer>();
421 smFile = new TreeMap<String, JMenu>();
422 smCompare = new TreeMap<String, JMenu>();
423 popupMenu2Parent = new HashMap<JPopupMenu, JMenu>();
424
425 // File menu
426 menu = new JMenu("File");
427 menu.setMnemonic(KeyEvent.VK_F);
428 mmInfo = makeMenuItem(LABEL_FILE_INFO, null, menu);
429 // Load
430 submenu = new JMenu("Load from");
431 popupMenu2Parent.put(submenu.getPopupMenu(),submenu);
432 if(Start.USE_DATABASE) {
433 mmLoadGraph = makeMenuItem("Graph database...",null,submenu);
434 mmLoadPdbase = makeMenuItem("Pdbase...",null,submenu);
435 mmLoadMsd = makeMenuItem("MSD...",null, submenu);
436 }
437 mmLoadFtp = makeMenuItem("Online PDB...", null, submenu);
438 mmLoadPdb = makeMenuItem("PDB file...", null, submenu);
439 mmLoadCm = makeMenuItem("Contact map file...", null, submenu);
440 menu.add(submenu);
441 smFile.put("Load", submenu);
442 // Save
443 submenu = new JMenu("Save to");
444 popupMenu2Parent.put(submenu.getPopupMenu(),submenu);
445 mmSaveCmFile = makeMenuItem("Contact map file...", null, submenu);
446 mmSavePng = makeMenuItem("PNG file...", null, submenu);
447 if(Start.USE_DATABASE) {
448 mmSaveGraphDb = makeMenuItem("Graph database...", null, submenu);
449 }
450 mmSaveAli = makeMenuItem("Alignment...", null, submenu);
451 menu.add(submenu);
452 smFile.put("Save", submenu);
453 // Print, Quit
454 mmPrint = makeMenuItem(LABEL_FILE_PRINT, null, menu);
455 mmQuit = makeMenuItem(LABEL_FILE_QUIT, null, menu);
456 addToJMenuBar(menu);
457
458 // View menu
459 menu = new JMenu("View");
460 menu.setMnemonic(KeyEvent.VK_V);
461 mmViewShowPdbResSers = makeMenuItem("Toggle show PDB residue numbers", icon_deselected, menu);
462 mmViewRulers = makeMenuItem("Toggle rulers", icon_deselected, menu);
463 mmViewIconBar = makeMenuItem("Toggle icon bar", icon_deselected, menu); // doesn't work properly if icon bar is floatable
464 menu.addSeparator();
465 mmViewHighlightComNbh = makeMenuItem("Toggle highlight of cells by common neighbourhood size", icon_deselected, menu);
466 mmViewShowDensity = makeMenuItem("Toggle show contact density", icon_deselected, menu);
467 mmViewShowDistMatrix = makeMenuItem("Toggle show distance matrix", icon_deselected, menu);
468 addToJMenuBar(menu);
469
470 // Select menu
471 menu = new JMenu("Select");
472 menu.setMnemonic(KeyEvent.VK_S);
473 mmSelectAll = makeMenuItem("All contacts", null, menu);
474 mmSelectByResNum = makeMenuItem("By residue number...", null, menu);
475 menu.addSeparator();
476 mmSelectHelixHelix = makeMenuItem("Helix-Helix contacts", null, menu);
477 mmSelectBetaBeta = makeMenuItem("Strand-Strand contacts", null, menu);
478 mmSelectInterSsContacts = makeMenuItem("Contacts between SS elements", null, menu);
479 mmSelectIntraSsContacts = makeMenuItem("Contacts within SS elements", null, menu);
480 addToJMenuBar(menu);
481
482 // Color menu
483 menu = new JMenu("Color");
484 menu.setMnemonic(KeyEvent.VK_C);
485 mmColorChoose = makeMenuItem("Choose painting color...", icon_colorwheel, menu);
486 mmColorPaint = makeMenuItem("Color selected contacts", icon_color, menu);
487 mmColorReset= makeMenuItem("Reset contact colors to black", icon_black, menu);
488 addToJMenuBar(menu);
489
490 // Action menu, TODO: split into 'Mode' and 'Action'
491 menu = new JMenu("Action");
492 menu.setMnemonic(KeyEvent.VK_A);
493 squareM = makeMenuItem(LABEL_SQUARE_SELECTION_MODE, icon_square_sel_mode, menu);
494 fillM = makeMenuItem(LABEL_FILL_SELECTION_MODE, icon_fill_sel_mode, menu);
495 rangeM = makeMenuItem(LABEL_DIAGONAL_SELECTION_MODE,icon_diag_sel_mode, menu);
496 if(Start.INCLUDE_GROUP_INTERNALS) {
497 nodeNbhSelM = makeMenuItem(LABEL_NODE_NBH_SELECTION_MODE, icon_nbh_sel_mode, menu);
498 comNeiM = makeMenuItem(LABEL_SHOW_COMMON_NBS_MODE, icon_show_com_nbs_mode, menu);
499 }
500 mmSelModeColor = makeMenuItem(LABEL_SEL_MODE_COLOR, icon_sel_mode_color, menu);
501 if (Start.USE_PYMOL) {
502 menu.addSeparator();
503 sendM = makeMenuItem(LABEL_SHOW_CONTACTS_3D, icon_show_sel_cont_3d, menu);
504 if(Start.INCLUDE_GROUP_INTERNALS) {
505 triangleM = makeMenuItem(LABEL_SHOW_TRIANGLES_3D, icon_show_triangles_3d, menu);
506 }
507 }
508 menu.addSeparator();
509 delEdgesM = makeMenuItem(LABEL_DELETE_CONTACTS, icon_del_contacts, menu);
510 addToJMenuBar(menu);
511
512 // Comparison Menu
513 menu = new JMenu("Compare");
514 menu.setMnemonic(KeyEvent.VK_P);
515 // Load
516 submenu = new JMenu(LABEL_COMPARE_CM);
517 menu.add(submenu);
518 smCompare.put("Load", submenu);
519 if(Start.USE_DATABASE) {
520 mmLoadGraph2 = makeMenuItem("Graph database...",null,submenu);
521 mmLoadPdbase2 = makeMenuItem("Pdbase...",null,submenu);
522 mmLoadMsd2 = makeMenuItem("MSD...",null, submenu);
523 }
524 mmLoadFtp2 = makeMenuItem("Online PDB...", null, submenu);
525 mmLoadPdb2 = makeMenuItem("PDB file...", null, submenu);
526 mmLoadCm2 = makeMenuItem("Contact map file...", null, submenu);
527 menu.addSeparator();
528 mmSelCommonContactsInComparedMode = makeMenuItem("Toggle show common contacts", icon_selected, menu);
529 mmSelFirstStrucInComparedMode = makeMenuItem("Toggle show contacts unique in first structure", icon_selected, menu);
530 mmSelSecondStrucInComparedMode = makeMenuItem("Toggle show contacts unique in second structure ", icon_selected, menu);
531 menu.addSeparator();
532 mmToggleDiffDistMap = makeMenuItem("Toggle show difference map", icon_deselected, menu);
533 menu.addSeparator();
534 mmSuposition = makeMenuItem("Superimpose from selection",null,menu);
535 mmSuposition.setEnabled(false);
536 mmShowAlignedResidues = makeMenuItem("Show corresponding residues from selection",null,menu);
537 mmShowAlignedResidues.setEnabled(false);
538 addToJMenuBar(menu);
539
540 // Help menu
541 menu = new JMenu("Help");
542 menu.setMnemonic(KeyEvent.VK_H);
543 mmHelpHelp = makeMenuItem("Help", null, menu);
544 mmHelpWriteConfig = makeMenuItem("Write example configuration file", null, menu);
545 mmHelpAbout = makeMenuItem("About", null, menu);
546 addToJMenuBar(menu);
547
548 // Status bar
549 // if (mod!= null){
550 // int[] statusRuler = new int[3];
551 // statusRuler = cmPane.getRulerCoordinates();
552 // String r1 = "" + statusRuler[0] + "";
553 // String r2 = "" + statusRuler[1] + "";
554 // String r3 = "" + statusRuler[2] + "";
555
556
557 // statusBar.setText(r1 +" , " + r2 + " , " +r3);
558 // statusPane.setLayout(new BorderLayout());
559 // statusPane.add(statusBar, BorderLayout.CENTER);
560 // statusPane.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
561 // }
562
563 // Creating contact map pane if model loaded
564 if(mod != null) {
565 // testing: use two separate layers for contacts and interaction
566 // TestCmBackgroundPane cmPaneBg = new TestCmBackgroundPane(mod, this);
567 // TestCmInteractionPane cmPaneInt = new TestCmInteractionPane(mod, this, cmPaneBg);
568 // cmp.setLayout(new OverlayLayout(cmp));
569 // cmp.add(cmPaneInt);
570 // cmp.add(cmPaneBg);
571
572 // alternative: use JLayeredPane
573 // TestCmInteractionPane cmPaneInt = new TestCmInteractionPane(mod, this);
574 // TestCmBackgroundPane cmPaneBg = new TestCmBackgroundPane(mod, this);
575 // cmp2.setLayout(new OverlayLayout(cmp2));
576 // cmp2.add(cmPaneInt, new Integer(2));
577 // cmp2.add(cmPaneBg, new Integer(1));
578 //add cmp2 to contentPane
579
580 cmPane = new ContactMapPane(mod, this);
581 cmp.add(cmPane, BorderLayout.CENTER);
582 topRuler = new ResidueRuler(cmPane,mod,this,ResidueRuler.TOP);
583 leftRuler = new ResidueRuler(cmPane,mod,this,ResidueRuler.LEFT);
584 topRul.add(topRuler);
585 leftRul.add(leftRuler);
586 }
587
588 // Add everything to the content pane
589 this.tbPane.add(toolBar, BorderLayout.NORTH); // tbPane is necessary if toolBar is floatable
590 this.tbPane.add(cmp,BorderLayout.CENTER); // otherwise can add these to contentPane directly
591 this.getContentPane().add(tbPane, BorderLayout.CENTER); // and get rid of this line
592 if(showRulers) {
593 cmp.add(topRul, BorderLayout.NORTH);
594 cmp.add(leftRul, BorderLayout.WEST);
595 }
596 //this.getContentPane().add(statusPane,BorderLayout.SOUTH);
597
598 // menu item types to be disregarded
599 disregardedTypes = new HashSet<Class<?>>();
600 disregardedTypes.add(JPopupMenu.Separator.class);
601 disregardedTypes.add(JToolBar.Separator.class);
602
603 // toggle the visibility of menu-items
604 setAccessibility(initMenuBarAccessibility(mod!=null),true,getJMenuBar(),disregardedTypes);
605
606 // Show GUI
607 pack();
608 setVisible(true);
609 }
610
611 /**
612 * Adds a menu to the menubar of this View object. Moreover, some mappings are done:
613 * <ul>
614 * <li>mapping from menu identifier (string value obtained by <code>menu.getText()</code>)</li>
615 * <li>mapping from the menu's JPopupMenu to the menu</li>
616 * </ul>
617 * @param menu the menu to be added
618 */
619 public void addToJMenuBar(JMenu menu) {
620 getJMenuBar().add(menu);
621 menu2idx.put(menu.getText(), getJMenuBar().getMenuCount()-1);
622 popupMenu2Parent.put(menu.getPopupMenu(),menu);
623 }
624
625 /**
626 * Toggles the visibility status of all components in the map.
627 * @param components items to be considered
628 * @param parentCheck enable this to consider the visibility of the parent component which means whenever all child-components of the parent component are invisible make the parent component invisible, too.
629 * @param topLevelComponent pointer to the top level component where changes to its visibility is prohibited
630 * @param disregardedTypes collection of component types not to be considered
631 */
632 public void setAccessibility(Map<Component,Boolean> components, boolean parentCheck, Component topLevelComponent, Collection<Class<?>> disregardedTypes) {
633 for( Component c : components.keySet() ) {
634 if( c != null ) {
635 setAccessibility(c,components.get(c),parentCheck,topLevelComponent,disregardedTypes);
636 }
637 }
638 }
639
640 /**
641 * Toggles the visibility status of the given component. As its visibility
642 * might have an effect on its parent component we also have to consider
643 * the parent component. Nevertheless, the desired treatment of the parent
644 * component can be set as well. The recursive ascension in the component
645 * tree stops if the given component is the top level component.
646 * @param comp component whose visibility shall be changed
647 * @param visible the new visibility status of <code>comp</code>. Enable
648 * this to make it visible
649 * @param parentCheck toggles the parent check. If this is enabled the
650 * parents visibility mode will be adapted with respect to the visibility
651 * mode of <code>comp</code>
652 * @param topLevelComponent the top level component. Stop if
653 * <code>comp</code> equals this component.key
654 * @param disregardedTypes collection of component types not to be
655 * considered
656 * @see #setAccessibility(Map, boolean, Component, Collection)
657 */
658 public void setAccessibility(Component comp, boolean visible, boolean parentCheck, Component topLevelComponent, Collection<Class<?>> disregardedTypes) {
659
660 // try {
661 // System.out.println("set:"+((AbstractButton) comp).getText());
662 // } catch(Exception e) {
663 // System.out.println("not an abstract button:"+comp.getClass());
664 // System.out.println("comp==popup:"+(comp==this.popup));
665 // }
666
667 if( comp == topLevelComponent ) {
668 return;
669 }
670
671 Component parent = comp.getParent();
672
673 if(parent != topLevelComponent) {
674 // disable and hide element
675 comp.setEnabled(visible);
676 //comp.setVisible(visible);
677 }
678
679 if( parentCheck ) {
680
681 JMenu menu = popupMenu2Parent.get(parent);
682 if( parent == null || menu == null ) {
683 return;
684 }
685
686 if( visible == false && parent.isEnabled() ) {
687
688 // shall hold pointers to the siblings of 'comp', that is the
689 // children of 'parent'
690 Component[] siblings;
691
692 // get child-list
693 if( parent.getClass() == JPopupMenu.class || parent.getClass() == Container.class ) {
694 siblings = ((Container) parent).getComponents();
695 } else {
696 System.err.println("Cannot handle component type: " + parent.getClass());
697 return;
698 }
699
700 boolean allDisabled = true;
701
702 // check all sibling components of 'comp'
703 for( Component c: siblings ) {
704 if( !disregardedTypes.contains(c.getClass()) ) {
705 if( c.isEnabled() ) {
706 allDisabled = false;
707 break;
708 }
709 }
710 }
711
712 if( allDisabled ) {
713 if( parent.getClass() == JPopupMenu.class ) {
714 setAccessibility(popupMenu2Parent.get(parent),false,true,topLevelComponent,disregardedTypes);
715 } else {
716 setAccessibility(parent,false,true,topLevelComponent,disregardedTypes);
717 }
718 }
719
720 } else if ( visible == true ) {
721 setAccessibility(parent,true,true,topLevelComponent,disregardedTypes);
722 }
723 }
724 }
725
726 /**
727 * Gets all menu items (for the menu-bar as well as for the popup-menu),
728 * that is {@link JMenuItem} and {@link JMenu} objects.
729 * @return a map containg all menu item of this View instance
730 */
731 @SuppressWarnings("unused")
732 private Map<Component,Boolean> getMenuItemToggleMap() {
733 HashMap<Component,Boolean> h = new HashMap<Component, Boolean>();
734 Class<?> componentClass;
735
736 try {
737 for(Field f : this.getClass().getDeclaredFields() ) {
738 componentClass = f.getDeclaringClass();
739 if( componentClass == JMenuItem.class ) {
740 h.put((JMenuItem) f.get(this),true);
741 } else if (componentClass == JMenu.class) {
742 h.put((JMenuItem) f.get(this),true);
743 }
744 }
745 } catch (IllegalAccessException e) {
746 System.err.println("Error: " + e.getMessage());
747 } // menu -> View
748 return h;
749 }
750
751 /**
752 * Gets a map containing accessibility rules for the initialization of the
753 * menu-bar. Use this map as an input to function
754 * {@link #setAccessibility(Map, boolean, Component, Collection)}.
755 * @param hasMod set this to true if the View holds a first model
756 * @return a map containing accessibility rules for menu bar at startup
757 */
758 private Map<Component,Boolean> initMenuBarAccessibility(boolean hasMod) {
759 HashMap<Component,Boolean> map = new HashMap<Component, Boolean>();
760
761 // menu -> File
762 map.put(smFile.get("Save"), hasMod);
763 map.put(mmSaveAli,false);
764 map.put(mmPrint,hasMod);
765 map.put(mmInfo,hasMod);
766 // menu -> View
767 map.put(mmViewShowPdbResSers, hasMod);
768 map.put(mmViewRulers, hasMod);
769 map.put(mmViewHighlightComNbh, hasMod);
770 map.put(mmViewShowDensity, hasMod);
771 map.put(mmViewShowDistMatrix, hasMod);
772 // menu -> Select
773 map.put(mmSelectAll, hasMod);
774 map.put(mmSelectByResNum, hasMod);
775 map.put(mmSelectHelixHelix, hasMod);
776 map.put(mmSelectBetaBeta, hasMod);
777 map.put(mmSelectInterSsContacts, hasMod);
778 map.put(mmSelectIntraSsContacts, hasMod);
779 // menu -> Color
780 map.put(mmColorChoose, hasMod);
781 map.put(mmColorPaint, hasMod);
782 map.put(mmColorReset, hasMod);
783 // menu -> Action
784 map.put(squareM, hasMod);
785 map.put(fillM, hasMod);
786 map.put(rangeM, hasMod);
787 map.put(nodeNbhSelM, hasMod);
788 map.put(comNeiM, hasMod);
789 map.put(mmSelModeColor, hasMod);
790 map.put(sendM, hasMod);
791 map.put(triangleM, hasMod);
792 map.put(delEdgesM, hasMod);
793 // menu -> Compare
794 map.put(smCompare.get("Load"), hasMod);
795 map.put(mmSelCommonContactsInComparedMode,false);
796 map.put(mmSelFirstStrucInComparedMode,false);
797 map.put(mmSelSecondStrucInComparedMode,false);
798 map.put(mmToggleDiffDistMap,false);
799 //map.put(this.getJMenuBar().getMenu(menu2idx.get("Compare")), hasMod);
800
801 return map;
802 }
803
804 /**
805 * Gets the accessibility rules for the popup-menu item which can be
806 * applied with {@link #setAccessibility(Map, boolean, Component, Collection)}
807 * if a second model has been loaded.
808 * @return a map containing accessibility rules for the popup-menu items in
809 * the compare mode
810 */
811 private Map<Component,Boolean> compareModePopupMenuAccessibility() {
812 HashMap<Component, Boolean> map = new HashMap<Component, Boolean>();
813
814 map.put(nodeNbhSelP, false);
815 map.put(comNeiP, false);
816 map.put(pmSelModeColor, false);
817 map.put(triangleP, false);
818 map.put(popupSendEdge, false);
819
820 return map;
821 }
822
823 /**
824 * Gets the accessibility rules for the menu bar item which can be
825 * applied with {@link #setAccessibility(Map, boolean, Component, Collection)}
826 * if a second model has been loaded.
827 * @return a map containing accessibility rules for the menu bar item in
828 * the compare mode
829 */
830 private Map<Component,Boolean> compareModeMenuBarAccessibility() {
831 HashMap<Component,Boolean> map = new HashMap<Component, Boolean>();
832
833 // menu -> File
834 map.put(mmInfo,true);
835 map.put(mmSaveCmFile,false);
836 map.put(mmSaveGraphDb, false);
837 map.put(mmSaveAli, true);
838 // menu -> View
839 map.put(mmViewShowPdbResSers,false);
840 map.put(mmViewRulers,false);
841 map.put(mmViewHighlightComNbh,false);
842 map.put(mmViewShowDensity,false);
843 map.put(mmViewShowDistMatrix,false);
844 // menu -> Select
845 map.put(mmSelectByResNum,false);
846 map.put(mmSelectHelixHelix,false);
847 map.put(mmSelectBetaBeta,false);
848 map.put(mmSelectInterSsContacts,false);
849 map.put(mmSelectIntraSsContacts,false);
850 // menu -> Color
851 map.put(mmColorChoose,false);
852 map.put(mmColorPaint,false);
853 map.put(mmColorReset,false);
854 // menu -> Action
855 map.put(nodeNbhSelM,false);
856 map.put(comNeiM,false);
857 map.put(mmSelModeColor,false);
858 map.put(triangleM,false);
859 // menu -> Compare
860 map.put(mmSelCommonContactsInComparedMode,true);
861 map.put(mmSelFirstStrucInComparedMode,true);
862 map.put(mmSelSecondStrucInComparedMode,true);
863 map.put(mmToggleDiffDistMap,true);
864 map.put(smCompare.get("Load"),false);
865
866 return map;
867 }
868
869 /**
870 * Gets the accessibility rules for the buttons of the toolbar which can be
871 * applied with {@link #setAccessibility(Map, boolean, Component, Collection)}
872 * if a second model has been loaded.
873 * @return a map containing accessibility rules for the buttons of the
874 * toolbar in the compare mode
875 */
876 private Map<Component,Boolean> compareModeButtonAccessibility() {
877 HashMap<Component,Boolean> map = new HashMap<Component, Boolean>();
878
879 map.put(tbNbhSel, false);
880 map.put(tbShowComNbh, false);
881 map.put(tbSelModeColor, false);
882 map.put(tbShowComNbh3D, false);
883
884 return map;
885 }
886
887 /*------------------------------ event handling -------------------------*/
888
889 /**
890 * Handling action events for all menu items.
891 */
892 public void actionPerformed (ActionEvent e) {
893
894 /* ---------- File Menu ---------- */
895
896 // Load
897 if(e.getSource() == mmLoadGraph) {
898 handleLoadFromGraphDb(FIRST_MODEL);
899 }
900 if(e.getSource() == mmLoadPdbase) {
901 handleLoadFromPdbase(FIRST_MODEL);
902
903 }
904 if(e.getSource() == mmLoadMsd) {
905 handleLoadFromMsd(FIRST_MODEL);
906 }
907 if(e.getSource() == mmLoadPdb) {
908 handleLoadFromPdbFile(FIRST_MODEL);
909 }
910 if(e.getSource() == mmLoadFtp) {
911 handleLoadFromFtp(FIRST_MODEL);
912 }
913 if(e.getSource() == mmLoadCm) {
914 handleLoadFromCmFile(FIRST_MODEL);
915 }
916
917 // Save
918 if(e.getSource() == mmSaveGraphDb) {
919 handleSaveToGraphDb();
920 }
921 if(e.getSource() == mmSaveCmFile) {
922 handleSaveToCmFile();
923 }
924 if(e.getSource() == mmSavePng) {
925 handleSaveToPng();
926 }
927 if(e.getSource() == mmSaveAli) {
928 handleSaveAlignment();
929 }
930
931 // Info, Print, Quit
932 if(e.getSource() == mmInfo || e.getSource() == tbFileInfo) {
933 handleInfo();
934 }
935 if(e.getSource() == mmPrint || e.getSource() == tbFilePrint) {
936 handlePrint();
937 }
938 if(e.getSource() == mmQuit || e.getSource() == tbFileQuit) {
939 handleQuit();
940 }
941
942 /* ---------- View Menu ---------- */
943
944 if(e.getSource() == mmViewShowPdbResSers) {
945 handleShowPdbResSers();
946 }
947 if(e.getSource() == mmViewRulers) {
948 handleShowRulers();
949 }
950 if(e.getSource() == mmViewIconBar) {
951 handleShowIconBar();
952 }
953 if(e.getSource() == mmViewHighlightComNbh) {
954 handleShowNbhSizeMap();
955 }
956 if(e.getSource() == mmViewShowDensity) {
957 handleShowDensityMap();
958 }
959 if(e.getSource() == mmViewShowDistMatrix) {
960 handleShowDistanceMap();
961 }
962
963 /* ---------- Select menu ---------- */
964
965 if(e.getSource() == mmSelectAll ) {
966 handleSelectAll();
967 }
968 if(e.getSource() == mmSelectByResNum ) {
969 handleSelectByResNum();
970 }
971 if(e.getSource() == mmSelectHelixHelix ) {
972 handleSelectHelixHelix();
973 }
974 if(e.getSource() == mmSelectBetaBeta ) {
975 handleSelectBetaBeta();
976 }
977 if(e.getSource() == mmSelectInterSsContacts ) {
978 handleSelectInterSsContacts();
979 }
980 if(e.getSource() == mmSelectIntraSsContacts ) {
981 handleSelectIntraSsContacts();
982 }
983
984 /* ---------- Color menu ---------- */
985
986 if(e.getSource() == mmColorReset) {
987 handleColorReset();
988 }
989 if(e.getSource() == mmColorPaint) {
990 handleColorPaint();
991 }
992 if(e.getSource() == mmColorChoose) {
993 handleColorSelect();
994 }
995
996 /* ---------- Action menu ---------- */
997
998 // Selection modes
999
1000 // square button clicked
1001 if (e.getSource() == squareM || e.getSource() == squareP || e.getSource() == tbSquareSel ) {
1002 setSelectionMode(SQUARE_SEL);
1003 }
1004 // fill button clicked
1005 if (e.getSource() == fillM || e.getSource() == fillP || e.getSource() == tbFillSel) {
1006 setSelectionMode(FILL_SEL);
1007 }
1008 // diagonal selection clicked
1009 if (e.getSource() == rangeM || e.getSource() == rangeP || e.getSource() == tbDiagSel) {
1010 setSelectionMode(DIAG_SEL);
1011 }
1012 // node neihbourhood selection button clicked
1013 if (e.getSource() == nodeNbhSelM || e.getSource() == nodeNbhSelP || e.getSource() == tbNbhSel) {
1014 setSelectionMode(NODE_NBH_SEL);
1015 }
1016 // showing com. Nei. button clicked
1017 if (e.getSource() == comNeiM || e.getSource() == comNeiP || e.getSource() == tbShowComNbh) {
1018 setSelectionMode(SHOW_COMMON_NBH);
1019 }
1020 // color selection mode button clicked
1021 if (e.getSource() == mmSelModeColor || e.getSource() == pmSelModeColor || e.getSource() == tbSelModeColor) {
1022 setSelectionMode(SEL_MODE_COLOR);
1023 }
1024
1025 // Actions
1026
1027 // send selection button clicked
1028 if (e.getSource() == sendM || e.getSource() == sendP || e.getSource() == tbShowSel3D) {
1029 handleShowSelContacts3D();
1030 }
1031 // send com.Nei. button clicked
1032 if(e.getSource()== triangleM || e.getSource()== triangleP || e.getSource() == tbShowComNbh3D) {
1033 handleShowTriangles3D();
1034 }
1035 // delete selected edges button clicked
1036 if (e.getSource() == delEdgesM || e.getSource() == delEdgesP || e.getSource() == tbDelete) {
1037 handleDeleteSelContacts();
1038 }
1039 // send current edge (only available in popup menu)
1040 if(e.getSource() == popupSendEdge) {
1041 handleShowDistance3D();
1042 }
1043
1044 /* ---------- Comparison Menu ---------- */
1045
1046
1047 /** for the contact map comparison load menu */
1048
1049
1050 if(e.getSource() == mmLoadGraph2) {
1051 handleLoadFromGraphDb(SECOND_MODEL);
1052 }
1053 if(e.getSource() == mmLoadPdbase2) {
1054 handleLoadFromPdbase(SECOND_MODEL);
1055 }
1056 if(e.getSource() == mmLoadMsd2) {
1057 handleLoadFromMsd(SECOND_MODEL);
1058 }
1059 if(e.getSource() == mmLoadPdb2) {
1060 handleLoadFromPdbFile(SECOND_MODEL);
1061 }
1062 if(e.getSource() == mmLoadFtp2) {
1063 handleLoadFromFtp(SECOND_MODEL);
1064 }
1065 if(e.getSource() == mmLoadCm2) {
1066 handleLoadFromCmFile(SECOND_MODEL);
1067 }
1068
1069 if(e.getSource() == mmSelCommonContactsInComparedMode || e.getSource() == tbShowCommon) {
1070 handleSelContactsInComparedMode();
1071 }
1072
1073 if(e.getSource() == mmSelFirstStrucInComparedMode || e.getSource() == tbShowFirstStructure) {
1074 handleSelFirstStrucInComparedMode();
1075 }
1076
1077 if(e.getSource() == mmSelSecondStrucInComparedMode || e.getSource() == tbShowSecondStructure) {
1078 handleSelSecondStrucInComparedMode();
1079 }
1080
1081 if(e.getSource() == mmToggleDiffDistMap) {
1082 handleToggleDiffDistMap();
1083 }
1084
1085 if( e.getSource() == mmSuposition ) {
1086 handleSuperposition();
1087 }
1088
1089 if( e.getSource() == mmShowAlignedResidues ) {
1090 handleShowAlignedResidues3D();
1091 }
1092
1093 /* ---------- Help Menu ---------- */
1094
1095 if(e.getSource() == mmHelpAbout) {
1096 handleHelpAbout();
1097 }
1098 if(e.getSource() == mmHelpHelp) {
1099 handleHelpHelp();
1100 }
1101 if(e.getSource() == mmHelpWriteConfig) {
1102 handleHelpWriteConfig();
1103 }
1104
1105 /* ---------------- Invisible Notifiers --------------- */
1106 if( e.getSource() == sadpNotifier && sadpNotifier.notification() == SADPDialog.DONE ) {
1107 handlePairwiseAlignmentResults(sadpNotifier);
1108 }
1109
1110 }
1111
1112
1113 /* -------------------- File Menu -------------------- */
1114
1115 private void handleLoadFromGraphDb(boolean secondModel) {
1116 if(!Start.isDatabaseConnectionAvailable()) {
1117 showNoDatabaseConnectionWarning();
1118 } else {
1119 if (secondModel == SECOND_MODEL && mod == null){
1120 this.showNoContactMapWarning();
1121 } else{
1122 LoadDialog dialog;
1123 try {
1124 dialog = new LoadDialog(this, "Load from graph database", new LoadAction(secondModel) {
1125 public void doit(Object o, String f, String ac, int modelSerial, String cc, String ct, double dist, int minss, int maxss, String db, int gid) {
1126 View view = (View) o;
1127 view.doLoadFromGraphDb(db, gid, secondModel);
1128 }
1129 }, null, null, null, null, null, null, null, null, Start.DEFAULT_GRAPH_DB, "");
1130
1131 actLoadDialog = dialog;
1132 dialog.showIt();
1133
1134 } catch (LoadDialogConstructionError e) {
1135 System.err.println("Failed to load the load-dialog.");
1136 }
1137 }
1138 }
1139 }
1140
1141 public void doLoadFromGraphDb(String db, int gid, boolean secondModel) {
1142 System.out.println("Loading from graph database");
1143 System.out.println("Database:\t" + db);
1144 System.out.println("Graph Id:\t" + gid);
1145 try {
1146 Model mod = new GraphDbModel(gid, db);
1147 if(secondModel) {
1148 //handleLoadSecondModel(mod);
1149 mod2 = mod;
1150 handlePairwiseAlignment();
1151 } else {
1152 this.spawnNewViewWindow(mod);
1153 }
1154 } catch(ModelConstructionError e) {
1155 showLoadError(e.getMessage());
1156 }
1157 }
1158
1159 private void handleLoadFromPdbase(boolean secondModel) {
1160 if(!Start.isDatabaseConnectionAvailable()) {
1161 showNoDatabaseConnectionWarning();
1162 } else {
1163 if (secondModel == SECOND_MODEL && mod == null){
1164 this.showNoContactMapWarning();
1165 } else{
1166 try {
1167 LoadDialog dialog = new LoadDialog(this, "Load from Pdbase", new LoadAction(secondModel) {
1168 public void doit(Object o, String f, String ac, int modelSerial, String cc, String ct, double dist, int minss, int maxss, String db, int gid) {
1169 View view = (View) o;
1170 view.doLoadFromPdbase(ac, modelSerial, cc, ct, dist, minss, maxss, db, secondModel);
1171 }
1172 }, null, "", "1", "", Start.DEFAULT_CONTACT_TYPE, String.valueOf(Start.DEFAULT_DISTANCE_CUTOFF), "", "", Start.DEFAULT_PDB_DB, null);
1173 dialog.setChainCodeGetter(new Getter(dialog) {
1174 public Object get() throws GetterError {
1175 LoadDialog dialog = (LoadDialog) getObject();
1176 String pdbCode = dialog.getSelectedAc();
1177 String db = dialog.getSelectedDb();
1178 try {
1179 PdbaseModel mod = new PdbaseModel(pdbCode,"",0.0,1,1,db);
1180 return mod.getChains();
1181 } catch (PdbCodeNotFoundError e) {
1182 throw new GetterError("Failed to read chains from pdbase:" + e.getMessage());
1183 } catch (SQLException e) {
1184 throw new GetterError("Failed to read chains from pdbase:" + e.getMessage());
1185 }
1186 }
1187 });
1188 dialog.setModelsGetter(new Getter(dialog) {
1189 public Object get() throws GetterError {
1190 LoadDialog dialog = (LoadDialog) getObject();
1191 String pdbCode = dialog.getSelectedAc();
1192 String db = dialog.getSelectedDb();
1193 try {
1194 PdbaseModel mod = new PdbaseModel(pdbCode,"",0.0,1,1,db);
1195 return mod.getModels();
1196 } catch (PdbCodeNotFoundError e) {
1197 throw new GetterError("Failed to read models from pdbase:" + e.getMessage());
1198 } catch (SQLException e) {
1199 throw new GetterError("Failed to read models from pdbase:" + e.getMessage());
1200 }
1201 }
1202 });
1203 actLoadDialog = dialog;
1204 dialog.showIt();
1205 } catch (LoadDialogConstructionError e) {
1206 System.err.println("Failed to load the load-dialog.");
1207 }
1208 }
1209 }
1210 }
1211
1212 public void doLoadFromPdbase(String ac, int modelSerial, String cc, String ct, double dist, int minss, int maxss, String db, boolean secondModel) {
1213 System.out.println("Loading from Pdbase");
1214 System.out.println("PDB code:\t" + ac);
1215 System.out.println("Model serial:\t" + modelSerial);
1216 System.out.println("Chain code:\t" + cc);
1217 System.out.println("Contact type:\t" + ct);
1218 System.out.println("Dist. cutoff:\t" + dist);
1219 System.out.println("Min. Seq. Sep.:\t" + (minss==-1?"none":minss));
1220 System.out.println("Max. Seq. Sep.:\t" + (maxss==-1?"none":maxss));
1221 System.out.println("Database:\t" + db);
1222 try{
1223 Model mod = new PdbaseModel(ac, ct, dist, minss, maxss, db);
1224 mod.load(cc, modelSerial);
1225 if(secondModel) {
1226 //handleLoadSecondModel(mod);
1227 mod2 = mod;
1228 handlePairwiseAlignment();
1229 } else {
1230 this.spawnNewViewWindow(mod);
1231 }
1232 } catch(ModelConstructionError e) {
1233 showLoadError(e.getMessage());
1234 } catch (PdbCodeNotFoundError e) {
1235 showLoadError(e.getMessage());
1236 } catch (SQLException e) {
1237 showLoadError(e.getMessage());
1238 }
1239 }
1240
1241 private void handleLoadFromMsd(boolean secondModel) {
1242 if(!Start.isDatabaseConnectionAvailable()) {
1243 showNoDatabaseConnectionWarning();
1244 } else {
1245 if (secondModel == SECOND_MODEL && mod == null){
1246 this.showNoContactMapWarning();
1247 } else{
1248 try {
1249 LoadDialog dialog = new LoadDialog(this, "Load from MSD", new LoadAction(secondModel) {
1250 public void doit(Object o, String f, String ac, int modelSerial, String cc, String ct, double dist, int minss, int maxss, String db, int gid) {
1251 View view = (View) o;
1252 view.doLoadFromMsd(ac, modelSerial, cc, ct, dist, minss, maxss, db, secondModel);
1253 }
1254 }, null, "", "1", "", Start.DEFAULT_CONTACT_TYPE, String.valueOf(Start.DEFAULT_DISTANCE_CUTOFF), "", "", Start.DEFAULT_MSDSD_DB, null);
1255 dialog.setChainCodeGetter(new Getter(dialog) {
1256 public Object get() throws GetterError {
1257 LoadDialog dialog = (LoadDialog) getObject();
1258 String pdbCode = dialog.getSelectedAc();
1259 String db = dialog.getSelectedDb();
1260 MsdsdModel mod = new MsdsdModel(pdbCode,"",0.0,1,1,db);
1261 return mod.getChains();
1262 }
1263 });
1264 dialog.setModelsGetter(new Getter(dialog) {
1265 public Object get() throws GetterError {
1266 LoadDialog dialog = (LoadDialog) getObject();
1267 String pdbCode = dialog.getSelectedAc();
1268 String db = dialog.getSelectedDb();
1269 MsdsdModel mod = new MsdsdModel(pdbCode,"",0.0,1,1,db);
1270 return mod.getModels();
1271 }
1272 });
1273 actLoadDialog = dialog;
1274 dialog.showIt();
1275 } catch (LoadDialogConstructionError e) {
1276 System.err.println("Failed to load load-dialog.");
1277 }
1278 }
1279 }
1280 }
1281
1282 public void doLoadFromMsd(String ac, int modelSerial, String cc, String ct, double dist, int minss, int maxss, String db, boolean secondModel) {
1283 System.out.println("Loading from MSD");
1284 System.out.println("PDB code:\t" + ac);
1285 System.out.println("Model index:\t" + modelSerial);
1286 System.out.println("Chain code:\t" + cc);
1287 System.out.println("Contact type:\t" + ct);
1288 System.out.println("Dist. cutoff:\t" + dist);
1289 System.out.println("Min. Seq. Sep.:\t" + (minss==-1?"none":minss));
1290 System.out.println("Max. Seq. Sep.:\t" + (maxss==-1?"none":maxss));
1291 System.out.println("Database:\t" + db);
1292 try {
1293 Model mod = new MsdsdModel(ac, ct, dist, minss, maxss, db);
1294 mod.load(cc, modelSerial);
1295 if(secondModel) {
1296 //handleLoadSecondModel(mod);
1297 mod2 = mod;
1298 handlePairwiseAlignment();
1299 } else {
1300 this.spawnNewViewWindow(mod);
1301 }
1302 } catch(ModelConstructionError e) {
1303 showLoadError(e.getMessage());
1304 }
1305 }
1306
1307 private void handleLoadFromPdbFile(boolean secondModel) {
1308
1309 if (secondModel == SECOND_MODEL && mod == null){
1310 this.showNoContactMapWarning();
1311 } else{
1312 try {
1313 LoadDialog dialog = new LoadDialog(this, "Load from Pdb file", new LoadAction(secondModel) {
1314 public void doit(Object o, String f, String ac, int modelSerial, String cc, String ct, double dist, int minss, int maxss, String db, int gid) {
1315 View view = (View) o;
1316 view.doLoadFromPdbFile(f, modelSerial, cc, ct, dist, minss, maxss, secondModel);
1317 }
1318 }, "", null, "1", "", Start.DEFAULT_CONTACT_TYPE, String.valueOf(Start.DEFAULT_DISTANCE_CUTOFF), "", "", null, null);
1319 dialog.setChainCodeGetter(new Getter(dialog) {
1320 public Object get() throws GetterError {
1321 LoadDialog dialog = (LoadDialog) getObject();
1322 String pdbFilename = dialog.getSelectedFileName();
1323 try {
1324 PdbFileModel mod = new PdbFileModel(pdbFilename,"",0.0,1,1);
1325 return mod.getChains();
1326 } catch (ModelConstructionError e) {
1327 throw new GetterError("Failed to read chains from ftp:"+e.getMessage());
1328 }
1329 }
1330 });
1331 dialog.setModelsGetter(new Getter(dialog) {
1332 public Object get() throws GetterError {
1333 LoadDialog dialog = (LoadDialog) getObject();
1334 String pdbFilename = dialog.getSelectedFileName();
1335 try {
1336 PdbFileModel mod = new PdbFileModel(pdbFilename,"",0.0,1,1);
1337 return mod.getModels();
1338 } catch (ModelConstructionError e) {
1339 throw new GetterError("Failed to read models from ftp:"+e.getMessage());
1340 }
1341 }
1342 });
1343 actLoadDialog = dialog;
1344 dialog.showIt();
1345 } catch (LoadDialogConstructionError e1) {
1346 System.err.println("Failed to load the load-dialog.");
1347 }
1348 }
1349 }
1350
1351 public void doLoadFromPdbFile(String f, int modelSerial, String cc, String ct, double dist, int minss, int maxss, boolean secondModel) {
1352 System.out.println("Loading from Pdb file");
1353 System.out.println("Filename:\t" + f);
1354 System.out.println("Model serial:\t" + modelSerial);
1355 System.out.println("Chain code:\t" + cc);
1356 System.out.println("Contact type:\t" + ct);
1357 System.out.println("Dist. cutoff:\t" + dist);
1358 System.out.println("Min. Seq. Sep.:\t" + (minss==-1?"none":minss));
1359 System.out.println("Max. Seq. Sep.:\t" + (maxss==-1?"none":maxss));
1360 try {
1361 Model mod = new PdbFileModel(f, ct, dist, minss, maxss);
1362 mod.load(cc, modelSerial);
1363 if(secondModel) {
1364 //handleLoadSecondModel(mod);
1365 mod2 = mod;
1366 handlePairwiseAlignment();
1367 } else {
1368 this.spawnNewViewWindow(mod);
1369 }
1370 } catch(ModelConstructionError e) {
1371 showLoadError(e.getMessage());
1372 }
1373 }
1374
1375 private void handleLoadFromCmFile(boolean secondModel) {
1376
1377 if (secondModel == SECOND_MODEL && mod == null){
1378 this.showNoContactMapWarning();
1379 } else{
1380 try {
1381 LoadDialog dialog = new LoadDialog(this, "Load from Contact map file", new LoadAction(secondModel) {
1382 public void doit(Object o, String f, String ac, int modelSerial, String cc, String ct, double dist, int minss, int maxss, String db, int gid) {
1383 View view = (View) o;
1384 view.doLoadFromCmFile(f, secondModel);
1385 }
1386 }, "", null, null, null, null, null, null, null, null, null);
1387 actLoadDialog = dialog;
1388 dialog.showIt();
1389 } catch (LoadDialogConstructionError e) {
1390 System.err.println("Failed to load the load-dialog.");
1391 }
1392 }
1393 }
1394
1395 public void doLoadFromCmFile(String f, boolean secondModel) {
1396 System.out.println("Loading from contact map file "+f);
1397 try {
1398 Model mod = new ContactMapFileModel(f);
1399 if(secondModel) {
1400 //handleLoadSecondModel(mod);
1401 mod2 = mod;
1402 handlePairwiseAlignment();
1403 } else {
1404 this.spawnNewViewWindow(mod);
1405 }
1406 } catch(ModelConstructionError e) {
1407 showLoadError(e.getMessage());
1408 }
1409 }
1410
1411 private void handleLoadFromFtp(boolean secondModel) {
1412 if (secondModel == SECOND_MODEL && mod == null){
1413 this.showNoContactMapWarning();
1414 } else{
1415 try {
1416 LoadDialog dialog = new LoadDialog(this, "Load from online PDB", new LoadAction(secondModel) {
1417 public void doit(Object o, String f, String ac, int modelSerial, String cc, String ct, double dist, int minss, int maxss, String db, int gid) {
1418 View view = (View) o;
1419 view.doLoadFromFtp(ac, modelSerial, cc, ct, dist, minss, maxss, secondModel);
1420 }
1421 }, null, "", "1", "", Start.DEFAULT_CONTACT_TYPE, String.valueOf(Start.DEFAULT_DISTANCE_CUTOFF), "", "", null, null);
1422
1423 actLoadDialog = dialog;
1424 dialog.showIt();
1425 } catch (LoadDialogConstructionError e) {
1426 // TODO Auto-generated catch block
1427 e.printStackTrace();
1428 }
1429
1430 }
1431 }
1432
1433 public void doLoadFromFtp(String ac, int modelSerial, String cc, String ct, double dist, int minss, int maxss, boolean secondModel) {
1434 System.out.println("Loading from online PDB");
1435 System.out.println("PDB code:\t" + ac);
1436 System.out.println("Model serial:\t" + modelSerial);
1437 System.out.println("Chain code:\t" + cc);
1438 System.out.println("Contact type:\t" + ct);
1439 System.out.println("Dist. cutoff:\t" + dist);
1440 System.out.println("Min. Seq. Sep.:\t" + (minss==-1?"none":minss));
1441 System.out.println("Max. Seq. Sep.:\t" + (maxss==-1?"none":maxss));
1442 try{
1443 Model mod = new PdbFtpModel(ac, ct, dist, minss, maxss);
1444 mod.load(cc, modelSerial);
1445 if(secondModel) {
1446 //handleLoadSecondModel(mod);
1447 mod2 = mod;
1448 handlePairwiseAlignment();
1449 } else {
1450 this.spawnNewViewWindow(mod);
1451 }
1452 } catch(ModelConstructionError e) {
1453 showLoadError(e.getMessage());
1454 } catch (IOException e) {
1455 System.err.println("Failed to load structure from ftp:" + e.getMessage());
1456 }
1457 }
1458
1459 /**
1460 * Handles the computation of the pairwise contact map alignment of the
1461 * two passed models in a new thread.
1462 * @param mod1 first model
1463 * @param mod2 second model
1464 */
1465 private void handlePairwiseAlignment() {
1466 String error = null;
1467
1468 actLoadDialog.dispose();
1469 Object[] possibilities = {"compute internal structure alignment","load alignment from file","apply greedy residue mapping","compute Needleman-Wunsch sequence alignment"};
1470 String source = (String) JOptionPane.showInputDialog(this, "Chose alignment source ...", "Pairwise Protein Alignment", JOptionPane.PLAIN_MESSAGE, null, possibilities, possibilities[0]);
1471
1472 if( source != null ) {
1473 try {
1474 if( source == possibilities[0] ) {
1475 // compute contact map alignment using SADP
1476 doPairwiseSadpAlignment(mod, mod2);
1477 } else if( source == possibilities[1] ) {
1478 // load a user provided alignment from an external source
1479 doLoadPairwiseAlignment(mod,mod2);
1480 } else if( source == possibilities[2] ) {
1481 // do a greedy residue-residue alignment
1482 doGreedyPairwiseAlignment(mod, mod2);
1483 } else if( source == possibilities[3] ) {
1484 // do a greedy residue-residue alignment
1485 doPairwiseSequenceAlignment(mod, mod2);
1486 } else {
1487 System.err.println("Error: Detected unhandled input option for the alignment retrieval!");
1488 return;
1489 }
1490 } catch (AlignmentConstructionError e) {
1491 error = e.getMessage();
1492 } catch (DifferentContactMapSizeError e) {
1493 error = e.getMessage();
1494 } catch (FileNotFoundException e) {
1495 error = e.getMessage();
1496 } catch (PirFileFormatError e) {
1497 error = e.getMessage();
1498 } catch (FastaFileFormatError e) {
1499 error = e.getMessage();
1500 } catch (IOException e) {
1501 error = e.getMessage();
1502 }
1503 finally{
1504 if(error != null) {
1505 // reset all fields connected to the compare mode and clean up the scene
1506 mod2 = null; alignedMod1 = null; alignedMod2 = null; ali = null;
1507 JOptionPane.showMessageDialog(this, error, "Error", JOptionPane.ERROR_MESSAGE);
1508
1509 }
1510 }
1511
1512 }
1513 }
1514
1515 /**
1516 * Enables and disables some GUI features for the compare mode.
1517 */
1518 private void setGUIStatusCompareMode() {
1519 // enable computation of the superposition and the showing of
1520 // corresponding residues for both structures
1521 mmSuposition.setEnabled(true);
1522 mmShowAlignedResidues.setEnabled(true);
1523
1524 // disable/enable some menu-bar items, popup-menu items and buttons
1525 setAccessibility(compareModeMenuBarAccessibility(), true, getJMenuBar(), disregardedTypes);
1526 setAccessibility(compareModePopupMenuAccessibility(), true, null, disregardedTypes);
1527 setAccessibility(compareModeButtonAccessibility(), true, null, disregardedTypes);
1528
1529 // disable rulers
1530 if(showRulers) {
1531 handleShowRulers();
1532 }
1533
1534 }
1535
1536 /**
1537 * Loads the pairwise alignment for the given model from a external source.
1538 * @param mod1 the first model
1539 * @param mod2 the second model
1540 */
1541 public void doLoadPairwiseAlignment(Model mod1, Model mod2)
1542 throws FileNotFoundException, IOException, PirFileFormatError, FastaFileFormatError,
1543 AlignmentConstructionError, DifferentContactMapSizeError {
1544
1545 // open global file-chooser and get the name the alignment file
1546 JFileChooser fileChooser = Start.getFileChooser();
1547 int ret = fileChooser.showOpenDialog(this);
1548 File source = null;
1549 if(ret == JFileChooser.APPROVE_OPTION) {
1550 source = fileChooser.getSelectedFile();
1551 } else {
1552 return;
1553 }
1554
1555 // load alignment
1556 ali = new Alignment(source.getPath(),"FASTA");
1557
1558 // prepare expected sequence identifiers of 'mod1' and 'mod2' in
1559 // 'ali'
1560 String name1 = mod1.getPDBCode() + mod1.getChainCode();
1561 String name2 = mod2.getPDBCode() + mod2.getChainCode();
1562
1563 // as we cannot guess identifiers we throw an exception if either
1564 // of them is not defined
1565 if( !(ali.hasTag(name1) && ali.hasTag(name2)) ) {
1566 throw new AlignmentConstructionError(
1567 "Cannot assign a sequence to each structure! The expected sequence tags are:\n"+
1568 "for the first structure: " + name1 + "\n" +
1569 "for the second structure: " + name2
1570 );
1571 }
1572
1573 // compute aligned graphs
1574 PairwiseAlignmentGraphConverter pagc = new PairwiseAlignmentGraphConverter(ali,name1,name2,mod1.getGraph(),mod2.getGraph());
1575
1576 // create the aligned models from the original once
1577 alignedMod1 = mod1.copy();
1578 alignedMod1.setGraph(pagc.getFirstGraph());
1579 alignedMod2 = mod2.copy();
1580 alignedMod2.setGraph(pagc.getSecondGraph());
1581
1582 // load stuff onto the contact map pane and the visualizer
1583 doLoadModelsOntoContactMapPane(alignedMod1, alignedMod2, ali, name1, name2);
1584 doLoadModelOntoVisualizer(alignedMod2);
1585
1586 // adapt GUI behavior
1587 setGUIStatusCompareMode();
1588 }
1589
1590 /**
1591 * Computes the pairwise contact map alignment of the two passed models in
1592 * a new thread.
1593 * @param mod1 first model
1594 * @param mod2 second model
1595 */
1596 public void doPairwiseSadpAlignment(Model mod1, Model mod2) {
1597 SADPResult result = new SADPResult();
1598 SADPRunner runner = new SADPRunner(mod1,mod2,result);
1599 // version 1.0 used to be as simple as possible -> no preferences
1600 // settings available
1601 SADPDialog sadpDiag = new SADPDialog(
1602 this,
1603 "Pairwise Protein Alignment",
1604 runner,
1605 result,
1606 (Start.INCLUDE_GROUP_INTERNALS?SADPDialog.CONSTRUCT_EVERYTHING:SADPDialog.CONSTRUCT_WITHOUT_START_AND_PREFERENCES));
1607 sadpNotifier = sadpDiag.getNotifier();
1608
1609 if( sadpDiag.getConstructionStatus() == SADPDialog.CONSTRUCT_WITHOUT_START_AND_PREFERENCES ) {
1610 sadpDiag.getStartButton().doClick();
1611 }
1612
1613 sadpDiag.createGUI();
1614 }
1615
1616 /**
1617 * Constructs a pairwise sequence alignment using the Needleman-Wunsch algorithm with default parameters.
1618 * @param mod1 the first model
1619 * @param mod2 the second model
1620 * @throws AlignmentConstructionError
1621 */
1622 public void doPairwiseSequenceAlignment(Model mod1, Model mod2) throws AlignmentConstructionError {
1623 String seq1 = mod1.getSequence();
1624 String seq2 = mod2.getSequence();
1625
1626 if(seq1 == null || seq2 == null || seq1.length() == 0 || seq2.length() == 0) {
1627 throw new AlignmentConstructionError("No sequence found.");
1628 }
1629
1630 String name1 = mod1.getPDBCode()+mod1.getChainCode();
1631 String name2 = mod2.getPDBCode()+mod2.getChainCode();
1632
1633 PairwiseSequenceAlignment jalign = null;
1634 try {
1635 jalign = new PairwiseSequenceAlignment(seq1, seq2, name1, name2);
1636 } catch (PairwiseSequenceAlignmentException e) {
1637 throw new AlignmentConstructionError("Error during alignment: " + e.getMessage());
1638 }
1639 jalign.printAlignment();
1640 String[] alignedSeqs = jalign.getAlignedSequences();
1641 String alignedSeq1 = alignedSeqs[0];
1642 String alignedSeq2 = alignedSeqs[1];
1643
1644 // create alignement
1645 TreeMap<String,String> name2seq = new TreeMap<String, String>();
1646 name2seq.put(name1, alignedSeq1);
1647 name2seq.put(name2, alignedSeq2);
1648 ali = new Alignment(name2seq);
1649 //ali.printSimple();
1650
1651 // use alignment along with the graphs of the original models to
1652 // create the gapped graphs
1653 PairwiseAlignmentGraphConverter pagc = new PairwiseAlignmentGraphConverter(ali,name1,name2,mod1.getGraph(),mod2.getGraph());
1654 alignedMod1 = mod1.copy();
1655 alignedMod1.setGraph(pagc.getFirstGraph());
1656 alignedMod2 = mod2.copy();
1657 alignedMod2.setGraph(pagc.getSecondGraph());
1658
1659 // load stuff onto the contact map pane and the visualizer
1660 try {
1661 doLoadModelsOntoContactMapPane(alignedMod1, alignedMod2, ali, name1, name2);
1662 } catch (DifferentContactMapSizeError e) {
1663 throw new AlignmentConstructionError("Sizes of aligned contact maps do not match: " + e.getMessage());
1664 }
1665 doLoadModelOntoVisualizer(alignedMod2);
1666
1667 // adapt GUI behavior
1668 setGUIStatusCompareMode();
1669 }
1670
1671 /**
1672 * Construct a pairwise alignment of the given models in a rather greedy
1673 * manner: The residues of both models are mapped index-wise, i.e. residue
1674 * 1 in the first model is mapped to residue 1 in the second and so on. The
1675 * shorter sequence is being extended with gap characters to accomplish the
1676 * length of the longer sequence. If either (or both) sequence(s) do(es)
1677 * not provide sequence information the sequence length is being estimated
1678 * by size of the underlying graph structure (i.e. the maximum node index).
1679 * In that case, the sequences do only consist of X's.
1680 * @param mod1 the first model
1681 * @param mod2 the second model
1682 * @throws AlignmentConstructionError
1683 */
1684 public void doGreedyPairwiseAlignment(Model mod1, Model mod2)
1685 throws AlignmentConstructionError, DifferentContactMapSizeError {
1686
1687 String alignedSeq1 = mod1.getSequence();
1688 String alignedSeq2 = mod2.getSequence();
1689 int len1,len2,cap;
1690 StringBuffer s = null;
1691 char gap = Alignment.getGapCharacter();
1692
1693 if( alignedSeq1 == null || alignedSeq1.length() == 0 ) { // changed by HS, hope this is safer
1694
1695 len1 = mod1.getGraph().getFullLength();
1696
1697 if( alignedSeq2 == null || alignedSeq2.length() == 0) {
1698 // alignedSeq1 -> NOT present, alignedSeq2 -> NOT present
1699
1700 len2 = mod2.getGraph().getFullLength();
1701 cap = Math.max(len1,len2);
1702 s = new StringBuffer(cap);
1703
1704
1705 // fill dummy string with 'X' characters denoting unobserved
1706 // residues in the size of the longer sequence
1707 for(int i = 0; i < cap; ++i) {
1708 s.append('X');
1709 }
1710
1711 if( len1 < len2 ) {
1712 alignedSeq2 = new String(s);
1713
1714 // replace the different position in the aligned sequences
1715 // with gap characters in the shorter one
1716 for(int i = len1; i < len2; ++i) {
1717 s.setCharAt(i, gap);
1718 }
1719
1720 alignedSeq1 = new String(s);
1721
1722 } else if( len1 > len2 ){
1723 alignedSeq1 = new String(s);
1724
1725 // replace the different position in the aligned sequences
1726 // with gap characters in the shorter one
1727 for(int i = len1; i < len2; ++i) {
1728 s.setCharAt(i, gap);
1729 }
1730
1731 alignedSeq2 = new String(s);
1732 }
1733 } else {
1734 // alignedSeq1 -> NOT present, alignedSeq2 -> present
1735
1736 len2 = alignedSeq2.length();
1737 s = new StringBuffer(Math.max(len1, len2));
1738
1739 for(int i = 0; i < len1; ++i) {
1740 s.append('X');
1741 }
1742
1743 if( len1 < len2 ) {
1744 // appends gaps to alignedSeq1
1745 for(int i = len1; i < len2; ++i) {
1746 s.append(gap);
1747 }
1748
1749 alignedSeq1 = new String(s);
1750
1751 } else if( len1 > len2 ) {
1752 alignedSeq1 = new String(s);
1753
1754 // appends gaps to alignedSeq2
1755 for(int i = 0; i < len1-len2; ++i) {
1756 s.setCharAt(i, gap);
1757 }
1758
1759 alignedSeq2 += s;
1760 }
1761 }
1762 } else {
1763
1764 len1 = alignedSeq1.length();
1765
1766 if( alignedSeq2 == null || alignedSeq2 == "" ) {
1767 // alignedSeq1 -> present, alignedSeq2 -> NOT present
1768
1769 len2 = mod2.getGraph().getFullLength();
1770 s = new StringBuffer(Math.max(len1, len2));
1771
1772 for(int i = 0; i < len2; ++i) {
1773 s.append('X');
1774 }
1775
1776 if( len1 < len2 ) {
1777 alignedSeq2 = new String(s);
1778
1779 // append gaps to alignedSeq1
1780 for(int i = 0; i < len2-len1; ++i) {
1781 s.setCharAt(i, gap);
1782 }
1783
1784 alignedSeq1 += s.substring(0,len2-len1);
1785
1786 } else if( len1 > len2 ) {
1787 // append gaps to alignedSeq2
1788 for(int i = len2; i < len1-len2; ++i) {
1789 s.append(gap);
1790 }
1791
1792 alignedSeq2 = new String(s);
1793 }
1794 } else {
1795 // alignedSeq1 -> present, alignedSeq2 -> present
1796
1797 // append gaps to the shorter of alignedSeq1 and alignedSeq2
1798 len2 = alignedSeq2.length();
1799
1800 if( len1 != len2 ) {
1801 cap = Math.abs(len1-len2);
1802 s = new StringBuffer(cap);
1803
1804 for(int i = 0; i < cap; ++i) {
1805 s.append(gap);
1806 }
1807 }
1808
1809 if( len1 < len2 ) {
1810 alignedSeq1 += s;
1811 } else if( len1 > len2 ) {
1812 alignedSeq2 += s;
1813 }
1814 }
1815 }
1816
1817 // create alignement
1818 TreeMap<String,String> name2seq = new TreeMap<String, String>();
1819 String name1 = mod1.getPDBCode()+mod1.getChainCode();
1820 String name2 = mod2.getPDBCode()+mod2.getChainCode();
1821 name2seq.put(name1, alignedSeq1);
1822 name2seq.put(name2, alignedSeq2);
1823 ali = new Alignment(name2seq);
1824
1825 // use alignment along with the graphs of the original models to
1826 // create the gapped graphs
1827 PairwiseAlignmentGraphConverter pagc = new PairwiseAlignmentGraphConverter(ali,name1,name2,mod1.getGraph(),mod2.getGraph());
1828 alignedMod1 = mod1.copy();
1829 alignedMod1.setGraph(pagc.getFirstGraph());
1830 alignedMod2 = mod2.copy();
1831 alignedMod2.setGraph(pagc.getSecondGraph());
1832
1833 // load stuff onto the contact map pane and the visualizer
1834 doLoadModelsOntoContactMapPane(alignedMod1, alignedMod2, ali, name1, name2);
1835 doLoadModelOntoVisualizer(alignedMod2);
1836
1837 // adapt GUI behavior
1838 setGUIStatusCompareMode();
1839 }
1840
1841 /**
1842 * Handles the results retrieval of the SADP run which has invoked this
1843 * notifier.
1844 * @param notifier a notifier of an SADP run
1845 */
1846 private void handlePairwiseAlignmentResults(SADPDialogDoneNotifier notifier) {
1847 try {
1848 Integer exitStatus = notifier.notification();
1849
1850 if( exitStatus == ToolDialog.DONE ) {
1851 //SADPRunner runner = notifier.getRunner();
1852 SADPResult result = notifier.getResult();
1853 alignedMod1 = result.getFirstOutputModel();
1854 alignedMod2 = result.getSecondOutputModel();
1855 ali = result.getAlignment();
1856
1857 doLoadModelsOntoContactMapPane(alignedMod1, alignedMod2, ali, result.getFirstName(), result.getSecondName());
1858 doLoadModelOntoVisualizer(alignedMod2);
1859
1860 // adapt GUI behavior
1861 setGUIStatusCompareMode();
1862 }
1863 } catch (Exception e) {
1864 JOptionPane.showMessageDialog(this, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
1865 mod2 = null;
1866 alignedMod1 = null;
1867 alignedMod2 = null;
1868 ali = null;
1869 System.gc();
1870 }
1871 }
1872
1873 /**
1874 * Loads the given aligned models onto the contact map panel.
1875 * @param alignedMod1 the first aligned model
1876 * @param alignedMod2 the second aligned model
1877 * @param ali alignment of rediues in <code>alignedMod1</code> to residues
1878 * in <code>alignedMod2</code>
1879 * @param name1 sequence identifier (tag) of <code>alignedMod1</code> in
1880 * <code>ali</code>
1881 * @param name2 sequence identifier (tag) of <code>alignedMod2</code> in
1882 * <code>ali</code>
1883 * @throws DifferentContactMapSizeError
1884 */
1885 private void doLoadModelsOntoContactMapPane(Model alignedMod1, Model alignedMod2, Alignment ali, String name1, String name2)
1886 throws DifferentContactMapSizeError {
1887
1888 // add alignment
1889 cmPane.setAlignment(ali, name1, name2);
1890
1891 // add first model and update the image buffer
1892 cmPane.setModel(alignedMod1);
1893 cmPane.updateScreenBuffer();
1894
1895 // add the second model and update the image buffer
1896 cmPane.addSecondModel(alignedMod2); // throws DifferentContactMapSizeError
1897 compareStatus = true;
1898 cmPane.toggleCompareMode(compareStatus);
1899 cmPane.updateScreenBuffer();
1900
1901 // finally repaint the whole thing to display the whole set of contacts
1902 cmPane.repaint();
1903 }
1904
1905 /**
1906 * Loads the given model onto the visualizer.
1907 * @param mod the model to be loaded
1908 */
1909 private void doLoadModelOntoVisualizer(Model mod) {
1910 Start.getPyMolAdaptor().loadStructure(mod.getTempPdbFileName(), mod.getPDBCode(), mod.getChainCode(), true);
1911 Start.getPyMolAdaptor().sendCommand("orient");
1912 }
1913
1914 private void handleSuperposition() {
1915 doSuperposition(mod, mod2,
1916 mod.getPDBCode()+mod.getChainCode(),
1917 mod2.getPDBCode()+mod2.getChainCode(),
1918 ali,
1919 cmPane.getSelectedContacts() );
1920 }
1921
1922 /**
1923 * Superimposes the given models with respect the given alignment. Instead
1924 * of considering the alignment as a whole it is reduced to the induced
1925 * alignment columns defined by a set of contacts. The residues incident to
1926 * the contact in the selection can be mapped to alignment columns which
1927 * construct the set of paired residues (matches and/or mismatches) to be
1928 * consulted for the superpositioning.
1929 * @param mod1 the first model
1930 * @param mod2 the second model
1931 * @param name1 sequence identifier of <code>mod1</code> in the alignment
1932 * @param name2 sequence identifier of <code>mod2</code> in the alignment
1933 * @param ali alignment of residues in <code>mod1</code> to residues in
1934 * <code>mod2</code>
1935 * @param selection set of contacts to be considered
1936 */
1937 public void doSuperposition(Model mod1, Model mod2, String name1, String name2, Alignment ali, IntPairSet[] selection) {
1938
1939 try {
1940 TreeSet<Integer> positions = getAlignmentPositionsFromSelection(mod1, mod2, selection, ali, true);
1941
1942 if( positions.isEmpty() ) {
1943 showNo3DCoordFromComparedSelection();
1944 return;
1945 }
1946
1947 TreeSet<String> projectionTags = new TreeSet<String>();
1948
1949 // get consecutive sequence chunks in mod1 from positions
1950 projectionTags.add(name2);
1951 IntervalSet chunks1 = ali.getMatchingBlocks(name1, projectionTags, positions, 1);
1952 //System.out.println("chunks1:"+chunks1);
1953
1954 if( chunks1.isEmpty() ) {
1955 showNo3DCoordFromComparedSelection();
1956 return;
1957 }
1958
1959 // get consecutive sequence chunks in mod2 from positions
1960 projectionTags.clear();
1961 projectionTags.add(name1);
1962 IntervalSet chunks2 = ali.getMatchingBlocks(name2, projectionTags, positions, 1);
1963 //System.out.println("chunks2:"+chunks2);
1964
1965 if( chunks2.isEmpty() ) {
1966 // this one should catch at the same time as the one above.
1967 // this is only to make sure
1968 showNo3DCoordFromComparedSelection();
1969 return;
1970 }
1971
1972 // we let pymol compute the pairwise fitting
1973 Start.getPyMolAdaptor().pairFitSuperposition(
1974 mod1.getPDBCode(), mod1.getChainCode(),/*to identity first model*/
1975 mod2.getPDBCode(), mod2.getChainCode(),/*to identify second model*/
1976 chunks1, chunks2); /*intervals of corresponding residues*/
1977
1978 } catch (EmptyContactSelectionError e) {
1979 showNo3DCoordFromComparedSelection();
1980 } catch (CoordinatesNotFoundError e) {
1981 if( e.getModel() == mod ) {
1982 showNo3DCoordsWarning();
1983 } else if( e.getModel() == mod2 ) {
1984 showNo3DCoordsSecondModelWarning();
1985 } else {
1986 System.err.println("Error: Unrecognized model in function doSuperposition(Model, Model, ContactMapPane, Alignment)");
1987 }
1988 }
1989 }
1990
1991 /**
1992 * Sends the induced residue-residue alignment of the given contact
1993 * selection to the visualizer.
1994 * @param mod1 the first model
1995 * @param mod2 the second model
1996 * @param name1 sequence identifier of <code>mod1</code> in the alignment
1997 * @param name2 sequence identifier of <code>mod2</code> in the alignment
1998 * @param ali alignment of residues in <code>mod1</code> to residues in
1999 * <code>mod2</code>
2000 * @param selection selection of contacts to be considered
2001 */
2002 public void doShowAlignedResidues3D(Model mod1, Model mod2, String name1, String name2, Alignment ali, IntPairSet[] selection) {
2003 try {
2004 // get all addressed alignment columns, do not consider column
2005 // which contain unobserved residues (indicated by the 'true')
2006 TreeSet<Integer> columns = getAlignmentPositionsFromSelection(mod1, mod2, selection, ali, true);
2007
2008 if( columns.isEmpty() ) {
2009 showNo3DCoordFromComparedSelection();
2010 return;
2011 }
2012
2013 // extract the residue indices from the 'columns', do not only
2014 // consider (mis)matches
2015 IntPairSet residuePairs = new IntPairSet();
2016 int pos1,pos2;
2017 for(int col : columns) {
2018 pos1 = ali.al2seq(name1,col);
2019 pos2 = ali.al2seq(name2,col);
2020
2021 if( pos1 != -1 && pos2 != -1 ) {
2022 residuePairs.add(new Pair<Integer>(pos1,pos2));
2023 }
2024 }
2025
2026 if( residuePairs.isEmpty() ) {
2027 showNo3DCoordFromComparedSelection();
2028 return;
2029 }
2030
2031 // send selection of (mis)matching residues to PyMOL
2032 Start.getPyMolAdaptor().sendTwoChainsEdgeSelection(
2033 mod1.getPDBCode(), mod1.getChainCode(),
2034 mod2.getPDBCode(), mod2.getChainCode(),
2035 "AlignedResi"+mod1.getChainCode()+mod2.getChainCode(),
2036 "yellow",
2037 pymolSelSerial,
2038 residuePairs,
2039 false, true); // do not dash the line, do center selection
2040
2041 } catch (EmptyContactSelectionError e) {
2042 showNo3DCoordFromComparedSelection();
2043 } catch (CoordinatesNotFoundError e) {
2044 if( e.getModel() == mod ) {
2045 showNo3DCoordsWarning();
2046 } else if( e.getModel() == mod2 ) {
2047 showNo3DCoordsSecondModelWarning();
2048 } else {
2049 System.err.println("Error: Unrecognized model in function doSuperposition(Model, Model, EdgeSet[] , Alignment)!");
2050 }
2051 }
2052 }
2053
2054
2055 /**
2056 * Extracts the indices of all alignment columns which are obtained by the
2057 * set of currently selected contacts.
2058 *
2059 * @param mod1 first model
2060 * @param mod2 second model
2061 * @param selection contact selection
2062 * @param ali sequence alignment between <code>mod1</code> and
2063 * <code>mod2</code>
2064 * @param observedOnly enable this flag to neglect columns which contain
2065 * unobserved residues
2066 *
2067 * @return the alignment position. this set may be empty if the contacts
2068 * in the given selection do only point to unobserved residues.
2069 *
2070 * @throws CoordinatesNotFoundError
2071 * @throws EmptyContactSelectionError
2072 */
2073 public TreeSet<Integer> getAlignmentPositionsFromSelection(Model mod1, Model mod2, IntPairSet[] selection, Alignment ali, boolean observedOnly)
2074 throws CoordinatesNotFoundError, EmptyContactSelectionError {
2075
2076 // TODO: in future versions we should put this function to the contact map pane.
2077
2078 // 3D-coordinates are required for both models in the observedOnly
2079 if( observedOnly && !mod1.has3DCoordinates() ) {
2080 throw new CoordinatesNotFoundError(mod1);
2081 }
2082 if( observedOnly && !mod2.has3DCoordinates() ) {
2083 throw new CoordinatesNotFoundError(mod2);
2084 }
2085
2086 // create list of positions to be combined to consecutive chunks
2087 // further below from the set of selected contacts
2088 // [Please alway keep in mind, that the anchors of the selected
2089 // contacts correspond to the aligned models. Further below we access
2090 // the pdb-coordinates of the original graph. We can do that via
2091 // mapping from the alignment space (which assignes to the node
2092 // indexing in the aligned models) to the sequence space (which in
2093 // turn addresses the indexing in the orignal ones)]
2094 TreeSet<Integer> positions = new TreeSet<Integer>();
2095 for( int i=0; i<selection.length; ++i ) {
2096 // we have again to take account for the sequence <-> alignment
2097 // indexing problem, which essentially means that we have to
2098 // substract 1 to map from sequence space to the alignment space
2099 // as 'positions' is supposed to hold alignment positions
2100 for( int n : selection[i].getIncidentNodes() ) {
2101 positions.add(n-1);
2102 }
2103 }
2104
2105 // this is only to be able to distinguish between 'positions' being
2106 // empty due to non-existing coordinates or due to an empty contact
2107 // selection
2108 if( positions.isEmpty() ) {
2109 throw new EmptyContactSelectionError();
2110 }
2111
2112 // make tags to retrieve the correct sequences from the alignment
2113 String name1 = mod1.getPDBCode() + mod1.getChainCode();
2114 String name2 = mod2.getPDBCode() + mod2.getChainCode();
2115
2116 // delete all position that do not have valid 3D-coordinates
2117 if( observedOnly ) {
2118 Pdb coordsMod1 = mod1.get3DCoordinates();
2119 Pdb coordsMod2 = mod2.get3DCoordinates();
2120 int p;
2121 for( Iterator<Integer> it = positions.iterator(); it.hasNext(); ) {
2122 p = it.next();
2123 // TODO: what we actually should do here is to check whether the current 'p' has coordinates for the CA atoms as the superposition is performed on CA backbone
2124 if( !(coordsMod1.hasCoordinates(ali.al2seq(name1,p))
2125 && coordsMod2.hasCoordinates(ali.al2seq(name2,p)) ) ) {
2126 it.remove();
2127 }
2128 }
2129 }
2130
2131 return positions;
2132 }
2133
2134
2135 /**
2136 * Load second model onto the contact map pane.
2137 * @deprecated This one is meant to be a fallback routine if the strategy of pairwise alignment failes for any reason.
2138 */
2139 @SuppressWarnings("unused")
2140 private void handleLoadSecondModel(Model mod)
2141 throws DifferentContactMapSizeError {
2142 cmPane.addSecondModel(mod); // throws DifferentContactMapSizeError
2143 compareStatus = true;
2144 cmPane.toggleCompareMode(compareStatus);
2145 doLoadModelOntoVisualizer(mod);
2146 Start.getPyMolAdaptor().alignStructure(cmPane.getFirstModel().getPDBCode(), cmPane.getFirstModel().getChainCode(), cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode());
2147 }
2148
2149 private void handleSaveToGraphDb() {
2150 if(this.mod == null) {
2151 showNoContactMapWarning();
2152 } else if(!Start.isDatabaseConnectionAvailable()) {
2153 showNoDatabaseConnectionWarning();
2154 } else {
2155 String ret = JOptionPane.showInputDialog(this, (Object) "<html>Name of database to save to:<br></html>");
2156 if(ret != null) {
2157 if(ret.length() > 0) {
2158 doSaveToGraphDb(ret);
2159 } else {
2160 JOptionPane.showMessageDialog(this, "No database name given. Contact map not saved.", "Warning", JOptionPane.WARNING_MESSAGE);
2161 }
2162 }
2163 }
2164 }
2165
2166 public void doSaveToGraphDb(String dbName) {
2167 try {
2168 mod.writeToGraphDb(dbName);
2169 System.out.println("Saving contact map to database " + dbName + ".");
2170 } catch (SQLException e) {
2171 System.err.println("Error when trying to write to database " + dbName + ": " + e.getMessage());
2172 }
2173 }
2174
2175 private void handleSaveToCmFile() {
2176 if(this.mod == null) {
2177 //System.out.println("No contact map loaded yet.");
2178 showNoContactMapWarning();
2179 } else {
2180 int ret = Start.getFileChooser().showSaveDialog(this);
2181 if(ret == JFileChooser.APPROVE_OPTION) {
2182 File chosenFile = Start.getFileChooser().getSelectedFile();
2183 String path = chosenFile.getPath();
2184 try {
2185 this.mod.writeToContactMapFile(path);
2186 } catch(IOException e) {
2187 System.err.println("Error writing to file " + path);
2188 }
2189 }
2190 }
2191 }
2192
2193 private void handleSaveToPng() {
2194 if(this.mod == null) {
2195 //System.out.println("No contact map loaded yet.");
2196 showNoContactMapWarning();
2197 } else {
2198 int ret = Start.getFileChooser().showSaveDialog(this);
2199 if(ret == JFileChooser.APPROVE_OPTION) {
2200 File chosenFile = Start.getFileChooser().getSelectedFile();
2201
2202 // Create a buffered image in which to draw
2203 BufferedImage bufferedImage = new BufferedImage(cmPane.getWidth(), cmPane.getHeight(), BufferedImage.TYPE_INT_RGB);
2204
2205 // Create a graphics contents on the buffered image
2206 Graphics2D g2d = bufferedImage.createGraphics();
2207
2208 // Draw the current contact map window to Image
2209 cmPane.paintComponent(g2d);
2210
2211 try {
2212 ImageIO.write(bufferedImage, "png", chosenFile);
2213 System.out.println("File " + chosenFile.getPath() + " saved.");
2214 } catch (IOException e) {
2215 System.err.println("Error while trying to write to PNG file " + chosenFile.getPath());
2216 }
2217 }
2218 }
2219 }
2220
2221 private void handleSaveAlignment() {
2222 doSaveAlignment(ali);
2223 }
2224
2225 public void doSaveAlignment(Alignment ali) {
2226 if(ali == null) {
2227 //System.out.println("No contact map loaded yet.");
2228 showCannotSaveEmptyAlignment();
2229 } else {
2230 int ret = Start.getFileChooser().showSaveDialog(this);
2231 if(ret == JFileChooser.APPROVE_OPTION) {
2232 File chosenFile = Start.getFileChooser().getSelectedFile();
2233 try {
2234 ali.writeFasta(new FileOutputStream(chosenFile), 80, true);
2235 } catch (IOException e) {
2236 System.err.println("Error while trying to write to FASTA file " + chosenFile.getPath());
2237 }
2238 }
2239 }
2240 }
2241
2242 private void handleInfo() {
2243 if(this.mod == null) {
2244 //System.out.println("No contact map loaded yet.");
2245 showNoContactMapWarning();
2246 } else {
2247 // String seq = mod.getSequence();
2248 // String s = seq.length() <= 10?(seq.length()==0?"Unknown":seq):seq.substring(0,10) + "...";
2249 // String message = "Pdb code: " + mod.getPDBCode() + "\n"
2250 // + "Chain code: " + mod.getChainCode() + "\n"
2251 // + "Contact type: " + mod.getContactType() + "\n"
2252 // + "Distance cutoff: " + mod.getDistanceCutoff() + "\n"
2253 // + "Min Seq Sep: " + (mod.getMinSequenceSeparation()<1?"none":mod.getMinSequenceSeparation()) + "\n"
2254 // + "Max Seq Sep: " + (mod.getMaxSequenceSeparation()<1?"none":mod.getMaxSequenceSeparation()) + "\n"
2255 // + "\n"
2256 // + "Contact map size: " + mod.getMatrixSize() + "\n"
2257 // + "Unobserved Residues: " + mod.getNumberOfUnobservedResidues() + "\n"
2258 // + "Number of contacts: " + mod.getNumberOfContacts() + "\n"
2259 // + "Directed: " + (mod.isDirected()?"Yes":"No")
2260 // + "\n"
2261 // + "Sequence: " + s + "\n"
2262 // + "Secondary structure: " + mod.getSecondaryStructure().getComment();
2263 // JOptionPane.showMessageDialog(this,
2264 // message,
2265 // "Contact map info",
2266 // JOptionPane.PLAIN_MESSAGE);
2267
2268 String seq = mod.getSequence();
2269 String s1 = seq.length() <= 10?(seq.length()==0?"Unknown":seq):seq.substring(0,10) + "...";
2270 String s2 = "";
2271 int numSelectedContacts = 0;
2272 if( mod2 == null ) {
2273 // settings if mod2 is absent
2274 numSelectedContacts = cmPane.getSelContacts().size();
2275 } else {
2276 // settings if mod2 is present
2277 seq = mod2.getSequence();
2278 s2 = seq.length() <= 10?(seq.length()==0?"Unknown":seq):seq.substring(0,10) + "...";
2279
2280 IntPairSet[] selectedContacts = cmPane.getSelectedContacts();
2281 IntPairSet union = new IntPairSet();
2282 for(int i = 0; i < selectedContacts.length; ++i ) {
2283 union.addAll(selectedContacts[i]);
2284 }
2285 numSelectedContacts = union.size();
2286 }
2287
2288 String message =
2289 "<html><table>" +
2290 /* print pdb code */
2291 "<tr><td>Pdb Code:</td><td>" + mod.getPDBCode() + "</td>" +
2292 (mod2 == null ? "" : "<td>" + mod2.getPDBCode() + "</td>") + "</tr>" +
2293 /* print chain code */
2294 "<tr><td>Chain code:</td><td>" + mod.getChainCode() + "</td>" +
2295 (mod2 == null ? "" : "<td>" + mod2.getChainCode() + "</td>") + "</tr>" +
2296 /* print contact type */
2297 "<tr><td>Contact type:</td><td>" + mod.getContactType() + "</td>" +
2298 (mod2 == null ? "" : "<td>" + mod2.getContactType() + "</td>") + "</tr>" +
2299 /* print distance cutoff */
2300 "<tr><td>Distance cutoff:</td><td>" + mod.getDistanceCutoff() + "</td>" +
2301 (mod2 == null ? "" : "<td>" + mod2.getDistanceCutoff() + "</td>") + "</tr>" +
2302 /* print minimal sequence separation */
2303 "<tr><td>Min Seq Sep:</td><td>" + (mod.getMinSequenceSeparation()<1?"none":mod.getMinSequenceSeparation()) + "</td>" +
2304 (mod2 == null ? "" : "<td>" + (mod2.getMinSequenceSeparation()<1?"none":mod2.getMinSequenceSeparation()) + "</td>") + "</tr>" +
2305 /* print maximal sequence separation */
2306 "<tr><td>Max Seq Sep:</td><td>" + (mod.getMaxSequenceSeparation()<1?"none":mod.getMaxSequenceSeparation()) + "</td>" +
2307 (mod2 == null ? "" : "<td>" + (mod2.getMaxSequenceSeparation()<1?"none":mod2.getMaxSequenceSeparation()) + "</td>") + "</tr>" +
2308
2309 /* BLANK LINE */
2310 "<tr><th>&#160;</th><th>&#160;</th><th>&#160;</th></tr>" +
2311
2312 /* print contact map size */
2313 "<tr><td>Contact map size:</td><td>" + mod.getMatrixSize() + "</td>" +
2314 (mod2 == null ? "" : "<td>" + mod2.getMatrixSize() + "</td>") + "</tr>" +
2315 /* print number of unobserved residues */
2316 "<tr><td>Unobserved Residues:</td><td>" + mod.getNumberOfUnobservedResidues() + "</td>" +
2317 (mod2 == null ? "" : "<td>" + mod2.getNumberOfUnobservedResidues() + "</td>") + "</tr>" +
2318 /* print number of contacts */
2319 "<tr><td>Number of contacts:</td><td>" + mod.getNumberOfContacts() + "</td>" +
2320 (mod2 == null ? "" : "<td>" + mod2.getNumberOfContacts() + "</td>") + "</tr>" +
2321 /* print whether graph is directed */
2322 "<tr><td>Directed:</td><td>" + (mod.isDirected()?"Yes":"No") + "</td>" +
2323 (mod2 == null ? "" : "<td>" + (mod2.isDirected()?"Yes":"No") + "</td>") + "</tr>" +
2324
2325 /* BLANK LINE */
2326 "<tr><th>&#160;</th><th>&#160;</th><th>&#160;</th></tr>" +
2327
2328 /* print the first ten characters of all available sequences */
2329 "<tr><td>Sequence:</td><td>" + s1 + "</td>" +
2330 (mod2 == null ? "" : "<td>" + s2 + "</td>") + "</tr>" +
2331 /* print secondary structure source */
2332 "<tr><td>Secondary structure:</td><td>" + mod.getSecondaryStructure().getComment() + "</td>" +
2333 (mod2 == null ? "" : "<td>" + mod2.getSecondaryStructure().getComment() + "</td></tr>") +
2334
2335 /* BLANK LINE */
2336 "<tr><th>&#160;</th><th>&#160;</th><th>&#160;</th></tr>" +
2337 (mod2 == null ? "" : "<tr><td>Number of common contacts:</td><td>" + cmPane.getCommonContacts(1, 2).size() + "</td>") +
2338 "<tr><td>Number of selected contacts:</td><td>" + numSelectedContacts + "</td>";
2339
2340
2341 JOptionPane.showMessageDialog(this,
2342 message,
2343 "Contact map info",
2344 JOptionPane.PLAIN_MESSAGE);
2345 }
2346 }
2347
2348 private void handlePrint() {
2349 if(this.mod == null) {
2350 //System.out.println("No contact map loaded yet.");
2351 showNoContactMapWarning();
2352 } else {
2353 PrintUtil.printComponent(this.cmPane);
2354 }
2355 }
2356
2357 private void handleQuit() {
2358 System.exit(0);
2359 }
2360
2361 /* -------------------- View Menu -------------------- */
2362
2363 /**
2364 *
2365 */
2366 private void handleShowPdbResSers() {
2367 if(mod==null) {
2368 showNoContactMapWarning();
2369 } else if (!mod.has3DCoordinates()){
2370 showNo3DCoordsWarning();
2371 } else {
2372 showPdbSers = !showPdbSers; // TODO: Move this to CMPane?
2373 cmPane.updateScreenBuffer();
2374 if(showPdbSers) {
2375 mmViewShowPdbResSers.setIcon(icon_selected);
2376 } else {
2377 mmViewShowPdbResSers.setIcon(icon_deselected);
2378 }
2379 }
2380 }
2381
2382 /**
2383 *
2384 */
2385 private void handleShowRulers() {
2386 if(mod==null) {
2387 showNoContactMapWarning();
2388 } else {
2389 showRulers = !showRulers;
2390 if(showRulers) {
2391 cmp.add(topRul, BorderLayout.NORTH);
2392 cmp.add(leftRul, BorderLayout.WEST);
2393 mmViewRulers.setIcon(icon_selected);
2394 } else {
2395 cmp.remove(topRul);
2396 cmp.remove(leftRul);
2397 mmViewRulers.setIcon(icon_deselected);
2398 }
2399 this.pack();
2400 this.repaint();
2401 }
2402 }
2403
2404 /**
2405 *
2406 */
2407 private void handleShowIconBar() {
2408 showIconBar = !showIconBar;
2409 if(showIconBar) {
2410 toolBar.setVisible(true);
2411 mmViewIconBar.setIcon(icon_selected);
2412 } else {
2413 toolBar.setVisible(false);
2414 mmViewIconBar.setIcon(icon_deselected);
2415 }
2416 this.repaint();
2417 }
2418
2419 /**
2420 *
2421 */
2422 private void handleShowNbhSizeMap() {
2423 if(mod==null) {
2424 showNoContactMapWarning();
2425 } else {
2426 showNbhSizeMap = !showNbhSizeMap;
2427 cmPane.toggleNbhSizeMap(showNbhSizeMap);
2428 if (showNbhSizeMap) {
2429 mmViewHighlightComNbh.setIcon(icon_selected);
2430 } else {
2431 mmViewHighlightComNbh.setIcon(icon_deselected);
2432 }
2433 }
2434 }
2435
2436 /**
2437 *
2438 */
2439 private void handleShowDensityMap() {
2440 if(mod==null) {
2441 showNoContactMapWarning();
2442 } else {
2443 showDensityMap = !showDensityMap;
2444 cmPane.toggleDensityMap(showDensityMap);
2445 if(showDensityMap) {
2446 mmViewShowDensity.setIcon(icon_selected);
2447 } else {
2448 mmViewShowDensity.setIcon(icon_deselected);
2449 }
2450 }
2451 }
2452
2453 /**
2454 *
2455 */
2456 private void handleShowDistanceMap() {
2457 if(mod==null) {
2458 showNoContactMapWarning();
2459 } else if (!mod.has3DCoordinates()){
2460 showNo3DCoordsWarning();
2461 } else {
2462 showDistanceMap = !showDistanceMap;
2463 cmPane.toggleDistanceMap(showDistanceMap);
2464 if(showDistanceMap) {
2465 mmViewShowDistMatrix.setIcon(icon_selected);
2466 } else {
2467 mmViewShowDistMatrix.setIcon(icon_deselected);
2468 }
2469 }
2470 }
2471
2472 /* -------------------- Select menu -------------------- */
2473
2474 private void handleSelectAll() {
2475 if(mod==null) {
2476 showNoContactMapWarning();
2477 } else {
2478 cmPane.selectAllContacts();
2479 }
2480 }
2481
2482 private void handleSelectByResNum() {
2483 if(mod==null) {
2484 showNoContactMapWarning();
2485 } else {
2486 String selStr = (String)JOptionPane.showInputDialog(
2487 this,
2488 "Enter residue numbers to be selected:\n"
2489 + "e.g. 1-5,7,10-11",
2490 "");
2491 if (selStr == null) {
2492 // user clicked cancel
2493 return;
2494 } else {
2495 if(!Interval.isValidSelectionString(selStr)) {
2496 showInvalidSelectionStringWarning();
2497 return;
2498 } else {
2499 int selectedContacts = cmPane.selectByResNum(selStr);
2500 System.out.println(selectedContacts + " contacts selected");
2501 }
2502 }
2503 }
2504 }
2505
2506 private void handleSelectHelixHelix() {
2507 if(mod==null) {
2508 showNoContactMapWarning();
2509 } else
2510 if(!mod.hasSecondaryStructure()) {
2511 showNoSecondaryStructureWarning();
2512 } else {
2513 cmPane.selectHelixHelix();
2514 }
2515 }
2516
2517 private void handleSelectBetaBeta() {
2518 if(mod==null) {
2519 showNoContactMapWarning();
2520 } else
2521 if(!mod.hasSecondaryStructure()) {
2522 showNoSecondaryStructureWarning();
2523 } else {
2524 cmPane.selectBetaBeta();
2525 }
2526 }
2527
2528 private void handleSelectInterSsContacts() {
2529 if(mod==null) {
2530 showNoContactMapWarning();
2531 } else
2532 if(!mod.hasSecondaryStructure()) {
2533 showNoSecondaryStructureWarning();
2534 } else {
2535 cmPane.selectInterSsContacts();
2536 }
2537 }
2538
2539 private void handleSelectIntraSsContacts() {
2540 if(mod==null) {
2541 showNoContactMapWarning();
2542 } else
2543 if(!mod.hasSecondaryStructure()) {
2544 showNoSecondaryStructureWarning();
2545 } else {
2546 cmPane.selectIntraSsContacts();
2547 }
2548 }
2549
2550
2551 /* -------------------- Color menu -------------------- */
2552
2553 private void handleColorSelect() {
2554 JDialog chooseDialog = JColorChooser.createDialog(this, "Choose color", true, Start.getColorChooser(),
2555 new ActionListener() {
2556 public void actionPerformed(ActionEvent e){
2557 Color c = Start.getColorChooser().getColor();
2558 currentPaintingColor = c;
2559 System.out.println("Color changed to " + c);
2560 }
2561 } , null); // no handler for cancel button
2562 chooseDialog.setVisible(true);
2563 }
2564
2565 private void handleColorPaint() {
2566 if(mod==null) {
2567 showNoContactMapWarning();
2568 } else if(cmPane.getSelContacts().size() == 0) {
2569 showNoContactsSelectedWarning();
2570 } else {
2571 cmPane.paintCurrentSelection(currentPaintingColor);
2572 cmPane.resetSelections();
2573 cmPane.repaint();
2574 }
2575 }
2576
2577 private void handleColorReset() {
2578 if(mod==null) {
2579 showNoContactMapWarning();
2580 } else {
2581 cmPane.resetUserContactColors();
2582 }
2583 }
2584
2585 /* -------------------- Action menu -------------------- */
2586
2587 /**
2588 *
2589 */
2590 private void handleShowSelContacts3D() {
2591 if(mod==null) {
2592 showNoContactMapWarning();
2593 } else if(!mod.has3DCoordinates()) {
2594 showNo3DCoordsWarning();
2595 } else if(!Start.isPyMolConnectionAvailable()) {
2596 showNoPyMolConnectionWarning();
2597 } else if(cmPane.getSelContacts().size() == 0) {
2598 showNoContactsSelectedWarning();
2599 } else if (cmPane.hasSecondModel()){
2600
2601
2602 String firstModelContactColor = "magenta";
2603 String secondModelContactColor = "green";
2604
2605 common = this.getSelCommonContactsInComparedMode();
2606 firstS = this.getSelFirstStrucInComparedMode();
2607 secondS = this.getSelSecondStrucInComparedMode();
2608
2609
2610 // only second structure contacts
2611 if (common == false && firstS == false && secondS == true){
2612 IntPairSet[] array = cmPane.getSelectedContacts();
2613 IntPairSet trueGreen = array[0]; // red contacts
2614 String selectionType = cmPane.getSecondModel().getChainCode();
2615
2616 //disable all old objects and selections and enable the two actual objects
2617 Start.getPyMolAdaptor().setView(mod.getPDBCode(), mod.getChainCode(), cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode());
2618
2619 // present contacts in second structure
2620 Start.getPyMolAdaptor().edgeSelection(cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode(), "PresCont"+selectionType, secondModelContactColor, pymolSelSerial, trueGreen, false, false);
2621
2622 // unpresent contacts in main structure
2623 Start.getPyMolAdaptor().edgeSelection(mod.getPDBCode(), mod.getChainCode(), "AbsCont" + selectionType, firstModelContactColor, pymolSelSerial, trueGreen, true, true);
2624
2625 String memberNameA1 = "AbsCont" + selectionType+ mod.getPDBCode()+ mod.getChainCode()+ "Sel"+ pymolSelSerial;
2626 String memberNameB1 = "PresCont" + selectionType+ cmPane.getSecondModel().getPDBCode()+ cmPane.getSecondModel().getChainCode()+ "Sel"+ pymolSelSerial;
2627
2628 // grouping main structure selection
2629 Start.getPyMolAdaptor().groupSelections(mod.getPDBCode(), mod.getChainCode(), pymolSelSerial, memberNameA1, "");
2630 // grouping second structure selection
2631 Start.getPyMolAdaptor().groupSelections(cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode(), pymolSelSerial, memberNameB1, "");
2632 // grouping complete selection
2633 Start.getPyMolAdaptor().sendCommand("cmd.group(name = 'Selection"+ pymolSelSerial +"', members= '"+ mod.getPDBCode()+mod.getChainCode() + "Sel"+ pymolSelSerial+" " + cmPane.getSecondModel().getPDBCode()+cmPane.getSecondModel().getChainCode()+"Sel"+ pymolSelSerial+"' ), ");
2634
2635
2636 this.pymolSelSerial++;
2637 }
2638
2639 // only first structure contacts
2640 else if (common == false && firstS == true && secondS == false){
2641 IntPairSet[] array = cmPane.getSelectedContacts();
2642 IntPairSet trueRed = array[0]; // red contacts
2643 String selectionType = mod.getChainCode();
2644
2645 //disable all old objects and selections and enable the two actual objects
2646 Start.getPyMolAdaptor().setView(mod.getPDBCode(), mod.getChainCode(), cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode());
2647
2648 // present contacts in main structure
2649 Start.getPyMolAdaptor().edgeSelection(mod.getPDBCode(), mod.getChainCode(), "PresCont"+selectionType, firstModelContactColor, pymolSelSerial, trueRed, false, false);
2650 // unpresent contacts in second structure
2651 Start.getPyMolAdaptor().edgeSelection(cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode(), "AbsCont" + selectionType, secondModelContactColor, pymolSelSerial, trueRed, true, true);
2652
2653
2654 String memberNameA1 = "PresCont" + selectionType+ mod.getPDBCode()+ mod.getChainCode()+ "Sel"+ pymolSelSerial;
2655 String memberNameB1 = "AbsCont" + selectionType+ cmPane.getSecondModel().getPDBCode()+ cmPane.getSecondModel().getChainCode()+ "Sel" + pymolSelSerial;
2656
2657 // grouping main structure selection
2658 Start.getPyMolAdaptor().groupSelections(mod.getPDBCode(), mod.getChainCode(), pymolSelSerial, memberNameA1, "");
2659 // grouping second structure selection
2660 Start.getPyMolAdaptor().groupSelections(cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode(), pymolSelSerial,memberNameB1, "");
2661 // grouping complete selection
2662 Start.getPyMolAdaptor().sendCommand("cmd.group(name = 'Selection"+ pymolSelSerial +"', members= '"+ mod.getPDBCode()+mod.getChainCode() + "Sel"+ pymolSelSerial+" "+ cmPane.getSecondModel().getPDBCode()+cmPane.getSecondModel().getChainCode()+"Sel"+ pymolSelSerial+"' ), ");
2663
2664 this.pymolSelSerial++;
2665 }
2666
2667 // only first and second structure contacts
2668 else if (common == false && firstS == true && secondS == true){
2669 IntPairSet[] array = cmPane.getSelectedContacts();
2670 IntPairSet trueRed = array[0]; // red contacts
2671 IntPairSet trueGreen = array[1]; // green contacts
2672 String selectionType = mod.getChainCode() + cmPane.getSecondModel().getChainCode();
2673
2674 // all contacts are either red or green.
2675 // red contacts are n PyMol: red and not dashed in main structure && green and dashed in second structure
2676 // green contacts: analogous w.r.t. second structure and main structure
2677
2678 //disable all old objects and selections and enable the two actual objects
2679 Start.getPyMolAdaptor().setView(mod.getPDBCode(), mod.getChainCode(), cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode());
2680
2681 //present and unpresent contacts in main structure
2682 Start.getPyMolAdaptor().edgeSelection(mod.getPDBCode(), mod.getChainCode(), "PresCont"+selectionType, firstModelContactColor, pymolSelSerial, trueRed, false, false);
2683 Start.getPyMolAdaptor().edgeSelection(mod.getPDBCode(), mod.getChainCode(), "AbsCont"+selectionType, firstModelContactColor, pymolSelSerial,trueGreen, true, false);
2684
2685 // present and unpresent contacts in second structure
2686 Start.getPyMolAdaptor().edgeSelection(cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode(), "PresCont"+selectionType, secondModelContactColor, pymolSelSerial, trueGreen, false, false);
2687 Start.getPyMolAdaptor().edgeSelection(cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode(), "AbsCont"+selectionType, secondModelContactColor, pymolSelSerial, trueRed, true, true);
2688
2689
2690 String memberNameA1 = "PresCont" + selectionType + mod.getPDBCode()+ mod.getChainCode()+ "Sel"+ pymolSelSerial;
2691 String memberNameA2 = "AbsCont" + selectionType+ mod.getPDBCode()+ mod.getChainCode()+ "Sel"+ pymolSelSerial;
2692 String memberNameB1 = "PresCont" + selectionType+ cmPane.getSecondModel().getPDBCode()+ cmPane.getSecondModel().getChainCode() + "Sel" + pymolSelSerial;
2693 String memberNameB2 = "AbsCont" + selectionType+ cmPane.getSecondModel().getPDBCode()+ cmPane.getSecondModel().getChainCode() + "Sel" + pymolSelSerial;
2694
2695 // grouping main structure selection
2696 Start.getPyMolAdaptor().groupSelections(mod.getPDBCode(), mod.getChainCode(), pymolSelSerial,memberNameA1, memberNameA2);
2697 // grouping second structure selection
2698 Start.getPyMolAdaptor().groupSelections(cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode(), pymolSelSerial,memberNameB1, memberNameB2);
2699 // grouping complete selection
2700 Start.getPyMolAdaptor().sendCommand("cmd.group(name = 'Selection"+ pymolSelSerial +"', members= '"+ mod.getPDBCode()+mod.getChainCode() + "Sel"+ pymolSelSerial+" " + cmPane.getSecondModel().getPDBCode()+cmPane.getSecondModel().getChainCode()+"Sel"+ pymolSelSerial+"' ), ");
2701
2702 this.pymolSelSerial++;
2703 }
2704
2705 // only common toggle mode
2706 else if (common == true && firstS == false && secondS == false){
2707 IntPairSet[] array = cmPane.getSelectedContacts();
2708 IntPairSet trueRed = array[0]; // red contacts
2709 IntPairSet trueGreen = array[1]; // green contacts
2710 String selectionType = mod.getChainCode() + cmPane.getSecondModel().getChainCode();
2711
2712 // no unpresent contacts
2713
2714 //disable all old objects and selections and enable the two actual objects
2715 Start.getPyMolAdaptor().setView(mod.getPDBCode(), mod.getChainCode(), cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode());
2716
2717 // present contacts in main and second structure
2718 Start.getPyMolAdaptor().edgeSelection(mod.getPDBCode(), mod.getChainCode(), "PresCont"+selectionType, firstModelContactColor, pymolSelSerial, trueRed, false, false);
2719 Start.getPyMolAdaptor().edgeSelection(cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode(), "PresCont"+selectionType, secondModelContactColor, pymolSelSerial, trueGreen, false, true);
2720
2721 String memberNameA1 = "PresCont" + selectionType+ mod.getPDBCode()+ mod.getChainCode()+ "Sel"+ pymolSelSerial;
2722 String memberNameB1 = "PresCont" + selectionType+ cmPane.getSecondModel().getPDBCode()+cmPane.getSecondModel().getChainCode() + "Sel"+ pymolSelSerial;
2723
2724 // grouping main structure selection
2725 Start.getPyMolAdaptor().groupSelections(mod.getPDBCode(), mod.getChainCode(), pymolSelSerial,memberNameA1,"");
2726 // grouping second structure selection
2727 Start.getPyMolAdaptor().groupSelections(cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode(), pymolSelSerial,memberNameB1,"");
2728 // grouping complete selection
2729 Start.getPyMolAdaptor().sendCommand("cmd.group(name = 'Selection"+ pymolSelSerial +"', members= '"+ mod.getPDBCode()+mod.getChainCode() + "Sel"+ pymolSelSerial+" " + cmPane.getSecondModel().getPDBCode()+cmPane.getSecondModel().getChainCode()+"Sel"+ pymolSelSerial+"' ), ");
2730
2731 this.pymolSelSerial++;
2732 }
2733
2734 // common and first structure mode == complete first structure
2735 else if (common == true && firstS == true && secondS == false){
2736 IntPairSet[] array = cmPane.getSelectedContacts();
2737 IntPairSet trueRed = array[0]; // red contacts
2738 IntPairSet trueGreen = array[1]; // green contacts
2739 String selectionType = mod.getChainCode();
2740
2741 //disable all old objects and selections and enable the two actual objects
2742 Start.getPyMolAdaptor().setView(mod.getPDBCode(), mod.getChainCode(), cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode());
2743
2744 //present contacts in main structure
2745 Start.getPyMolAdaptor().edgeSelection(mod.getPDBCode(), mod.getChainCode(), "PresCont"+selectionType, firstModelContactColor, pymolSelSerial, trueRed, false, false);
2746 Start.getPyMolAdaptor().edgeSelection(mod.getPDBCode(), mod.getChainCode(), "PresCont"+selectionType, firstModelContactColor, pymolSelSerial, trueGreen, false, false);
2747
2748 // present contacts in second structure
2749 Start.getPyMolAdaptor().edgeSelection(cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode(), "PresCont"+selectionType, secondModelContactColor, pymolSelSerial, trueRed, false, true);
2750 // unpresent contacts in second structure
2751 Start.getPyMolAdaptor().edgeSelection(cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode(), "AbsCont"+ selectionType, secondModelContactColor, pymolSelSerial, trueGreen, true, false);
2752
2753 String memberNameA1 = "PresCont" + selectionType+ mod.getPDBCode() + mod.getChainCode()+ "Sel"+ pymolSelSerial;
2754 String memberNameB1 = "PresCont" + selectionType+ cmPane.getSecondModel().getPDBCode()+ cmPane.getSecondModel().getChainCode() + "Sel"+ pymolSelSerial;
2755 String memberNameB2 = "AbsCont" + selectionType+ cmPane.getSecondModel().getPDBCode()+ cmPane.getSecondModel().getChainCode() + "Sel"+ pymolSelSerial;
2756
2757 // grouping main structure selection
2758 Start.getPyMolAdaptor().groupSelections(mod.getPDBCode(), mod.getChainCode(), pymolSelSerial, memberNameA1,"");
2759 // grouping second structure selection
2760 Start.getPyMolAdaptor().groupSelections(cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode(), pymolSelSerial,memberNameB1, memberNameB2);
2761 // grouping complete selection
2762 Start.getPyMolAdaptor().sendCommand("cmd.group(name = 'Selection"+ pymolSelSerial +"', members= '"+ mod.getPDBCode()+mod.getChainCode() + "Sel"+ pymolSelSerial+" " + cmPane.getSecondModel().getPDBCode()+cmPane.getSecondModel().getChainCode()+"Sel"+ pymolSelSerial+"' ), ");
2763
2764 this.pymolSelSerial++;
2765 }
2766
2767 // common and second structure mode == complete second structure
2768 else if (common == true && firstS == false && secondS == true){
2769 IntPairSet[] array = cmPane.getSelectedContacts();
2770 IntPairSet trueRed = array[0]; // red cTrueontacts
2771 IntPairSet trueGreen = array[1]; // green contacts
2772 String selectionType = cmPane.getSecondModel().getChainCode();
2773
2774 //disable all old objects and selections and enable the two actual objects
2775 Start.getPyMolAdaptor().setView(mod.getPDBCode(), mod.getChainCode(), cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode());
2776
2777 // present contacts in main structure
2778 Start.getPyMolAdaptor().edgeSelection(mod.getPDBCode(), mod.getChainCode(), "PresCont"+selectionType, firstModelContactColor, pymolSelSerial, trueGreen, false, false);
2779 // unpresent contacts in main structure
2780 Start.getPyMolAdaptor().edgeSelection(mod.getPDBCode(), mod.getChainCode(), "AbsCont" + selectionType, firstModelContactColor, pymolSelSerial, trueRed, true, false);
2781
2782 // present contacts in second structure
2783 Start.getPyMolAdaptor().edgeSelection(cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode(), "PresCont"+selectionType, secondModelContactColor, pymolSelSerial, trueGreen, false, false);
2784 Start.getPyMolAdaptor().edgeSelection(cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode(), "PresCont"+selectionType, secondModelContactColor, pymolSelSerial, trueRed, false, true);
2785
2786
2787 String memberNameA1 = "PresCont" + selectionType + mod.getPDBCode()+ mod.getChainCode()+ "Sel"+ pymolSelSerial;
2788 String memberNameA2 = "AbsCont" + selectionType+ mod.getPDBCode()+ mod.getChainCode()+ "Sel"+ pymolSelSerial;
2789 String memberNameB1 = "PresCont" + selectionType+ cmPane.getSecondModel().getPDBCode()+ cmPane.getSecondModel().getChainCode() + "Sel"+ pymolSelSerial;
2790
2791 // grouping main structure selection
2792 Start.getPyMolAdaptor().groupSelections(mod.getPDBCode(), mod.getChainCode(),pymolSelSerial, memberNameA1, memberNameA2);
2793 // grouping second structure selection
2794 Start.getPyMolAdaptor().groupSelections(cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode(),pymolSelSerial, memberNameB1, "");
2795 // grouping complete selection
2796 Start.getPyMolAdaptor().sendCommand("cmd.group(name = 'Selection"+ pymolSelSerial +"', members= '"+ mod.getPDBCode()+mod.getChainCode() + "Sel"+ pymolSelSerial+" "+ cmPane.getSecondModel().getPDBCode()+cmPane.getSecondModel().getChainCode()+"Sel"+ pymolSelSerial+"' ), ");
2797
2798 this.pymolSelSerial++;
2799 }
2800 else if (common == true && firstS == true && secondS == true){
2801 IntPairSet[] array = cmPane.getSelectedContacts();
2802 IntPairSet trueRed = array[0]; // red contacts
2803 IntPairSet trueGreen = array[1]; // green contacts
2804 IntPairSet trueCommon = array[2]; // common contacts
2805 String selectionType = mod.getChainCode()+cmPane.getSecondModel().getChainCode();
2806
2807 //disable all old objects and selections and enable the two actual objects
2808 Start.getPyMolAdaptor().setView(mod.getPDBCode(), mod.getChainCode(), cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode());
2809
2810 // present contacts in both structures
2811 Start.getPyMolAdaptor().edgeSelection(mod.getPDBCode(), mod.getChainCode(), "PresCont"+selectionType, firstModelContactColor, pymolSelSerial, trueCommon, false, false);
2812 Start.getPyMolAdaptor().edgeSelection(cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode(), "PresCont"+selectionType, secondModelContactColor, pymolSelSerial, trueCommon, false, false);
2813
2814 // present and unpresent contacts only in main structure
2815 Start.getPyMolAdaptor().edgeSelection(mod.getPDBCode(), mod.getChainCode(), "PresCont"+selectionType, firstModelContactColor, pymolSelSerial, trueRed, false, false);
2816 Start.getPyMolAdaptor().edgeSelection(mod.getPDBCode(), mod.getChainCode(), "AbsCont"+ selectionType, firstModelContactColor, pymolSelSerial, trueGreen, true, false);
2817
2818 // present and unpresent contacts only in second struture
2819 Start.getPyMolAdaptor().edgeSelection(cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode(), "PresCont"+selectionType, secondModelContactColor, pymolSelSerial, trueGreen, false, false);
2820 Start.getPyMolAdaptor().edgeSelection(cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode(), "AbsCont" +selectionType, secondModelContactColor, pymolSelSerial, trueRed, true, true);
2821
2822
2823 String memberNameA1 = "PresCont" + selectionType + mod.getPDBCode()+ mod.getChainCode()+ "Sel"+ pymolSelSerial;
2824 String memberNameA2 = "AbsCont" + selectionType+ mod.getPDBCode()+ mod.getChainCode()+ "Sel"+ pymolSelSerial;
2825 String memberNameB1 = "PresCont" + selectionType+ cmPane.getSecondModel().getPDBCode()+ cmPane.getSecondModel().getChainCode() + "Sel" + pymolSelSerial;
2826 String memberNameB2 = "AbsCont" + selectionType+ cmPane.getSecondModel().getPDBCode()+ cmPane.getSecondModel().getChainCode() + "Sel" + pymolSelSerial;
2827
2828 // grouping main structure selection
2829 Start.getPyMolAdaptor().groupSelections(mod.getPDBCode(), mod.getChainCode(), pymolSelSerial,memberNameA1, memberNameA2);
2830 // grouping second structure selection
2831 Start.getPyMolAdaptor().groupSelections(cmPane.getSecondModel().getPDBCode(), cmPane.getSecondModel().getChainCode(), pymolSelSerial,memberNameB1, memberNameB2);
2832 // grouping complete structure
2833 Start.getPyMolAdaptor().sendCommand("cmd.group(name = 'Selection"+ pymolSelSerial +"', members= '"+ mod.getPDBCode()+mod.getChainCode() + "Sel"+ pymolSelSerial+" " + cmPane.getSecondModel().getPDBCode()+cmPane.getSecondModel().getChainCode()+"Sel"+ pymolSelSerial+"' ), ");
2834
2835
2836 this.pymolSelSerial++;
2837 }
2838 }
2839 else {
2840 IntPairSet[] array = cmPane.getSelectedContacts();
2841 IntPairSet contacts = array[0];
2842 String selectionType = mod.getChainCode();
2843
2844 //disable all old objects and selections
2845 Start.getPyMolAdaptor().sendCommand("disable all");
2846 Start.getPyMolAdaptor().sendCommand("enable " + mod.getPDBCode()+mod.getChainCode());
2847
2848 Start.getPyMolAdaptor().edgeSelection(mod.getPDBCode(), mod.getChainCode(), selectionType, "color magenta, ", pymolSelSerial, contacts, false, true);
2849 this.pymolSelSerial++;
2850 }
2851 }
2852
2853
2854 /**
2855 *
2856 */
2857 private void handleShowDistance3D() {
2858 if(mod==null) {
2859 showNoContactMapWarning();
2860 } else if(!mod.has3DCoordinates()) {
2861 showNo3DCoordsWarning();
2862 } else if(!Start.isPyMolConnectionAvailable()) {
2863 showNoPyMolConnectionWarning();
2864 } else {
2865 Start.getPyMolAdaptor().sendSingleEdge(mod.getPDBCode(), mod.getChainCode(), pymolSelSerial, cmPane.getRightClickCont());
2866 this.pymolSelSerial++;
2867 }
2868 }
2869
2870 /**
2871 *
2872 */
2873 private void handleShowTriangles3D() {
2874 if(mod==null) {
2875 showNoContactMapWarning();
2876 } else if(!mod.has3DCoordinates()) {
2877 showNo3DCoordsWarning();
2878 } else if(!Start.isPyMolConnectionAvailable()) {
2879 showNoPyMolConnectionWarning();
2880 } else if(cmPane.getCommonNbh() == null) {
2881 showNoCommonNbhSelectedWarning();
2882 } else {
2883 Start.getPyMolAdaptor().showTriangles(mod.getPDBCode(), mod.getChainCode(), cmPane.getCommonNbh(), pymolNbhSerial); // TODO: get rid of NbhSerial
2884 this.pymolNbhSerial++;
2885 }
2886 }
2887
2888 /**
2889 * Sends set aligned residues to the visualizer. Calls function
2890 * {@link #doShowAlignedResidues3D(Model, Model, String, String, Alignment, EdgeSet[])}
2891 * with the currently selected contacts being set to the selected contacts.
2892 */
2893 private void handleShowAlignedResidues3D() {
2894 doShowAlignedResidues3D(mod, mod2,
2895 mod.getPDBCode()+mod.getChainCode(),
2896 mod2.getPDBCode()+mod2.getChainCode(),
2897 ali,
2898 cmPane.getSelectedContacts());
2899 }
2900
2901 /**
2902 *
2903 */
2904 private void handleDeleteSelContacts() {
2905 if(mod==null) {
2906 showNoContactMapWarning();
2907 } else if(cmPane.getSelContacts().size() == 0) {
2908 showNoContactsSelectedWarning();
2909 } else {
2910 cmPane.deleteSelectedContacts();
2911 }
2912 }
2913
2914
2915 /* -------------------- Compare menu -------------------- */
2916
2917
2918 private void handleSelContactsInComparedMode(){
2919 if(mod==null) {
2920 showNoContactMapWarning();
2921 } else
2922 if(!cmPane.hasSecondModel()) {
2923 showNoSecondContactMapWarning();
2924 } else {
2925 selCommonContactsInComparedMode = !selCommonContactsInComparedMode;
2926 cmPane.toggleCompareMode(selCommonContactsInComparedMode);
2927 if(selCommonContactsInComparedMode) {
2928 mmSelCommonContactsInComparedMode.setIcon(icon_selected);
2929 } else {
2930 mmSelCommonContactsInComparedMode.setIcon(icon_deselected);
2931 }
2932 }
2933 tbShowCommon.setSelected(selCommonContactsInComparedMode);
2934 }
2935
2936 private void handleSelFirstStrucInComparedMode(){
2937 if(mod==null) {
2938 showNoContactMapWarning();
2939 } else
2940 if(!cmPane.hasSecondModel()) {
2941 showNoSecondContactMapWarning();
2942 } else {
2943 selFirstStrucInComparedMode = !selFirstStrucInComparedMode;
2944 cmPane.toggleCompareMode(selFirstStrucInComparedMode);
2945 tbShowFirstStructure.setSelected(selFirstStrucInComparedMode);
2946 if(selFirstStrucInComparedMode) {
2947 mmSelFirstStrucInComparedMode.setIcon(icon_selected);
2948 } else {
2949 mmSelFirstStrucInComparedMode.setIcon(icon_deselected);
2950 }
2951 }
2952 tbShowFirstStructure.setSelected(selFirstStrucInComparedMode);
2953 }
2954
2955 private void handleSelSecondStrucInComparedMode(){
2956 if(mod==null) {
2957 showNoContactMapWarning();
2958 } else
2959 if(!cmPane.hasSecondModel()) {
2960 showNoSecondContactMapWarning();
2961 } else {
2962 selSecondStrucInComparedMode = !selSecondStrucInComparedMode;
2963 cmPane.toggleCompareMode(selSecondStrucInComparedMode);
2964 if(selSecondStrucInComparedMode) {
2965 mmSelSecondStrucInComparedMode.setIcon(icon_selected);
2966 } else {
2967 mmSelSecondStrucInComparedMode.setIcon(icon_deselected);
2968 }
2969 }
2970 tbShowSecondStructure.setSelected(selSecondStrucInComparedMode);
2971 }
2972
2973 private void handleToggleDiffDistMap() {
2974 if(mod==null) {
2975 showNoContactMapWarning();
2976 } else if (!mod.has3DCoordinates()){
2977 showNo3DCoordsWarning();
2978 } else if (!cmPane.hasSecondModel()) {
2979 showNoSecondContactMapWarning();
2980 } else if (!cmPane.mod2.has3DCoordinates()) {
2981 showNo3DCoordsSecondModelWarning();
2982 } else {
2983 showDiffDistMap = !showDiffDistMap;
2984 cmPane.toggleDiffDistMap(showDiffDistMap);
2985 if(showDiffDistMap) {
2986 mmToggleDiffDistMap.setIcon(icon_selected);
2987 } else {
2988 mmToggleDiffDistMap.setIcon(icon_deselected);
2989 }
2990 }
2991 }
2992
2993 /* -------------------- Help menu -------------------- */
2994
2995 private void handleHelpWriteConfig() {
2996 try {
2997 Start.writeExampleConfigFile(Start.CONFIG_FILE_NAME);
2998 System.out.println("Writing example configuration file " + new File(Start.CONFIG_FILE_NAME).getAbsolutePath());
2999 } catch(IOException e) {
3000 System.err.println("Could not write configuration file " + new File(Start.CONFIG_FILE_NAME).getAbsolutePath());
3001 }
3002 }
3003
3004 private void handleHelpAbout() {
3005 JOptionPane.showMessageDialog(this,
3006 "<html><center>" +
3007 "<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" +
3008 "Contact Map Viewer v"+Start.VERSION +
3009 "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>" +
3010 "<p>(C) AG Lappe 2007</p>" +
3011 "</center></html>",
3012 "About",
3013 JOptionPane.PLAIN_MESSAGE);
3014 }
3015
3016 private void handleHelpHelp() {
3017 JOptionPane.showMessageDialog(this,
3018 "<html>" +
3019 "General<br>" +
3020 "- Click right mouse button in contact map for a context menu of available actions<br>" +
3021 "<br>" +
3022 "Square selection mode<br>" +
3023 "- Click on a contact to select it<br>" +
3024 "- Drag the mouse to select a rectangular area of contacts<br>" +
3025 "- Hold 'Ctrl' while selecting to add to the current selection<br>" +
3026 "- Click on a non-contact to reset the current selection<br>" +
3027 "<br>" +
3028 "Fill selection mode<br>" +
3029 "- Click on a contact to start a fill selection from that contact<br>" +
3030 "- Hold 'Ctrl' while selecting to add to the current selection<br>" +
3031 "<br>" +
3032 "Diagonal selection mode<br>" +
3033 "- Click to select all contacts along a diagonal<br>" +
3034 "- Click and drag to select multiple diagonals<br>" +
3035 "- Hold 'Ctrl' while selecting to add to the current selection<br>" +
3036 "<br>" +
3037 "Node neighbourhood selection mode<br>" +
3038 "- Click on a residue in the ruler or in the diagonal to select its contacts<br>" +
3039 "- Click on a cell in the upper half to select all contacts of that pair of residues<br>" +
3040 "- Hold 'Ctrl' while selecting to add to the current selection<br>" +
3041 "<br>" +
3042 "Show selected contacts in PyMol<br>" +
3043 "- Shows the currently selected contacts as edges in PyMol<br>" +
3044 "<br>" +
3045 "Show common neigbours<br>" +
3046 "- Click on a contact or non-contact to see the common neighbours for that pair of residues<br>" +
3047 "<br>" +
3048 "Show common neighbours in PyMol<br>" +
3049 "- Shows the last shown common neighbours as triangles in PyMol<br>" +
3050 "<br>" +
3051 "Delete selected contacts<br>" +
3052 "- Permanently deletes the selected contacts from the contact map<br>" +
3053 "</html>",
3054 "Help",
3055 JOptionPane.PLAIN_MESSAGE);
3056 }
3057
3058 /* -------------------- Warnings -------------------- */
3059
3060 /** Shows a window with a warning message that no contact map is loaded yet */
3061 private void showNoContactMapWarning() {
3062 JOptionPane.showMessageDialog(this, "No contact map loaded yet", "Warning", JOptionPane.INFORMATION_MESSAGE);
3063 }
3064
3065 /** Shows a window with a warning message that no secondary structure information is available */
3066 private void showNoSecondaryStructureWarning() {
3067 JOptionPane.showMessageDialog(this, "No secondary structure information available", "Warning", JOptionPane.INFORMATION_MESSAGE);
3068 }
3069
3070 /** Shows a window with a warning message that no second contact map is loaded yet (for comparison functions) */
3071 private void showNoSecondContactMapWarning() {
3072 JOptionPane.showMessageDialog(this, "No second contact map loaded yet", "Warning", JOptionPane.INFORMATION_MESSAGE);
3073 }
3074
3075 /** Warning dialog to be shown if a function is being called which requires 3D coordinates and they are missing */
3076 private void showNo3DCoordsWarning(){
3077 JOptionPane.showMessageDialog(this, "No 3D coordinates are associated with this contact map", "Warning", JOptionPane.INFORMATION_MESSAGE);
3078 }
3079
3080 /** Warning dialog to be shown if a comparison function is being called which requires 3D coordinates and they are missing */
3081 private void showNo3DCoordsSecondModelWarning(){
3082 JOptionPane.showMessageDialog(this, "No 3D coordinates are associated with this contact map", "Warning", JOptionPane.INFORMATION_MESSAGE);
3083 }
3084
3085 @SuppressWarnings("unused")
3086 private void showNo3DCoordFromSelection() {
3087 JOptionPane.showMessageDialog(this, "Cannot assign any 3D-coordinates to the given selection.", "3D Coordinates Error.", JOptionPane.ERROR_MESSAGE);
3088 }
3089
3090 private void showNo3DCoordFromComparedSelection() {
3091 Object[] message = {"Cannot assign any 3D-coordinates to the given selection.",
3092 "Please create your contact selection from the set of common contacts only."};
3093 JOptionPane.showMessageDialog(this, message, "3D Coordinates Error", JOptionPane.ERROR_MESSAGE);
3094 }
3095
3096 /** Error dialog to be shown if loading a model failed. */
3097 private void showLoadError(String message) {
3098 JOptionPane.showMessageDialog(this, "<html>Failed to load structure:<br>" + message + "</html>", "Load Error", JOptionPane.ERROR_MESSAGE);
3099 }
3100
3101 /** Error dialog to be shown when trying to do a db operation without a db connection */
3102 private void showNoDatabaseConnectionWarning() {
3103 JOptionPane.showMessageDialog(this, "Failed to perform operation. No database connection available.", "Warning", JOptionPane.INFORMATION_MESSAGE);
3104 }
3105
3106 /** Error dialog to be shown when trying to do a db operation without a db connection */
3107 private void showNoPyMolConnectionWarning() {
3108 JOptionPane.showMessageDialog(this, "Failed to perform operation. No Communication with PyMol available", "Warning", JOptionPane.INFORMATION_MESSAGE);
3109 }
3110
3111 private void showNoCommonNbhSelectedWarning() {
3112 JOptionPane.showMessageDialog(this, "No common neighbourhood selected (Use Show Common Neighbours Mode)", "Warning", JOptionPane.INFORMATION_MESSAGE);
3113 }
3114
3115 private void showNoContactsSelectedWarning() {
3116 JOptionPane.showMessageDialog(this, "No contacts selected", "Warning", JOptionPane.INFORMATION_MESSAGE);
3117 }
3118
3119 @SuppressWarnings("unused")
3120 private void showDifferentSizeContactMapsError() {
3121 JOptionPane.showMessageDialog(this, "The two contact maps cannot be compared because they have different size.", "Cannot compare contact maps", JOptionPane.ERROR_MESSAGE);
3122 }
3123
3124 private void showInvalidSelectionStringWarning() {
3125 JOptionPane.showMessageDialog(this, "Invalid selection string", "Warning", JOptionPane.INFORMATION_MESSAGE);
3126 }
3127
3128 private void showCannotSaveEmptyAlignment() {
3129 JOptionPane.showMessageDialog(this, "Cannot save empty alignment!", "Save error", JOptionPane.ERROR_MESSAGE);
3130 }
3131
3132
3133 /*---------------------------- public methods ---------------------------*/
3134
3135 /**
3136 * Create and show a new view window, showing a contact map based on the given model and dispose the current one.
3137 * TODO: Currently being abused as a constructor for new windows (something the real constructor should do).
3138 */
3139 public void spawnNewViewWindow(Model mod) {
3140
3141 String wintitle = "Contact Map of " + mod.getPDBCode() + " " + mod.getChainCode();
3142 View view = new View(mod, wintitle);
3143 if(view == null) {
3144 JOptionPane.showMessageDialog(this, "Couldn't initialize contact map window", "Load error", JOptionPane.ERROR_MESSAGE);
3145 //System.exit(-1);
3146 } else {
3147 if(this.mod == null ) {
3148 // print the new View directly on top of the previous one if
3149 // this was empty
3150 Rectangle old_r = this.getBounds();
3151 Rectangle cur_r = view.getBounds();
3152 Rectangle new_r = new Rectangle(old_r.x,old_r.y,cur_r.width,cur_r.height);
3153 view.setBounds(new_r);
3154 }
3155 view.toFront();
3156
3157 System.out.println("Contact map " + mod.getPDBCode() + " " + mod.getChainCode() + " loaded.");
3158
3159 if(ContactMapPane.BG_PRELOADING) {
3160 view.cmPane.preloadBackgroundMaps();
3161 }
3162
3163 if (Start.isPyMolConnectionAvailable() && mod.has3DCoordinates()) {
3164 // load structure in PyMol
3165 Start.getPyMolAdaptor().loadStructure(mod.getTempPdbFileName(), mod.getPDBCode(), mod.getChainCode(), false);
3166
3167 }
3168 // if previous window was empty (not showing a contact map) dispose it
3169 if(this.mod == null) {
3170 this.setVisible(false);
3171 this.dispose();
3172 }
3173 }
3174 }
3175
3176 /**
3177 * Sets the comparison mode to the given state. If comparison mode is enabled, buttons
3178 * for comparing structures become active otherwise they become inactive.
3179 * @param state
3180 */
3181 public void setComparisonMode(boolean state) {
3182 comparisonMode = !comparisonMode;
3183 if(comparisonMode) {
3184 tbShowCommon.setVisible(true);
3185 tbShowFirstStructure.setVisible(true);
3186 tbShowSecondStructure.setVisible(true);
3187 } else {
3188 tbShowCommon.setEnabled(false);
3189 tbShowFirstStructure.setVisible(false);
3190 tbShowSecondStructure.setVisible(false);
3191 }
3192 }
3193
3194 /* -------------------- getter methods -------------------- */
3195 // TODO: Make all these parameters of calls to CMPane
3196 /**
3197 * Returns the current selection mode. The selection mode defines the meaning of user mouse actions.
3198 * @return The current selection mode
3199 */
3200 public int getCurrentSelectionMode(){
3201 return currentSelectionMode;
3202 }
3203
3204 public boolean getCompareStatus(){
3205 return compareStatus;
3206 }
3207
3208 /**
3209 * Returns whether showing the pdb residue serials is switched on
3210 */
3211 public boolean getShowPdbSers() {
3212 return showPdbSers;
3213 }
3214
3215 /**
3216 * Returns whether showing the common neighbourhood size map is switched on
3217 */
3218 public boolean getShowNbhSizeMap() {
3219 return showNbhSizeMap;
3220 }
3221
3222 /**
3223 * Returns whether showing the density map is switched on
3224 */
3225 public boolean getShowDensityMap() {
3226 return this.showDensityMap;
3227 }
3228
3229 /**
3230 * Returns whether showing the distance map is switched on
3231 */
3232 public boolean getShowDistMap() {
3233 return this.showDistanceMap;
3234 }
3235
3236 /**
3237 * Returns whether selection of contacts of both structures on compared contact map is switched on
3238 */
3239 public boolean getSelCommonContactsInComparedMode() {
3240 return this.selCommonContactsInComparedMode;
3241 }
3242
3243 /**
3244 * Returns whether selection of contacts of the first structure on compared contact map is switched on
3245 */
3246 public boolean getSelFirstStrucInComparedMode() {
3247 return this.selFirstStrucInComparedMode;
3248 }
3249
3250 /**
3251 * Returns whether selection of contacts of the second structure on compared contact map is switched on
3252 */
3253 public boolean getSelSecondStrucInComparedMode() {
3254 return this.selSecondStrucInComparedMode;
3255 }
3256
3257 /**
3258 * Returns whether showing the difference distance map (in comparison mode) is switched on
3259 */
3260 public boolean getShowDiffDistMap() {
3261 return this.showDiffDistMap;
3262 }
3263 }