add/edit module almost done
[samba-gtk.git] / pysrvsvc.py
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3
4 """ srvsvc related dialogues"""
5
6 import gtk
7 import gobject
8 import os
9 import sys
10 from samba.dcerpc import srvsvc
11
12
13 class srvsvcConnectDialog(gtk.Dialog):
14
15     """Connect Dialog"""
16
17     def __init__(
18         self,
19         server,
20         transport_type,
21         username,
22         password='',
23         ):
24         super(srvsvcConnectDialog, self).__init__()
25
26         self.server_address = server
27         self.username = username
28         self.password = password
29         self.transport_type = transport_type
30
31         self.create()
32
33         self.update_sensitivity()
34
35     def create(self):
36         self.set_title('Connect to Samba Share Server')
37         self.set_border_width(5)
38         self.set_icon_name(gtk.STOCK_CONNECT)
39         self.set_resizable(False)
40
41         self.vbox.set_spacing(5)
42
43         # artwork
44
45         self.artwork = gtk.VBox()
46
47         self.samba_image_filename = os.path.join(sys.path[0], 'images',
48                 'samba-logo-small.png')
49         self.samba_image = gtk.Image()
50         self.samba_image.set_from_file(self.samba_image_filename)
51         self.artwork.pack_start(self.samba_image, True, True, 0)
52
53         label = gtk.Label('Opening Windows to A Wider World')
54         box = gtk.HBox()
55         box.pack_start(label, True, True, 0)
56         self.artwork.pack_start(box, True, True, 0)
57
58         label = gtk.Label('Samba Control Center')
59         box = gtk.HBox()
60         box.pack_start(label, True, True, 0)
61         self.artwork.pack_start(box, True, True, 0)
62
63         self.vbox.pack_start(self.artwork, False, True, 0)
64
65         # server frame
66
67         self.server_frame = gtk.Frame('Server')
68         self.vbox.pack_start(self.server_frame, False, True, 0)
69
70         table = gtk.Table(3, 2)
71         table.set_border_width(5)
72         self.server_frame.add(table)
73
74         label = gtk.Label(' Server address: ')
75         label.set_alignment(0, 0.5)
76         table.attach(label, 0, 1, 0, 1, gtk.FILL,gtk.FILL | gtk.EXPAND, 0, 0)
77
78         self.server_address_entry = gtk.Entry()
79         self.server_address_entry.set_text(self.server_address)
80         self.server_address_entry.set_activates_default(True)
81         self.server_address_entry.set_tooltip_text('Enter the Server Address')
82         table.attach(self.server_address_entry, 1, 2, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 1, 1)
83
84         label = gtk.Label(' Username: ')
85         label.set_alignment(0, 0.5)
86         table.attach(label,0,1,1,2,gtk.FILL,gtk.FILL | gtk.EXPAND,0,0)
87
88         self.username_entry = gtk.Entry()
89         self.username_entry.set_text(self.username)
90         self.username_entry.set_activates_default(True)
91         self.username_entry.set_tooltip_text('Enter your Username')
92         table.attach(self.username_entry,1,2,1,2,gtk.FILL | gtk.EXPAND,gtk.FILL | gtk.EXPAND,1,1)
93         label = gtk.Label(' Password: ')
94         label.set_alignment(0, 0.5)
95         table.attach(label, 0, 1, 2, 3, gtk.FILL,gtk.FILL | gtk.EXPAND, 0, 0)
96
97         self.password_entry = gtk.Entry()
98         self.password_entry.set_text(self.password)
99         self.password_entry.set_visibility(False)
100         self.password_entry.set_activates_default(True)
101         self.password_entry.set_tooltip_text('Enter your Password')
102         table.attach(self.password_entry, 1, 2, 2, 3, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 1, 1)
103
104         # transport frame
105
106         self.transport_frame = gtk.Frame(' Transport type ')
107         self.vbox.pack_start(self.transport_frame, False, True, 0)
108
109         vbox = gtk.VBox()
110         vbox.set_border_width(5)
111         self.transport_frame.add(vbox)
112
113         self.rpc_smb_tcpip_radio_button = gtk.RadioButton(None,
114                 'RPC over SMB over TCP/IP ')
115         self.rpc_smb_tcpip_radio_button.set_tooltip_text('ncacn_np type : Recomended (default)'
116                 )  # # according MS-SRVS specification
117         self.rpc_smb_tcpip_radio_button.set_active(self.transport_type
118                  == 0)
119         vbox.pack_start(self.rpc_smb_tcpip_radio_button)
120
121         self.rpc_tcpip_radio_button = \
122             gtk.RadioButton(self.rpc_smb_tcpip_radio_button,
123                             'RPC over TCP/IP')
124         self.rpc_tcpip_radio_button.set_tooltip_text('ncacn_ip_tcp type')
125         self.rpc_tcpip_radio_button.set_active(self.transport_type == 1)
126         vbox.pack_start(self.rpc_tcpip_radio_button)
127
128         self.localhost_radio_button = \
129             gtk.RadioButton(self.rpc_tcpip_radio_button, 'Localhost')
130         self.localhost_radio_button.set_tooltip_text('ncalrpc type')  # # MS-SRVS specification
131         self.localhost_radio_button.set_active(self.transport_type == 2)
132         vbox.pack_start(self.localhost_radio_button)
133
134         self.action_area.set_layout(gtk.BUTTONBOX_END)
135
136         self.cancel_button = gtk.Button('Cancel', gtk.STOCK_CANCEL)
137         self.cancel_button.set_tooltip_text('Cancel and Quit')
138         self.add_action_widget(self.cancel_button, gtk.RESPONSE_CANCEL)
139
140         self.connect_button = gtk.Button('Connect', gtk.STOCK_CONNECT)
141         self.connect_button.set_flags(gtk.CAN_DEFAULT)
142         self.connect_button.set_tooltip_text('OK / Connect to Server')
143         self.add_action_widget(self.connect_button, gtk.RESPONSE_OK)
144
145         self.set_default_response(gtk.RESPONSE_OK)
146
147         self.rpc_smb_tcpip_radio_button.connect('toggled',
148                 self.on_radio_button_toggled)
149         self.rpc_tcpip_radio_button.connect('toggled',
150                 self.on_radio_button_toggled)
151         self.localhost_radio_button.connect('toggled',
152                 self.on_radio_button_toggled)
153
154     def get_server_address(self):
155             return self.server_address_entry.get_text().strip()
156
157     def get_username(self):
158             return self.username_entry.get_text().strip()
159
160     def get_password(self):
161             return self.password_entry.get_text()
162
163     def update_sensitivity(self):
164             server_required = \
165                 not self.localhost_radio_button.get_active()
166             self.server_address_entry.set_sensitive(server_required)
167
168     def get_transport_type(self):
169             if self.rpc_smb_tcpip_radio_button.get_active():
170                 return 0
171             elif self.rpc_tcpip_radio_button.get_active():
172                 return 1
173             elif self.localhost_radio_button.get_active():
174                 return 2
175             else:
176                 return -1
177
178     def on_radio_button_toggled(self, widget):
179             self.update_sensitivity()
180
181
182 class ShareAddEditDialog(gtk.Dialog):
183
184     """ Share add and edit dialog
185
186  If 'edit_mode' is set to True then in Edit mode .
187  Immutable fields are automatically greyed out.
188   """
189
190     def __init__(self, pipe_manager, share=None):
191         """ Class initialiser """
192         super(ShareAddEditDialog, self).__init__()
193         self.pipe = pipe_manager
194         self.islocal = self.pipe.islocal
195
196
197         if share is None :
198             self.edit_mode = 0
199             self.share = self.pipe.get_share_object()
200         else :
201             self.edit_mode =  1
202             self.share = share
203         self.share_to_fields()
204
205
206
207
208     def ():
209         """ Function doc """
210         
211     def set_window_edit_mode(self):
212         """ Deactivates a bunch of widgets in Edit mode """
213         if self.edit_mode is True:
214             self.share_name_entry.set_sensitive(False)
215             self.stype_disktree_radio_button.set_sensitive(False)
216             self.stype_printq_radio_button.set_sensitive(False)
217             self.stype_ipc_radio_button.set_sensitive(False)
218             self.sflag_temp_check_button.set_sensitive(False)
219             self.sflag_hidden_check_button.set_sensitive(False)
220
221
222     def  get_stype_final(self):
223         """ Calculates share type from base type and share flags """
224         stype = self.stype
225         if self.flags[0] :
226             stype |= srvsvc.STYPE_TEMPORARY
227         if self.flags[1] :
228             stype |= -(srvsvc.STYPE_HIDDEN)
229         return stype
230
231
232
233     def  share_to_fields(self):
234         """ Gets values from the share . """
235         self.name = self.share.name
236         self.stype = self.pipe.get_share_type_info(self.share.type,'base_type')
237         self.flags = self.pipe.get_share_type_info(self.share.type,'flags')
238         self.comment = self.share.comment
239         self.max_users = self.share.max_users
240         self.password = self.share.password
241         self.path = self.share.path
242
243
244
245     def collect_fields(self):
246         """ Collects fields from the GUI and saves in class variables """
247         self.name = self.share_name_entry.get_text()
248         self.comment = self.share_comment_entry.get_text()
249         self.password = self.share_name_entry.get_text()
250         # Now to handle the share type resolution
251         if self.stype_disktree_radio_button.get_active() :
252             self.stype = srvsvc.STYPE_DISKTREE
253         elif self.stype_printq_radio_button.get_active() :
254             self.stype = srvsvc.STYPE_PRINTQ
255         else:
256             self.stype = srvsvc.STYPE_IPC
257         # check flags
258         self.flags = (False,False)
259         if self.sflag_temp_check_button.get_active():
260             self.flags[0] = True
261         if self.sflag_hidden_check_button.get_active():
262             self.flags[1] = True
263         if self.islocal :
264             self.path =  self.entry_button.get_filename()
265         else:
266             self.path = self.path_entry.get_text()
267         self.max_users = self.max_users_spinbox.get_value_as_int()
268
269
270
271     def  fields_to_share(self):
272         """ Create a share type 502 object from the fields collected """
273         share = self.pipe.get_share_object(name= self.name,
274                     stype= self.get_stype_final(),
275                     comment= self.comment,
276                     max_users= self.max_users,
277                     password= self.password,
278                     path = self.path
279                     )
280         return share
281
282
283
284     def  create(self):
285         """ Create the window """
286         self.set_title([" New Share",
287                     " Edit Share : "][self.edit_mode]+ " " + self.name)
288         self.icon_name = ["network","network-folder","network-printer",
289                             "network","network-pipe"][self.stype]
290         self.icon_filename = \
291         os.path.join(sys.path[0], "images", (self.icon_name+'.png'))
292         self.set_icon_from_file(self.icon_filename)
293         self.vbox.set_spacing(3)
294         self.set_border_width(5)
295
296
297         #artwork
298         self.desc_box= gtk.HBox()
299         self.vbox.pack_start(self.desc_box,False,True,0)
300
301         hbox = gtk.HBox()
302         icon =  gtk.Image()
303         icon.set_from_file(self.icon_filename)
304
305         hbox.pack_start(icon, False, True, 0)
306         self.desc_box.pack_start(hbox,False, True, 0)
307
308
309         hbox = gtk.HBox()
310         label = gtk.Label()
311         if edit_mode :
312             label.set_text("Edit The Share")
313         else :
314             label.set_text("Add a New Share")
315         label.set_alignment(0, 0.5)
316         hbox.pack_start(label, True, True, 0)
317         self.desc_box.pack_start(hbox,True, True, 0)
318
319         # main box
320
321         self.main_box  = gtk.HBox()
322         self.vbox.pack_start(self.main_box,True,True,0)
323
324         #vertical logo
325         vbox = gtk.VBox()
326         samba_image_filename = os.path.join(sys.path[0], 'images',
327                 'samba-logo-vertical.png')
328         samba_image = gtk.Image()
329         samba_image.set_from_file(samba_image_filename)
330         vbox.pack_end(samba_image, False, True, 0)
331
332         self.main_box.pack_start(vbox, False, True, 0)
333
334         # the main form
335
336         self.form_box = gtk.VBox(3)
337         self.main_box.pack_start(self.form_box, True, True, 0)
338
339         # Name , password and comment (npc) frame
340         frame = gtk.Frame("Name and Comment")
341         self.form_box.pack_start(frame, True, True, 0)
342         frame.set_border_width(5)
343
344         table = gtk.Table(4,2)
345         table.set_border_width(5)
346         table.set_row_spacings(3)
347         table.set_col_spacings(6)
348
349         frame.add(table)
350
351         label = gtk.Label("Share Name : ")
352         label.set_alignment(0, 0.5)
353         table.attach(label, 0, 1, 0, 1, gtk.FILL,gtk.FILL | gtk.EXPAND, 0, 0)
354
355         self.share_name_entry = gtk.Entry()
356         self.share_name_entry.set_tooltip_text('Enter the Share Name')
357         self.share_name_entry.set_text(self.sname)
358         # dcesrv_srvsvc name check does this but just to reduce chances of an error limit max length
359         if self.flags(1):
360             self.share_name_entry.set_max_length(12)
361         else:
362             self.share_name_entry.set_max_length(80)
363         table.attach(self.share_name_entry, 1, 2, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 1, 1)
364
365         label = gtk.Label("Comment  : ")
366         label.set_alignment(0, 0.5)
367         table.attach(label, 0, 1, 1, 2, gtk.FILL,gtk.FILL | gtk.EXPAND, 0, 0)
368
369         self.share_comment_entry = gtk.Entry()
370         self.share_comment_entry.set_max_length(48) # max allowed is 48 MS-SRVS
371         self.share_comment_entry.set_activates_default(True)
372         self.share_comment_entry.set_text(self.comment)
373         self.share_comment_entry.set_tooltip_text('Add a Comment or Description of the Share, Will default to share_type description')
374         table.attach(self.share_comment_entry, 1, 2, 1, 2, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 1, 1)
375
376         label = gtk.Label(' Password  : ')
377         label.set_alignment(0, 0.5)
378         table.attach(label, 0, 1, 2, 3, gtk.FILL,gtk.FILL | gtk.EXPAND, 0, 0)
379
380         self.share_password_entry = gtk.Entry()
381         self.share_password_entry.set_max_length()
382         self.share_password_entry.set_activates_default(True)
383         self.share_password_entry.set_text(self.password)
384         self.share_password_entry.set_visibility(False)
385         self.share_password_entry.set_tooltip_text('Set a Share Password')
386         table.attach(self.share_password_entry, 1, 2, 2, 3, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 1, 1)
387         
388         self.set_pw_visiblity = gtk.CheckButton("Visible")
389         self.set_pw_visiblity.set_tooltip_text('Enable or disable the password visiblity')
390         self.set_pw_visiblity.set_active(False)
391         table.attach(self.set_pw_visiblity, 1, 2, 3, 4,gtk.SHRINK,gtk.FILL, 0, 0)
392         self.set_pw_visiblity.connecct()
393         
394
395         # Share frame
396         frame = gtk.Frame("Share Type")
397         self.form_box.pack_start(frame, True, True, 0)
398
399         table = gtk.Table(1,2,True)
400         frame.add(table)
401
402         # Base Share Types
403         vbox = gtk.VBox(True)
404         vbox.set_border_width(5)
405         table.attach(vbox,0,1,0,1,gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 1, 1)
406
407         # Radio buttons
408         self.stype_disktree_radio_button = gtk.RadioButton(None,'Disktree')
409         self.stype_disktree_radio_button.set_tooltip_text('Disktree (folder) type Share. Default')
410         self.stype_disktree_radio_button.set_active(self.stype == srvsvc.STYPE_DISKTREE)
411         vbox.pack_start(self.stype_disktree_radio_button)
412
413         self.stype_printq_radio_button = gtk.RadioButton(self.stype_disktree_radio_button,'Print Queue')
414         self.stype_printq_radio_button.set_tooltip_text('Shared Print Queue')
415         self.stype_printq_radio_button.set_active(self.stype == srvsvc.STYPE_PRINTQ)
416         vbox.pack_start(self.stype_printq_radio_button)
417
418         self.stype_ipc_radio_button = gtk.RadioButton(self.stype_printq_radio_button,'IPC ')
419         self.stype_ipc_radio_button.set_tooltip_text('Shared Interprocess Communication Pipe (IPC).')
420         self.stype_ipc_radio_button.set_active(self.stype == srvsvc.STYPE_IPC)
421         vbox.pack_start(self.stype_ipc_radio_button)
422
423         # Special Share Flags
424         vbox = gtk.VBox(True)
425         vbox.set_border_width(5)
426         table.attach(vbox,1,2,0,1,gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 1, 1)
427
428         # Check buttons
429         self.sflag_temp_check_button = gtk.CheckButton(self.sflag_default_check_button,'Temporary')
430         self.sflag_temp_check_button.set_tooltip_text('Make share Temporary')
431         self.sflag_temp_check_button.set_active(self.flags[0])
432         vbox.pack_start(self.sflag_temp_check_button)
433
434         self.sflag_hidden_check_button = gtk.CheckButton(self.sflag_temp_check_button,'Hidden ')
435         self.sflag_hidden_check_button.set_tooltip_text('Make share hidden.')
436         self.sflag_hidden_check_button.set_active(self.flags[1])
437         vbox.pack_start(self.sflag_hidden_check_button)
438
439         # Path frame
440
441         frame = gtk.Frame("Path")
442         self.form_box.pack_start(frame, True, True, 0)
443         frame.set_border_width(5)
444
445         table = gtk.Table(1,2)
446         table.set_col_spacings(6)
447
448         label = gtk.Label("Share path : ")
449         label.set_alignment(0, 0.5)
450         table.attach(label, 0, 1, 0, 1, gtk.FILL,gtk.FILL | gtk.EXPAND, 0, 0)
451
452         # FIXME may need another parameter to select type of selctor in combination with local
453         # eg selecting a ipc / printer may be easier with a path
454
455         if self.islocal :
456             self.file_button = gtk.FileChooserButton('Browse')
457             self.file_button.set_current_folder('/home')
458             self.file_button.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
459             self.file_button.set_tooltip_text('Select the folder to share')
460             table.attach(self.file_button, 1, 2, 0, 1, gtk.FILL,gtk.FILL | gtk.EXPAND, 0, 0)
461         else:
462             self.file_button = gtk.Entry()
463             self.file_entry.set_text(self.path)
464             self.file_entry.set_tooltip_text('Path to the folder to share')
465             table.attach(self.file_entry, 1, 2, 0, 1, gtk.FILL,gtk.FILL | gtk.EXPAND, 0, 0)
466
467         # max users frame
468
469         frame = gtk.Frame("Max Users")
470         self.form_box.pack_start(frame, True, True, 0)
471         frame.set_border_width(5)
472
473         table = gtk.Table(1,2)
474         table.set_col_spacings(6)
475
476         label = gtk.Label("Max Users : ")
477         label.set_alignment(0, 0.5)
478         table.attach(label, 0, 1, 0, 1, gtk.FILL,gtk.FILL | gtk.EXPAND, 0, 0)
479
480         # adjustment for max users spinbox
481         self.max_users_adjustment = gtk.Adjustment(self.max_users,1,0xFFFFFFFF,1,5)
482
483         self.max_users_spinbox = gtk.SpinButton(adjustment)
484         self.max_users_spinbox.set_numeric(True)
485         self.max_users_spinbox.set_tooltip_text('Max Users for the Share')
486         table.attach(self.max_users_spinbox, 1, 2, 0, 1, gtk.FILL,gtk.FILL | gtk.EXPAND, 0, 0)