#!/usr/bin/env python
#############################################################################
# IceMe
# =====
#
# Copyright 2000-2002, Dirk Moebius <dmoebius@gmx.net>
# and Mike Hostetler <thehaas@binary.net
#
# This work comes with no warranty regarding its suitability for any purpose.
# The author is not responsible for any damages caused by the use of this
# program.
#############################################################################
import glob
import os
import stat
import gdkpixbuf
from popen2 import popen2
from gtk import *
import GtkExtra
from constants import *
from MessageBox import *
from Preferences import Preferences
from IceMenuTree import IceMenuTree
from MenuParser import MenuParser
from IconSelectionDialog import IconSelectionDialog
from PreviewWindow import PreviewWindow
from KeyEditor import KeyEditor
from VERSION import VERSION
class IceMe(GtkWindow):
########################################################################
# init GUI
########################################################################
def __init__(self, preferences):
GtkWindow.__init__(self, WINDOW_TOPLEVEL, "IceMe")
self.set_default_size(600, 400)
self.connect("delete_event", mainquit)
self.preferences = preferences
self.iconsel_dlg = None
self.do_update_widgets = 0
self.key_editor_dlg = None
self.__initIconCache(preferences.getIconPaths())
menu = self.__initMenu()
tb = self.__initToolbar()
self.tree = IceMenuTree(self)
self.tree.connect("tree-select-row", self.on_tree_select_row)
self.tree.connect_after("drag-begin", self.on_tree_drag_begin)
self.tree.connect_after("drag-end", self.on_tree_drag_end)
self.tree.show()
scr = GtkScrolledWindow()
scr.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
scr.add(self.tree)
scr.show()
name_label = GtkLabel("Name:")
name_label.set_alignment(1.0, 0.5)
name_label.show()
self.name = GtkEntry()
self.name.connect("changed", self.on_name_changed)
self.name.show()
self.command_label = GtkLabel("Command:")
self.command_label.set_alignment(1.0, 0.5)
self.command_label.show()
self.command = GtkEntry()
self.command.connect("changed", self.on_command_changed)
self.command.show()
cmd_iconname = os.path.join(SCRIPT_DIR, "pixmaps", "open.xpm")
cmd_icon = GtkPixmap(self, cmd_iconname, None)
cmd_icon.show()
self.command_button = GtkButton()
self.command_button.add(cmd_icon)
self.command_button.connect("clicked", self.on_command_button_clicked)
self.command_button.show()
command_hbox = GtkHBox(FALSE, 5)
command_hbox.pack_start(self.command)
command_hbox.pack_start(self.command_button, expand=FALSE, fill=FALSE)
command_hbox.show()
icon_label = GtkLabel("Icon:")
icon_label.set_alignment(1.0, 0.5)
icon_label.show()
self.icon_name = GtkEntry()
self.icon_name.connect("focus-out-event", self.on_icon_name_focus_out_event)
self.icon_name.show()
dummy, pix, mask = self.getCachedIcon("-")
self.icon = GtkPixmap(pix, mask)
self.icon.show()
self.icon_button = GtkButton(None)
self.icon_button.add(self.icon)
self.icon_button.connect("clicked", self.on_icon_button_clicked)
self.icon_button.show()
icon_hbox = GtkHBox(FALSE, 5)
icon_hbox.pack_start(self.icon_name)
icon_hbox.pack_start(self.icon_button, expand=FALSE, fill=FALSE)
icon_hbox.show()
sep = GtkHSeparator()
sep.show()
self.is_restart = GtkCheckButton("Start as a new window manager")
self.is_restart.connect("toggled", self.on_is_restart_toggled)
self.is_restart.show()
self.add_shortcut = GtkButton("Add shortcut...")
self.add_shortcut.connect("clicked", self.on_add_shortcut_clicked)
self.add_shortcut.show()
table = GtkTable(2, 6, FALSE)
table.attach(name_label, 0, 1, 0, 1, yoptions=0)
table.attach(self.name, 1, 2, 0, 1, yoptions=0)
table.attach(self.command_label, 0, 1, 1, 2, yoptions=0)
table.attach(command_hbox, 1, 2, 1, 2, yoptions=0)
table.attach(icon_label, 0, 1, 2, 3, yoptions=0)
table.attach(icon_hbox, 1, 2, 2, 3, yoptions=0)
table.attach(sep, 0, 2, 3, 4, yoptions=0)
table.attach(self.is_restart, 1, 2, 4, 5, yoptions=0)
table.attach(self.add_shortcut, 1, 2, 5, 6, yoptions=0)
table.set_border_width(10)
table.set_row_spacings(5)
table.set_col_spacings(5)
table.show()
self.rightframe = GtkFrame("Menu entry")
self.rightframe.set_border_width(10)
self.rightframe.add(table)
self.rightframe.show()
hpaned = GtkHPaned()
hpaned.pack1(scr, TRUE, TRUE)
hpaned.pack2(self.rightframe, FALSE, FALSE)
hpaned.set_position(300)
hpaned.show()
self.statusbar = GtkStatusbar()
self.statusbar_context = self.statusbar.get_context_id("main")
self.setStatus("IceMe v" + VERSION)
self.statusbar.show()
vbox = GtkVBox()
vbox.pack_start(menu, expand=FALSE)
vbox.pack_start(tb, expand=FALSE)
vbox.pack_start(hpaned)
vbox.pack_start(self.statusbar, expand=FALSE)
vbox.show()
self.add(vbox)
self.show()
self.__initToolTips()
self.__initTree()
self.__initIcePref()
def __initToolTips(self):
tips = GtkTooltips()
tips.set_tip(self.command_button,
"Click here to select an executable via a file selection box.")
tips.set_tip(self.icon_button,
"Click here to select another icon")
tips.set_tip(self.is_restart,
"If selected, this entry will cause IceWM to quit and start "
"the command as new window manager.")
def __initTree(self):
self.do_update_widgets = 0
menu_file = self.preferences.getIceWMFile("menu")
programs_file = self.preferences.getIceWMFile("programs")
toolbar_file = self.preferences.getIceWMFile("toolbar")
rootnode = self.tree.init(menu_file, programs_file, toolbar_file)
self.do_update_widgets = 1
self.tree.select(rootnode)
def __initMenu(self):
ag = GtkAccelGroup()
itemf = GtkItemFactory(GtkMenuBar, "<main>", ag)
itemf.create_items([
# path key callback action# type
("/_File", None, None, 0, "<Branch>"),
("/_File/_Save", "<control>S", self.on_save, 1, ""),
("/_File/_Revert", "<control>R", self.on_revert, 2, ""),
("/_File/_Preview", "<control>P", self.on_preview, 3, ""),
("/_File/sep1", None, None, 4, "<Separator>"),
("/_File/_Exit", "<control>Q", mainquit, 5, ""),
("/_Edit", None, None, 6, "<Branch>"),
("/_Edit/_Cut", "<control>X", self.on_cut, 7, ""),
("/_Edit/C_opy", "<control>C", self.on_copy, 8, ""),
("/_Edit/_Paste", "<control>V", self.on_paste, 9, ""),
("/_Edit/sep2", None, None, 10, "<Separator>"),
("/_Edit/_Delete", None, self.on_delete, 11, ""),
("/_Edit/sep3", None, None, 12, "<Separator>"),
("/_Edit/_IceWM preferences", None, self.on_icepref, 13, ""),
("/_Edit/_Shortcuts", None, self.on_shortcuts, 14, ""),
("/_Help", None, None, 15, "<LastBranch>"),
("/_Help/_About...", None, self.on_about, 16, "")
])
self.add_accel_group(ag)
menu = itemf.get_widget("<main>")
menu.show()
# remember some menu entries that may be disabled later:
self.menu_cut = itemf.get_widget_by_action(7)
self.menu_copy = itemf.get_widget_by_action(8)
self.menu_paste = itemf.get_widget_by_action(9)
self.menu_delete = itemf.get_widget_by_action(11)
self.menu_icepref = itemf.get_widget_by_action(13)
hdlbox = GtkHandleBox()
hdlbox.add(menu)
hdlbox.show()
return hdlbox
def __getTbButton(self, name, pic, callback, tooltip):
return self.tb.append_item(name, tooltip, None,
GtkPixmap(self, os.path.join(SCRIPT_DIR, "pixmaps", pic)),
callback)
def __initToolbar(self):
self.tb = GtkToolbar(ORIENTATION_HORIZONTAL, TOOLBAR_ICONS)
self.tb.set_space_size(10)
self.tb_save = self.__getTbButton(
"Save", "save.xpm", self.on_save,
"Save the menu")
self.tb_revert = self.__getTbButton(
"Revert", "revert.xpm", self.on_revert,
"Revert to last saved version")
self.tb_preview = self.__getTbButton(
"Preview", "preview.xpm", self.on_preview,
"Preview the menu as IceWM would display it")
self.tb.append_space()
self.tb_new_entry = self.__getTbButton(
"New Entry", "new_entry.xpm", self.on_new_entry,
"Create a new normal entry")
self.tb_new_sep = self.__getTbButton(
"New Sep.", "new_sep.xpm", self.on_new_sep,
"Create a new separator")
self.tb_new_menu = self.__getTbButton(
"New Menu", "new_menu.xpm", self.on_new_submenu,
"Create a new submenu")
self.tb.append_space()
self.tb_cut = self.__getTbButton(
"Cut", "edit_cut.xpm", self.on_cut,
"Cut selected entry to buffer")
self.tb_copy = self.__getTbButton(
"Copy", "edit_copy.xpm", self.on_copy,
"Copy selected entry to buffer")
self.tb_paste = self.__getTbButton(
"Paste", "edit_paste.xpm", self.on_paste,
"Paste buffer under current selection")
self.tb_delete = self.__getTbButton(
"Delete", "edit_delete.xpm", self.on_delete,
"Delete selected entry")
self.tb.append_space()
self.tb_up = self.__getTbButton(
"Up", "up.xpm", self.on_move_up,
"Move selected entry up")
self.tb_down = self.__getTbButton(
"Down", "down.xpm", self.on_move_down,
"Move selected entry down")
self.tb.append_space()
self.tb_icepref = self.__getTbButton(
"Preferences", "icepref.xpm", self.on_icepref,
"Edit the IceWM preferences with IcePref")
self.tb_shortcuts = self.__getTbButton(
"Shortcuts", "keys.xpm", self.on_shortcuts,
"Edit shortcuts")
self.tb.show()
hdlbox = GtkHandleBox()
hdlbox.add(self.tb)
hdlbox.show()
return hdlbox
def __initIcePref(self):
# check if IcePref is there. If not, disable the corresponding menu
# and toolbar buttons.
is_there = FALSE
cmd = string.split(ICEPREF)[0]
if cmd[0] == os.sep:
# absolute filename:
# the file must have read and execute access and be regular:
if os.access(cmd, R_OK|X_OK) and os.path.isfile(cmd):
is_there = TRUE
else:
# search in $PATH:
for path in PATH:
fcmd = os.path.join(path, cmd)
if os.access(fcmd, R_OK|X_OK) and os.path.isfile(cmd):
is_there = TRUE
break
self.menu_icepref.set_sensitive(is_there)
self.tb_icepref.set_sensitive(is_there)
def __initIconCache(self, icon_paths):
self.icons = {}
for dir in icon_paths:
for type in ICON_TYPES:
for patt in ICON_PATTERNS:
iconfiles = glob.glob(os.path.join(dir, patt+"."+type))
for filename in iconfiles:
name = os.path.basename(filename)
if "_" in name:
name = string.split(name,"_")[0]
if not name in self.icons.keys():
self.icons[name] = filename
# load some default icons:
self.icons["-"] = \
os.path.join(SCRIPT_DIR, "pixmaps", "empty.xpm")
self.icons["$ice_me_clipboard$"] = \
os.path.join(SCRIPT_DIR, "pixmaps", "ice_me_clipboard.xpm")
self.icons["$ice_me_icewm$"] = \
os.path.join(SCRIPT_DIR, "pixmaps", "ice_me_icewm.xpm")
########################################################################
# misc. functions
########################################################################
def __updateWidgets(self):
if not self.do_update_widgets:
# don't update widgets right now (because a tree drag is running)
return
is_menu = not self.cur_node.is_leaf
is_sep = self.tree.isSeparator(self.cur_node)
is_normal = not (is_menu or is_sep)
is_inactive = self.tree.isInactive(self.cur_node)
# enable/disable items on right frame:
self.command_label.set_sensitive(is_normal)
self.command.set_sensitive(is_normal)
self.command_button.set_sensitive(is_normal)
self.is_restart.set_sensitive(is_normal)
self.add_shortcut.set_sensitive(is_normal)
self.rightframe.set_sensitive(not (is_inactive or is_sep))
# enable/disable toolbar/menu buttons:
can_up = self.tree.canMoveUp(self.cur_node)
can_down = self.tree.canMoveDown(self.cur_node)
self.tb_up.set_sensitive(not is_inactive and can_up)
self.tb_down.set_sensitive(not is_inactive and can_down)
# buttons/menus, that delete something:
can_delete = self.tree.canDelete(self.cur_node)
self.tb_cut.set_sensitive(can_delete)
self.menu_cut.set_sensitive(can_delete)
self.tb_copy.set_sensitive(can_delete)
self.menu_copy.set_sensitive(can_delete)
self.tb_delete.set_sensitive(can_delete)
self.menu_delete.set_sensitive(can_delete)
# buttons that insert something:
has_paste = self.tree.hasPasteData()
can_insert = self.tree.canInsertOn(self.cur_node)
self.tb_paste.set_sensitive(can_insert and has_paste)
self.menu_paste.set_sensitive(can_insert and has_paste)
self.tb_new_entry.set_sensitive(can_insert)
self.tb_new_sep.set_sensitive(can_insert)
self.tb_new_menu.set_sensitive(can_insert)
# set data items on right frame:
if not is_sep:
self.name.set_text(self.tree.getNodeName(self.cur_node))
else:
self.name.set_text("")
self.command.set_text(self.tree.getNodeCommand(self.cur_node))
self.setIconButton(self.tree.getNodeIconName(self.cur_node))
is_restart = self.tree.getNodeType(self.cur_node) == MENUTREE_RESTART
self.is_restart.set_active(is_restart)
def getCachedIcon(self, shortname):
"Returns (<filename>, <pixmap>, <mask>)"
if (shortname.find("_") != -1) and not(shortname.startswith("$")):
shortname = shortname.split("_")[0]
if not shortname:
shortname = "-"
val = self.icons.get(shortname)
if val is None:
# fall back to empty icon:
val = self.icons["-"]
if type(val) == type(""):
try:
newheight, newwidth = 16,16
img = gdkpixbuf.new_from_file(val)
img2 = img.scale_simple(newheight,newwidth,gdkpixbuf.INTERP_BILINEAR)
pix,mask = img2.render_pixmap_and_mask()
# if mask is None, something strange happened.
# This always happens with $ice_me_icewm$, but may happen with
# others. Let's just hope it's a xpm file. -- mikeh
if mask == None:
pix, mask = create_pixmap_from_xpm(self, None, self.icons[shortname])
except IOError, msg:
sys.stderr.write("*** couldn't open icon %s: %s" % (val, msg))
pix, mask = create_pixmap_from_xpm(self, None, self.icons["-"])
newval = (val, pix, mask)
self.icons[shortname] = newval
return newval
else:
return val
def setIconButton(self, shortname):
self.icon_name.set_text("")
self.icon_button.remove(self.icon)
if shortname is None or shortname == "-":
shortname = ""
filename, new_pix, new_mask = self.getCachedIcon(shortname)
self.icon = GtkPixmap(new_pix, new_mask)
self.icon.show()
self.icon_button.add(self.icon)
self.icon_name.set_text(shortname)
def setStatus(self, text):
self.statusbar.push(self.statusbar_context, text)
while events_pending():
mainiteration()
def writeTree(self):
errmsgs = []
menu = self.preferences.getIceWMFile("menu", FALSE)
fd = self.openMenufile("menu", menu, errmsgs)
if fd: self.writeSubTree(fd, self.tree.getMainMenuNode())
if fd: fd.close()
programs = self.preferences.getIceWMFile("programs", FALSE)
fd = self.openMenufile("programs", programs, errmsgs)
if fd: self.writeSubTree(fd, self.tree.getProgramsNode())
if fd: fd.close()
toolbar = self.preferences.getIceWMFile("toolbar", FALSE)
fd = self.openMenufile("toolbar", toolbar, errmsgs)
if fd: self.writeSubTree(fd, self.tree.getToolbarNode())
if fd: fd.close()
if errmsgs:
self.setStatus("There were some errors.")
message("Error saving menu", errmsgs, pixmap=ICON_ALERT)
else:
self.setStatus("Saved.")
def openMenufile(self, short_filename, full_filename, errmsgs):
f = None
home_filename = os.path.join(HOME_ICEWM, short_filename)
if self.preferences.getIgnoreHomeOption():
# try to save to the original location (should only work as root):
try:
f = open(full_filename, "w")
except IOError, msg:
errmsgs.append(
"You specified '--ignore-home', but I couldn't\n"
"write the %s file, probably because you\n"
"don't have write access. The error message was:\n"
"%s\n"
"I'll try writing to your $HOME.\n" % (short_filename, msg))
if not f:
# try to save in the home directory:
try:
if not os.path.isdir(HOME_ICEWM): os.mkdir(HOME_ICEWM)
f = open(home_filename, "w")
except IOError, msg:
errmsgs.append(
"I couldn't write the %s file to your home dir.\n"
"The error message was:\n"
"%s\n"
"The file will not be saved!\n" % (short_filename, msg))
return None
return f
def writeSubTree(self, fd, node, level=0):
for child in node.children:
if self.tree.isInactive(child): return
type = self.tree.getNodeType(child)
indent = " "*level
if type == MENUTREE_SEPARATOR:
fd.write("%sseparator\n" % indent)
else:
name = self.tree.getNodeName(child)
icon = self.tree.getNodeIconName(child)
if not icon: icon = "-"
if type == MENUTREE_SUBMENU:
fd.write('%smenu "%s" "%s" {\n' % (indent, name, icon))
self.writeSubTree(fd, child, level+1)
fd.write("%s}\n" % indent)
else:
command = self.tree.getNodeCommand(child)
if type == MENUTREE_PROG:
fd.write('%sprog "%s" "%s" %s\n'
% (indent, name, icon, command))
elif type == MENUTREE_RESTART:
fd.write('%srestart "%s" "%s" %s\n'
% (indent, name, icon, command))
########################################################################
# callbacks
########################################################################
def on_tree_drag_begin(self, widget, context):
self.do_update_widgets = 0
def on_tree_drag_end(self, widget, context):
self.do_update_widgets = 1
self.__updateWidgets()
def on_tree_select_row(self, tree, node, col):
self.cur_node = node
self.__updateWidgets()
def on_command_button_clicked(self, button):
self.setStatus("Please select an executable.")
cmd = GtkExtra.file_open_box()
if cmd:
self.command.set_text(cmd)
self.setStatus("")
def on_icon_button_clicked(self, button):
global icons
icons = self.icons
class MyIconSelectionDialog(IconSelectionDialog):
def getPictureList(self):
keys = icons.keys()
keys.remove("-")
keys.remove("$ice_me_clipboard$")
keys.remove("$ice_me_icewm$")
keys.sort()
picturelist = map(lambda x, icons=icons: (x, icons[x]), keys)
return picturelist
if self.iconsel_dlg is None:
self.iconsel_dlg = MyIconSelectionDialog(7)
old_icon_name = self.tree.getNodeIconName(self.cur_node)
# show icon select dialog and return selected shortname:
new_icon_name, dummy = self.iconsel_dlg.getSelectedIcon(old_icon_name)
if new_icon_name is not None:
# a selection was made. update node data:
self.tree.setNodeIconName(self.cur_node, new_icon_name)
# update icon button:
self.setIconButton(new_icon_name)
# update tree:
dummy, pix, mask = self.getCachedIcon(new_icon_name)
self.tree.setNodeIcon(self.cur_node, pix, mask)
def on_name_changed(self, namefield):
if self.tree.isSeparator(self.cur_node):
return
new_text = namefield.get_text()
self.tree.setNodeName(self.cur_node, new_text)
def on_command_changed(self, commandfield):
new_text = commandfield.get_text()
self.tree.setNodeCommand(self.cur_node, new_text)
def on_icon_name_focus_out_event(self, iconnamefield, event):
"fired when the user changed the icon text and leaves the field"
# get new icon name:
icon_name = iconnamefield.get_text()
# update node data:
self.tree.setNodeIconName(self.cur_node, icon_name)
# update icon button:
self.setIconButton(icon_name)
# update tree:
dummy, pix, mask = self.getCachedIcon(icon_name)
self.tree.setNodeIcon(self.cur_node, pix, mask)
def on_is_restart_toggled(self, button):
# update node data:
if button.get_active():
self.tree.setNodeType(self.cur_node, MENUTREE_RESTART)
else:
self.tree.setNodeType(self.cur_node, MENUTREE_PROG)
def on_add_shortcut_clicked(self, button):
if not self.key_editor_dlg:
self.key_editor_dlg = KeyEditor(self.preferences)
self.key_editor_dlg.show()
self.key_editor_dlg.add_shortcut("None", self.tree.getNodeCommand(
self.cur_node))
def on_save(self, x=None, y=None):
self.setStatus("Saving...")
self.writeTree()
if self.key_editor_dlg:
self.key_editor_dlg.save()
def on_revert(self, x=None, y=None):
self.setStatus("Reverting...")
self.__initTree()
self.setStatus("Reverted to the last saved version.")
def on_preview(self, x=None, y=None):
self.setStatus("Displaying preview window...")
empty_name, empty_pix, empty_mask = self.getCachedIcon("-")
win = PreviewWindow(self.tree, empty_pix, empty_mask)
win.show()
def on_icepref(self, x=None, y=None):
self.setStatus("Running IcePref...")
popen2(ICEPREF)
def on_shortcuts(self, x=None, y=None):
self.setStatus("Edit shortcuts. Opening the shortcuts window...")
if not self.key_editor_dlg:
self.key_editor_dlg = KeyEditor(self.preferences)
self.key_editor_dlg.show()
def on_about(self, x=None, y=None):
message("About IceMe",
"IceMe v%s\n"
"\n"
"A menu editor for IceWM written in Python and GTK.\n"
"Copyright (c) 2000-2002 by Dirk Moebius <dmoebius@gmx.net>\n"
"and Mike Hostetler <thehaas@binary.net>"
"\n"
"See the file COPYING for license information (GPL).\n"
"Please visit the IceMe homepage at:\n"
"http://iceme.sourceforge.net" % VERSION)
def on_new_entry(self, button):
node = self.tree.insertNode(self.cur_node, MENUTREE_PROG,
"New entry", "file", "")
self.tree.select(node)
def on_new_submenu(self, button):
node = self.tree.insertNode(self.cur_node, MENUTREE_SUBMENU,
"New submenu", "folder", "")
self.tree.select(node)
def on_new_sep(self, button):
node = self.tree.insertNode(self.cur_node, MENUTREE_SEPARATOR,
None, None, None)
self.tree.select(node)
def on_move_up(self, button):
node = self.cur_node
self.tree.move(node, node.parent, self.tree.getNodeUpperSibling(node))
self.__updateWidgets()
def on_move_down(self, button):
node = self.cur_node
self.tree.move(node, node.parent, node.sibling.sibling)
self.__updateWidgets()
def on_cut(self, x=None, y=None):
# remember current node/position:
if self.cur_node.sibling:
next_node = self.cur_node.sibling
else:
next_node = self.cur_node.parent
# cut node to clipboard:
self.tree.cut(self.cur_node)
# select next node/position:
self.cur_node = next_node
self.tree.select(next_node)
def on_copy(self, x=None, y=None):
self.tree.copy(self.cur_node)
def on_paste(self, x=None, y=None):
self.tree.paste(self.cur_node)
def on_delete(self, x=None, y=None):
# remember current node/position:
if self.cur_node.sibling:
next_node = self.cur_node.sibling
else:
next_node = self.cur_node.parent
# delete node
self.tree.delete(self.cur_node)
# select next node/position:
self.cur_node = next_node
self.tree.select(next_node)
############################################################################
# main
############################################################################
def usage():
print "Usage: %s [OPTION]... [DIR]" % sys.argv[0]
print """A menueditor for IceWM.
If DIR is specified, the global icewm menu, programs and toolbar files as
well as the icons subdir are taken from this directory. Otherwise the program
will look in some well known standard locations, usually /usr/local/lib/icewm
and /usr/X11R6/lib/X11/icewm. See the FAQ for information about file and icon
lookup.
-i, --ignore-home Don't look in $HOME/.icewm for configuration files and
icons. Use this, if you are root and want to edit the
global menu files.
-h, --help Print this help and exit.
Report bugs to <thehaas@binary.net>.
"""
def main():
prefs = Preferences(sys.argv)
if prefs.getErrorCode() or prefs.getHelpOption():
usage()
sys.exit(prefs.getErrorCode())
i = IceMe(prefs)
mainloop()
if __name__ == "__main__":
main()
|