/usr/share/pyshared/reinteract/application.py is in reinteract 0.5.0-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | # Copyright 2008-2009 Owen Taylor
#
# This file is part of Reinteract and distributed under the terms
# of the BSD license. See the file COPYING in the Reinteract
# distribution for full details.
#
########################################################################
#
# The global application object; it from global_settings because it handles tracking
# the user interface objects of the current session, rather than global options and
# preferences.
import gtk
import re
import os
import sys
# SEE BOTTOM OF FILE FOR MOST LOCAL IMPORTS
#
# Done that way to allow 'from Application import application'
# We'll have to rethink this if we ever statically compile reinteract
from application_state import ApplicationState
from global_settings import global_settings
_VALID_CHAR = re.compile("[A-Za-z0-9._ -]")
class Application():
def __init__(self):
self.__unsaved_indices = []
self.windows = set()
self.__about_dialog = None
config_folder = global_settings.config_dir
if not os.path.exists(config_folder):
os.makedirs(config_folder)
state_location = os.path.join(config_folder, 'reinteract.state')
self.state = ApplicationState(state_location)
def get_notebook_infos(self):
paths = []
recent = self.state.get_recent_notebooks()
notebooks_dir = global_settings.notebooks_dir
recent_paths = [os.path.abspath(r.path) for r in recent]
folder_paths = [os.path.join(notebooks_dir, f) for f in os.listdir(notebooks_dir)]
paths = recent_paths + folder_paths
example_state = self.state.get_notebook_state(global_settings.examples_dir)
if example_state.get_last_opened() == -1:
paths.append(global_settings.examples_dir)
paths = [p for p in paths if os.path.isdir(p)]
paths = list(set((os.path.normpath(path) for path in paths)))
return [NotebookInfo(p) for p in paths]
def validate_name(self, name):
# Remove surrounding whitespace
name = name.strip()
if name == "":
raise ValueError("Name cannot be empty")
# Replace series of whitespace with a single space
name = name.replace("\s+", " ")
bad_chars = set()
for c in name:
if not _VALID_CHAR.match(c):
bad_chars.add(c)
bad = ", ".join(("'" + c + "'" for c in bad_chars))
if len(bad_chars) == 1:
raise ValueError("Name contains invalid character: %s" % bad)
elif len(bad_chars) > 0:
raise ValueError("Name contains invalid characters: %s" % bad)
elif name.startswith("."):
raise ValueError("Name cannot start with a '.'")
return name
def __make_notebook_window(self, notebook):
if global_settings.mini_mode:
global MiniWindow
from mini_window import MiniWindow
return MiniWindow(notebook)
else:
global NotebookWindow
from notebook_window import NotebookWindow
return NotebookWindow(notebook)
def open_notebook(self, path):
for window in self.windows:
if window.path == path:
window.window.present()
return window
notebook = Notebook(path)
window = self.__make_notebook_window(notebook)
window.show()
self.windows.add(window)
self.state.notebook_opened(path)
return window
def find_notebook_path(self, path):
# Given a path, possibly inside a notebook, find the notebook and the relative
# path of the notebook inside the file
relative = None
tmp = path
while True:
if os.path.isdir(tmp):
if os.path.exists(os.path.join(tmp, "index.rnb")):
return tmp, relative
parent, basename = os.path.split(tmp)
if parent == tmp: # At the root
# As a transition thing, for now allow specifying a folder without
# an index.rnb as a folder
if os.path.isdir(path):
return path, None
else:
return None, None
tmp = parent
if relative == None:
relative = basename
else:
relative = os.path.join(basename, relative)
return tmp, relative
def open_path(self, path):
"""Figure out what path points to, and open it appropriately"""
absolute = os.path.abspath(path)
basename, dirname = os.path.split(absolute)
if basename.lower() == "index.rnb":
notebook_path, relative = dirname, None
else:
notebook_path, relative = self.find_notebook_path(absolute)
if notebook_path:
window = self.open_notebook(notebook_path)
if relative and relative in window.notebook.files:
window.open_file(window.notebook.files[relative])
else:
global EditorWindow
from editor_window import EditorWindow
window = EditorWindow()
if not window.load(absolute):
window.window.destroy()
return False
window.show()
self.windows.add(window)
return True
def create_notebook(self, path, description=None):
os.makedirs(path)
notebook = Notebook(path)
if description != None:
notebook.info.description = description
window = self.__make_notebook_window(notebook)
window.show()
self.windows.add(window)
self.state.notebook_opened(path)
return window
def create_notebook_dialog(self, parent=None):
return new_notebook.run(parent)
def open_notebook_dialog(self, parent=None):
return open_notebook.run(parent)
def on_about_dialog_destroy(self, dialog):
self.__about_dialog = None
def show_about_dialog(self, parent=None):
if not self.__about_dialog:
self.__about_dialog = AboutDialog()
self.__about_dialog.connect("destroy", self.on_about_dialog_destroy)
self.__about_dialog.set_transient_for(parent)
self.__about_dialog.present()
def quit(self):
for window in self.windows:
if not window.confirm_discard():
return
self.state.flush()
gtk.main_quit()
def window_closed(self, window):
self.windows.remove(window)
if not global_settings.main_menu_mode and len(self.windows) == 0:
self.quit()
def allocate_unsaved_index(self):
"""Allocate an index to be used when displaying an unsaved object ("Unsaved Worksheet 1")"""
for i in xrange(0, len(self.__unsaved_indices)):
if not self.__unsaved_indices[i]:
self.__unsaved_indices[i] = True
return i + 1
self.__unsaved_indices.append(True)
return len(self.__unsaved_indices)
def free_unsaved_index(self, index):
"""Free an index previously returned by allocate_unsaved_index()"""
self.__unsaved_indices[index - 1] = False
# The global singleton
application = Application()
from about_dialog import AboutDialog
from notebook import Notebook
from notebook_info import NotebookInfo
import new_notebook
import open_notebook
if global_settings.main_menu_mode:
from main_menu import main_menu
|