summaryrefslogtreecommitdiffstats
path: root/displayconfig/displayconfigwidgets.py
diff options
context:
space:
mode:
Diffstat (limited to 'displayconfig/displayconfigwidgets.py')
-rw-r--r--displayconfig/displayconfigwidgets.py809
1 files changed, 809 insertions, 0 deletions
diff --git a/displayconfig/displayconfigwidgets.py b/displayconfig/displayconfigwidgets.py
new file mode 100644
index 0000000..7484ac5
--- /dev/null
+++ b/displayconfig/displayconfigwidgets.py
@@ -0,0 +1,809 @@
+
+from qt import *
+from kdecore import *
+from kdeui import *
+import os
+from displayconfigabstraction import *
+
+# Running as the root user or not?
+isroot = os.getuid()==0
+
+############################################################################
+class ResizeSlider(QVGroupBox):
+ """ An abstracted QSlider in a nice box to change the resolution of a screen """
+ def __init__(self,parent):
+ # Screen size group
+ QVGroupBox.__init__(self,parent)
+ self.updating_gui = True
+ self._buildGUI()
+ self.updating_gui = False
+
+ def _buildGUI(self):
+ self.setTitle(i18n("Screen Size"))
+ self.setInsideSpacing(KDialog.spacingHint())
+ self.setInsideMargin(KDialog.marginHint())
+
+ hbox3 = QHBox(self)
+ hbox3.setSpacing(KDialog.spacingHint())
+ label = QLabel(hbox3,"textLabel2_4")
+ label.setText(i18n("Lower"))
+ self.screensizeslider = QSlider(hbox3,"slider1")
+ self.screensizeslider.setMinValue(0)
+ self.screensizeslider.setMaxValue(4)
+ self.screensizeslider.setPageStep(1)
+ self.screensizeslider.setOrientation(QSlider.Horizontal)
+ self.screensizeslider.setTickmarks(QSlider.Below)
+ self.connect(self.screensizeslider,SIGNAL("valueChanged(int)"),self.slotResolutionChange)
+ label = QLabel(hbox3)
+ label.setText(i18n("Higher"))
+
+ self.resolutionlabel = QLabel(self)
+ self.resolutionlabel.setText("640x400")
+
+ def setScreen(self, screen):
+ self.updating_gui = True
+ self.screen = screen
+ self.screensizeslider.setMaxValue(len(screen.getAvailableResolutions())-1)
+ self.screensizeslider.setValue(screen.getResolutionIndex())
+ self.updating_gui = False
+ self.setResolutionIndex(screen.getResolutionIndex())
+
+ def slotResolutionChange(self,i):
+ """ Pass signal from slider through to App """
+ if self.updating_gui:
+ return
+ self.setResolutionIndex(i)
+ self.emit(PYSIGNAL("resolutionChange(int)"),(i,))
+
+ def setMaxValue(self,value):
+ self.updating_gui = True
+ self.screensizeslider.setMaxValue(value)
+ self.updating_gui = False
+
+ def setMinValue(self,value):
+ self.updating_gui = True
+ self.screensizeslider.setMinValue(value)
+ self.updating_gui = False
+
+ def setValue(self,value):
+ self.updating_gui = True
+ self.screensizeslider.setValue(value)
+ self.updating_gui = False
+
+ def value(self):
+ return self.screensizeslider.value()
+
+ def setResolutionLabel(self,text):
+ self.resolutionlabel.setText(text)
+
+ def setResolutionIndex(self,i):
+ self.updating_gui = True
+ width,height = self.screen.getAvailableResolutions()[i]
+ self.setResolutionLabel(i18n("%1 x %2").arg(width).arg(height))
+ self.updating_gui = False
+
+############################################################################
+class MonitorPreview(QWidget):
+ """ A ResizableMonitor is an Image in a grid which has resizable edges,
+ fixed-size corners and is thus expandable. """
+ ROTATE_0 = 0
+ ROTATE_90 = 1
+ ROTATE_180 = 2
+ ROTATE_270 = 3
+
+ def __init__(self, parent=None, imagedir="", name=None):
+ QWidget.__init__(self,parent)
+
+ self.rotation = MonitorPreview.ROTATE_0
+
+ self.screen_width = 1280
+ self.screen_height = 1024
+
+ self.reflect_x = False
+ self.reflect_y = False
+
+ self.setBackgroundMode(Qt.NoBackground)
+
+ self.imagedir = imagedir + "monitor_resizable/"
+
+ self.image_monitor = QPixmap(self.imagedir+"monitor.png")
+ self.image_monitor_wide = QPixmap(self.imagedir+"monitor_wide.png")
+ self.image_monitor_r90 = QPixmap(self.imagedir+"monitor_r90.png")
+ self.image_monitor_wide_r90 = QPixmap(self.imagedir+"monitor_wide_r90.png")
+
+ self.image_background = QPixmap(self.imagedir+"background.png")
+ self.image_background_wide = QPixmap(self.imagedir+"background_wide.png")
+ self.image_background_r90 = QPixmap(self.imagedir+"background_r90.png")
+ self.image_background_wide_r90 = QPixmap(self.imagedir+"background_wide_r90.png")
+
+ self.image_window = QPixmap(self.imagedir+"window_4th.png")
+ self.image_window_bottom_left = QPixmap(self.imagedir+"window_bottom_left_4th.png")
+ self.image_window_bottom_right = QPixmap(self.imagedir+"window_bottom_right_4th.png")
+
+ def sizeHint(self):
+ max_width = max(self.image_monitor.width(), self.image_monitor_wide.width(),
+ self.image_monitor_r90.width(), self.image_monitor_wide_r90.width())
+ max_height = max(self.image_monitor.height(), self.image_monitor_wide.height(),
+ self.image_monitor_r90.height(), self.image_monitor_wide_r90.height())
+ return QSize(max_width, max_height)
+
+ def sizePolicy(self):
+ return QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
+
+ def paintEvent(self,paint_event):
+ screen_width = self.screen_width
+ screen_height = self.screen_height
+
+ # Widescreen format: preview width: 176, height: 99, 16:9
+ is_wide = abs(float(screen_width)/float(screen_height)-16.0/9.0) < 0.2
+
+ if not is_wide:
+ preview_screen_width = 152
+ preview_screen_height = 114
+ else:
+ preview_screen_width = 176
+ preview_screen_height = 99
+
+ if self.rotation==MonitorPreview.ROTATE_0 or self.rotation==MonitorPreview.ROTATE_180:
+ # Normal, landscape orientation.
+ if not is_wide:
+ screen_x_offset = 23
+ screen_y_offset = 15
+ image_background = self.image_background
+ else:
+ screen_x_offset = 23
+ screen_y_offset = 29
+ image_background = self.image_background_wide
+ else:
+ # Portrait orientation. Swap some values around.
+ t = preview_screen_width
+ preview_screen_width = preview_screen_height
+ preview_screen_height = t
+
+ t = screen_width
+ screen_width = screen_height
+ screen_height = t
+
+ if not is_wide:
+ screen_x_offset = 42
+ screen_y_offset = 15
+ image_background = self.image_background_r90
+ else:
+ screen_x_offset = 50
+ screen_y_offset = 15
+ image_background = self.image_background_wide_r90
+
+ # Draw everything off screen in a buffer
+ preview_buffer = QPixmap(preview_screen_width,preview_screen_height)
+ painter = QPainter(preview_buffer)
+
+ # Draw the background on the monitor's screen
+ painter.drawPixmap(0, 0, image_background)
+
+ # Work out the scaling factor for the eye candy in the preview winodw.
+ scale_factor = 4.0*float(preview_screen_width) / float(screen_width)
+ transform_matrix = QWMatrix().scale(scale_factor,scale_factor)
+
+ # Draw the little window on the background
+ scaled_window = self.image_window.xForm(transform_matrix)
+
+ sx = (preview_screen_width-scaled_window.width())/2
+ sy = (preview_screen_height-scaled_window.height())/2
+ if sx < 0:
+ sx = 0
+ if sy < 0:
+ sy = 0
+ sw = scaled_window.width()
+ if sw>preview_screen_width:
+ sw = preview_screen_width
+
+ sh = scaled_window.height()
+ if sh>preview_screen_height:
+ sh = preview_screen_height
+
+ painter.drawPixmap(sx, sy, scaled_window, 0, 0, sw, sh)
+
+ # Now draw the clock in the lower right corner
+ scaled_window = self.image_window_bottom_right.xForm(transform_matrix)
+
+ sx = preview_screen_width - scaled_window.width()
+ sy = preview_screen_height - scaled_window.height()
+ sw = scaled_window.width()#preview_screen_width/2
+ sh = scaled_window.height()
+
+ sx_offset = 0
+ if sx<0: # Some simple clipping for the left edge
+ sx_offset = -sx
+ sw = preview_screen_width
+ sx = 0
+
+ painter.drawPixmap(sx, sy, scaled_window, sx_offset, 0, sw, sh)
+
+ # Now draw the k menu in the lower left corner
+ scaled_window = self.image_window_bottom_left.xForm(transform_matrix)
+
+ sx = 0
+ sy = preview_screen_height - scaled_window.height()
+ sw = preview_screen_width/2 # Just draw on the left side of the preview.
+ sh = scaled_window.height()
+ painter.drawPixmap(sx, sy, scaled_window, 0, 0, sw, sh)
+ painter.end()
+
+ # Transform the preview image. Do reflections.
+ reflect_x = 1
+ if self.reflect_x:
+ reflect_x = -1
+ reflect_y = 1
+ if self.reflect_y:
+ reflect_y = -1
+
+ preview_buffer = preview_buffer.xForm(QWMatrix().scale(reflect_x,reflect_y))
+
+ # Draw the monitor on another buffer.
+ off_screen_buffer = QPixmap(self.width(),self.height())
+ off_screen_painter = QPainter(off_screen_buffer)
+
+ # Erase the buffer first
+ off_screen_painter.setBackgroundColor(self.paletteBackgroundColor())
+ off_screen_painter.eraseRect(0, 0, off_screen_buffer.width(), off_screen_buffer.height())
+
+ if self.rotation==MonitorPreview.ROTATE_0 or self.rotation==MonitorPreview.ROTATE_180:
+ if not is_wide:
+ image_monitor = self.image_monitor
+ else:
+ image_monitor = self.image_monitor_wide
+ else:
+ if not is_wide:
+ image_monitor = self.image_monitor_r90
+ else:
+ image_monitor = self.image_monitor_wide_r90
+
+ top_edge = self.height()-image_monitor.height()
+ left_edge = (self.width()-image_monitor.width())/2
+
+ # Draw the monitor
+ off_screen_painter.drawPixmap(left_edge, top_edge, image_monitor)
+ off_screen_painter.end()
+
+ # Copy the preview onto the off screen buffer with the monitor.
+ bitBlt(off_screen_buffer, left_edge+screen_x_offset, top_edge+screen_y_offset, preview_buffer,
+ 0, 0, preview_buffer.width(), preview_buffer.height(),Qt.CopyROP, False)
+
+ # Update the widget
+ bitBlt(self, 0, 0, off_screen_buffer, 0, 0, self.width(), self.height(), Qt.CopyROP, False)
+
+ def setResolution(self,width,height):
+ self.screen_width = width
+ self.screen_height = height
+ self.update()
+
+ def setRotation(self, rotation):
+ self.rotation = rotation
+ self.update()
+
+ def setReflectX(self, enable):
+ self.reflect_x = enable
+ self.update()
+
+ def setReflectY(self, enable):
+ self.reflect_y = enable
+ self.update()
+
+############################################################################
+class DualMonitorPreview(QWidget):
+ """ This is the Widget to use elsewhere. It consists of a canvas and an
+ arbitrary number of gizmos on the canvas. The gizmos can be dragged and
+ dropped around. Painting is double-buffered so flickering should not occur.
+ """
+ def __init__(self, parent, size, imagedir):
+ QWidget.__init__(self,parent)
+ self.setBackgroundMode(Qt.NoBackground)
+
+ self.imagedir = imagedir + "dualhead/"
+ self.snap_distance = 25
+ self.snapping = True
+ self.size = size
+ self.position = XSetup.POSITION_LEFTOF
+
+ self.current_screen = 0
+
+ self.resize(size,size)
+ self.setMouseTracking(True)
+
+ self.gizmos = []
+ self.gizmos.append(MovingGizmo("Monitor 1","monitor_1.png",QPoint(20,50),self.imagedir))
+ self.gizmos.append(MovingGizmo("Monitor 2","monitor_2.png",QPoint(180,50),self.imagedir))
+
+ self.gizmos[0].setWidth(1280)
+ self.gizmos[0].setHeight(1024)
+ self.gizmos[0].setHighlightColor(self.colorGroup().highlight())
+ self.gizmos[1].setWidth(1280)
+ self.gizmos[1].setHeight(1024)
+ self.gizmos[1].setHighlightColor(self.colorGroup().highlight())
+
+ self.dragging = False
+ self.dragging_gizmo = 0
+ self.drag_handle = None
+
+ self._positionGizmos()
+ self.setCurrentScreen(0)
+
+ def minimumSizeHint(self):
+ return QSize(self.size,self.size)
+
+ def setCurrentScreen(self,screen):
+ self.current_screen = screen
+ self.gizmos[0].setHighlight(screen==0)
+ self.gizmos[1].setHighlight(screen==1)
+ self.update()
+
+ def getCurrentScreen(self):
+ return self.current_screen
+
+ def setPosition(self,position):
+ self.position = position
+ self._positionGizmos()
+ self.update()
+
+ def getPosition(self):
+ """Returns one of XSetup.POSITION_LEFTOF, XSetup.POSITION_RIGHTOF,
+ XSetup.POSITION_ABOVE or XSetup.POSITION_BELOW.
+ """
+ return self.position
+
+ def setScreenResolution(self,screenNumber,width,height):
+ self.gizmos[screenNumber].setWidth(width)
+ self.gizmos[screenNumber].setHeight(height)
+ self.setPosition(self.position) # Reposition and force update.
+
+ def _positionGizmos(self):
+ g1 = self.gizmos[0]
+ g2 = self.gizmos[1]
+
+ # Treat POSITION_RIGHTOF and POSITION_BELOW as LEFTOF and ABOVE with the
+ # gizmos swapped around.
+ if self.position==XSetup.POSITION_RIGHTOF or self.position==XSetup.POSITION_BELOW:
+ tmp = g1
+ g1 = g2
+ g2 = tmp
+
+ if self.position==XSetup.POSITION_LEFTOF or self.position==XSetup.POSITION_RIGHTOF:
+ x = -g1.getWidth()
+ y = -max(g1.getHeight(), g2.getHeight())/2
+ g1.setPosition(QPoint(x,y))
+
+ x = 0
+ g2.setPosition(QPoint(x,y))
+
+ else:
+ x = -max(g1.getWidth(), g2.getWidth())/2
+ y = -g1.getHeight()
+ g1.setPosition(QPoint(x,y))
+
+ y = 0
+ g2.setPosition(QPoint(x,y))
+
+ def mousePressEvent(self,event):
+ # Translate the point in the window into our gizmo space.
+ world_point = self._getGizmoMatrix().invert()[0].map(event.pos())
+
+ # If the mouse is in the air space of a gizmo, then we change the cursor to
+ # indicate that the gizmo can be dragged.
+ for giz in self.gizmos:
+ if giz.getRect().contains(world_point):
+ self.setCurrentScreen(self.gizmos.index(giz))
+ break
+ else:
+ return
+
+ # Pressing down the mouse button on a gizmo also starts a drag operation.
+ self.dragging = True
+ self.dragging_gizmo = self.getCurrentScreen()
+ self.drag_handle = world_point - self.gizmos[self.dragging_gizmo].getPosition()
+
+ # Let other people know that a gizmo has been selected.
+ self.emit(PYSIGNAL("pressed()"), (self.current_screen,) )
+
+ def mouseReleaseEvent(self,event):
+ if not self.dragging:
+ return
+
+ # Translate the point in the window into our gizmo space.
+ world_point = self._getGizmoMatrix().invert()[0].map(event.pos())
+
+ if self._moveGizmo(world_point):
+ self.setPosition(self.drag_position)
+ self.emit(PYSIGNAL("positionChanged()"), (self.position,) )
+ else:
+ self.setPosition(self.position)
+ self.dragging = False
+
+ def mouseMoveEvent(self,event):
+ # Translate the point in the window into our gizmo space.
+ world_point = self._getGizmoMatrix().invert()[0].map(event.pos())
+
+ # If the mouse is in the air space of a gizmo, then we change the cursor to
+ # indicate that the gizmo can be dragged.
+ for giz in self.gizmos:
+ if giz.getRect().contains(world_point):
+ self.setCursor(QCursor(Qt.SizeAllCursor))
+ break
+ else:
+ self.unsetCursor()
+
+ if self.dragging:
+ self._moveGizmo(world_point)
+ self.update()
+
+ return
+
+ def _moveGizmo(self,worldPoint):
+ new_drag_position = worldPoint-self.drag_handle
+
+ # Drag gizmo is simply the thing being dragged.
+ drag_gizmo = self.gizmos[self.dragging_gizmo]
+ drag_x = new_drag_position.x()
+ drag_y = new_drag_position.y()
+
+ # Snap gizmo is other (stationary) thing that we "snap" against.
+ snap_gizmo = self.gizmos[1-self.dragging_gizmo]
+ snap_x = snap_gizmo.getPosition().x()
+ snap_y = snap_gizmo.getPosition().y()
+
+ # Calculate the list of "snap points".
+ snap_points = [
+ (snap_x-drag_gizmo.getWidth(), snap_y), # Left of
+ (snap_x+snap_gizmo.getWidth(), snap_y), # Right of
+ (snap_x, snap_y-drag_gizmo.getHeight()), # Above
+ (snap_x, snap_y+snap_gizmo.getHeight())] # Below
+
+ # Find the snap point that the drag gizmo is closest to.
+ best_index = -1
+ best_distance = 0
+ i = 0
+ for snap_point in snap_points:
+ dx = snap_point[0] - drag_x
+ dy = snap_point[1] - drag_y
+ distance_squared = dx*dx + dy*dy
+ if best_index==-1 or distance_squared < best_distance:
+ best_index = i
+ best_distance = distance_squared
+ i += 1
+
+ # Lookup the best dualhead position that this configuration matches.
+ if self.dragging_gizmo==0:
+ self.drag_position = [
+ XSetup.POSITION_LEFTOF,
+ XSetup.POSITION_RIGHTOF,
+ XSetup.POSITION_ABOVE,
+ XSetup.POSITION_BELOW][best_index]
+ else:
+ self.drag_position = [
+ XSetup.POSITION_RIGHTOF,
+ XSetup.POSITION_LEFTOF,
+ XSetup.POSITION_BELOW,
+ XSetup.POSITION_ABOVE][best_index]
+
+ # Convert the auto-snap distance in pixels into a distance in the gizmo coordinate system.
+ world_snap_distance = self.snap_distance / self._getGizmoToPixelsScaleFactor()
+
+ # Should this drag gizmo visually snap?
+ snapped = False
+ if best_distance <= (world_snap_distance*world_snap_distance):
+ new_drag_position = QPoint(snap_points[best_index][0],snap_points[best_index][1])
+ snapped = True
+
+ # Move the gizmo
+ self.gizmos[self.dragging_gizmo].setPosition(new_drag_position)
+
+ return snapped
+
+ def paintEvent(self,event=None):
+ QWidget.paintEvent(self,event)
+
+ # Paint to an off screen buffer first. Later we copy it to widget => flicker free.
+ off_screen_buffer = QPixmap(self.width(),self.height())
+ off_screen_painter = QPainter(off_screen_buffer)
+
+ # Erase the buffer first
+ off_screen_painter.setBackgroundColor(self.colorGroup().mid() )
+ off_screen_painter.eraseRect(0, 0, off_screen_buffer.width(), off_screen_buffer.height())
+
+ #
+ off_screen_painter.setWorldMatrix(self._getGizmoMatrix())
+
+ # Paint the non-selected gizmo first.
+ self.gizmos[ 1-self.current_screen ].paint(off_screen_painter)
+
+ # Now paint the selected gizmo
+ self.gizmos[self.current_screen].paint(off_screen_painter)
+
+ # Turn off the world matrix transform.
+ off_screen_painter.setWorldXForm(False)
+
+ # Draw the rounded border
+ off_screen_painter.setPen(QPen(self.colorGroup().dark(),1))
+ off_screen_painter.drawRoundRect(0,0,self.width(),self.height(),2,2)
+
+ off_screen_painter.end()
+
+ # Update the widget
+ bitBlt(self, 0, 0, off_screen_buffer, 0, 0, self.width(), self.height(), Qt.CopyROP, False)
+
+ def _getGizmoMatrix(self):
+ matrix = QWMatrix()
+ matrix.translate(self.width()/2,self.height()/2)
+
+ scale_factor = self._getGizmoToPixelsScaleFactor()
+ matrix.scale(scale_factor,scale_factor)
+ return matrix
+
+ def _getGizmoToPixelsScaleFactor(self):
+ g1 = self.gizmos[0]
+ g2 = self.gizmos[1]
+ size = min(self.width(),self.height())
+ vscale = float(self.height()) / (2.1 * (g1.getHeight()+g2.getHeight()))
+ hscale = float(self.width()) / (2.1 * (g1.getWidth()+g2.getWidth()))
+ return min(vscale,hscale)
+
+############################################################################
+class MovingGizmo(object):
+ """A gizmo represents a screen/monitor. It also has a width and height that
+ correspond to the resolution of screen."""
+
+ def __init__(self,label,filename,initial_pos=QPoint(0,0),imagedir="."):
+ self.width = 100
+ self.height = 100
+ self.pixmap = QPixmap(imagedir+filename)
+
+ self.highlight = False
+ self.highlight_color = QColor(255,0,0)
+
+ self.setPosition(initial_pos)
+
+ # Used for caching the scaled pixmap.
+ self.scaled_width = -1
+ self.scaled_height = -1
+
+ def setHighlight(self,enable):
+ self.highlight = enable
+
+ def setHighlightColor(self,color):
+ self.highlight_color = color
+
+ def setPosition(self,position):
+ self.position = position
+
+ def getSize(self):
+ return QSize(self.width,self.height)
+
+ def getPosition(self):
+ return self.position
+
+ def getRect(self):
+ return QRect(self.position,self.getSize())
+
+ def setWidth(self,width):
+ self.width = width
+
+ def getWidth(self):
+ return self.width
+
+ def setHeight(self,height):
+ self.height = height
+
+ def getHeight(self):
+ return self.height
+
+ def paint(self,painter):
+ painter.save()
+ if self.highlight:
+ pen = QPen(self.highlight_color,6)
+ painter.setPen(pen)
+
+ painter.drawRect(self.position.x(), self.position.y(), self.width, self.height)
+
+ to_pixels_matrix = painter.worldMatrix()
+ top_left_pixels = to_pixels_matrix.map(self.position)
+ bottom_right_pixels = to_pixels_matrix.map( QPoint(self.position.x()+self.width, self.position.y()+self.height) )
+
+ # Scale the pixmap.
+ scaled_width = bottom_right_pixels.x() - top_left_pixels.x()
+ scaled_height = bottom_right_pixels.y() - top_left_pixels.y()
+
+ if (scaled_width,scaled_height) != (self.scaled_width,self.scaled_height):
+ scale_matrix = QWMatrix()
+ scale_matrix.scale(
+ float(scaled_width)/float(self.pixmap.width()),
+ float(scaled_height)/float(self.pixmap.height()) )
+
+ self.scaled_pixmap = self.pixmap.xForm(scale_matrix)
+ (self.scaled_width,self.scaled_height) = (scaled_width,scaled_height)
+
+ # Paste in the scaled pixmap.
+ bitBlt(painter.device(), top_left_pixels.x(), top_left_pixels.y(), self.scaled_pixmap, 0, 0,
+ self.scaled_pixmap.width(), self.scaled_pixmap.height(),Qt.CopyROP, False)
+
+ painter.restore()
+
+############################################################################
+class GfxCardWidget(QVGroupBox):
+ def __init__(self, parent, xsetup, gfxcard, gfxcarddialog, monitordialog):
+ global imagedir
+ QVGroupBox.__init__(self,parent)
+
+ self.xsetup = xsetup
+ self.gfxcard = gfxcard
+ self.gfxcarddialog = gfxcarddialog
+ self.monitordialog = monitordialog
+ self._buildGUI()
+ self._syncGUI()
+
+ def _buildGUI(self):
+ # Create the GUI
+
+ gridwidget = QWidget(self)
+ grid = QGridLayout(gridwidget,2+3*len(self.gfxcard.getScreens()))
+ grid.setSpacing(KDialog.spacingHint())
+ grid.setColStretch(0,0)
+ grid.setColStretch(1,0)
+ grid.setColStretch(2,0)
+ grid.setColStretch(3,1)
+ grid.setColStretch(4,0)
+
+ gfxcardpic = QLabel(gridwidget)
+ gfxcardpic.setPixmap(UserIcon('hi32-gfxcard'))
+ grid.addMultiCellWidget(gfxcardpic,0,1,0,0)
+
+ label = QLabel(gridwidget)
+ label.setText(i18n("Graphics card:"))
+ grid.addWidget(label,0,1)
+
+ self.gfxcardlabel = QLabel(gridwidget)
+ grid.addWidget(self.gfxcardlabel,0,2)
+
+ label = QLabel(gridwidget)
+ label.setText(i18n("Driver:"))
+ grid.addWidget(label,1,1)
+
+ self.driverlabel = QLabel(gridwidget)
+ grid.addMultiCellWidget(self.driverlabel,1,1,2,3)
+
+ gfxbutton = QPushButton(gridwidget)
+ gfxbutton.setText(i18n("Configure..."))
+ self.connect(gfxbutton,SIGNAL("clicked()"),self.slotGfxCardConfigureClicked)
+ grid.addWidget(gfxbutton,0,4)
+ gfxbutton.setEnabled(self.xsetup.mayModifyXorgConfig())
+
+ # Add all of the screens
+ row = 2
+ count = 1
+ self.monitorlabels = []
+ self.monitor_buttons = []
+ self.monitor_roles = []
+ for screen in self.gfxcard.getScreens():
+ frame = QFrame(gridwidget)
+ frame.setFrameShape(QFrame.HLine)
+ frame.setFrameShadow(QFrame.Sunken)
+ grid.addMultiCellWidget(frame,row,row,0,4)
+ row += 1
+
+ monitorpic = QLabel(gridwidget)
+ monitorpic.setPixmap(UserIcon('hi32-display'))
+ grid.addMultiCellWidget(monitorpic,row,row+1,0,0)
+
+ # Monitor label
+ label = QLabel(gridwidget)
+ if len(self.gfxcard.getScreens())==1:
+ label.setText(i18n("Monitor:"))
+ else:
+ label.setText(i18n("Monitor #%1:").arg(count))
+ grid.addWidget(label,row,1)
+
+ self.monitorlabels.append(QLabel(gridwidget))
+ grid.addMultiCellWidget(self.monitorlabels[-1],row,row,2,3)
+
+ # Role pulldown
+ if len(self.xsetup.getAllScreens())!=1:
+ label = QLabel(gridwidget)
+ label.setText(i18n("Role:"))
+ grid.addWidget(label,row+1,1)
+
+ role_combo = KComboBox(False,gridwidget)
+ role_combo.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
+ self.monitor_roles.append(role_combo)
+ role_combo.insertItem(i18n("Primary (1)"))
+ role_combo.insertItem(i18n("Secondary (2)"))
+ if len(self.xsetup.getAllScreens())>=3:
+ role_combo.insertItem(i18n("Unused"))
+ self.connect(role_combo,SIGNAL("activated(int)"),self.slotRoleSelected)
+ grid.addWidget(role_combo,row+1,2)
+ role_combo.setEnabled(self.xsetup.mayModifyXorgConfig())
+
+ monitorbutton = QPushButton(gridwidget)
+ self.monitor_buttons.append(monitorbutton)
+ monitorbutton.setText(i18n("Configure..."))
+ self.connect(monitorbutton,SIGNAL("clicked()"),self.slotMonitorConfigureClicked)
+ grid.addWidget(monitorbutton,row,4)
+ monitorbutton.setEnabled(self.xsetup.mayModifyXorgConfig())
+ row += 2
+ count += 1
+
+ def syncConfig(self):
+ self._syncGUI()
+
+ def _syncGUI(self):
+ if self.gfxcard.getGfxCardModel() is not None:
+ self.setTitle(self.gfxcard.getGfxCardModel().getName())
+ self.gfxcardlabel.setText(self.gfxcard.getGfxCardModel().getName())
+
+ if self.gfxcard.isProprietaryDriver():
+ try:
+ # Displayconfig thinks there is a proprietary driver
+ self.driverlabel.setText(self.gfxcard.getGfxCardModel().getProprietaryDriver())
+ except TypeError, errormsg:
+ # If there isn't it dies, so try again LP: #198269
+ self.driverlabel.setText(self.gfxcard.getGfxCardModel().getDriver())
+ else:
+ self.driverlabel.setText(self.gfxcard.getGfxCardModel().getDriver())
+ else:
+ self.setTitle(i18n("<Unknown>"))
+ self.gfxcardlabel.setText(i18n("<Unknown>"))
+ self.driverlabel.setText(i18n("<none>"))
+
+ # Sync the screens and monitors.
+ for i in range(len(self.gfxcard.getScreens())):
+ screen = self.gfxcard.getScreens()[i]
+
+ if screen.getMonitorModel() is None:
+ monitor_name = i18n("<unknown>")
+ else:
+ monitor_name = QString(screen.getMonitorModel().getName())
+ if screen.getMonitorAspect()==ModeLine.ASPECT_16_9:
+ monitor_name.append(i18n(" (widescreen)"))
+ self.monitorlabels[i].setText(monitor_name)
+
+ if len(self.xsetup.getAllScreens())!=1:
+ self.monitor_roles[i].setCurrentItem(
+ {XSetup.ROLE_PRIMARY: 0,
+ XSetup.ROLE_SECONDARY: 1,
+ XSetup.ROLE_UNUSED: 2}
+ [self.xsetup.getScreenRole(screen)])
+
+ def slotGfxCardConfigureClicked(self):
+ result = self.gfxcarddialog.do(self.gfxcard.getGfxCardModel(), \
+ self.gfxcard.isProprietaryDriver(), self.gfxcard.getDetectedGfxCardModel(),
+ self.gfxcard.getVideoRam())
+
+ (new_card_model, new_proprietary_driver, new_video_ram) = result
+
+ if new_card_model is self.gfxcard.getGfxCardModel() and \
+ new_proprietary_driver==self.gfxcard.isProprietaryDriver() and \
+ new_video_ram==self.gfxcard.getVideoRam():
+ return
+ self.gfxcard.setGfxCardModel(new_card_model)
+ self.gfxcard.setProprietaryDriver(new_proprietary_driver)
+ self.gfxcard.setVideoRam(new_video_ram)
+ self._syncGUI()
+ self.emit(PYSIGNAL("configChanged"), () )
+
+ def slotMonitorConfigureClicked(self):
+ screen_index = self.monitor_buttons.index(self.sender())
+ screen_obj = self.gfxcard.getScreens()[screen_index]
+
+ (new_monitor_model,new_aspect) = self.monitordialog.do(screen_obj.getMonitorModel(),
+ screen_obj.getMonitorAspect(),
+ self.xsetup.getGfxCards()[0].getScreens()[0] is screen_obj)
+
+ screen_obj.setMonitorModel(new_monitor_model)
+ screen_obj.setMonitorAspect(new_aspect)
+ self._syncGUI()
+ self.emit(PYSIGNAL("configChanged"), () )
+
+ def slotRoleSelected(self,index):
+ screen_index = self.monitor_roles.index(self.sender())
+ screen_obj = self.gfxcard.getScreens()[screen_index]
+ self.xsetup.setScreenRole(screen_obj,[XSetup.ROLE_PRIMARY,XSetup.ROLE_SECONDARY,XSetup.ROLE_UNUSED][index])
+
+ self._syncGUI()
+ self.emit(PYSIGNAL("configChanged"), () )