Detect a new kind of Zip format (PK00).
[rox-archive.git] / box.py
blob5136d6a6114cd17181a0544d6297d2238fa8d29e
1 import sys, os
3 import rox
4 from rox import saving, g
6 import formats
8 class ArchiveBox(saving.SaveBox, saving.Saveable):
9 "A savebox with an operation selector."
10 def __init__(self):
11 self.data = None
12 self.operation = None
13 self.ops = None
14 saving.SaveBox.__init__(self, self, '', 'text/plain')
16 def save_cancelled(self):
17 assert formats.current_command
18 formats.current_command.kill()
20 def set_save_in_progress(self, busy):
21 if self.operation:
22 self.operation.set_sensitive(not busy)
23 saving.SaveBox.set_save_in_progress(self, busy)
25 def build_main_area(self):
26 self.vbox.add(self.save_area)
28 self.operation = g.OptionMenu()
29 self.vbox.pack_start(self.operation, False, True, 0)
30 self.operation.show()
31 self.operation.set_border_width(5)
32 self.updating = 0
34 self.delete_choice = g.CheckButton(_('Delete file afterwards?'))
35 self.vbox.pack_start(self.delete_choice, True, True, 0)
37 self.ops_menu = g.Menu()
38 self.operation.set_menu(self.ops_menu)
40 def set_data(self, data):
41 assert not self.data
43 self.data = data
44 self.save_mode = data.mode
45 ops = [op for op in formats.operations if op.can_handle(data)]
47 name = data.default_name
48 self.save_area.entry.set_text(name)
49 start = name.rfind('/') + 1
50 #self.save_area.entry.select_region(start, -1)
51 g.Editable.select_region(self.save_area.entry, start, -1)
53 # Add all supported ops to the menu.
54 self.ops = []
55 last = None
56 for op in ops:
57 if last and last != op.__class__:
58 item = g.MenuItem()
59 item.show()
60 self.ops_menu.append(item)
61 self.ops.append(None)
62 last = op.__class__
63 item = g.MenuItem(str(op))
64 item.show()
65 self.ops_menu.append(item)
66 self.ops.append(op)
68 # Select the default
69 try:
70 self.operation.set_history(self.ops.index(data.default))
71 except ValueError:
72 print >>sys.stderr, "Warning: %s not in ops list!" % data.default
74 self.operation.connect('changed', self.op_changed)
75 self.save_area.entry.connect('changed', self.name_changed)
77 self.save_area.set_type(data.default.type)
79 if isinstance(data, formats.FileData) and data.path != '-':
80 self.delete_choice.show()
82 def name_changed(self, entry):
83 if self.updating:
84 return
85 self.updating = 1
87 name = entry.get_text()
88 i = 0
89 for op in self.ops:
90 if op and name.endswith('.' + op.extension):
91 self.operation.set_history(i)
92 break
93 i += 1
95 self.updating = 0
97 def op_changed(self, operation):
98 op = self.ops[operation.get_history()]
99 assert op
100 self.set_type(op.type)
102 if self.updating:
103 return
104 self.updating = 1
106 name = self.save_area.entry.get_text()
107 for op2 in self.ops:
108 if op2 and name.endswith('.' + op2.extension):
109 name = name[:-len(op2.extension)-1]
110 break
111 if op.add_extension:
112 name += '.' + op.extension
113 self.save_area.entry.set_text(name)
114 start = name.rfind('/') + 1
115 #self.save_area.entry.select_region(start, -1)
116 g.Editable.select_region(self.save_area.entry, start, -1)
118 self.updating = 0
120 def save_to_file(self, path):
121 op = self.ops[self.operation.get_history()]
122 if hasattr(op, 'save_to_file'):
123 op.save_to_file(self.data, path)
124 else:
125 saving.Saveable.save_to_file(self, path)
127 #If the delete_choice is set, try to remove the file
128 if self.delete_choice.get_active():
129 try:
130 os.remove(sys.argv[1])
131 except:
132 rox.report_exception()
134 def can_save_to_selection(self):
135 if self.ops:
136 op = self.ops[self.operation.get_history()]
137 if op.type == 'inode/directory':
138 return False
139 return saving.Saveable.can_save_to_selection(self)
141 def save_to_stream(self, stream):
142 op = self.ops[self.operation.get_history()]
143 op.save_to_stream(self.data, stream)