Package gui :: Module misc
[hide private]
[frames] | no frames]

Source Code for Module gui.misc

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2009 Michael Bieri                                            # 
  4  # Copyright (C) 2010-2012 Edward d'Auvergne                                   # 
  5  #                                                                             # 
  6  # This file is part of the program relax.                                     # 
  7  #                                                                             # 
  8  # relax is free software; you can redistribute it and/or modify               # 
  9  # it under the terms of the GNU General Public License as published by        # 
 10  # the Free Software Foundation; either version 2 of the License, or           # 
 11  # (at your option) any later version.                                         # 
 12  #                                                                             # 
 13  # relax is distributed in the hope that it will be useful,                    # 
 14  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 15  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 16  # GNU General Public License for more details.                                # 
 17  #                                                                             # 
 18  # You should have received a copy of the GNU General Public License           # 
 19  # along with relax; if not, write to the Free Software                        # 
 20  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   # 
 21  #                                                                             # 
 22  ############################################################################### 
 23   
 24  # Module docstring. 
 25  """Miscellaneous functions used throughout the GUI.""" 
 26   
 27  # Python module imports. 
 28  from copy import deepcopy 
 29  import os 
 30  import platform 
 31  from textwrap import wrap 
 32  import wx 
 33   
 34  # relax module imports. 
 35  from relax_errors import AllRelaxErrors 
 36  from status import Status; status = Status() 
 37   
 38  # relax GUI module imports. 
 39  from gui.errors import gui_raise 
 40   
 41   
42 -def add_border(box, border=0, packing=wx.VERTICAL, debug=False):
43 """Create the main part of the frame, returning the central sizer. 44 45 @param box: The box sizer element to pack the borders into. 46 @type box: wx.BoxSizer instance 47 @keyword border: The size of the border in pixels. 48 @type border: int 49 @keyword packing: Specify if the central sizer should be vertically or horizontally packed. 50 @type packing: wx.VERTICAL or wx.HORIZONTAL 51 @keyword debug: A flag which if true will make colourful borders. 52 @type debug: bool 53 @return: The central sizer. 54 @rtype: wx.BoxSizer instance 55 """ 56 57 # The orientation of the sub sizer. 58 orient = box.GetOrientation() 59 if orient == wx.HORIZONTAL: 60 orient_sub = wx.VERTICAL 61 else: 62 orient_sub = wx.HORIZONTAL 63 64 # Some sizers. 65 sizer_sub = wx.BoxSizer(orient_sub) 66 sizer_cent = wx.BoxSizer(packing) 67 68 # Left and right borders (debugging). 69 if debug: 70 # Left coloured panel. 71 panel = wx.Panel(box.GetContainingWindow(), -1) 72 panel.SetSize((border, border)) 73 panel.SetBackgroundColour("Red") 74 box.Add(panel, 0, wx.EXPAND|wx.ALL) 75 76 # Centre. 77 box.Add(sizer_sub, 1, wx.EXPAND|wx.ALL) 78 79 # Top coloured panel. 80 panel = wx.Panel(box.GetContainingWindow(), -1) 81 panel.SetSize((border, border)) 82 panel.SetBackgroundColour("Yellow") 83 box.Add(panel, 0, wx.EXPAND|wx.ALL) 84 85 # Left and right borders. 86 else: 87 box.AddSpacer(border) 88 box.Add(sizer_sub, 1, wx.EXPAND|wx.ALL) 89 box.AddSpacer(border) 90 91 # Top and bottom borders (debugging). 92 if debug: 93 # Top coloured panel. 94 panel = wx.Panel(box.GetContainingWindow(), -1) 95 panel.SetSize((border, border)) 96 panel.SetBackgroundColour("Blue") 97 sizer_sub.Add(panel, 0, wx.EXPAND|wx.ALL) 98 99 # Centre. 100 sizer_sub.Add(sizer_cent, 1, wx.EXPAND|wx.ALL) 101 102 # Bottom coloured panel. 103 panel = wx.Panel(box.GetContainingWindow(), -1) 104 panel.SetSize((border, border)) 105 panel.SetBackgroundColour("Green") 106 sizer_sub.Add(panel, 0, wx.EXPAND|wx.ALL) 107 108 # Top and bottom borders. 109 else: 110 sizer_sub.AddSpacer(border) 111 sizer_sub.Add(sizer_cent, 1, wx.EXPAND|wx.ALL) 112 sizer_sub.AddSpacer(border) 113 114 # Return the central sizer. 115 return sizer_cent
116 117
118 -def format_table(table):
119 """Format the text by stripping whitespace. 120 121 @param table: The table. 122 @type table: lists of lists of str 123 @return: The formatted table. 124 @rtype: str 125 """ 126 127 # Initialise some variables. 128 text = '' 129 num_rows = len(table.cells) 130 num_cols = len(table.headings) 131 132 # The column widths. 133 widths = [] 134 for j in range(num_cols): 135 widths.append(len(table.headings[j])) 136 for i in range(num_rows): 137 for j in range(num_cols): 138 # The element is larger than the previous. 139 if len(table.cells[i][j]) > widths[j]: 140 widths[j] = len(table.cells[i][j]) 141 142 # The free space for the text. 143 used = 0 144 used += 2 # Start of the table ' '. 145 used += 2 # End of the table ' '. 146 used += 3 * (num_cols - 1) # Middle of the table ' '. 147 free_space = status.text_width - used 148 149 # The maximal width for all cells. 150 free_width = sum(widths) 151 152 # Column wrapping. 153 if free_width > free_space: 154 # New structures. 155 new_widths = deepcopy(widths) 156 num_cols_wrap = num_cols 157 free_space_wrap = free_space 158 col_wrap = [True] * num_cols 159 160 # Loop. 161 while 1: 162 # The average column width. 163 ave_width = free_space_wrap / num_cols_wrap 164 165 # Rescale. 166 rescale = False 167 for i in range(num_cols): 168 # Remove the column from wrapping if smaller than the average wrapped width. 169 if col_wrap[i] and new_widths[i] < ave_width: 170 # Recalculate. 171 free_space_wrap = free_space_wrap - new_widths[i] 172 num_cols_wrap -= 1 173 rescale = True 174 175 # Remove the column from wrapping. 176 col_wrap[i] = False 177 178 # Done. 179 if not rescale: 180 # Set the column widths. 181 for i in range(num_cols): 182 if new_widths[i] > ave_width: 183 new_widths[i] = ave_width 184 break 185 186 # No column wrapping. 187 else: 188 new_widths = widths 189 col_wrap = [False] * num_cols 190 191 # The total table width. 192 total_width = sum(new_widths) + used 193 194 # The header. 195 text += " " + "_" * (total_width - 2) + "\n\n" # Top rule and black line. 196 text += table_line(text=table.headings, widths=new_widths) # The headings. 197 text += table_line(widths=new_widths, bottom=True) # Middle rule. 198 199 # The table contents. 200 for i in range(num_rows): 201 # Column text, with wrapping. 202 col_text = [table.cells[i]] 203 num_lines = 1 204 for j in range(num_cols): 205 if col_wrap[j]: 206 # Wrap. 207 lines = wrap(col_text[0][j], new_widths[j]) 208 209 # Count the lines. 210 num_lines = len(lines) 211 212 # Replace the column text. 213 for k in range(num_lines): 214 # New row of empty text. 215 if len(col_text) <= k: 216 col_text.append(['']*num_cols) 217 218 # Pack the data. 219 col_text[k][j] = lines[k] 220 221 # Blank line (between rows when asked, and for the first row after the header). 222 if table.spacing or i == 1: 223 text += table_line(widths=new_widths) 224 225 # The contents. 226 for k in range(num_lines): 227 text += table_line(text=col_text[k], widths=new_widths) 228 229 # The bottom. 230 text += table_line(widths=new_widths, bottom=True) # Bottom rule. 231 232 # Add a newline. 233 text += '\n' 234 235 # Return the table text. 236 return text
237 238
239 -def open_file(file, force_text=False):
240 """Open the file in the platform's native editor/viewer. 241 242 @param file: The path of the file to open. 243 @type file: str 244 @keyword force_text: A flag which if True will cause a text editor to be launched. 245 @type force_text: bool 246 """ 247 248 # Windows. 249 if platform.uname()[0] in ['Windows', 'Microsoft']: 250 # Text file. 251 if force_text: 252 os.system('notepad %s' % os.path.normpath(file)) 253 254 # All other files. 255 else: 256 os.startfile(os.path.normpath(file)) 257 258 # Mac OS X. 259 elif platform.uname()[0] == 'Darwin': 260 # Text file. 261 if force_text: 262 os.system('open -t %s' % file) 263 264 # All other files. 265 else: 266 os.system('open %s' % file) 267 268 # POSIX Systems with xdg-open. 269 else: 270 os.system('/usr/bin/xdg-open %s' % file)
271 272
273 -def protected_exec(fn, *args, **kargs):
274 """Apply the given function, catching all RelaxErrors. 275 276 All args and keyword args supplied will be directly applied to the given function. 277 278 @param fn: The function to apply. 279 @type fn: func 280 @return: The status of execution. 281 @rtype: bool 282 """ 283 284 # Apply the function. 285 try: 286 apply(fn, args, kargs) 287 288 # Catch RelaxErrors. 289 except AllRelaxErrors, instance: 290 # Raise the error in debugging mode. 291 if status.debug: 292 raise 293 294 # Display a dialog with the error. 295 gui_raise(instance, raise_flag=False) 296 297 # Failure. 298 return False 299 300 # Success. 301 return True
302 303
304 -def table_line(text=None, widths=None, bottom=False):
305 """Format a line of a table. 306 307 @keyword text: The list of table elements. If not given, an empty line will be be produced. 308 @type text: list of str or None 309 @keyword widths: The list of column widths for the table. 310 @type widths: list of int 311 @keyword botton: A flag which if True will cause a table bottom line to be produced. 312 @type bottom: bool 313 @return: The table line. 314 @rtype: str 315 """ 316 317 # Initialise. 318 if bottom: 319 line = " _" 320 else: 321 line = " " 322 323 # Loop over the columns. 324 for i in range(len(widths)): 325 # The column separator. 326 if i > 0: 327 if bottom: 328 line += "___" 329 else: 330 line += " " 331 332 # A bottom line. 333 if bottom: 334 line += "_" * widths[i] 335 336 # Empty line. 337 elif text == None: 338 line += " " * widths[i] 339 340 # The text. 341 else: 342 line += text[i] 343 line += " " * (widths[i] - len(text[i])) 344 345 # Close the line. 346 if bottom: 347 line += "_ \n" 348 else: 349 line += " \n" 350 351 # Return the text. 352 return line
353