| 1 | # ============================================================================ |
|---|
| 2 | # |
|---|
| 3 | # Copyright (C) 2007-2008 Conceptive Engineering bvba. All rights reserved. |
|---|
| 4 | # www.conceptive.be / project-camelot@conceptive.be |
|---|
| 5 | # |
|---|
| 6 | # This file is part of the Camelot Library. |
|---|
| 7 | # |
|---|
| 8 | # This file may be used under the terms of the GNU General Public |
|---|
| 9 | # License version 2.0 as published by the Free Software Foundation |
|---|
| 10 | # and appearing in the file LICENSE.GPL included in the packaging of |
|---|
| 11 | # this file. Please review the following information to ensure GNU |
|---|
| 12 | # General Public Licensing requirements will be met: |
|---|
| 13 | # http://www.trolltech.com/products/qt/opensource.html |
|---|
| 14 | # |
|---|
| 15 | # If you are unsure which license is appropriate for your use, please |
|---|
| 16 | # review the following information: |
|---|
| 17 | # http://www.trolltech.com/products/qt/licensing.html or contact |
|---|
| 18 | # project-camelot@conceptive.be. |
|---|
| 19 | # |
|---|
| 20 | # This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE |
|---|
| 21 | # WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
|---|
| 22 | # |
|---|
| 23 | # For use of this library in commercial applications, please contact |
|---|
| 24 | # project-camelot@conceptive.be |
|---|
| 25 | # |
|---|
| 26 | # ============================================================================ |
|---|
| 27 | |
|---|
| 28 | import logging |
|---|
| 29 | |
|---|
| 30 | logger = logging.getLogger('mainwindow') |
|---|
| 31 | logger.setLevel(logging.INFO) |
|---|
| 32 | |
|---|
| 33 | # |
|---|
| 34 | # Dummy imports to fool the windows installer and force |
|---|
| 35 | # it to include the right packages |
|---|
| 36 | # |
|---|
| 37 | from sqlalchemy.databases import sqlite |
|---|
| 38 | import sqlite3 |
|---|
| 39 | |
|---|
| 40 | from PyQt4.QtCore import Qt |
|---|
| 41 | from PyQt4 import QtGui, QtCore |
|---|
| 42 | from PyQt4 import QtWebKit |
|---|
| 43 | |
|---|
| 44 | from camelot.view.art import Icon |
|---|
| 45 | from camelot.action import createAction, addActions |
|---|
| 46 | from camelot.view.controls.navpane import NavigationPane |
|---|
| 47 | from camelot.view.controls.printer import Printer |
|---|
| 48 | from camelot.view.model_thread import post |
|---|
| 49 | |
|---|
| 50 | QT_MAJOR_VERSION = float('.'.join(str(QtCore.QT_VERSION_STR).split('.')[0:2])) |
|---|
| 51 | |
|---|
| 52 | from camelot.core.utils import ugettext as _ |
|---|
| 53 | |
|---|
| 54 | |
|---|
| 55 | class MainWindow(QtGui.QMainWindow): |
|---|
| 56 | """Main window GUI""" |
|---|
| 57 | |
|---|
| 58 | def __init__(self, app_admin, parent=None): |
|---|
| 59 | from workspace import construct_workspace |
|---|
| 60 | logger.debug('initializing main window') |
|---|
| 61 | QtGui.QMainWindow.__init__(self, parent) |
|---|
| 62 | |
|---|
| 63 | self.app_admin = app_admin |
|---|
| 64 | |
|---|
| 65 | logger.debug('setting up workspace') |
|---|
| 66 | self.workspace = construct_workspace(self) |
|---|
| 67 | |
|---|
| 68 | logger.debug('setting child windows dictionary') |
|---|
| 69 | |
|---|
| 70 | logger.debug('setting central widget to our workspace') |
|---|
| 71 | self.setCentralWidget(self.workspace) |
|---|
| 72 | |
|---|
| 73 | self.connect( |
|---|
| 74 | self.workspace, |
|---|
| 75 | QtCore.SIGNAL('subWindowActivated(QMdiSubWindow *)'), |
|---|
| 76 | self.updateMenus |
|---|
| 77 | ) |
|---|
| 78 | |
|---|
| 79 | logger.debug('creating navigation pane') |
|---|
| 80 | self.createNavigationPane() |
|---|
| 81 | |
|---|
| 82 | logger.debug('creating all the required actions') |
|---|
| 83 | self.createActions() |
|---|
| 84 | |
|---|
| 85 | logger.debug('creating the menus') |
|---|
| 86 | self.createMenus() |
|---|
| 87 | |
|---|
| 88 | logger.debug('creating the toolbars') |
|---|
| 89 | self.createToolBars() |
|---|
| 90 | |
|---|
| 91 | logger.debug('creating status bar') |
|---|
| 92 | self.createStatusBar() |
|---|
| 93 | |
|---|
| 94 | logger.debug('updating menus') |
|---|
| 95 | self.updateMenus() |
|---|
| 96 | |
|---|
| 97 | logger.debug('reading saved settings' ) |
|---|
| 98 | self.readSettings() |
|---|
| 99 | |
|---|
| 100 | logger.debug('setting up printer object') |
|---|
| 101 | self.printer = Printer() |
|---|
| 102 | |
|---|
| 103 | logger.debug('setting up window title') |
|---|
| 104 | self.setWindowTitle(self.app_admin.get_name()) |
|---|
| 105 | |
|---|
| 106 | #QtCore.QTimer.singleShot(0, self.doInitialization) |
|---|
| 107 | logger.debug('initialization complete') |
|---|
| 108 | |
|---|
| 109 | # Application settings |
|---|
| 110 | |
|---|
| 111 | def about(self): |
|---|
| 112 | logger.debug('showing about message box') |
|---|
| 113 | abtmsg = self.app_admin.get_about() |
|---|
| 114 | QtGui.QMessageBox.about(self, _('About'), _(abtmsg)) |
|---|
| 115 | logger.debug('about message closed') |
|---|
| 116 | |
|---|
| 117 | def readSettings(self): |
|---|
| 118 | # TODO: improve settings reading |
|---|
| 119 | settings = QtCore.QSettings() |
|---|
| 120 | self.restoreGeometry(settings.value('geometry').toByteArray()) |
|---|
| 121 | # Don't restore state, since it messes up the toolbar if stuff was |
|---|
| 122 | # added |
|---|
| 123 | # self.restoreState(settings.value('state').toByteArray()) |
|---|
| 124 | |
|---|
| 125 | def writeSettings(self): |
|---|
| 126 | # TODO: improve settings saving |
|---|
| 127 | logger.debug('writing application settings') |
|---|
| 128 | settings = QtCore.QSettings() |
|---|
| 129 | settings.setValue('geometry', QtCore.QVariant(self.saveGeometry())) |
|---|
| 130 | settings.setValue('state', QtCore.QVariant(self.saveState())) |
|---|
| 131 | logger.debug('settings written') |
|---|
| 132 | |
|---|
| 133 | def display_exception_message_box(self, exc_info): |
|---|
| 134 | from controls.exception import model_thread_exception_message_box |
|---|
| 135 | model_thread_exception_message_box(exc_info) |
|---|
| 136 | |
|---|
| 137 | def runAction(self, name, callable): |
|---|
| 138 | progress = QtGui.QProgressDialog('Please wait', QtCore.QString(), 0, 0) |
|---|
| 139 | progress.setWindowTitle(name) |
|---|
| 140 | progress.show() |
|---|
| 141 | post( |
|---|
| 142 | callable, |
|---|
| 143 | progress.close, |
|---|
| 144 | exception=self.display_exception_message_box |
|---|
| 145 | ) |
|---|
| 146 | |
|---|
| 147 | def createActions(self): |
|---|
| 148 | icon_save = Icon('tango/16x16/actions/document-save.png').fullpath() |
|---|
| 149 | icon_pgsetup = Icon('tango/16x16/actions/document-properties.png').fullpath() |
|---|
| 150 | icon_print = Icon('tango/16x16/actions/document-print.png').fullpath() |
|---|
| 151 | icon_preview = Icon('tango/16x16/actions/document-print-preview.png').fullpath() |
|---|
| 152 | icon_copy = Icon('tango/16x16/actions/edit-copy.png').fullpath() |
|---|
| 153 | |
|---|
| 154 | icon_new = Icon('tango/16x16/actions/document-new.png').fullpath() |
|---|
| 155 | icon_delete = Icon('tango/16x16/places/user-trash.png').fullpath() |
|---|
| 156 | |
|---|
| 157 | icon_gofirst = Icon('tango/16x16/actions/go-first.png').fullpath() |
|---|
| 158 | icon_golast = Icon('tango/16x16/actions/go-last.png').fullpath() |
|---|
| 159 | icon_gonext = Icon('tango/16x16/actions/go-next.png').fullpath() |
|---|
| 160 | icon_goprevious = Icon('tango/16x16/actions/go-previous.png').fullpath() |
|---|
| 161 | |
|---|
| 162 | icon_excel = Icon('tango/16x16/mimetypes/x-office-spreadsheet.png').fullpath() |
|---|
| 163 | icon_word = Icon('tango/16x16/mimetypes/x-office-document.png').fullpath() |
|---|
| 164 | icon_mail = Icon('tango/16x16/actions/mail-message-new.png').fullpath() |
|---|
| 165 | |
|---|
| 166 | icon_import = Icon('tango/16x16/mimetypes/text-x-generic.png').fullpath() |
|---|
| 167 | |
|---|
| 168 | icon_help = Icon('tango/16x16/apps/help-browser.png').fullpath() |
|---|
| 169 | |
|---|
| 170 | # TODO: change some of the status tips |
|---|
| 171 | self.saveAct = createAction( |
|---|
| 172 | parent=self, |
|---|
| 173 | text=_('&Save'), |
|---|
| 174 | slot=self.save, |
|---|
| 175 | shortcut=QtGui.QKeySequence.Save, |
|---|
| 176 | actionicon=icon_save, |
|---|
| 177 | tip=_('Save') |
|---|
| 178 | ) |
|---|
| 179 | |
|---|
| 180 | self.pageSetupAct = createAction( |
|---|
| 181 | parent=self, |
|---|
| 182 | text=_('Page Setup...'), |
|---|
| 183 | slot=self.pageSetup, |
|---|
| 184 | actionicon=icon_pgsetup, |
|---|
| 185 | tip=_('Page Setup...') |
|---|
| 186 | ) |
|---|
| 187 | |
|---|
| 188 | self.printAct = createAction( |
|---|
| 189 | parent=self, |
|---|
| 190 | text=_('Print...'), |
|---|
| 191 | slot=self.printDoc, |
|---|
| 192 | shortcut=QtGui.QKeySequence.Print, |
|---|
| 193 | actionicon=icon_print, |
|---|
| 194 | tip=_('Print...') |
|---|
| 195 | ) |
|---|
| 196 | |
|---|
| 197 | self.previewAct = createAction( |
|---|
| 198 | parent=self, |
|---|
| 199 | text=_('Print Preview'), |
|---|
| 200 | slot=self.previewDoc, |
|---|
| 201 | actionicon=icon_preview, |
|---|
| 202 | tip=_('Print Preview') |
|---|
| 203 | ) |
|---|
| 204 | |
|---|
| 205 | self.exitAct= createAction( |
|---|
| 206 | parent=self, |
|---|
| 207 | text=_('E&xit'), |
|---|
| 208 | slot=self.close, |
|---|
| 209 | tip=_('Exit the application') |
|---|
| 210 | ) |
|---|
| 211 | |
|---|
| 212 | self.copyAct = createAction( |
|---|
| 213 | parent=self, |
|---|
| 214 | text=_('&Copy'), |
|---|
| 215 | slot=self.copy, |
|---|
| 216 | shortcut=QtGui.QKeySequence.Copy, |
|---|
| 217 | actionicon=icon_copy, |
|---|
| 218 | tip=_("Duplicate the selected rows") |
|---|
| 219 | ) |
|---|
| 220 | |
|---|
| 221 | # BUG: there is a problem with setting a key sequence for closing |
|---|
| 222 | # a subwindow. PyQt adopts defaults from specific platforms |
|---|
| 223 | # but we want the sequence Ctrl+W on every platform. there- |
|---|
| 224 | # fore we set the string 'Ctrl+W', but PyQt defaults will |
|---|
| 225 | # still work. |
|---|
| 226 | self.closeAct = createAction( |
|---|
| 227 | parent=self, |
|---|
| 228 | text=_('Cl&ose'), |
|---|
| 229 | slot=self.workspace.closeActiveSubWindow, |
|---|
| 230 | shortcut='Ctrl+W', |
|---|
| 231 | tip=_('Close the active window') |
|---|
| 232 | ) |
|---|
| 233 | |
|---|
| 234 | self.closeAllAct = createAction( |
|---|
| 235 | parent=self, |
|---|
| 236 | text=_('Close &All'), |
|---|
| 237 | slot=self.workspace.closeAllSubWindows, |
|---|
| 238 | tip=_('Close all the windows') |
|---|
| 239 | ) |
|---|
| 240 | |
|---|
| 241 | self.cascadeAct = createAction( |
|---|
| 242 | parent=self, |
|---|
| 243 | text=_('&Cascade windows'), |
|---|
| 244 | slot=self.workspace.cascadeSubWindows, |
|---|
| 245 | tip=_('Arranges all the child windows in a cascade pattern.') |
|---|
| 246 | ) |
|---|
| 247 | |
|---|
| 248 | self.separatorAct = QtGui.QAction(self) |
|---|
| 249 | self.separatorAct.setSeparator(True) |
|---|
| 250 | |
|---|
| 251 | self.aboutAct = createAction( |
|---|
| 252 | parent=self, |
|---|
| 253 | text=_('&About'), |
|---|
| 254 | slot=self.about, |
|---|
| 255 | tip=_("Show the application's About box") |
|---|
| 256 | ) |
|---|
| 257 | |
|---|
| 258 | self.helpAct = createAction( |
|---|
| 259 | parent=self, |
|---|
| 260 | text=_('Help'), |
|---|
| 261 | slot=self.help, |
|---|
| 262 | shortcut=QtGui.QKeySequence.HelpContents, |
|---|
| 263 | actionicon=icon_help, |
|---|
| 264 | tip=_('Help content') |
|---|
| 265 | ) |
|---|
| 266 | |
|---|
| 267 | self.newAct = createAction( |
|---|
| 268 | parent=self, |
|---|
| 269 | text=_('New'), |
|---|
| 270 | slot=self.new, |
|---|
| 271 | shortcut=QtGui.QKeySequence.New, |
|---|
| 272 | actionicon=icon_new, |
|---|
| 273 | tip=_('New') |
|---|
| 274 | ) |
|---|
| 275 | |
|---|
| 276 | self.deleteAct = createAction( |
|---|
| 277 | parent=self, |
|---|
| 278 | text=_('Delete'), |
|---|
| 279 | slot=self.delete, |
|---|
| 280 | shortcut=QtGui.QKeySequence.Delete, |
|---|
| 281 | actionicon=icon_delete, |
|---|
| 282 | tip=_('Delete') |
|---|
| 283 | ) |
|---|
| 284 | |
|---|
| 285 | self.viewFirstAct = createAction( |
|---|
| 286 | parent=self, |
|---|
| 287 | text=_('First'), |
|---|
| 288 | slot=self.viewFirst, |
|---|
| 289 | shortcut=QtGui.QKeySequence.MoveToStartOfDocument, |
|---|
| 290 | actionicon=icon_gofirst, |
|---|
| 291 | tip=_('First') |
|---|
| 292 | ) |
|---|
| 293 | |
|---|
| 294 | self.viewLastAct = createAction( |
|---|
| 295 | parent=self, |
|---|
| 296 | text=_('Last'), |
|---|
| 297 | slot=self.viewLast, |
|---|
| 298 | shortcut=QtGui.QKeySequence.MoveToEndOfDocument, |
|---|
| 299 | actionicon=icon_golast, |
|---|
| 300 | tip=_('Last') |
|---|
| 301 | ) |
|---|
| 302 | |
|---|
| 303 | self.viewNextAct = createAction( |
|---|
| 304 | parent=self, |
|---|
| 305 | text=_('Next'), |
|---|
| 306 | slot=self.viewNext, |
|---|
| 307 | shortcut=QtGui.QKeySequence.MoveToNextPage, |
|---|
| 308 | actionicon=icon_gonext, |
|---|
| 309 | tip=_('Next') |
|---|
| 310 | ) |
|---|
| 311 | |
|---|
| 312 | self.viewPreviousAct = createAction( |
|---|
| 313 | parent=self, |
|---|
| 314 | text=_('Previous'), |
|---|
| 315 | slot=self.viewPrevious, |
|---|
| 316 | shortcut=QtGui.QKeySequence.MoveToPreviousPage, |
|---|
| 317 | actionicon=icon_goprevious, |
|---|
| 318 | tip=_('Previous') |
|---|
| 319 | ) |
|---|
| 320 | |
|---|
| 321 | if QT_MAJOR_VERSION > 4.3: |
|---|
| 322 | self.viewFirstAct.setIconVisibleInMenu(False) |
|---|
| 323 | self.viewLastAct.setIconVisibleInMenu(False) |
|---|
| 324 | self.viewNextAct.setIconVisibleInMenu(False) |
|---|
| 325 | self.viewPreviousAct.setIconVisibleInMenu(False) |
|---|
| 326 | |
|---|
| 327 | self.exportToExcelAct = createAction( |
|---|
| 328 | parent=self, |
|---|
| 329 | text=_('Export to MS Excel'), |
|---|
| 330 | slot=self.exportToExcel, |
|---|
| 331 | actionicon=icon_excel, |
|---|
| 332 | tip=_('Export to MS Excel') |
|---|
| 333 | ) |
|---|
| 334 | |
|---|
| 335 | self.exportToWordAct = createAction( |
|---|
| 336 | parent=self, |
|---|
| 337 | text=_('Export to MS Word'), |
|---|
| 338 | slot=self.exportToWord, |
|---|
| 339 | actionicon=icon_word, |
|---|
| 340 | tip=_('Export to MS Word') |
|---|
| 341 | ) |
|---|
| 342 | |
|---|
| 343 | self.exportToMailAct = createAction( |
|---|
| 344 | parent=self, |
|---|
| 345 | text=_('Send by e-mail'), |
|---|
| 346 | slot=self.exportToMail, |
|---|
| 347 | actionicon=icon_mail, |
|---|
| 348 | tip=_('Send by e-mail') |
|---|
| 349 | ) |
|---|
| 350 | |
|---|
| 351 | self.importFromFileAct = createAction( |
|---|
| 352 | parent=self, |
|---|
| 353 | text=_('Import from file'), |
|---|
| 354 | slot=self.importFromFile, |
|---|
| 355 | actionicon=icon_import, |
|---|
| 356 | tip=_('Import from file') |
|---|
| 357 | ) |
|---|
| 358 | |
|---|
| 359 | from camelot.action.refresh import SessionRefresh |
|---|
| 360 | |
|---|
| 361 | self.sessionRefreshAct = SessionRefresh(self) |
|---|
| 362 | |
|---|
| 363 | self.app_actions = [] |
|---|
| 364 | for action in self.app_admin.get_actions(): |
|---|
| 365 | |
|---|
| 366 | def bind_action(parent, action): |
|---|
| 367 | |
|---|
| 368 | def slot(*args): |
|---|
| 369 | action.run(parent) |
|---|
| 370 | |
|---|
| 371 | return slot |
|---|
| 372 | |
|---|
| 373 | self.app_actions.append( |
|---|
| 374 | createAction( |
|---|
| 375 | parent=self, |
|---|
| 376 | text=unicode(action.get_verbose_name()), |
|---|
| 377 | slot=bind_action(self, action), |
|---|
| 378 | actionicon=action.get_icon().getQIcon(), |
|---|
| 379 | tip=unicode(action.get_verbose_name()) |
|---|
| 380 | ) |
|---|
| 381 | ) |
|---|
| 382 | |
|---|
| 383 | # QAction slots and methods implementations |
|---|
| 384 | |
|---|
| 385 | def help(self): |
|---|
| 386 | TOP_LEVEL = None |
|---|
| 387 | self.view = QtWebKit.QWebView(TOP_LEVEL) |
|---|
| 388 | #print self.app_admin.get_help_url() |
|---|
| 389 | #print self.app_admin.get_help_base() |
|---|
| 390 | #index_file = open(self.app_admin.get_help_url(),'r') |
|---|
| 391 | #self.view.setHtml (index_file.read(), self.app_admin.get_help_base()) |
|---|
| 392 | self.view.load(self.app_admin.get_help_url()) |
|---|
| 393 | self.view.setWindowTitle(_('Help Browser')) |
|---|
| 394 | self.view.setWindowIcon(self.helpAct.icon()) |
|---|
| 395 | self.view.show() |
|---|
| 396 | |
|---|
| 397 | def save(self): |
|---|
| 398 | pass |
|---|
| 399 | |
|---|
| 400 | def saveAs(self): |
|---|
| 401 | pass |
|---|
| 402 | |
|---|
| 403 | def copy(self): |
|---|
| 404 | self.activeMdiChild().widget().copy_selected_rows() |
|---|
| 405 | |
|---|
| 406 | def printDoc(self): |
|---|
| 407 | self.previewDoc() |
|---|
| 408 | |
|---|
| 409 | def previewDoc(self): |
|---|
| 410 | active = self.activeMdiChild() |
|---|
| 411 | from camelot.admin.form_action import PrintHtmlFormAction |
|---|
| 412 | |
|---|
| 413 | class PrintPreview(PrintHtmlFormAction): |
|---|
| 414 | |
|---|
| 415 | def html(self, entity_getter): |
|---|
| 416 | return active.widget().toHtml() |
|---|
| 417 | |
|---|
| 418 | action = PrintPreview('Print Preview') |
|---|
| 419 | action.run(lambda:None) |
|---|
| 420 | |
|---|
| 421 | def new(self): |
|---|
| 422 | self.activeMdiChild().widget().newRow() |
|---|
| 423 | |
|---|
| 424 | def delete(self): |
|---|
| 425 | self.activeMdiChild().widget().deleteSelectedRows() |
|---|
| 426 | |
|---|
| 427 | def pageSetup(self): |
|---|
| 428 | pass |
|---|
| 429 | |
|---|
| 430 | def viewFirst(self): |
|---|
| 431 | """selects view's first row""" |
|---|
| 432 | active = self.activeMdiChild() |
|---|
| 433 | active.widget().viewFirst() |
|---|
| 434 | |
|---|
| 435 | def viewLast(self): |
|---|
| 436 | """selects view's last row""" |
|---|
| 437 | active = self.activeMdiChild() |
|---|
| 438 | active.widget().viewLast() |
|---|
| 439 | |
|---|
| 440 | def viewNext(self): |
|---|
| 441 | """selects view's next row""" |
|---|
| 442 | active = self.activeMdiChild() |
|---|
| 443 | active.widget().viewNext() |
|---|
| 444 | |
|---|
| 445 | def viewPrevious(self): |
|---|
| 446 | """selects view's previous row""" |
|---|
| 447 | active = self.activeMdiChild() |
|---|
| 448 | active.widget().viewPrevious() |
|---|
| 449 | |
|---|
| 450 | def exportToExcel(self): |
|---|
| 451 | """creates an excel file from the view""" |
|---|
| 452 | |
|---|
| 453 | def export(): |
|---|
| 454 | from export.excel import open_data_with_excel |
|---|
| 455 | title = self.activeMdiChild().widget().getTitle() |
|---|
| 456 | columns = self.activeMdiChild().widget().getColumns() |
|---|
| 457 | data = [d for d in self.activeMdiChild().widget().getData()] |
|---|
| 458 | open_data_with_excel(title, columns, data) |
|---|
| 459 | |
|---|
| 460 | post(export) |
|---|
| 461 | |
|---|
| 462 | def exportToWord(self): |
|---|
| 463 | """Use windows COM to export the active child window to MS word, |
|---|
| 464 | by using its toHtml function""" |
|---|
| 465 | |
|---|
| 466 | def export(): |
|---|
| 467 | from export.word import open_html_in_word |
|---|
| 468 | html = self.activeMdiChild().widget().toHtml() |
|---|
| 469 | open_html_in_word(html) |
|---|
| 470 | |
|---|
| 471 | post(export) |
|---|
| 472 | |
|---|
| 473 | def exportToMail(self): |
|---|
| 474 | |
|---|
| 475 | def export(): |
|---|
| 476 | from export.outlook import open_html_in_outlook |
|---|
| 477 | html = self.activeMdiChild().widget().toHtml() |
|---|
| 478 | open_html_in_outlook(html) |
|---|
| 479 | |
|---|
| 480 | post(export) |
|---|
| 481 | |
|---|
| 482 | def importFromFile(self): |
|---|
| 483 | self.activeMdiChild().widget().importFromFile() |
|---|
| 484 | |
|---|
| 485 | def createMenus(self): |
|---|
| 486 | |
|---|
| 487 | self.fileMenu = self.menuBar().addMenu(_('&File')) |
|---|
| 488 | addActions(self.fileMenu, ( |
|---|
| 489 | self.closeAct, |
|---|
| 490 | None, |
|---|
| 491 | self.saveAct, |
|---|
| 492 | None, |
|---|
| 493 | self.pageSetupAct, |
|---|
| 494 | self.previewAct, |
|---|
| 495 | self.printAct, |
|---|
| 496 | None |
|---|
| 497 | )) |
|---|
| 498 | |
|---|
| 499 | self.exportMenu = QtGui.QMenu(_('Export To')) |
|---|
| 500 | addActions(self.exportMenu, ( |
|---|
| 501 | self.exportToExcelAct, |
|---|
| 502 | self.exportToWordAct, |
|---|
| 503 | self.exportToMailAct, |
|---|
| 504 | )) |
|---|
| 505 | self.fileMenu.addMenu(self.exportMenu) |
|---|
| 506 | |
|---|
| 507 | self.importMenu = QtGui.QMenu(_('Import From')) |
|---|
| 508 | addActions(self.importMenu, (self.importFromFileAct,)) |
|---|
| 509 | self.fileMenu.addMenu(self.importMenu) |
|---|
| 510 | |
|---|
| 511 | addActions(self.fileMenu, (None, self.exitAct)) |
|---|
| 512 | |
|---|
| 513 | self.editMenu = self.menuBar().addMenu(_('&Edit')) |
|---|
| 514 | |
|---|
| 515 | addActions(self.editMenu, (self.copyAct,)) |
|---|
| 516 | |
|---|
| 517 | self.viewMenu = self.menuBar().addMenu(_('View')) |
|---|
| 518 | addActions(self.viewMenu, (self.sessionRefreshAct,)) |
|---|
| 519 | gotoMenu = self.viewMenu.addMenu(_('Go To')) |
|---|
| 520 | addActions(gotoMenu, ( |
|---|
| 521 | self.viewFirstAct, |
|---|
| 522 | self.viewPreviousAct, |
|---|
| 523 | self.viewNextAct, |
|---|
| 524 | self.viewLastAct |
|---|
| 525 | )) |
|---|
| 526 | self.windowMenu = self.menuBar().addMenu(_('&Window')) |
|---|
| 527 | self.connect( |
|---|
| 528 | self.windowMenu, |
|---|
| 529 | QtCore.SIGNAL('aboutToShow()'), |
|---|
| 530 | #self.updateWindowMenu |
|---|
| 531 | self.app_admin.update_window_menu(self) |
|---|
| 532 | ) |
|---|
| 533 | |
|---|
| 534 | self.menuBar().addSeparator() |
|---|
| 535 | |
|---|
| 536 | self.helpMenu = self.menuBar().addMenu(_('&Help')) |
|---|
| 537 | addActions(self.helpMenu, (self.helpAct, self.aboutAct)) |
|---|
| 538 | |
|---|
| 539 | def updateMenus(self): |
|---|
| 540 | hasMdiChild = (self.activeMdiChild() is not None) |
|---|
| 541 | self.saveAct.setEnabled(hasMdiChild) |
|---|
| 542 | self.closeAct.setEnabled(hasMdiChild) |
|---|
| 543 | |
|---|
| 544 | self.closeAllAct.setEnabled(hasMdiChild) |
|---|
| 545 | self.cascadeAct.setEnabled(hasMdiChild) |
|---|
| 546 | |
|---|
| 547 | self.pageSetupAct.setEnabled(hasMdiChild) |
|---|
| 548 | self.previewAct.setEnabled(hasMdiChild) |
|---|
| 549 | self.printAct.setEnabled(hasMdiChild) |
|---|
| 550 | |
|---|
| 551 | self.newAct.setEnabled(hasMdiChild) |
|---|
| 552 | self.deleteAct.setEnabled(hasMdiChild) |
|---|
| 553 | self.copyAct.setEnabled(hasMdiChild) |
|---|
| 554 | self.viewFirstAct.setEnabled(hasMdiChild) |
|---|
| 555 | self.viewPreviousAct.setEnabled(hasMdiChild) |
|---|
| 556 | self.viewNextAct.setEnabled(hasMdiChild) |
|---|
| 557 | self.viewLastAct.setEnabled(hasMdiChild) |
|---|
| 558 | |
|---|
| 559 | self.exportToWordAct.setEnabled(hasMdiChild) |
|---|
| 560 | self.exportToExcelAct.setEnabled(hasMdiChild) |
|---|
| 561 | self.exportToMailAct.setEnabled(hasMdiChild) |
|---|
| 562 | |
|---|
| 563 | self.importFromFileAct.setEnabled(hasMdiChild) |
|---|
| 564 | |
|---|
| 565 | self.separatorAct.setVisible(hasMdiChild) |
|---|
| 566 | |
|---|
| 567 | #def updateWindowMenu(self): |
|---|
| 568 | # self.windowMenu.clear() |
|---|
| 569 | # self.windowMenu.addAction(self.closeAllAct) |
|---|
| 570 | # self.windowMenu.addAction(self.cascadeAct) |
|---|
| 571 | # self.windowMenu.addAction(self.separatorAct) |
|---|
| 572 | |
|---|
| 573 | # windows = self.workspace.subWindowList() |
|---|
| 574 | |
|---|
| 575 | # self.separatorAct.setVisible(len(windows) != 0) |
|---|
| 576 | |
|---|
| 577 | # for i, child in enumerate(windows): |
|---|
| 578 | # title = child.windowTitle() |
|---|
| 579 | # if i < 9: |
|---|
| 580 | # text = _('&%s %s' % (i+1, title)) |
|---|
| 581 | # else: |
|---|
| 582 | # text = _('%s %s' % (i+1, title)) |
|---|
| 583 | |
|---|
| 584 | # action = self.windowMenu.addAction(text) |
|---|
| 585 | # action.setCheckable(True) |
|---|
| 586 | # action.setChecked(child == self.activeMdiChild()) |
|---|
| 587 | |
|---|
| 588 | # def create_window_activator(window): |
|---|
| 589 | |
|---|
| 590 | # def activate_window(): |
|---|
| 591 | # self.workspace.setActiveSubWindow(window) |
|---|
| 592 | |
|---|
| 593 | # return activate_window |
|---|
| 594 | |
|---|
| 595 | # self.connect( |
|---|
| 596 | # action, |
|---|
| 597 | # QtCore.SIGNAL('triggered()'), |
|---|
| 598 | # create_window_activator(child) |
|---|
| 599 | # ) |
|---|
| 600 | |
|---|
| 601 | # Toolbars |
|---|
| 602 | |
|---|
| 603 | def get_tool_bar(self): |
|---|
| 604 | return self.tool_bar |
|---|
| 605 | |
|---|
| 606 | def createToolBars(self): |
|---|
| 607 | # |
|---|
| 608 | # All actions are put in one toolbar, to ease unit testing and |
|---|
| 609 | # generation of screenshots |
|---|
| 610 | # |
|---|
| 611 | self.tool_bar = self.addToolBar(_('Toolbar')) |
|---|
| 612 | self.tool_bar.setObjectName('ToolBar') |
|---|
| 613 | self.tool_bar.setMovable(False) |
|---|
| 614 | self.tool_bar.setFloatable(False) |
|---|
| 615 | addActions(self.tool_bar, ( |
|---|
| 616 | self.newAct, |
|---|
| 617 | self.copyAct, |
|---|
| 618 | self.deleteAct, |
|---|
| 619 | self.viewFirstAct, |
|---|
| 620 | self.viewPreviousAct, |
|---|
| 621 | self.viewNextAct, |
|---|
| 622 | self.viewLastAct |
|---|
| 623 | )) |
|---|
| 624 | |
|---|
| 625 | addActions(self.tool_bar, ( |
|---|
| 626 | self.exportToExcelAct, |
|---|
| 627 | self.exportToWordAct, |
|---|
| 628 | self.exportToMailAct, |
|---|
| 629 | )) |
|---|
| 630 | |
|---|
| 631 | addActions(self.tool_bar, (self.printAct, self.previewAct)) |
|---|
| 632 | |
|---|
| 633 | addActions(self.tool_bar, (self.helpAct,)) |
|---|
| 634 | |
|---|
| 635 | if self.app_actions: |
|---|
| 636 | addActions(self.tool_bar, self.app_actions) |
|---|
| 637 | |
|---|
| 638 | # Navigation Pane |
|---|
| 639 | |
|---|
| 640 | def createNavigationPane(self): |
|---|
| 641 | self.navpane = NavigationPane(self.app_admin, parent=self) |
|---|
| 642 | self.addDockWidget(Qt.LeftDockWidgetArea, self.navpane) |
|---|
| 643 | |
|---|
| 644 | self.connect( |
|---|
| 645 | self.navpane.treewidget, |
|---|
| 646 | QtCore.SIGNAL('itemClicked(QTreeWidgetItem *, int)'), |
|---|
| 647 | self.createMdiChild |
|---|
| 648 | ) |
|---|
| 649 | |
|---|
| 650 | # Interface for child windows |
|---|
| 651 | |
|---|
| 652 | def createMdiChild(self, item): |
|---|
| 653 | index = self.navpane.treewidget.indexFromItem(item) |
|---|
| 654 | section_item = self.navpane.items[index.row()] |
|---|
| 655 | child = section_item.get_action().run(self.workspace) |
|---|
| 656 | assert child != None |
|---|
| 657 | subwindow = self.workspace.addSubWindow(child) |
|---|
| 658 | subwindow.showMaximized() |
|---|
| 659 | |
|---|
| 660 | def activeMdiChild(self): |
|---|
| 661 | return self.workspace.activeSubWindow() |
|---|
| 662 | |
|---|
| 663 | # Statusbar |
|---|
| 664 | |
|---|
| 665 | def createStatusBar(self): |
|---|
| 666 | from controls.statusbar import StatusBar |
|---|
| 667 | statusbar = StatusBar(self) |
|---|
| 668 | self.setStatusBar(statusbar) |
|---|
| 669 | statusbar.showMessage(_('Ready'), 5000) |
|---|
| 670 | |
|---|
| 671 | # Events |
|---|
| 672 | |
|---|
| 673 | def closeEvent(self, event): |
|---|
| 674 | self.workspace.closeAllSubWindows() |
|---|
| 675 | if self.activeMdiChild(): |
|---|
| 676 | event.ignore() |
|---|
| 677 | else: |
|---|
| 678 | self.writeSettings() |
|---|
| 679 | event.accept() |
|---|