~allsymes/vineyard/fixes

« back to all changes in this revision

Viewing changes to data/widgets/programs.py

  • Committer: Christian Dannie Storgaard
  • Date: 2010-02-26 04:54:30 UTC
  • Revision ID: cybolic@gmail.com-20100226045430-9m9c7p5h7nehzs39
Got program monitoring and error info handling back into a working (and prettier) state. Added some missing functionality touches to the program editing. Added a custom CellRenderer for prettier display of the program listing.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
#
4
4
# Copyright (c) 2007-2009 Christian Dannie Storgaard
5
5
#
6
 
import gtk, pango, re, os
 
6
import gobject, gtk, pango, re, os
7
7
import common, icons
8
8
import wine
9
9
 
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)
46
46
        
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)
51
53
        
52
54
        self.widgets['treeview'].append_column(self.widgets['treeview_column'])
53
55
        
88
90
        
89
91
        self.widgets['vbox'].show_all()
90
92
    
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)
96
 
 
97
 
            if 'description' in info:
98
 
                model.append([ icon, "%s\n<small>%s</small>" % (name, info['description']) ])
99
 
            else:
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'])
 
96
        else:
 
97
            return program_data['name']
 
98
    
 
99
    def _model_add_section(self, model, header, programdict, first=False):
 
100
        if first == True:
 
101
            model.append([None, '<header first>%s</header>' % header])
 
102
        else:
 
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]
 
106
            
 
107
            model.append([
 
108
                icons.getIconPixbufFromProgram(program_data),
 
109
                self._get_markup_from_program_data(program_data)
 
110
            ])
101
111
    
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'])
133
143
 
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])
184
194
        
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,))
191
201
                    return False
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()
395
405
        
 
406
        self.widgets['entry_name'].grab_focus()
 
407
        self.widgets['dialog'].set_default_response(gtk.RESPONSE_OK)
 
408
        
396
409
        self.widgets['dialog'].connect('response', self._on_dialog_response)
397
410
        
398
411
        self.widgets['filechooserdialog_program_icon'] = common.filechooserdialog_new_with_filters(
429
442
        self.icon_filename = None
430
443
        if icon:
431
444
                self.widgets['image_icon'].set_from_pixbuf(icon)
432
 
        if terminal:
 
445
        if terminal == True:
433
446
            self.widgets['combobox_type'].set_active(1)
434
447
        else:
435
448
            self.widgets['combobox_type'].set_active(0)
452
465
            self.program_data.update({'name': name, 'programcommand': command, 'description': description, 'terminal': terminal, 'uninstall': uninstall})
453
466
            if icon != None:
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
456
469
 
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
465
478
 
466
479
            """ Update the listview with the new info """
471
484
                column_num = 1,
472
485
                startswith = True
473
486
            )
474
 
            if description.strip():
475
 
                title = "%s\n<small>%s</small>" % (name, description)
476
 
            else:
477
 
                title = name
 
487
            
 
488
            title = self._get_markup_from_program_data({'name': name, 'description': description})
478
489
            
479
490
            pixbuf = common.pixbuf_new_from_program_data(self.program_data, force_update=True)
480
491
            
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)
547
 
        return process.pid
 
557
        gobject.timeout_add_seconds(1, self._start_monitoring)
 
558
        self.pid = process.pid
548
559
 
549
 
    def _start_monitoring(self, pid):
550
 
        process = RUNNING_PROGRAMS[pid]
 
560
    def _start_monitoring(self):
 
561
        process = RUNNING_PROGRAMS[self.pid]
551
562
        process.poll()
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
574
584
            return False
575
585
        else:
576
586
            return True
577
587
 
578
588
    def _on_dialog_main_response(self, dialog, response):
579
589
        dialog.destroy()
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)}
609
619
                    else:
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
623
633
            else:
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)
629
638
 
630
639
            #self.widgets['dialog-programerror'].set_title(_("Error information for %s") % process.name)
631
640
            #self.widgets['dialog-programerror'].set_sensitive(False)
662
671
        
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)
666
677
        
667
678
        vbox.pack_start(label, expand=False, fill=True)
668
679
        
 
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)
 
685
        
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)
672
690
        
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)
675
693
        else:
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)
679
697
        
680
698
        hbox.pack_start(vbox, expand=True, fill=True)
681
699