4
4
# Copyright (c) 2007-2009 Christian Dannie Storgaard
6
import gtk, pango, re, os
6
import gobject, gtk, pango, re, os
44
44
self.widgets['treeview_column'].pack_start(renderer_app_icon, False)
45
45
self.widgets['treeview_column'].set_cell_data_func(renderer_app_icon, common.cell_data_function_icon_markup_icon)
47
renderer_app = gtk.CellRendererText()
47
#renderer_app = gtk.CellRendererText()
48
renderer_app = common.CellRendererHeaderText()
48
49
renderer_app.set_property("ellipsize", pango.ELLIPSIZE_END)
49
50
self.widgets['treeview_column'].pack_start(renderer_app, True)
50
self.widgets['treeview_column'].set_cell_data_func(renderer_app, common.cell_data_function_icon_markup_markup)
51
#self.widgets['treeview_column'].set_cell_data_func(renderer_app, common.cell_data_function_icon_markup_markup)
52
self.widgets['treeview_column'].add_attribute(renderer_app, 'markup', 1)
52
54
self.widgets['treeview'].append_column(self.widgets['treeview_column'])
89
91
self.widgets['vbox'].show_all()
91
def _model_add_section(self, model, header, programdict):
92
model.append([None, '<header>%s</header>' % header])
93
for name in sorted(programdict.keys(), key=unicode.lower):
94
info = programdict[name]
95
icon = icons.getIconPixbufFromProgram(info)
97
if 'description' in info:
98
model.append([ icon, "%s\n<small>%s</small>" % (name, info['description']) ])
100
model.append([ icon, name ])
93
def _get_markup_from_program_data(self, program_data):
94
if 'description' in program_data:
95
return "%s\n<small>%s</small>" % (program_data['name'], program_data['description'])
97
return program_data['name']
99
def _model_add_section(self, model, header, programdict, first=False):
101
model.append([None, '<header first>%s</header>' % header])
103
model.append([None, '<header>%s</header>' % header])
104
for program_id in sorted(programdict.keys(), key=unicode.lower):
105
program_data = programdict[program_id]
108
icons.getIconPixbufFromProgram(program_data),
109
self._get_markup_from_program_data(program_data)
102
112
def reload(self, settings):
103
113
self.widgets['treeview'].set_sensitive(False)
131
141
if 'path' in program:
132
142
program['name'] = u"%s: %s" % (program['path'], program['name'])
134
self._model_add_section(liststore, _('Registered Programs'), registered_programs)
144
self._model_add_section(liststore, _('Registered Programs'), registered_programs, first=True)
135
145
self._model_add_section(liststore, _('Registered Libraries'), registered_libraries)
136
146
self._model_add_section(liststore, _('Menu Programs'), menu_programs)
137
147
self._model_add_section(liststore, _('Websites'), weblinks)
183
193
selected = unicode(common.treeview_get_selected_row(treeview)[1].split('\n')[0])
185
195
""" If the user clicked a header, select the first non-header row instead """
186
if selected.startswith('<header>'):
196
if selected.startswith('<header'):
187
197
model = treeview.get_model()
188
198
for rownr in range(len(model)):
189
if not model[rownr][1].split('\n')[0].startswith('<header>'):
199
if not model[rownr][1].split('\n')[0].startswith('<header'):
190
200
treeview.set_cursor((rownr,))
192
202
treeview.get_selection().unselect_all()
393
403
self.widgets['button_command'].connect('clicked', self._on_button_command_clicked)
394
404
self.widgets['dialog'].show_all()
406
self.widgets['entry_name'].grab_focus()
407
self.widgets['dialog'].set_default_response(gtk.RESPONSE_OK)
396
409
self.widgets['dialog'].connect('response', self._on_dialog_response)
398
411
self.widgets['filechooserdialog_program_icon'] = common.filechooserdialog_new_with_filters(
452
465
self.program_data.update({'name': name, 'programcommand': command, 'description': description, 'terminal': terminal, 'uninstall': uninstall})
454
467
self.program_data.update({'icon': icon})
455
print "Added/Updated program info: %s" % self.program_data
468
#print "Added/Updated program info: %s" % self.program_data
457
470
""" Save them in the registry """
458
471
wine.programs.setProgramOptions(self.program_data['_registrykey'], name=name, icon=icon, command=command, description=description, terminal=terminal, uninstall=uninstall)
460
473
""" Update our internal info """
461
474
if self.program_id == None or self.program_id in self.settings['programs']:
462
475
self.settings['programs'][self.program_id] = self.program_data
463
elif programname in self.settings['menuprograms']:
476
elif program_id in self.settings['menuprograms']:
464
477
self.settings['menuprograms'][self.program_id] = self.program_data
466
479
""" Update the listview with the new info """
472
485
startswith = True
474
if description.strip():
475
title = "%s\n<small>%s</small>" % (name, description)
488
title = self._get_markup_from_program_data({'name': name, 'description': description})
479
490
pixbuf = common.pixbuf_new_from_program_data(self.program_data, force_update=True)
543
554
process = wine.run(command)
544
555
RUNNING_PROGRAMS[process.pid] = process
545
556
RUNNING_PROGRAMS[process.pid].name = name
546
gobject.timeout_add_seconds(1, self._start_monitoring, process.pid)
557
gobject.timeout_add_seconds(1, self._start_monitoring)
558
self.pid = process.pid
549
def _start_monitoring(self, pid):
550
process = RUNNING_PROGRAMS[pid]
560
def _start_monitoring(self):
561
process = RUNNING_PROGRAMS[self.pid]
552
563
if process.returncode != None:
553
564
if process.returncode != 0:
558
569
dialog.set_icon_name('vineyard-preferences')
559
570
dialog.set_markup('<span weight="bold" size="larger">%s</span>' % \
560
571
_("The program exited with an error"))
561
dialog.format_secondary_markup(u'The program "%(program)s" did ' + \
562
u'not exit cleanly and any work or progress you may have ' + \
563
u'done in the program may have been lost.' % \
564
{'program': RUNNING_PROGRAMS[pid].name})
572
dialog.format_secondary_markup(unicode('The program <b>%(program)s</b> did ' + \
573
'not exit cleanly and any work or progress you may have ' + \
574
'done in the program may have been lost.') % \
575
{'program': common.escape_xml(process.name)})
565
576
settings = gtk.settings_get_default()
566
577
settings.set_property('gtk-alternative-button-order', True)
567
578
button_info = gtk.Button("More info")
570
581
dialog.set_default_response(gtk.RESPONSE_OK)
571
582
dialog.connect("response", self._on_dialog_main_response)
572
583
dialog.show_all()
573
dialog.program_pid = pid
578
588
def _on_dialog_main_response(self, dialog, response):
580
process = RUNNING_PROGRAMS[dialog.program_pid]
590
process = RUNNING_PROGRAMS[self.pid]
581
591
errortext = process.stderr.readlines()
582
592
if response == 10:
583
593
show_explanation = False
602
612
missing_packages = list(set(missing_packages))
603
613
if len(missing_packages):
604
614
if len(missing_packages) == 1:
605
text += "\n\n"+_("Based on this output it looks like " + \
615
text += str("\n\n"+_("Based on this output it looks like " + \
606
616
"you need to install <b>%(package)s</b> in order " + \
607
"to get \"%(program)s\" to run successfully.") % \
608
{'package': missing_packages[0], 'program': process.name}
617
"to get <b>%(program)s</b> to run successfully.")) % \
618
{'package': missing_packages[0], 'program': common.escape_xml(process.name)}
610
620
list_of_packages = _(", ").join([ "<b>%s</b>" % i for i in missing_packages[:-1] ])+ \
611
621
_(" and ")+missing_packages[-1]
612
text += "\n\n"+_("Based on this output it looks like " + \
622
text += str("\n\n"+_("Based on this output it looks like " + \
613
623
"you need to install %(packages)s in order to get " + \
614
"\"%(program)s\" to run successfully.") % \
615
{'packages': list_of_packages, 'program': process.name}
624
"<b>%(program)s</b> to run successfully.")) % \
625
{'packages': list_of_packages, 'program': common.escape_xml(process.name)}
616
626
#self.widgets['label-programerrorexplanation'].set_line_wrap(True)
617
627
#self.widgets['label-programerrorexplanation'].set_markup(text)
618
628
#self.widgets['label-programerrorexplanation'].show()
619
629
#self.widgets['vbox-programerrorexplanation'].show_all()
620
630
#textview = self.widgets['textview-programerrorexplanation']
621
#show_explanation = True
631
show_explanation = True
622
632
# We didn't find anything, just display the raw output
624
634
#self.widgets['label-programerrortitle'].set_markup('<span weight="bold" size="larger">%s</span>' % _("When running \"%s\" Wine returned the following errors:") % process.name)
625
635
#self.widgets['vbox-programerrornoexplanation'].show_all()
626
636
#textview = self.widgets['textview-programerror']
627
text = '<span weight="bold" size="larger">%s</span>' % \
628
_("When running \"%s\" Wine returned the following errors:") % process.name
637
text = _("When running <b>%s</b> Wine returned the following errors:") % common.escape_xml(process.name)
630
639
#self.widgets['dialog-programerror'].set_title(_("Error information for %s") % process.name)
631
640
#self.widgets['dialog-programerror'].set_sensitive(False)
663
672
label = gtk.Label()
664
673
label.set_line_wrap(True)
665
label.set_markup(title)
674
label.set_alignment(0.0, 0.5)
675
#label.set_markup('<span weight="bold" size="larger">%s</span>' % text)
676
label.set_markup('%s' % text)
667
678
vbox.pack_start(label, expand=False, fill=True)
680
scrolledwindow = gtk.ScrolledWindow()
681
scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
682
scrolledwindow.set_size_request(
683
common.widget_get_char_width(scrolledwindow)*80,
684
common.widget_get_char_height(scrolledwindow)*6)
669
686
textview = gtk.TextView()
670
687
textview.get_buffer().set_text(error)
671
688
textview.modify_font(pango.FontDescription('monospace'))
689
scrolledwindow.add(textview)
673
if show_explanation == None:
674
vbox.pack_start(textview, expand=True, fill=True)
691
if not show_explanation:
692
vbox.pack_start(scrolledwindow, expand=True, fill=True)
676
694
expander = gtk.Expander(_("Detailed error information"))
677
expander.add(textview)
678
vbox.pack_start(expander, expand=False, fill=True)
695
expander.add(scrolledwindow)
696
vbox.pack_start(expander, expand=True, fill=True)
680
698
hbox.pack_start(vbox, expand=True, fill=True)