mainwindow.py :  » GUI » Sketch » skencil-0.6.17 » Sketch » UI » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » GUI » Sketch 
Sketch » skencil 0.6.17 » Sketch » UI » mainwindow.py
# Sketch - A Python-based interactive drawing program
# Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 by Bernhard Herzog
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

import os, sys, string
from types import TupleType,ListType

from Sketch.Lib import util
from Sketch.warn import warn,warn_tb,INTERNAL,USER
from Sketch import _,config,load,plugins,SketchVersion
from Sketch import Publisher,Point,EmptyFillStyle,EmptyLineStyle,\
     EmptyPattern, Document, GuideLine, PostScriptDevice, SketchError
import Sketch
from Sketch.Graphics import image,eps
import Sketch.Scripting

from Sketch.const import DOCUMENT,CLIPBOARD,CLOSED,COLOR1,COLOR2
from Sketch.const import STATE,VIEW,MODE,SELECTION,POSITION,UNDO,EDITED,\
     CURRENTINFO

from Tkinter import TclVersion,TkVersion,Frame,Scrollbar
from Tkinter import X,BOTTOM,BOTH,TOP,HORIZONTAL,LEFT,Y
import Tkinter
from tkext import AppendMenu,UpdatedLabel,UpdatedButton,CommandButton,\
     CommandCheckbutton, MakeCommand, MultiButton
import tkext

from command import CommandClass,Keymap,Commands

from canvas import SketchCanvas
import ruler
from poslabel import PositionLabel
import palette, tooltips

import skpixmaps
pixmaps = skpixmaps.PixmapTk

import skapp



command_list = []

def AddCmd(name, menu_name, method_name = None, **kw):
    kw['menu_name'] = menu_name
    if not method_name:
  method_name = name
    cmd = apply(CommandClass, (name, method_name), kw)
    command_list.append(cmd)

def AddDocCmd(name, menu_name, method_name = None, **kw):
    kw['menu_name'] = menu_name
    if not method_name:
  method_name = name
    method_name = ('document', method_name)
    for key in CommandClass.callable_attributes:
  if kw.has_key(key):
      value = kw[key]
      if type(value) == type(""):
    kw[key] = ('document', value)
    if not kw.has_key('subscribe_to'):
  kw['subscribe_to'] = SELECTION
    if not kw.has_key('sensitive_cb'):
  kw['sensitive_cb'] = ('document', 'HasSelection')
    cmd = apply(CommandClass, (name, method_name), kw)
    command_list.append(cmd)


class SketchMainWindow(Publisher):

    tk_basename = 'sketch'
    tk_class_name = 'Sketch'

    def __init__(self, application, filename, run_script = None):
  self.application = application
  self.root = application.root # XXX
  self.filename = filename
        self.run_script = run_script
  self.canvas = None
  self.document = None
  self.commands = None
  self.NewDocument()
  self.create_commands()
  self.build_window()
  self.build_menu()
  self.build_toolbar()
  self.build_status_bar()
  self.__init_dlgs()

    def issue_document(self):
  self.issue(DOCUMENT, self.document)

    def create_commands(self):
  cmds = Commands()
  keymap = Keymap()
  for cmd_class in command_list:
      cmd = cmd_class.InstantiateFor(self)
      setattr(cmds, cmd.name, cmd)
      keymap.AddCommand(cmd)
  self.commands = cmds
  self.commands.Update()
  self.keymap = keymap

    def MapKeystroke(self, stroke):
  return self.keymap.MapKeystroke(stroke)

    def save_doc_if_edited(self, title = _("Save Document")):
  if self.document is not None and self.document.WasEdited():
      message = _("%s has been changed.\nDo you want to save it?") \
          % self.document.meta.filename
      result = self.application.MessageBox(title = title,
             message = message,
             buttons = tkext.YesNoCancel)
      if result == tkext.Yes:
    self.SaveToFileInteractive()
      return result
  return tkext.No

    def Document(self):
  return self.document

    def SetDocument(self, document):
  channels = (SELECTION, UNDO, MODE)
  old_doc = self.document
  if old_doc is not None:
      for channel in channels:
    old_doc.Unsubscribe(channel, self.issue, channel)
  self.document = document
  for channel in channels:
      self.document.Subscribe(channel, self.issue, channel)
  if self.canvas is not None:
      self.canvas.SetDocument(document)
  self.issue_document()
  # issue_document has to be called before old_doc is destroyed,
  # because destroying it causes all connections to be deleted and
  # some dialogs (derived from SketchDlg) try to unsubscribe in
  # response to our DOCUMENT message. The connector currently
  # raises an exception in this case. Perhaps it should silently
  # ignore Unsubscribe() calls with methods that are actually not
  # subscribers (any more)
  if old_doc is not None:
      old_doc.Destroy()
  self.set_window_title()
  if self.commands:
      self.commands.Update()

    AddCmd('NewDocument', _("New"), bitmap = pixmaps.NewDocument)
    def NewDocument(self):
  if self.save_doc_if_edited(_("New Document")) == tkext.Cancel:
      return
  self.SetDocument(Document(create_layer = 1))

    AddCmd('LoadFromFile', _("Open..."), bitmap = pixmaps.Open,
     key_stroke = 'C-o')
    AddCmd('LoadMRU0', '', 'LoadFromFile', args = 0, key_stroke = 'M-1',
     name_cb = lambda: os.path.split(config.preferences.mru_files[0])[1])
    AddCmd('LoadMRU1', '', 'LoadFromFile', args = 1, key_stroke = 'M-2',
     name_cb = lambda: os.path.split(config.preferences.mru_files[1])[1])
    AddCmd('LoadMRU2', '', 'LoadFromFile', args = 2, key_stroke = 'M-3',
     name_cb = lambda: os.path.split(config.preferences.mru_files[2])[1])
    AddCmd('LoadMRU3', '', 'LoadFromFile', args = 3, key_stroke = 'M-4',
     name_cb = lambda: os.path.split(config.preferences.mru_files[3])[1])
    def LoadFromFile(self, filename = None, directory = None):
  app = self.application
  if self.save_doc_if_edited(_("Open Document")) == tkext.Cancel:
      return
  if type(filename) == type(0):
      filename = config.preferences.mru_files[filename]
  if not filename:
            if not directory:
                directory = self.document.meta.directory
      if not directory:
    directory = os.getcwd()
      name = ''
      filename = app.GetOpenFilename(filetypes = skapp.openfiletypes(),
             initialdir = directory,
             initialfile = name)
      if not filename:
    return

  try:
      if not os.path.isabs(filename):
    filename = os.path.join(os.getcwd(), filename)
      doc = load.load_drawing(filename)
      self.SetDocument(doc)
      self.add_mru_file(filename)
  except SketchError, value:
      app.MessageBox(title = _("Open"),
         message = _("An error occurred:\n") + str(value))
      #warn_tb(USER, "An error occurred:\n", str(value))
      self.remove_mru_file(filename)
  else:
      messages = doc.meta.load_messages
      if messages:
    app.MessageBox(title = _("Open"),
             message=_("Warnings from the import filter:\n")
             + messages)
      doc.meta.load_messages = ''


    AddCmd('SaveToFile', _("Save"), 'SaveToFileInteractive',
     bitmap = pixmaps.Save, key_stroke = ('C-s', 'F2'))
    AddCmd('SaveToFileAs', _("Save As..."), 'SaveToFileInteractive', args = 1,
     key_stroke = ('C-w', 'F3'))
    def SaveToFileInteractive(self, use_dialog = 0):
  filename =  self.document.meta.fullpathname
  native_format = self.document.meta.native_format
  compressed_file = self.document.meta.compressed_file
  compressed = self.document.meta.compressed
  app = self.application
  if use_dialog or not filename or not native_format:
      dir = self.document.meta.directory
      if not dir:
    dir = os.getcwd()
      name = self.document.meta.filename
      basename, ext = os.path.splitext(name)
      if not native_format:
    name = basename + '.sk'
      filename = app.GetSaveFilename(filetypes = skapp.savefiletypes(),
             initialdir = dir,
             initialfile = name)
      if not filename:
    return
      extension = os.path.splitext(filename)[1]
      fileformat = plugins.guess_export_plugin(extension)
      if not fileformat:
    fileformat = plugins.NativeFormat
      compressed_file = '' # guess compression from filename
            compressed = ''
  else:
      fileformat = plugins.NativeFormat
  self.SaveToFile(filename, fileformat, compressed, compressed_file)

    def SaveToFile(self, filename, fileformat = None, compressed = '',
                   compressed_file = ''):
  app = self.application
  try:
      if not self.document.meta.backup_created:
    try:
        if compressed_file:
      util.make_backup(compressed_file)
        else:
      util.make_backup(filename)
    except util.BackupError, value:
        backupfile = value.filename
        strerror = value.strerror
        msg = (_("Cannot create backup file %(filename)s:\n"
           "%(message)s\n"
           "Choose `continue' to try saving anyway,\n"
           "or `cancel' to cancel.")
         % {'filename':`backupfile`, 'message':strerror})
        cancel = _("Cancel")
        result = app.MessageBox(title = _("Save To File"),
              message = msg, icon = 'warning',
              buttons = (_("Continue"), cancel))
        if result == cancel:
      return

    self.document.meta.backup_created = 1
      if fileformat is None:
    fileformat = plugins.NativeFormat
      try:
    saver = plugins.find_export_plugin(fileformat)
    if compressed:
        # XXX there should be a plugin interface for this kind
        # of post-processing
                    if compressed == "gzip":
                        cmd = 'gzip -c -9 > ' + util.sh_quote(compressed_file)
                    elif compressed == "bzip2":
                        cmd = 'bzip2 > ' + util.sh_quote(compressed_file)
                    file = os.popen(cmd, 'w')
                    saver(self.document, filename, file = file)
    else:
        saver(self.document, filename)
      finally:
    saver.UnloadPlugin()
  except IOError, value:
      if type(value) == type(()):
    value = value[1]
      app.MessageBox(title = _("Save To File"),
         message = _("Cannot save %(filename)s:\n"
               "%(message)s") \
         % {'filename':`os.path.split(filename)[1]`,
            'message':value},
         icon = 'warning')
      self.remove_mru_file(filename)
      return

  if fileformat == plugins.NativeFormat:
      dir, name = os.path.split(filename)
      # XXX should meta.directory be set for non-native formats as well
      self.document.meta.directory = dir
      self.document.meta.filename = name
      self.document.meta.fullpathname = filename
      self.document.meta.file_type = plugins.NativeFormat
      self.document.meta.native_format = 1
  if not compressed_file:
      self.document.meta.compressed_file = ''
      self.document.meta.compressed = ''
  if compressed_file:
      self.add_mru_file(compressed_file)
  else:
      self.add_mru_file(filename)

  self.set_window_title()



    AddCmd('SavePS', _("Save as PostScript..."), key_stroke = 'M-p')
    def SavePS(self, filename = None):
        app = self.application
        bbox = self.document.BoundingRect(visible = 0, printable = 1)
        if bbox is None:
            app.MessageBox(title = _("Save As PostScript"),
                           message = _("The document doesn't have "
                                       "any printable layers."),
                           icon = "warning")
            return
  if not filename:
      dir = self.document.meta.ps_directory
      if not dir:
    dir = self.document.meta.directory
      if not dir:
    dir = os.getcwd()
      name = self.document.meta.filename
      name, ext = os.path.splitext(name)
      name = name + '.ps'
      filename = app.GetSaveFilename(title = _("Save As PostScript"),
             filetypes = skapp.psfiletypes,
             initialdir = dir,
             initialfile = name)
      if not filename:
    return
        try:
            ps_dev = PostScriptDevice(filename, as_eps = 1,
                                      bounding_box = tuple(bbox),
                                      For = util.get_real_username(),
                                      CreationDate = util.current_date(),
                                      Title = os.path.basename(filename),
                                      document = self.document)
            self.document.Draw(ps_dev)
            ps_dev.Close()
            self.document.meta.ps_directory = os.path.split(filename)[0]
        except IOError, value:
            app.MessageBox(title = _("Save As PostScript"),
                           message = _("Cannot save %(filename)s:\n"
                                   "%(message)s") \
                           % {'filename':`os.path.split(filename)[1]`,
                              'message':value[1]},
                           icon = 'warning')

    def add_mru_file(self, filename):
  if filename:
      config.add_mru_file(filename)
      self.update_mru_files()

    def remove_mru_file(self, filename):
  if filename:
      config.remove_mru_file(filename)
      self.update_mru_files()

    def update_mru_files(self):
  self.commands.LoadMRU0.Update()
  self.commands.LoadMRU1.Update()
  self.commands.LoadMRU2.Update()
  self.commands.LoadMRU3.Update()
  self.file_menu.RebuildMenu()

    AddCmd('InsertFile', _("Insert Document..."))
    def InsertFile(self, filename = None):
  app = self.application
  if not filename:
      dir = self.document.meta.directory
      if not dir:
    dir = os.getcwd()
      name = ''
      filename = app.GetOpenFilename(filetypes = skapp.openfiletypes(),
             initialdir = dir,
             initialfile = name)
      if not filename:
    return

  try:
      if not os.path.isabs(filename):
    filename = os.path.join(os.getcwd(), filename)
      doc = load.load_drawing(filename)
      group = doc.as_group()
  except SketchError, value:
      app.MessageBox(title = _("Insert Document"),
         message = _("An error occurred:\n") + str(value))
      #warn_tb(USER, "An error occurred:\n", str(value))
      self.remove_mru_file(filename)
  else:
      messages = doc.meta.load_messages
      if messages:
    app.MessageBox(title = _("Insert Document"),
             message=_("Warnings from the import filter:\n")
             + messages)
      doc.meta.load_messages = ''
  #
  if group is not None:
      self.canvas.PlaceObject(group)
  else:
      app.MessageBox(title = _("Insert Document"),
         message=_("The document is empty"))


    AddCmd('LoadPalette', _("Load Palette..."))
    def LoadPalette(self, filename = None):
  if not filename:
      dir = config.std_res_dir
      if not dir:
    dir = os.getcwd()
      name = ''
      filename = self.application.GetOpenFilename(
    filetypes = palette.file_types,
    initialdir = dir,
    initialfile = name)
      if not filename:
    return

  pal = palette.LoadPalette(filename)
  if not pal:
      self.application.MessageBox(title = _("Load Palette"),
             message = _("Cannot load palette %(filename)s")
          % {'filename': filename})
  else:
      self.palette.SetPalette(pal)
      # XXX Should we just store the basename if the palette file
      # is located in the resource_dir?
      config.preferences.palette = filename

    def __init_dlgs(self):
  self.dialogs = {}

    def CreateDialog(self, module, dlgname):
  if self.dialogs.has_key(dlgname):
      dialog = self.dialogs[dlgname]
      dialog.deiconify_and_raise()
  else:
      exec "from %s import %s" % (module, dlgname)
      dlgclass = locals()[dlgname]
      dialog = dlgclass(self.root, self, self.document)
      dialog.Subscribe(CLOSED, self.__dlg_closed, dlgname)
      self.dialogs[dlgname] = dialog

    def HideDialogs(self):
  for dialog in self.dialogs.values():
      dialog.withdraw()
    AddCmd('HideDialogs', _("Hide Dialogs"))

    def ShowDialogs(self):
  for dialog in self.dialogs.values():
      dialog.deiconify_and_raise()
    AddCmd('ShowDialogs', _("Show Dialogs"))

    def __dlg_closed(self, dialog, name):
  try:
      del self.dialogs[name]
  except:
      # This might happen if the dialog is buggy...
      warn(INTERNAL, 'dialog %s alread removed from dialog list', name)

    AddCmd('CreateLayerDialog', _("Layers..."),
     'CreateDialog', args = ('layerdlg', 'LayerPanel'),
     key_stroke = 'F5')
    AddCmd('CreateAlignDialog', _("Align..."),
     'CreateDialog', args = ('aligndlg', 'AlignPanel'))
    AddCmd('CreateGridDialog', _("Grid..."),
     'CreateDialog', args = ('griddlg', 'GridPanel'))
    AddCmd('CreateLineStyleDialog', _("Line..."),
     'CreateDialog', args = ('linedlg', 'LinePanel'),
     key_stroke = 'F7')
    AddCmd('CreateFillStyleDialog', _("Fill..."),
     'CreateDialog', args = ('filldlg', 'FillPanel'),
     key_stroke = 'F6')
    AddCmd('CreateFontDialog', _("Font..."),
     'CreateDialog', args = ('fontdlg', 'FontPanel'))
    AddCmd('CreateStyleDialog', _("Styles..."),
     'CreateDialog', args = ('styledlg', 'StylePanel'))
    AddCmd('CreateBlendDialog', _("Blend..."),
     'CreateDialog', args = ('blenddlg', 'BlendPanel'),
     key_stroke = 'C-b')
    AddCmd('CreateLayoutDialog', _("Page Layout..."),
     'CreateDialog', args = ('layoutdlg', 'LayoutPanel'))
    #AddCmd('CreateExportDialog', 'Export...',
#     'CreateDialog', args = ('export', 'ExportPanel'))
    AddCmd('CreateCurveDialog', _("Curve Commands..."),
     'CreateDialog', args = ('curvedlg', 'CurvePanel'))
    AddCmd('CreateGuideDialog', _("Guide Lines..."),
     'CreateDialog', args = ('guidedlg', 'GuidePanel'))
    AddCmd('CreatePrintDialog', _("Print..."),
     'CreateDialog', args = ('printdlg', 'PrintPanel'),
     key_stroke = "C-p")

    AddCmd('CreateReloadPanel', _("Reload Module..."),
     'CreateDialog', args = ('reloaddlg', 'ReloadPanel'))

    def CreatePluginDialog(self, info):
        if info.HasCustomDialog():
            dialog = info.CreateCustomDialog(self.root, self, self.document)
        else:
            from plugindlg import PluginPanel
            dialog = PluginPanel(self.root, self, self.document, info)
        dialog.Subscribe(CLOSED, self.__dlg_closed, info.class_name)
        self.dialogs[info.class_name] = dialog

    AddCmd('SetOptions', _("Options..."))
    def SetOptions(self):
  import optiondlg
  optiondlg.OptionDialog(self.root, self.canvas)

    def set_window_title(self):
  self.root.client(util.gethostname())
  if self.document:
      appname = config.name
      meta = self.document.meta
      if meta.compressed:
    docname = os.path.split(meta.compressed_file)[1]
    docname = os.path.splitext(docname)[0]
      else:
    docname = self.document.meta.filename
      title = config.preferences.window_title_template % locals()
      command = (config.sketch_command, self.document.meta.fullpathname)
  else:
      title = config.name
      command = (config.sketch_command, )
  self.root.title(title)
  self.root.command(command)

    def UpdateCommands(self):
  self.canvas.UpdateCommands()

    def Run(self):
  #self.root.wait_visibility(self.canvas)
  if self.filename:
            if os.path.isdir(self.filename):
                filename = ''
                directory = self.filename
            else:
                filename = self.filename
                directory = ''
            self.LoadFromFile(filename, directory = directory)
      self.filename = ''
        if self.run_script:
            from Sketch.Scripting.script import Context
            dict = {'context': Context()}
            try:
                execfile(self.run_script, dict)
            except:
                warn_tb(USER, _("Error running script `%s'"), self.run_script)
  self.application.Mainloop()

    AddCmd('Exit', _("Exit"), key_stroke = ('M-Q', 'M-F4'))
    def Exit(self):
  if self.save_doc_if_edited(_("Exit")) != tkext.Cancel:
      self.commands = None
      self.application.Exit()

    def build_window(self):
  root = self.application.root
  self.mbar = Frame(root, name = 'menubar')
  self.mbar.pack(fill=X)
  self.tbar = Frame(root, name = 'toolbar')
  self.tbar.pack(fill=X)

  self.status_bar = Frame(root, name = 'statusbar')
  self.status_bar.pack(side = BOTTOM, fill=X)

  palette_frame = Frame(root, name = 'palette_frame')
  palette_frame.pack(side = BOTTOM, fill = X)

  frame = Frame(root, name = 'canvas_frame')
  frame.pack(side = TOP, fill = BOTH, expand = 1)
  vbar = Scrollbar(frame)
  vbar.grid(in_ = frame, column = 2, row = 1, sticky = 'ns')
  hbar = Scrollbar(frame, orient = HORIZONTAL)
  hbar.grid(in_ = frame, column = 1, row = 2, sticky = 'ew')
  hrule = ruler.Ruler(root, orient = ruler.HORIZONTAL)
  hrule.grid(in_ = frame, column = 1, row = 0, sticky = 'ew',
       columnspan = 2)
  vrule = ruler.Ruler(root, orient = ruler.VERTICAL)
  vrule.grid(in_ = frame, column = 0, row = 1, sticky = 'ns',
       rowspan = 2)
  tmp = Frame(frame, name = 'rulercorner')
  tmp.grid(column = 0, row = 0, sticky = 'news')

  resolution = config.preferences.screen_resolution
  self.canvas = SketchCanvas(root, toplevel = root,
           background = 'white', name = 'canvas',
           resolution = resolution, main_window = self,
           document = self.document)
  self.canvas.grid(in_ = frame, column = 1, row = 1, sticky = 'news')
  self.canvas.focus()
  self.canvas.SetScrollbars(hbar, vbar)
  self.canvas.SetRulers(hrule, vrule)
  hrule.SetCanvas(self.canvas)
  vrule.SetCanvas(self.canvas)
  frame.columnconfigure(0, weight = 0)
  frame.columnconfigure(1, weight = 1)
  frame.columnconfigure(2, weight = 0)
  frame.rowconfigure(0, weight = 0)
  frame.rowconfigure(1, weight = 1)
  frame.rowconfigure(2, weight = 0)
  hbar['command'] = self.canvas._w + ' xview'
  vbar['command'] = self.canvas._w + ' yview'

  # the palette
        button = MultiButton(palette_frame, bitmap = pixmaps.NoPattern,
                             command = self.no_pattern, args = 'fill')
        button.pack(side = LEFT)
        button.Subscribe('COMMAND2', self.no_pattern, 'line')
        
  pal = palette.GetStandardPalette()

  self.palette = palette.PaletteWidget(palette_frame, pal)
  ScrollXUnits = self.palette.ScrollXUnits
  ScrollXPages = self.palette.ScrollXPages
  CanScrollLeft = self.palette.CanScrollLeft
  CanScrollRight = self.palette.CanScrollRight
  for bitmap, command, args, sensitivecb in [
      (pixmaps.ArrArrLeft, ScrollXPages, -1, CanScrollLeft),
      (pixmaps.ArrLeft, ScrollXUnits, -1, CanScrollLeft),
      (pixmaps.ArrRight, ScrollXUnits, +1, CanScrollRight),
      (pixmaps.ArrArrRight, ScrollXPages, +1, CanScrollRight)]:
      button = UpdatedButton(palette_frame, bitmap = bitmap,
           command = command, args = args,
           sensitivecb = sensitivecb)
      button.pack(side = LEFT)
      self.palette.Subscribe(VIEW, button.Update)
      if bitmap == pixmaps.ArrLeft:
    self.palette.pack(side = LEFT, fill = X, expand = 1)

  self.palette.Subscribe(COLOR1, self.canvas.FillSolid)
  self.palette.Subscribe(COLOR2, self.canvas.LineColor)
  root.protocol('WM_DELETE_WINDOW', tkext.MakeMethodCommand(self.Exit))


    def make_file_menu(self):
  cmds = self.commands
  return map(MakeCommand,
       [cmds.NewDocument,
        cmds.LoadFromFile,
        cmds.SaveToFile,
        cmds.SaveToFileAs,
        cmds.SavePS,
        cmds.CreatePrintDialog,
        None,
        cmds.InsertFile,
        #cmds.CreateExportDialog,
        None,
        cmds.SetOptions,
        cmds.AboutBox,
        None,
        cmds.LoadMRU0,
        cmds.LoadMRU1,
        cmds.LoadMRU2,
        cmds.LoadMRU3,
        None,
        cmds.Exit])

    def make_edit_menu(self):
  cmds = self.canvas.commands
  return map(MakeCommand,
       [self.commands.Undo,
        self.commands.Redo,
        self.commands.ResetUndo,
        None,
        self.commands.CopySelected,
        self.commands.CutSelected,
        self.commands.PasteClipboard,
        self.commands.RemoveSelected,
        None,
        self.commands.SelectAll,
        None,
        self.commands.DuplicateSelected,
        None,
        [(_("Create"), {'auto_rebuild':self.creation_entries}),
         []],
        None,
        cmds.SelectionMode, cmds.EditMode,
        ])

    def creation_entries(self):
  cmds = self.canvas.commands
  entries = [cmds.CreateRectangle,
       cmds.CreateEllipse,
       cmds.CreatePolyBezier,
       cmds.CreatePolyLine,
       cmds.CreateSimpleText,
       self.commands.CreateImage,
       None]
  items = plugins.object_plugins.items()
  items.sort()
  place = self.place_plugin_object
  dialog = self.CreatePluginDialog
        group = self.create_plugin_group
  for name, plugin in items:
            if plugin.UsesSelection():
                entries.append((plugin.menu_text, group, plugin))
      elif plugin.HasParameters() or plugin.HasCustomDialog():
    entries.append((plugin.menu_text + '...', dialog, plugin))
      else:
    entries.append((plugin.menu_text, place, plugin))
  return map(MakeCommand, entries)

    def place_plugin_object(self, info):
  self.canvas.PlaceObject(info())

    def create_plugin_group(self, info):
        self.document.group_selected(info.menu_text, info.CallFactory)

    def PlaceObject(self, object):
        self.canvas.PlaceObject(object)

    def make_effects_menu(self):
  return map(MakeCommand,
       [self.commands.FlipHorizontal,
        self.commands.FlipVertical,
        None,
        self.commands.RemoveTransformation,
        None,
        self.commands.CreateBlendDialog,
        self.commands.CancelBlend,
        None,
        self.commands.CreateMaskGroup,
        self.commands.CreatePathText,
        ])

    def make_curve_menu(self):
  canvas = self.canvas
  cmds = self.canvas.commands.PolyBezierEditor
  return map(MakeCommand,
       [cmds.ContAngle,
        cmds.ContSmooth,
        cmds.ContSymmetrical,
        cmds.SegmentsToLines,
        cmds.SegmentsToCurve,
        cmds.SelectAllNodes,
        None,
        cmds.DeleteNodes,
        cmds.InsertNodes,
        None,
        cmds.CloseNodes,
        cmds.OpenNodes,
        None,
        self.commands.CombineBeziers,
        self.commands.SplitBeziers,
        None,
        self.commands.ConvertToCurve])

    def make_view_menu(self):
  def MakeEntry(scale, call = self.canvas.SetScale):
      percent = int(100 * scale)
      return (('%3d%%' % percent), call, scale)
  cmds = self.canvas.commands
  scale = map(MakeEntry, [ 0.125, 0.25, 0.5, 1, 2, 4, 8])
  return map(MakeCommand,
       [MakeEntry(1),
        [_("Zoom")] + scale,
                    cmds.ZoomIn,
                    cmds.ZoomOut,
        cmds.ZoomMode,
        None,
        cmds.FitToWindow,
        cmds.FitSelectedToWindow,
        cmds.FitPageToWindow,
        cmds.RestoreViewport,
        None,
        cmds.ForceRedraw,
        None,
        cmds.ToggleOutlineMode,
        cmds.TogglePageOutlineMode,
                    None,
        cmds.ToggleCrosshairs,
        None,
        self.commands.LoadPalette
        ])

    def make_arrange_menu(self):
        commands = [self.commands.CreateAlignDialog,
        None,
        self.commands.MoveSelectedToTop,
        self.commands.MoveSelectedToBottom,
        self.commands.MoveSelectionUp,
        self.commands.MoveSelectionDown,
        None,
        self.commands.AbutHorizontal,
        self.commands.AbutVertical,
        None,
        self.commands.GroupSelected,
        self.commands.UngroupSelected,
        None,
        self.canvas.commands.ToggleSnapToObjects,
        self.canvas.commands.ToggleSnapToGrid,
        self.commands.CreateGridDialog,
        None,
        self.canvas.commands.ToggleSnapToGuides,
        self.commands.AddHorizGuideLine,
        self.commands.AddVertGuideLine,
        self.commands.CreateGuideDialog]
        if config.preferences.show_advanced_snap_commands:
            commands.append(None)
            commands.append(self.canvas.commands.ToggleSnapMoveRelative)
            commands.append(self.canvas.commands.ToggleSnapBoundingRect)
        commands = commands + [None,
                               self.commands.CreateLayoutDialog
                               ]
        return map(MakeCommand, commands)

    def make_style_menu(self):
  return map(MakeCommand,
       [self.commands.FillNone,
        self.commands.CreateFillStyleDialog,
        self.canvas.commands.FillSolid,
        None,
        self.commands.LineNone,
        self.commands.CreateLineStyleDialog,
        None,
        self.commands.CreateStyleFromSelection,
        self.commands.CreateStyleDialog,
        self.commands.UpdateStyle,
        None,
        self.commands.CreateFontDialog
        ])

    def make_window_menu(self):
  cmds = self.commands
  return map(MakeCommand,
       [cmds.HideDialogs,
        cmds.ShowDialogs,
        None,
        cmds.CreateLayerDialog,
        cmds.CreateAlignDialog,
        cmds.CreateGridDialog,
        None,
        cmds.CreateLineStyleDialog,
        cmds.CreateFillStyleDialog,
        cmds.CreateFontDialog,
        cmds.CreateStyleDialog,
        None,
        cmds.CreateLayoutDialog,
        None,
        cmds.CreateBlendDialog,
        cmds.CreateCurveDialog
        ])

    def make_special_menu(self):
  cmdlist = [self.commands.python_prompt,
       self.commands.CreateReloadPanel,
       self.commands.DocumentInfo,
       None,
       self.commands.DumpXImage,
       self.commands.CreateClone,
       #self.commands.export_bitmap,
       ]
  Sketch.Issue(None, Sketch.const.ADD_TO_SPECIAL_MENU, cmdlist)
  return map(MakeCommand, cmdlist)

    def make_script_menu(self):
        tree = Sketch.Scripting.Registry.MenuTree()
        cmdlist = self.convert_menu_tree(tree)
  return map(MakeCommand, cmdlist)


    def convert_menu_tree(self, tree):
        result = []
        for title, item in tree:
            if type(item) == ListType:
                result.append([title] + self.convert_menu_tree(item))
            else:
                result.append((title, item.Execute))
        return result

    def build_menu(self):
  mbar = self.mbar
  self.file_menu = AppendMenu(mbar, _("File"), self.make_file_menu())
  AppendMenu(mbar, _("Edit"), self.make_edit_menu())
  AppendMenu(mbar, _("Effects"), self.make_effects_menu())
  AppendMenu(mbar, _("Curve"), self.make_curve_menu())
  AppendMenu(mbar, _("Arrange"), self.make_arrange_menu())
  AppendMenu(mbar, _("Style"), self.make_style_menu())
  AppendMenu(mbar, _("View"), self.make_view_menu())
  AppendMenu(mbar, _("Script"), self.make_script_menu())
  AppendMenu(mbar, _("Windows"), self.make_window_menu())
  if config.preferences.show_special_menu:
      AppendMenu(mbar, _("Special"), self.make_special_menu())
  self.update_mru_files()
  self.file_menu.RebuildMenu()

    def build_toolbar(self):
  tbar = self.tbar
  canvas = self.canvas

  cmds = [self.commands.NewDocument,
    self.commands.LoadFromFile,
    self.commands.SaveToFile,
    None,
    canvas.commands.EditMode,
    canvas.commands.SelectionMode,
    None,
    self.commands.Undo,
    self.commands.Redo,
    self.commands.RemoveSelected,
    None,
    self.commands.DuplicateSelected,
    self.commands.FlipHorizontal,
    self.commands.FlipVertical,
    None,
    self.commands.MoveSelectedToTop,
    self.commands.MoveSelectionUp,
    self.commands.MoveSelectionDown,
    self.commands.MoveSelectedToBottom,
    None,
    self.commands.GroupSelected,
    self.commands.UngroupSelected,
    None,
    canvas.commands.ZoomMode,
    canvas.commands.ToggleSnapToGrid,
    None,
    canvas.commands.CreateRectangle,
    canvas.commands.CreateEllipse,
    canvas.commands.CreatePolyBezier,
    canvas.commands.CreatePolyLine,
    canvas.commands.CreateSimpleText,
    self.commands.CreateImage,
    ]

  buttons = []
  for cmd in cmds:
      if cmd is None:
    b = Frame(tbar, class_ = 'TBSeparator')
    b.pack(side = LEFT, fill = Y)
      else:
    if cmd.is_check:
        b = CommandCheckbutton(tbar, cmd,
             highlightthickness = 0,
             takefocus = 0)
    else:
        b = CommandButton(tbar, cmd, highlightthickness = 0,
              takefocus = 0)
    tooltips.AddDescription(b, cmd.menu_name)
    b.pack(side = LEFT, fill = Y)

  def state_changed(buttons = buttons):
      for button in buttons:
    button.Update()

  canvas.Subscribe(STATE, state_changed)

    def build_status_bar(self):
  status_bar = self.status_bar
  canvas = self.canvas
  stat_mode = UpdatedLabel(status_bar, name = 'mode', text = '',
         updatecb = canvas.ModeInfoText)
  stat_mode.pack(side = 'left')
  stat_mode.Update()
  canvas.Subscribe(MODE, stat_mode.Update)

  stat_edited = UpdatedLabel(status_bar, name = 'edited', text = '',
           updatecb = self.EditedInfoText)
  stat_edited.pack(side = 'left')
  stat_edited.Update()
  self.Subscribe(UNDO, stat_edited.Update)

  stat_zoom = UpdatedLabel(status_bar, name = 'zoom', text = '',
         updatecb = canvas.ZoomInfoText)
  stat_zoom.pack(side = 'left')
  stat_zoom.Update()
  canvas.Subscribe(VIEW, stat_zoom.Update)

  stat_pos = PositionLabel(status_bar, name = 'position', text = '',
         updatecb = canvas.GetCurrentPos)
  stat_pos.pack(side = 'left')
  stat_pos.Update()
  canvas.Subscribe(POSITION, stat_pos.Update)

  stat_sel = UpdatedLabel(status_bar, name = 'selection', text = '',
        updatecb = canvas.CurrentInfoText)
  stat_sel.pack(side = 'left', fill = X, expand = 1)
  stat_sel.Update()
  update = stat_sel.Update
  canvas.Subscribe(SELECTION, update)
  canvas.Subscribe(CURRENTINFO, update)
  canvas.Subscribe(EDITED, update)

    def EditedInfoText(self):
  if self.document.WasEdited():
      return _("modified")
  return _("unmodified")


    AddCmd('AboutBox', _("About..."))
    def AboutBox(self):
  abouttext = _("Skencil (%(version)s)\n"
          "(c) 1996-2005 by Bernhard Herzog\n\n"
          "Versions:\n"
          "Python:\t%(py)s\tTcl:\t%(tcl)s\n"
          "Tkinter:\t%(tkinter)s\tTk:\t%(tk)s") \
        % {'version':SketchVersion,
           'py':string.split(sys.version)[0],
           'tcl':TclVersion,
           'tkinter':string.split(Tkinter.__version__)[1],
           'tk':TkVersion}

  self.application.MessageBox(title = _("About Skencil"),
            message = abouttext,
                                    icon = pixmaps.IconLarge)


    #
    #  Special methods. Mainly interesting for debugging
    #
    AddCmd('DocumentInfo', "Document Info...", key_stroke = 'F12')
    def DocumentInfo(self):
  text = self.document.DocumentInfo()

  from Sketch import _sketch
  meminfo = 'Memory:\n'\
      '# Bezier Paths:\t%d\n'\
      '# RGBColors:\t%d\n' \
      '# Rects:\t\t%d\n'\
      '# Trafos:\t\t%d\n'\
      '# Points:\t\t%d' % (_sketch.num_allocated(),
               _sketch.colors_allocated(),
               _sketch.rects_allocated(),
               _sketch.trafos_allocted(),
               _sketch.points_allocated())
  text = text + '\n\n' + meminfo

  self.application.MessageBox(title = 'Document Info', message = text,
            icon = 'info')

    AddCmd('DumpXImage', 'Dump XImage')
    def DumpXImage(self):
  gc = self.canvas.gc
  if gc.ximage:
      gc.ximage.dump_data("/tmp/ximage.dat")


#     AddCmd('export_bitmap', 'Export Bitmap')
#     def export_bitmap(self):
#  import export
#  export.export_bitmap(self.document)

    AddCmd('python_prompt', 'Python Prompt', key_stroke = 'F11')
    def python_prompt(self):
        if config.preferences.show_special_menu:
            import prompt
            prompt.PythonPrompt()


    #
    #  Insert Special Objects
    #

    #
    #  Create Image
    #

    def GetOpenImageFilename(self, title = None, initialdir = '',
           initialfile = '', no_eps = 0):
  if title is None:
      title = _("Load Image")
  if no_eps:
      filetypes = skapp.bitmapfiletypes
  else:
      filetypes = skapp.imagefiletypes
  filename = self.application.GetOpenFilename(title = title,
                filetypes = filetypes,
                initialdir = initialdir,
                initialfile = initialfile)
  return filename

    AddCmd('CreateImage', _("Load Raster/EPS Image..."),
           bitmap = pixmaps.Image, subscribe_to = None)
    def CreateImage(self, filename = None):
  if not filename:
      filename = self.GetOpenImageFilename(title = _("Load Image"),
             initialdir = config.preferences.image_dir,
             initialfile = '')
  if filename:
      try:
    file = open(filename, 'r')
    is_eps = eps.IsEpsFileStart(file.read(256))
    file.close()
    dir, name = os.path.split(filename)
    config.preferences.image_dir = dir
    if is_eps:
        imageobj = eps.EpsImage(filename = filename)
    else:
        imageobj = image.Image(imagefile = filename)
    self.canvas.PlaceObject(imageobj)
      except IOError, value:
    if type(value) == TupleType:
        value = value[1]
    self.application.MessageBox(title = _("Load Image"),
        message = _("Cannot load %(filename)s:\n"
              "%(message)s") \
        % {'filename':`os.path.split(filename)[1]`,
           'message':value},
        icon = 'warning')

    AddCmd('AddHorizGuideLine', _("Add Horizontal Guide Line"), 'AddGuideLine',
     args = 1)
    AddCmd('AddVertGuideLine', _("Add Vertical Guide Line"), 'AddGuideLine',
     args = 0)
    def AddGuideLine(self, horizontal = 1):
  self.canvas.PlaceObject(GuideLine(Point(0, 0), horizontal))

    #
    #
    #

    AddCmd('CreateStyleFromSelection', _("Name Style..."),
     sensitive_cb = ('document', 'CanCreateStyle'),
     subscribe_to = SELECTION)
    def CreateStyleFromSelection(self):
  import styledlg
  doc = self.document
  object = doc.CurrentObject()
  style_names = doc.GetStyleNames()
  if object:
      name = styledlg.GetStyleName(self.root, object, style_names)
      if name:
    name, which_properties = name
    doc.CreateStyleFromSelection(name, which_properties)

    def no_pattern(self, category):
        import styledlg
        if category == 'fill':
            title = _("No Fill")
            prop = 'fill_pattern'
        else:
            title = _("No Line")
            prop = 'line_pattern'
        styledlg.set_properties(self.root, self.document, title, category,
                                {prop: EmptyPattern})


    #
    #  Document commands
    #

    AddDocCmd('SelectAll', _("Select All"), sensitive_cb = 'IsSelectionMode',
        subscribe_to = MODE)
    AddDocCmd('SelectNextObject', _("Select Next"), key_stroke = 'M-Right')
    AddDocCmd('SelectPreviousObject', _("Select Previous"),
        key_stroke = 'M-Left')
    AddDocCmd('SelectFirstChild', _("Select First Child"),
        key_stroke = 'M-Down')
    AddDocCmd('SelectParent', _("Select Parent"), key_stroke = 'M-Up')

    # rearrange object

    AddDocCmd('RemoveSelected', _("Delete"), key_stroke = 'Delete',
        bitmap = pixmaps.Delete)

    AddDocCmd('MoveSelectedToTop', _("Move to Top"),
        bitmap = pixmaps.MoveToTop, key_stroke = 'Home')

    AddDocCmd('MoveSelectedToBottom', _("Move to Bottom"),
        bitmap = pixmaps.MoveToBottom, key_stroke = 'End')

    AddDocCmd('MoveSelectionUp', _("Move One Up"), bitmap = pixmaps.MoveOneUp,
        key_stroke = 'S-Prior')

    AddDocCmd('MoveSelectionDown', _("Move One Down"),
        bitmap = pixmaps.MoveOneDown, key_stroke = 'S-Next')

    AddDocCmd('DuplicateSelected', _("Duplicate"), bitmap = pixmaps.Duplicate,
        key_stroke = 'C-d')
    #

    AddDocCmd('GroupSelected', _("Group"), sensitive_cb = 'CanGroup',
        key_stroke = 'C-g', bitmap = pixmaps.Group)


    AddDocCmd('UngroupSelected', _("Ungroup"), sensitive_cb = 'CanUngroup',
        key_stroke = 'C-u', bitmap = pixmaps.Ungroup)

    #

    AddDocCmd('ConvertToCurve', _("Convert To Curve"),
        sensitive_cb = 'CanConvertToCurve')

    AddDocCmd('CombineBeziers', _("Combine Beziers"),
        sensitive_cb = 'CanCombineBeziers')

    AddDocCmd('SplitBeziers', _("Split Beziers"),
        sensitive_cb = 'CanSplitBeziers')

    #
    #  Align
    #
    AddDocCmd('AbutHorizontal', _("Abut Horizontal"))
    AddDocCmd('AbutVertical', _("Abut Vertical"))

    AddDocCmd('FlipHorizontal', _("Flip Horizontal"), 'FlipSelected',
        args = (1, 0), bitmap = pixmaps.FlipHorizontal)

    AddDocCmd('FlipVertical', _("Flip Vertical"), 'FlipSelected',
        args = (0, 1), bitmap = pixmaps.FlipVertical)


    # effects
    AddDocCmd('CancelBlend', _("Cancel Blend"),
        sensitive_cb = 'CanCancelBlend')

    AddDocCmd('RemoveTransformation', _("Remove Transformation"))

    AddDocCmd('CreateMaskGroup', _("Create Mask Group"),
        sensitive_cb = 'CanCreateMaskGroup')
    AddDocCmd('CreatePathText', _("Create Path Text"),
        sensitive_cb = 'CanCreatePathText')
    AddDocCmd('CreateClone', _("Create Clone"),
        sensitive_cb = 'CanCreateClone')


    #
    #  Cut/Paste
    #

    def CutCopySelected(self, method):
  objects = getattr(self.document, method)()
  if objects is not None:
      self.application.SetClipboard(objects)

    AddCmd('CopySelected', _("Copy"), 'CutCopySelected',
     args= ('CopyForClipboard',), subscribe_to = SELECTION,
     sensitive_cb = ('document', 'HasSelection'))
    AddCmd('CutSelected', _("Cut"), 'CutCopySelected',
     args= ('CutForClipboard',), subscribe_to = SELECTION,
     sensitive_cb = ('document', 'HasSelection'))
    AddCmd('PasteClipboard', _("Paste"),
     subscribe_to = ('application', CLIPBOARD),
     sensitive_cb = ('application', 'ClipboardContainsData'))
    def PasteClipboard(self):
  if self.application.ClipboardContainsData():
      obj = self.application.GetClipboard().Object()
      obj = obj.Duplicate()
      self.canvas.PlaceObject(obj)
    #
    #  Undo/Redo
    #

    AddDocCmd('Undo', _("Undo"), subscribe_to = UNDO,
        sensitive_cb = 'CanUndo', name_cb = 'UndoMenuText',
        key_stroke = 'C-z', bitmap = pixmaps.Undo)

    AddDocCmd('Redo', _("Redo"), subscribe_to = UNDO,
        sensitive_cb = 'CanRedo', name_cb = 'RedoMenuText',
        key_stroke = 'C-r', bitmap = pixmaps.Redo)

    AddDocCmd('ResetUndo', _("Discard Undo History"), subscribe_to = None,
        sensitive_cb = None)



    #
    #  Styles
    #
    AddDocCmd('FillNone', _("No Fill"), 'AddStyle', args = EmptyFillStyle)
    AddDocCmd('LineNone', _("No Line"), 'AddStyle', args = EmptyLineStyle)
    AddDocCmd('UpdateStyle', _("Update Style"), 'UpdateDynamicStyleSel')

    
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.