Example #1
0
    def _onTvFilesCustomContextMenuRequested(self, pos ):
        """Connected automatically by uic
        """
        menu = QMenu()
        
        menu.addAction( core.actionManager().action( "mFile/mClose/aCurrent" ) )
        menu.addAction( core.actionManager().action( "mFile/mSave/aCurrent" ) )
        menu.addAction( core.actionManager().action( "mFile/mReload/aCurrent" ) )
        menu.addSeparator()
        
        # sort menu
        sortMenu = QMenu( self )
        group = QActionGroup( sortMenu )

        group.addAction( self.tr( "Opening order" ) )
        group.addAction( self.tr( "File name" ) )
        group.addAction( self.tr( "URL" ) )
        group.addAction( self.tr( "Suffixes" ) )
        group.triggered.connect(self._onSortTriggered)
        sortMenu.addActions( group.actions() )
        
        for i, sortMode in enumerate(["OpeningOrder", "FileName", "URL", "Suffixes"]):
            action = group.actions()[i]
            action.setData( sortMode )
            action.setCheckable( True )
            if sortMode == self.model.sortMode():
                action.setChecked( True )
        
        aSortMenu = QAction( self.tr( "Sorting" ), self )
        aSortMenu.setMenu( sortMenu )
        aSortMenu.setIcon( QIcon( ":/enkiicons/sort.png" ))
        aSortMenu.setToolTip( aSortMenu.text() )
        
        menu.addAction( sortMenu.menuAction() )
        menu.exec_( self.tvFiles.mapToGlobal( pos ) )
Example #2
0
    def _update(self, action: QAction, initialize: bool):
        """updates the internal values from the given action."""
        if not self._action:
            return
        self._disconnectAction()
        self.changed.disconnect(self._updateToolTipWithKeySequence)
        if initialize:
            self.setSeparator(action.isSeparator())
            self.setMenuRole(action.menuRole())

        if self.hasAttribute(ProxyActionAttribute.UpdateIcon) or initialize:
            self.setIcon(action.icon())
            self.setIconText(action.iconText())
            self.setIconVisibleInMenu(action.isIconVisibleInMenu())

        if self.hasAttribute(ProxyActionAttribute.UpdateText) or initialize:
            self.setText(action.text())
            self._toolTip = action.toolTip()
            self._updateToolTipWithKeySequence()
            self.setStatusTip(action.statusTip())
            self.setWhatsThis(action.whatsThis())

        self.setCheckable(action.isCheckable())

        if not initialize:
            self.setChecked(action.isChecked())
            self.setEnabled(action.isEnabled())
            self.setVisible(action.isVisible())

        self._connectAction()
        self.changed.connect(self._updateToolTipWithKeySequence)
Example #3
0
 def __msgActionWarning(self, newAction: QAction, actionId: ItemId, oldAction: QAction or None):
     """
     :returns: a Warning text with the given Action's and ItemId's properties
     :param newAction: Action to take strings from
     :param  actionId: ItemId to take strings from
     """
     oldActionMsg = " {}/{}".format(oldAction.objectName(), oldAction.text()) if oldAction else ""
     msg = "addOverrideAction {}/{}: Action{} is already registered for context {} {}.".format(
         newAction.objectName(), newAction.text(), oldActionMsg, actionId.uniqueIdentifier, actionId.toSetting())
     return msg
Example #4
0
    def _onTvFilesCustomContextMenuRequested(self, pos):
        """Connected automatically by uic
        """
        menu = QMenu()

        menu.addAction(core.actionManager().action("mFile/mClose/aCurrent"))
        menu.addAction(core.actionManager().action("mFile/mSave/aCurrent"))
        menu.addAction(core.actionManager().action("mFile/mReload/aCurrent"))
        menu.addSeparator()

        # sort menu
        sortMenu = QMenu(self)
        group = QActionGroup(sortMenu)

        group.addAction(self.tr("Opening order"))
        group.addAction(self.tr("File name"))
        group.addAction(self.tr("URL"))
        group.addAction(self.tr("Suffixes"))
        group.triggered.connect(self._onSortTriggered)
        sortMenu.addActions(group.actions())

        for i, sortMode in enumerate(
            ["OpeningOrder", "FileName", "URL", "Suffixes"]):
            action = group.actions()[i]
            action.setData(sortMode)
            action.setCheckable(True)
            if sortMode == self.model.sortMode():
                action.setChecked(True)

        aSortMenu = QAction(self.tr("Sorting"), self)
        aSortMenu.setMenu(sortMenu)
        aSortMenu.setIcon(QIcon(":/enkiicons/sort.png"))
        aSortMenu.setToolTip(aSortMenu.text())

        menu.addAction(sortMenu.menuAction())
        menu.exec_(self.tvFiles.mapToGlobal(pos))
class InputSinkUI(SinkUI):

    def __init__(self, parent):
        self.mouse_pressed = False
        SinkUI.__init__(self, parent)
        self.setAcceptDrops(False)
        self.setContentsMargins(0,0,0,0)
        self.layout.setContentsMargins(6,2,6,0)

    def createMute(self):
        self.mute = InputMuteButton(self)
        self.mute.setSizePolicy(QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed,True))
        self.connect(self.mute, SIGNAL("clicked()"), self.on_mute_cb)

    def context_menu_create_custom(self):
        self.create_menu_switch_sink()
        self.create_menu_ladspa_effects()

    def create_menu_kill_sink(self):
        self.action_kill = QAction(i18n("Disconnect/kill"), self.popup_menu)
        self.popup_menu.addAction(self.action_kill)
        self.action_kill.triggered.connect(self.on_contextmenu_clicked)

    def context_menu_create_settings(self):
        pass

    def create_menu_switch_sink(self):
        sink_menu = QMenu(i18n("Move To"), self.popup_menu)
        sinks = self.veromix.get_sink_widgets()
        for sink in sinks:
            action = QAction(sink.name(), self.popup_menu)
            sink_menu.addAction(action)
        self.popup_menu.addMenu(sink_menu)

    def create_menu_ladspa_effects(self):
        if not self.veromix.is_ladspa_enabled():
            return

    def context_menu_create_effects(self):
        pass

    def on_contextmenu_clicked(self, action):
        if type(action) == bool:
            return
        if action.text() == self.action_kill.text():
            self.sink_input_kill()
            return 0
        # search ouputs for text, and move sink_input
        for sink in self.veromix.get_sink_widgets():
            if action.text() == sink.name():
                self.pa.move_sink_input(self.index, int(sink.index))
                return 0

    def getOutputIndex(self):
        return self.pa_sink.props["sink"]

    def update_label(self):
        text =  self.pa_sink.name
        bold = self.pa_sink.props["app"]

        iconname = None
        if self.pa_sink.props["app_icon"] != "None":
            iconname = self.pa_sink.props["app_icon"]
        if iconname == None and  self.pa_sink.props["app"] != "None":
            iconname = self.veromix.query_application(self.pa_sink.props["app"])
        if bold == "knotify":
            bold = i18n("Event Sounds")
            text = ""
            iconname = 'dialog-information'
        if bold == "npviewer.bin" or bold == "plugin-container":
            bold = i18n("Flash Player")
            text = ""
            iconname = 'flash'
        if bold == "chromium-browser":
            bold = i18n("Chromium Browser")
            text = ""
        if bold == "Skype":
            if text == "Event Sound":
                text = i18n("Event Sound")
            if text == "Output":
                text = i18n("Voice Output")

        if text == "LADSPA Stream" or (self.pa_sink.props["media.name"] == "LADSPA Stream"):
            for sink in self.veromix.get_sink_widgets():
                if sink.pa_sink.props["owner_module"] == self.pa_sink.props["owner_module"]:
                    bold = sink.pa_sink.props["device.ladspa.name"]
                    text = ""
                    iconname = sink.pa_sink.props["device.icon_name"]

        # FIXME
        if bold in ["", "None", None]:
            bold = text
            text = ""

        if text in ["None", None]:
            text = ""

        if iconname in ["", "None", None]:
            iconname = "mixer-pcm"

        if iconname :
            self.mute.setBigIconName(iconname)
            self.updateIcon()

        if self.slider:
            self.set_name(bold)
            self.slider.setText(text)
            self.slider.setBoldText(bold)

### Drag and Drop

    def mousePressEvent(self, event):
        self.mouse_pressed = True

    def mouseReleaseEvent(self, event):
        self.mouse_pressed = False

    def mouseMoveEvent(self,e):
        if self.mouse_pressed :
            self.startDrag(e)

    def startDrag(self,event):
        drag = QDrag(event.widget())
        drag.setPixmap(self.mute.icon().pixmap(self.size().height(),self.size().height()))
        mimedata = QMimeData()
        liste = []
        liste.append(QUrl( "veromix://sink_input_index:" + str(int(self.index))))
        mimedata.setUrls(liste)
        drag.setMimeData(mimedata)
        #drag.setHotSpot(event.pos() - self.rect().topLeft())
        dropAction = drag.start(Qt.MoveAction)
Example #6
0
 def createuiaction(self):
     action = QAction(QIcon(self.icon), self.icontext, None)
     if not self.valid[0]:
         action.setEnabled(False)
         action.setText(action.text() + " (invalid)")
     return action
Example #7
0
class FeatureFormBase(QWidget):
    requiredfieldsupdated = pyqtSignal(bool)
    formvalidation = pyqtSignal(bool)
    helprequest = pyqtSignal(str)
    showwidget = pyqtSignal(QWidget)
    loadform = pyqtSignal()
    rejected = pyqtSignal(str, int)
    accepted = pyqtSignal()
    enablesave = pyqtSignal(bool)
    showlargewidget = pyqtSignal(object, object, object, dict)

    def __init__(self, form, formconfig, feature, defaults, parent, *args, **kwargs):
        super(FeatureFormBase, self).__init__(parent)
        self.form = form
        self.formconfig = formconfig
        self.boundwidgets = CaseInsensitiveDict()
        self.requiredfields = CaseInsensitiveDict()
        self.feature = feature
        self.geomwidget = None
        self.defaults = defaults
        self.bindingvalues = CaseInsensitiveDict()
        self.editingmode = kwargs.get("editmode", False)
        self.widgetidlookup = {}
        self._has_save_buttons = False
        self.star_all_button = QAction(QIcon(":/icons/save_default_all"), "Star All", self, triggered=self.star_all)

    def open_large_widget(self, widgettype, lastvalue, callback, config=None):
        self.showlargewidget.emit(widgettype, lastvalue, callback, config)

    def form_actions(self):
        builtin = []
        if self._has_save_buttons:
            builtin.append(self.star_all_button)
        useractions = self.user_form_actions()
        if not useractions:
            useractions = []
        return builtin + useractions

    def star_all(self):
        """
        Star or unstar all buttons on the form.
        :param star_all: True to star all buttons on the form.
        """
        checked = self.star_all_button.text() == "Star All"
        buttons = self._field_save_buttons()
        for button in buttons:
            button.setChecked(checked)

        if checked:
            self.star_all_button.setText("Star None")
        else:
            self.star_all_button.setText("Star All")

    @property
    def is_capturing(self):
        return self.editingmode == False

    @is_capturing.setter
    def is_capturing(self, value):
        self.editingmode = not value

    def updaterequired(self, value):
        passed = self.allpassing
        self.formvalidation.emit(passed)

    def validateall(self):
        widgetwrappers = self.boundwidgets.itervalues()
        for wrapper in widgetwrappers:
            wrapper.validate()

    def setupui(self):
        """
        Setup the widget in the form
        """
        self.geomwidget = self.findcontrol("__geomwidget")

        widgetsconfig = copy.deepcopy(self.formconfig['widgets'])

        try:
            widgetsconfig = self.get_widgets(widgetsconfig)
        except AttributeError:
            pass

        layer = self.form.QGISLayer
        # Crash in QGIS if you lookup a field that isn't found.
        # We just make a dict with all fields lower because QgsFields is case sensitive.
        fields = {field.name().lower(): field for field in layer.pendingFields().toList()}

        # Build a lookup for events
        self.events = collections.defaultdict(list)
        for event in self.form.events:
            self.events[event['source']].append(event)

        widgetsconfig = copy.deepcopy(widgetsconfig)
        self.sectionwidgets = {}

        currentsection = None
        for config in widgetsconfig:
            widgettype = config['widget']
            if widgettype == "Section":
                name = config['name']
                currentsection = name
                self.sectionwidgets[name] = []
                continue

            field = config['field']
            if not field:
                utils.info("Skipping widget. No field defined")
                continue

            field = field.lower()

            if field in self.boundwidgets:
                utils.warning("Can't bind the same field ({}) twice.".format(field))
                continue

            widget = self.findcontrol(field)
            if widget is None:
                widget = roam.editorwidgets.core.createwidget(widgettype)
                config['hidden'] = True
                utils.info("No widget named {} found so we have made one.".format(field))

            label = self.findcontrol("{}_label".format(field))
            if label is None:
                utils.debug("No label found for {}".format(field))

            widgetconfig = config.get('config', {})
            widgetconfig['formwidget'] = self
            try:
                qgsfield = fields[field]
            except KeyError:
                utils.log("No field for ({}) found".format(field))

            context = dict(project=self.form.project,
                           form=self.form,
                           featureform=self)
            try:
                widgetwrapper = roam.editorwidgets.core.widgetwrapper(widgettype=widgettype,
                                                                      layer=self.form.QGISLayer,
                                                                      field=qgsfield,
                                                                      widget=widget,
                                                                      label=label,
                                                                      config=widgetconfig,
                                                                      context=context)
            except EditorWidgetException as ex:
                utils.exception(ex)
                continue

            widgetwrapper.default_events = config.get('default_events', ['capture'])
            readonlyrules = config.get('read-only-rules', [])

            if self.editingmode and 'editing' in readonlyrules:
                widgetwrapper.readonly = True
            elif 'insert' in readonlyrules or 'always' in readonlyrules:
                widgetwrapper.readonly = True

            widgetwrapper.hidden = config.get('hidden', False)

            widgetwrapper.newstyleform = self.formconfig.get("newstyle", False)
            widgetwrapper.required = config.get('required', False)
            widgetwrapper.id = config.get('_id', '')

            # Only connect widgets that have events
            if widgetwrapper.id in self.events:
                widgetwrapper.valuechanged.connect(partial(self.check_for_update_events, widgetwrapper))

            widgetwrapper.valuechanged.connect(self.updaterequired)

            try:
                changedslot = getattr(self, "widget_{}_changed".format(field))
                widgetwrapper.valuechanged.connect(changedslot)
            except AttributeError:
                pass

            widgetwrapper.largewidgetrequest.connect(RoamEvents.show_widget.emit)

            self._bindsavebutton(field)
            self.boundwidgets[field] = widgetwrapper
            try:
                self.widgetidlookup[config['_id']] = widgetwrapper
            except KeyError:
                pass

            if currentsection:
                self.sectionwidgets[currentsection].append(widgetwrapper)

    def widgets_for_section(self, name):
        try:
            return self.sectionwidgets[name]
        except KeyError:
            return []

    def get_widget_from_id(self, id):
        try:
            return self.widgetidlookup[id]
        except KeyError:
            return None

    def check_for_update_events(self, widget, value):
        if not self.feature:
            return

        from qgis.core import QgsExpression, QgsExpressionContext, QgsExpressionContextScope
        # If we don't have any events for this widgets just get out now
        if not widget.id in self.events:
            return

        events = self.events[widget.id]
        events = [event for event in events if event['event'].lower() == 'update']
        if not events:
            return

        feature = self.to_feature(no_defaults=True)

        for event in events:
            action = event['action'].lower()
            targetid = event['target']
            if targetid == widget.id:
                utils.log("Can't connect events to the same widget. ID {}".format(targetid))
                continue

            widget = self.get_widget_from_id(targetid)

            if not widget:
                utils.log("Can't find widget for id {} in form".format(targetid))
                continue

            condition = event['condition']
            expression = event['value']

            context = QgsExpressionContext()
            scope = QgsExpressionContextScope()
            scope.setVariable("value", value)
            scope.setVariable("field", widget.field)
            context.setFeature(feature)
            context.appendScope(scope)

            conditionexp = QgsExpression(condition)
            exp = QgsExpression(expression)

            if action.lower() == "show":
                widget.hidden = not conditionexp.evaluate(context)
            if action.lower() == "hide":
                widget.hidden = conditionexp.evaluate(context)
            if action == 'widget expression':
                if conditionexp.evaluate(context):
                    newvalue = self.widget_default(field, feature=feature)
                    widget.setvalue(newvalue)
            if action == 'set value':
                if conditionexp.evaluate(context):
                    newvalue = exp.evaluate(context)
                    widget.setvalue(newvalue)

    def bindvalues(self, values, update=False):
        """
        Bind the values to the form.
        """
        if not update:
            self.bindingvalues = CaseInsensitiveDict(values)
        else:
            for key, value in values.iteritems():
                try:
                    self.bindingvalues[key] = value
                except KeyError:
                    continue

        for field, value in values.iteritems():
            value = nullcheck(value)
            try:
                wrapper = self.boundwidgets[field]
                if hasattr(wrapper, 'savetofile') and wrapper.savetofile:
                    if value and not os.path.exists(value):
                        value = os.path.join(self.form.project.image_folder, value)

                self.boundwidgets[field].setvalue(value)
            except KeyError:
                utils.debug("Can't find control for field {}. Ignoring".format(field))

        self.validateall()
        if self.geomwidget and self.feature:
            self.geomwidget.set_geometry(self.feature.geometry())

    def bind_feature(self, feature):
        self.feature = feature
        values = self.form.values_from_feature(feature)
        self.bindvalues(values)

    def getvalues(self, no_defaults=False):
        def shouldsave(field):
            name = "{}_save".format(field)
            button = self.findcontrol(name)
            if not button is None:
                return button.isChecked()

        savedvalues = {}
        values = CaseInsensitiveDict(self.bindingvalues)
        for field, wrapper in self.boundwidgets.iteritems():
            if not no_defaults and wrapper.get_default_value_on_save:
                value = self.widget_default(field)
            else:
                value = wrapper.value()
                extradata = wrapper.extraData()
                values.update(extradata)

            # TODO this should put pulled out and unit tested. MOVE ME!
            # NOTE: This is photo widget stuff and really really doesn't belong here.
            if hasattr(wrapper, 'savetofile') and wrapper.savetofile and wrapper.saveable:
                if wrapper.filename and self.editingmode:
                    name = os.path.basename(wrapper.filename)
                    name, extension = os.path.splitext(name)

                    if wrapper.modified:
                        if not name.endswith("_edited"):
                            newend = "_edited{}".format(extension)
                            value = name + newend
                        else:
                            value = os.path.basename(wrapper.filename)
                    else:
                        value = os.path.basename(wrapper.filename)
                else:
                    if wrapper.modified:
                        value = wrapper.get_filename()
                    else:
                        value = ''

            if shouldsave(field):
                savedvalues[field] = value
            values[field] = value

        return values, savedvalues

    def findcontrol(self, name, all=False):
        regex = QRegExp("^{}$".format(QRegExp.escape(name)))
        regex.setCaseSensitivity(Qt.CaseInsensitive)
        try:
            if all:
                return self.findChildren(QWidget, regex)
            else:
                widget = self.findChildren(QWidget, regex)[0]
        except IndexError:
            widget = None
        return widget

    def _field_save_buttons(self):
        """
        Return all the save buttons for the form.
        :return:
        """
        for field in self.boundwidgets.keys():
            name = "{}_save".format(field)
            savebutton = self.findcontrol(name)
            if savebutton:
                yield savebutton

    def _bindsavebutton(self, field):
        name = "{}_save".format(field)
        button = self.findcontrol(name)
        if button is None:
            return

        button.setCheckable(not self.editingmode)
        button.setIcon(QIcon(":/icons/save_default"))
        button.setIconSize(QSize(24, 24))
        button.setChecked(field in self.defaults)
        button.setVisible(not self.editingmode)
        self._has_save_buttons = True

    def createhelplinks(self):
        def createhelplink(label, folder):
            def getHelpFile():
                # TODO We could just use the tooltip from the control to show help
                # rather then having to save out a html file.
                name = label.objectName()
                if name.endswith("_label"):
                    name = name[:-6]
                filename = "{}.html".format(name)
                filepath = os.path.join(folder, "help", filename)
                if os.path.exists(filepath):
                    return filepath
                else:
                    return None

            if label is None:
                return

            helpfile = getHelpFile()
            if helpfile:
                text = '<a href="{}">{}<a>'.format(helpfile, label.text())
                label.setText(text)
                label.linkActivated.connect(self.helprequest.emit)

        for label in self.findChildren(QLabel):
            createhelplink(label, self.form.folder)

    def widget_default(self, name, feature=None):
        """
        Return the default value for the given widget
        """
        try:
            widgetconfig = self.form.widget_by_field(name)
        except IndexError:
            raise KeyError("Widget with name {} not found on form".format(name))

        if not 'default' in widgetconfig:
            raise KeyError('Default value not defined for this field {}'.format(name))

        if not feature:
            feature = self.feature

        return defaults.widget_default(widgetconfig, feature, self.form.QGISLayer)

    def close_form(self, reason=None, level=1):
        self.rejected.emit(reason, level)

    def to_feature(self, no_defaults=False):
        """
        Create a QgsFeature from the current form values
        """
        if not self.feature:
            return

        feature = QgsFeature(self.feature.fields())
        feature.setGeometry(QgsGeometry(self.feature.geometry()))
        try:
            values, _ = self.getvalues(no_defaults=no_defaults)
        except TypeError:
            values, _ = self.getvalues()

        self.updatefeautrefields(feature, values)
        self.update_geometry(feature)
        return feature
Example #8
0
 def createuiaction(self):
     action = QAction(QIcon(self.icon), self.icontext, None)
     if not self.valid[0]:
         action.setEnabled(False)
         action.setText(action.text() + " (invalid)")
     return action
Example #9
0
class QMPCApp(QObject):
    __images__ = {
        'background':           "images/background.png",
    }
    
    __icons__  = {
        'homeButton':           "general_backspace",
        'volumeButton':         "general_speaker",
        'settingsButton':       "keyboard_menu",
        'prevButton':           "/etc/hildon/theme/mediaplayer/Back.png",
        'prevButtonPressed':    "/etc/hildon/theme/mediaplayer/BackPressed.png",
        'playButton':           "/etc/hildon/theme/mediaplayer/Play.png",
        'pauseButton':          "/etc/hildon/theme/mediaplayer/Pause.png",
        'stopButton':           "/etc/hildon/theme/mediaplayer/Stop.png",
        'stopButtonPressed':    "/etc/hildon/theme/mediaplayer/StopPressed.png",
        'nextButton':           "/etc/hildon/theme/mediaplayer/Forward.png",
        'nextButtonPressed':    "/etc/hildon/theme/mediaplayer/ForwardPressed.png",
        'repeatButton':         "/etc/hildon/theme/mediaplayer/Repeat.png",
        'repeatButtonPressed':  "/etc/hildon/theme/mediaplayer/RepeatPressed.png",
        'shuffleButton':        "/etc/hildon/theme/mediaplayer/Shuffle.png",
        'shuffleButtonPressed': "/etc/hildon/theme/mediaplayer/ShufflePressed.png",
    }

    def __init__(self):
        super(QMPCApp,self).__init__()
        self.mw = None
        self.initData()
        self.initMPD()
        self.initActions()
        self.initGUI()
        QTimer.singleShot(100,self.deferredStart)

    def deferredStart(self):
        if self.data.autoconnect: self.connectMPD()

    def initData(self):
        self.selectedServerName = None
        self.data = DataModel()
        self.data.loadSettings()
        self.imagehelper = ImageHelper(images=self.__images__,
                                       icons=self.__icons__)
        QApplication.instance().aboutToQuit.connect(self.data.saveSettings)

    def initActions(self):
        self.actionPlayer = QAction("Player", self)
        self.actionPlayer.triggered.connect(
            lambda: self.showWidget(self.player))
        self.actionPlaylist = QAction("Playlist",self)
        self.actionPlaylist.triggered.connect(
            lambda: self.showWidget(self.playlist))
        self.actionBrowser = QAction("Browser",self)
        self.actionBrowser.triggered.connect(
            lambda: self.showWidget(self.browser))

        self.actionOutputs = QAction("Outputs",self)
        self.actionOutputs.triggered.connect(self.showOutputs)
        self.actionStats = QAction("Statistics",self)
        self.actionStats.triggered.connect(self.showStats)
        self.actionPrefs = QAction("Preferences",self)
        self.actionPrefs.triggered.connect(self.showPrefs)
        self.actionConnect = QAction("Connect",self)
        self.actionConnect.triggered.connect(self.connectActivated)

    def initGUI(self):
        self.initStartScreen()
        self.initWidgets()
        
        if not have_maemo:
            self.mw     = QMainWindow()
            menu        = self.mw.menuBar()
            menufile    = menu.addMenu("&File")
            menuwindows = menu.addMenu("&Windows")
            self.mw.statusBar()
            menuwindows.addAction(self.actionPlayer)
            menuwindows.addAction(self.actionPlaylist)
            menuwindows.addAction(self.actionBrowser)
            menuwindows.addAction(self.actionOutputs)
            menuwindows.addAction(self.actionStats)
            menufile.addAction(self.actionConnect)
            menufile.addAction(self.actionPrefs)
            menufile.addSeparator()
            menufile.addAction("&Quit", QApplication.quit)
       
        self.setConnectionState(False)

    def initStartScreen(self):
        self.startscreen = StartScreen(self)
        self.startscreen.clicked.connect(self.connectActivated)
        if have_maemo:
            menu = QMenuBar(self.startscreen)
            menu.addAction(self.actionConnect)
            menu.addAction(self.actionPrefs)
            
    def initWidgets(self):
        # create subwidgets
        self.player   = Player(self)
        self.playlist = Playlist(self)
        self.browser  = Browser(self)
        if have_maemo:
            # build Maemo stack hierarchy
            self.playlist.setParent(self.player)
            self.browser.setParent(self.player)
            for w in [ self.player, self.playlist, self.browser ]:
                w.setAttribute( Qt.WA_Maemo5StackedWindow)
                w.setWindowFlags( w.windowFlags() | Qt.Window)

            # add menu bar
            menu = QMenuBar(self.player)
            menu.addAction(self.actionPlaylist)
            menu.addAction(self.actionBrowser)
            menu.addAction(self.actionStats)
            menu.addAction(self.actionOutputs)
            menu.addAction(self.actionPrefs)
            menu.addAction(self.actionConnect)
        else:
            self.stack = QStackedWidget()
            for w in [ self.player, self.playlist, self.browser ]:
                w.setParent(self.stack)
                self.stack.addWidget(w)

    def switchView(self, connected):
        if have_maemo:
            if connected:
                self.player.show()
                self.startscreen.hide()
            else:
                self.startscreen.show()
        else:
            cw = self.mw.centralWidget()
            if cw:
                cw.setParent(None)
                cw.hide()
            if connected:
                self.mw.setCentralWidget(self.stack)
                self.stack.show()
                self.showWidget(self.player)
            else:
                self.mw.setCentralWidget(self.startscreen)
                self.startscreen.show()
            self.mw.show()

    def showWidget(self,widget):
        if not have_maemo:
            self.stack.setCurrentWidget(widget)
        widget.show()

    def connectActivated(self):
        if self.actionConnect.text() == "Connect":
            self.connectMPD()
        else:
            self.disconnectMPD()

    def initMPD(self):
        self.mpd = MPDWrapper()
        self.mpdtimer = None
    
    def connectMPD(self,reconnect=False):
        selected = self.data.selectedServer()
        if not len(selected):
            InformationBox.information( self.mw, "Select server to connect")
            self.showPrefs()

        selected = self.data.selectedServer()
        if len(selected):
            name, address, port = selected
            try:
                if not reconnect:
                    InformationBox.information(
                        self.mw, "Connecting to <b>%s</b>" % name)
                    QApplication.processEvents()
                self.mpd.timeout = 10
                self.mpd.connect( str(address), int(port))
                if not reconnect:
                    InformationBox.information(
                        self.mw, "Connected to <b>%s</b>" % name)
                    QApplication.processEvents()
                    self.setConnectionState(True)
                    self.selectedServerName = name
                self.mpdtimer = self.startTimer(5000)
            except socket.timeout, e:
                self.setConnectionState(False)
                InformationBox.information( self.mw, "%s: %s" %(name,e))
                QApplication.processEvents()
            except socket.gaierror, e:
                self.setConnectionState(False)
                InformationBox.information( self.mw, "%s: %s" %(name,e[1]))
                QApplication.processEvents()
            except socket.error, e:
                self.setConnectionState(False)
                InformationBox.information( self.mw, "%s: %s" %(name,e[1]))
                QApplication.processEvents()