def setupUi(self):
        #create the card sheet on the left
        card = QWidget(self.editor)
        vlayout = QVBoxLayout(card)
        vlayout.addWidget(self.createIconWidget(card))
        vlayout.addWidget(self.createMainPropertiesWidget(card))
        
        #create the right pane: description + relations
        self.rightpane = QSplitter(self.editor)
        self.rightpane.setOrientation(Qt.Horizontal)
        
#        button = KPushButton()
#        button.setIcon(KIcon("edit-rename"))
#        button.setStyleSheet("border:none;")
#        hbox.addWidget(button)
        
        descriptionWidget = QWidget(self.rightpane)

        infoWidget = QWidget(descriptionWidget)

        hbox = QHBoxLayout(infoWidget)
        self.label = KLineEdit()
        shortcut = QShortcut(QKeySequence("Ctrl+L"), self.label);
        shortcut.activated.connect(self.editor.focusOnLabelField)
        
        self.label.setMinimumWidth(400)
        self.label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
#        p = QPalette()
#        p.setColor(QPalette.Text, p.color(QPalette.Disabled, QPalette.Text))
#        self.label.setPalette(p)
#        f = self.label.font()
#        f.setItalic(True)
#        self.label.setFont(f)
#        self.label.setText(i18n("Title..."))
#        self.label.setCursorPosition(0)
        
        
        self.label.textEdited.connect(self.onLabelEdited)
        hbox.setContentsMargins(0, 0, 0, 0)
        
        hbox.addWidget(self.label)
        
        spacerItem = QSpacerItem(1, 1, QSizePolicy.Minimum, QSizePolicy.Minimum)
        hbox.addItem(spacerItem)
        
        #typesInfo = QLabel(i18n("Type(s): "))
        self.typesInfo = KPushButton() 
        self.typesInfo.clicked.connect(self.editor.showResourceTypesDialog)
        
        hbox.addWidget(self.typesInfo)
        
        vboxlayout = QVBoxLayout(descriptionWidget)
        #gridlayout = QGridLayout(descriptionWidget)
   
#        descriptionLabel = QLabel(descriptionWidget)
#        descriptionLabel.setText(i18n("&Description:")) 
        self.description = KRichTextWidget(self.editor)
        self.description.setTabChangesFocus(False)
        self.description.setCheckSpellingEnabled(True)
        #self.description.setLineWrapMode(QTextEdit.NoWrap)
        self.description.setObjectName("Notes")
        self.description.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
#        descriptionLabel.setBuddy(self.description)

        self.toolBar = QToolBar(descriptionWidget)
        self.actionCollection = KActionCollection(descriptionWidget)
        self.description.createActions(self.actionCollection)
        for action in self.actionCollection.actions():
            if action.objectName() == "direction_ltr" or \
                action.objectName() == "direction_rtl" or \
                action.objectName() == "manage_link" or \
                action.objectName() == "action_to_plain_text":
                continue
            self.toolBar.addAction(action)

        shortcut = QShortcut(QKeySequence("Ctrl+Alt+X"), self.description);
        shortcut.activated.connect(self.editor.executeInlineQuery)

        shortcut = QShortcut(QKeySequence("Ctrl+Alt+Y"), self.description);
        shortcut.activated.connect(self.editor.suggestRelations)

        
        #hline = QFrame(descriptionWidget)
        #hline.setGeometry(QRect(150, 190, 118, 3))
        #hline.setFrameShape(QFrame.HLine)
        #hline.setFrameShadow(QFrame.Sunken)
        
        vboxlayout.addWidget(infoWidget)
        #vboxlayout.addWidget(hline)
#        gridlayout.addWidget(infoWidget, 0, 0, 1, 1)
#        gridlayout.addWidget(hline, 1, 0, 1, 1)
        
        infoWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
        
#        vboxlayout.addWidget(descriptionLabel)
        vboxlayout.addWidget(self.toolBar)
        vboxlayout.addWidget(self.description)
        
        self.relationsWidget = KTabWidget(self.rightpane)
        #vboxlayout = QVBoxLayout(relationsWidget)
        #self.relationsLabel = QLabel(relationsWidget)
        
        self.relationsTable = RelationsTable(mainWindow=self.editor.mainWindow, editor=self.description)
        self.propsTable = ResourcePropertiesTable(mainWindow=self.editor.mainWindow)
        
        self.relationsWidget.addTab(self.relationsTable , i18n("Relations"))
        self.relationsWidget.addTab(self.propsTable, i18n("Properties"))
        
#        self.relationsLabel.setBuddy(relationsTable)
#        vboxlayout.addWidget(self.relationsLabel)
#        vboxlayout.addWidget(relationsTable)
        
        self.rightpane.addWidget(descriptionWidget)
        self.rightpane.addWidget(self.relationsWidget)
        self.rightpane.setSizes([100, 300])
        self.rightpane.restoreState(self.editor.mainWindow.descriptionSplitterState)
        
        #self.tabs.addTab(self.description, "Description")
        #self.tabs.setTabPosition(QTabWidget.North)
        
        splitter = QSplitter(self.editor)
        hlayout = QHBoxLayout(self.editor)
        hlayout.addWidget(splitter)
        splitter.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        splitter.addWidget(card)
        splitter.addWidget(self.rightpane)
        splitter.setStretchFactor(0, 0)
        splitter.setStretchFactor(1, 1)

        self.updateFields()

        #update the description field only here since we actually don't want it to be updated
        #on save, unless we carefully make sure that all the ui is kept unchanged after resetting
        #the text: scrollbar position, caret position, selected text.
        if self.editor.resource:
            cursor = self.description.textCursor()
            pos = cursor.position()
            self.description.setText(self.editor.resource.description())
            cursor.setPosition(pos)
            self.description.setTextCursor(cursor)
class ResourceEditorUi(object):
    
    def __init__(self, editor):
        self.editor = editor
        self.labelEdited = False
        self.setupUi()
        
    def onLabelEdited(self, text):
        self.labelEdited = True
#        if text and len(text) > 0:
#            p = QPalette()
#            p.setColor(QPalette.Text, p.color(QPalette.Normal, QPalette.Text))
#            self.label.setPalette(p)
#            f = self.label.font()
#            f.setItalic(False)
#            self.label.setFont(f)
    
    def setupUi(self):
        #create the card sheet on the left
        card = QWidget(self.editor)
        vlayout = QVBoxLayout(card)
        vlayout.addWidget(self.createIconWidget(card))
        vlayout.addWidget(self.createMainPropertiesWidget(card))
        
        #create the right pane: description + relations
        self.rightpane = QSplitter(self.editor)
        self.rightpane.setOrientation(Qt.Horizontal)
        
#        button = KPushButton()
#        button.setIcon(KIcon("edit-rename"))
#        button.setStyleSheet("border:none;")
#        hbox.addWidget(button)
        
        descriptionWidget = QWidget(self.rightpane)

        infoWidget = QWidget(descriptionWidget)

        hbox = QHBoxLayout(infoWidget)
        self.label = KLineEdit()
        shortcut = QShortcut(QKeySequence("Ctrl+L"), self.label);
        shortcut.activated.connect(self.editor.focusOnLabelField)
        
        self.label.setMinimumWidth(400)
        self.label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
#        p = QPalette()
#        p.setColor(QPalette.Text, p.color(QPalette.Disabled, QPalette.Text))
#        self.label.setPalette(p)
#        f = self.label.font()
#        f.setItalic(True)
#        self.label.setFont(f)
#        self.label.setText(i18n("Title..."))
#        self.label.setCursorPosition(0)
        
        
        self.label.textEdited.connect(self.onLabelEdited)
        hbox.setContentsMargins(0, 0, 0, 0)
        
        hbox.addWidget(self.label)
        
        spacerItem = QSpacerItem(1, 1, QSizePolicy.Minimum, QSizePolicy.Minimum)
        hbox.addItem(spacerItem)
        
        #typesInfo = QLabel(i18n("Type(s): "))
        self.typesInfo = KPushButton() 
        self.typesInfo.clicked.connect(self.editor.showResourceTypesDialog)
        
        hbox.addWidget(self.typesInfo)
        
        vboxlayout = QVBoxLayout(descriptionWidget)
        #gridlayout = QGridLayout(descriptionWidget)
   
#        descriptionLabel = QLabel(descriptionWidget)
#        descriptionLabel.setText(i18n("&Description:")) 
        self.description = KRichTextWidget(self.editor)
        self.description.setTabChangesFocus(False)
        self.description.setCheckSpellingEnabled(True)
        #self.description.setLineWrapMode(QTextEdit.NoWrap)
        self.description.setObjectName("Notes")
        self.description.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
#        descriptionLabel.setBuddy(self.description)

        self.toolBar = QToolBar(descriptionWidget)
        self.actionCollection = KActionCollection(descriptionWidget)
        self.description.createActions(self.actionCollection)
        for action in self.actionCollection.actions():
            if action.objectName() == "direction_ltr" or \
                action.objectName() == "direction_rtl" or \
                action.objectName() == "manage_link" or \
                action.objectName() == "action_to_plain_text":
                continue
            self.toolBar.addAction(action)

        shortcut = QShortcut(QKeySequence("Ctrl+Alt+X"), self.description);
        shortcut.activated.connect(self.editor.executeInlineQuery)

        shortcut = QShortcut(QKeySequence("Ctrl+Alt+Y"), self.description);
        shortcut.activated.connect(self.editor.suggestRelations)

        
        #hline = QFrame(descriptionWidget)
        #hline.setGeometry(QRect(150, 190, 118, 3))
        #hline.setFrameShape(QFrame.HLine)
        #hline.setFrameShadow(QFrame.Sunken)
        
        vboxlayout.addWidget(infoWidget)
        #vboxlayout.addWidget(hline)
#        gridlayout.addWidget(infoWidget, 0, 0, 1, 1)
#        gridlayout.addWidget(hline, 1, 0, 1, 1)
        
        infoWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
        
#        vboxlayout.addWidget(descriptionLabel)
        vboxlayout.addWidget(self.toolBar)
        vboxlayout.addWidget(self.description)
        
        self.relationsWidget = KTabWidget(self.rightpane)
        #vboxlayout = QVBoxLayout(relationsWidget)
        #self.relationsLabel = QLabel(relationsWidget)
        
        self.relationsTable = RelationsTable(mainWindow=self.editor.mainWindow, editor=self.description)
        self.propsTable = ResourcePropertiesTable(mainWindow=self.editor.mainWindow)
        
        self.relationsWidget.addTab(self.relationsTable , i18n("Relations"))
        self.relationsWidget.addTab(self.propsTable, i18n("Properties"))
        
#        self.relationsLabel.setBuddy(relationsTable)
#        vboxlayout.addWidget(self.relationsLabel)
#        vboxlayout.addWidget(relationsTable)
        
        self.rightpane.addWidget(descriptionWidget)
        self.rightpane.addWidget(self.relationsWidget)
        self.rightpane.setSizes([100, 300])
        self.rightpane.restoreState(self.editor.mainWindow.descriptionSplitterState)
        
        #self.tabs.addTab(self.description, "Description")
        #self.tabs.setTabPosition(QTabWidget.North)
        
        splitter = QSplitter(self.editor)
        hlayout = QHBoxLayout(self.editor)
        hlayout.addWidget(splitter)
        splitter.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        splitter.addWidget(card)
        splitter.addWidget(self.rightpane)
        splitter.setStretchFactor(0, 0)
        splitter.setStretchFactor(1, 1)

        self.updateFields()

        #update the description field only here since we actually don't want it to be updated
        #on save, unless we carefully make sure that all the ui is kept unchanged after resetting
        #the text: scrollbar position, caret position, selected text.
        if self.editor.resource:
            cursor = self.description.textCursor()
            pos = cursor.position()
            self.description.setText(self.editor.resource.description())
            cursor.setPosition(pos)
            self.description.setTextCursor(cursor)


    def updateFields(self):
        if self.editor.resource:
            if hasattr(self, "name"):
                self.name.setText(self.editor.resource.property(Soprano.Vocabulary.NAO.prefLabel()).toString())


            if hasattr(self, "url"):
                if len(self.editor.resource.property(NIE.url).toString()) > 0:
                    self.url.setText(self.editor.resource.property(NIE.url).toString())
                else:
                    self.url.setText(self.editor.resource.uri())
                
            prefLabel = self.editor.resource.property(Soprano.Vocabulary.NAO.prefLabel()).toString()
            p = QPalette()
            p.setColor(QPalette.Text, p.color(QPalette.Normal, QPalette.Text))
            self.label.setPalette(p)
            f = self.label.font()
            f.setItalic(False)
            self.label.setFont(f)
            self.label.setText(prefLabel)
            
            types = ""
            for type in self.editor.resource.types():
                if type == Soprano.Vocabulary.RDFS.Resource():
                    continue
                typestr = str(type.toString())
                if typestr.find("#") > 0:
                    typestr = typestr[typestr.find("#") + 1:]
                elif typestr.find("nepomuk:/") == 0:
                    #this is a custom type, we need to get the label of the ressource
                    typeResource = Nepomuk.Resource(typestr)
                    typestr = typeResource.genericLabel()
                else:
                    typestr = typestr[typestr.rfind("/") + 1:]
                types = types + i18n(typestr) + ", "
            
            if len(types) > 0:
                types = types[0:len(types) - 2]
            self.typesInfo.setText(i18n("Type(s): ") + types)
            
            self.relationsTable.setResource(self.editor.resource)
            self.propsTable.setResource(self.editor.resource)
        

    def createIconWidget(self, parent):
        iconWidget = QWidget(parent)
        iconWidgetLayout = QHBoxLayout(iconWidget)
        self.iconButton = QPushButton();
        self.iconButton.setIcon(self.editor.resourceIcon())
        size = QSize(80, 80)
        self.iconButton.setIconSize(size)
        self.iconButton.setContentsMargins(40, 40, 40, 40)
        #button.setStyleSheet("border: 20px solid #fff;")
        self.iconButton.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        self.editor.connect(self.iconButton, SIGNAL("clicked()"), self.editor.selectIcon)
        iconWidgetLayout.addStretch(1)
        iconWidgetLayout.addWidget(self.iconButton)
        iconWidgetLayout.addStretch(1)
        return iconWidget

    def createMainPropertiesWidget(self, parent):
        propertiesWidget = QWidget(parent)

        self.gridlayout = QGridLayout(propertiesWidget)
#        self.gridlayout.setMargin(9)
#        self.gridlayout.setSpacing(6)
        self.gridlayout.setObjectName("gridlayout")
        
#        tagBox = QGroupBox(i18n("Tags"))
#        self.tags = Nepomuk.TagWidget()
#        vbox = QVBoxLayout(tagBox)
#        vbox.addWidget(self.tags)
#        self.gridlayout.addWidget(tagBox, 0, 0, 1, 2)

        #TODO: move this to a config panel so that types whose editor contains a dedicated URL field can be defined by the user
        classesWithUrlField = [Nepomuk.Types.Class(PIMO.Organization), Nepomuk.Types.Class(PIMO.Project),
                               Nepomuk.Types.Class(PIMO.Person),
                               Nepomuk.Types.Class(NCO.PersonContact),
                               Nepomuk.Types.Class(QUrl("http://purl.org/dc/dcmitype/Software"))]
        if self.editor.resource:
            flag = False
            for type in self.editor.resource.types():
                typeClass = Nepomuk.Types.Class(type)
                for parentClass in typeClass.allParentClasses():
                    if typeClass in classesWithUrlField or parentClass in classesWithUrlField:
                        self.addUrlBox(propertiesWidget)
                        flag = True
                        break
                if flag:
                    break
        else:
            typeClass = Nepomuk.Types.Class(self.editor.nepomukType)
            for parentClass in typeClass.allParentClasses():
                if typeClass in classesWithUrlField or parentClass in classesWithUrlField:
                    self.addUrlBox(propertiesWidget)
                    break
            
                
        spacerItem = QSpacerItem(1, 1, QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.gridlayout.addItem(spacerItem, 1, 0, 1, 1)
        
        return propertiesWidget

    def addUrlBox(self, propertiesWidget):
        box = QGroupBox(i18n("&URL"))
        
        vbox = QVBoxLayout(box)
        self.url = QLineEdit(propertiesWidget)
        self.url.setObjectName("url")
        
        
        vbox.addWidget(self.url)
        
        button = QPushButton(propertiesWidget)
        button.setText(i18n("Open"))
        button.clicked.connect(self.openWebPage)
        vbox.addWidget(button)
        self.gridlayout.addWidget(box, 0, 0, 1, 1)
        

    def openWebPage(self):
        kurl = KUrl(self.url.text())
        krun(kurl, QWidget(), False)
    
    def resourceLabel(self):
        return self.label.text()