def __init__(self, project, parent=None): """ Initialize the project block. :type project: str :type parent: QtWidgets.QWidget """ super().__init__(parent) self.nameLabel = QtWidgets.QLabel(os.path.basename(project), self) self.nameLabel.setContentsMargins(20, 0, 20, 0) self.nameLabel.setProperty('class', 'name') self.nameLabel.setFont(Font(bold=True)) self.pathLabel = QtWidgets.QLabel(compressPath(shortPath(project), 34), self) self.pathLabel.setContentsMargins(20, 0, 20, 0) self.pathLabel.setProperty('class', 'path') self.removeBtn = PHCQPushButton(self) self.removeBtn.setIcon(QtGui.QIcon(':icons/24/ic_close_black')) self.removeBtn.setToolTip('Remove Project') self.removeBtn.setVisible(False) connect(self.removeBtn.clicked, self.onRemoveButtonClicked) self.deleteBtn = PHCQPushButton(self) self.deleteBtn.setToolTip('Delete Project') self.deleteBtn.setIcon(QtGui.QIcon(':/icons/24/ic_delete_black')) self.deleteBtn.setVisible(False) connect(self.deleteBtn.clicked, self.onDeleteButtonClicked) self.leftWidget = QtWidgets.QWidget(self) self.leftWidget.setContentsMargins(0, 0, 0, 0) self.leftLayout = QtWidgets.QVBoxLayout(self.leftWidget) self.leftLayout.setContentsMargins(0, 0, 0, 0) self.leftLayout.setSpacing(0) self.leftLayout.addWidget(self.nameLabel) self.leftLayout.addWidget(self.pathLabel) self.rightWidget = QtWidgets.QWidget(self) self.rightWidget.setContentsMargins(0, 0, 10, 0) self.rightLayout = QtWidgets.QHBoxLayout(self.rightWidget) self.rightLayout.setContentsMargins(0, 0, 0, 0) self.rightLayout.setSpacing(0) self.rightLayout.addWidget(self.removeBtn) self.rightLayout.addWidget(self.deleteBtn) self.mainLayout = QtWidgets.QHBoxLayout(self) self.mainLayout.setContentsMargins(0, 0, 0, 0) self.mainLayout.addWidget(self.leftWidget) self.mainLayout.addWidget(self.rightWidget, 1, QtCore.Qt.AlignRight) self.installEventFilter(self) self.setContentsMargins(0, 0, 0, 0) self.setCursor(QtCore.Qt.PointingHandCursor) self.setFixedHeight(40) self.setFocusPolicy(QtCore.Qt.TabFocus) self.setToolTip(expandPath(project)) self.path = project
def __init__(self, project, parent=None): """ Initialize the project block. :type project: str :type parent: QtWidgets.QWidget """ super().__init__(parent) self.nameLabel = QtWidgets.QLabel(os.path.basename(project), self) self.nameLabel.setContentsMargins(20, 0, 20, 0) self.nameLabel.setProperty('class', 'name') self.nameLabel.setFont(Font('Roboto', 12, bold=True)) self.pathLabel = QtWidgets.QLabel(compressPath(shortPath(project), 34), self) self.pathLabel.setContentsMargins(20, 0, 20, 0) self.pathLabel.setProperty('class', 'path') self.pathLabel.setFont(Font('Roboto', 12)) self.deleteBtn = PHCQPushButton(self) self.deleteBtn.setIcon(QtGui.QIcon(':/icons/24/ic_delete_black')) self.deleteBtn.setVisible( not isSubPath(expandPath('@examples/'), project)) connect(self.deleteBtn.clicked, self.onDeleteButtonClicked) self.leftWidget = QtWidgets.QWidget(self) self.leftWidget.setContentsMargins(0, 0, 0, 0) self.leftLayout = QtWidgets.QVBoxLayout(self.leftWidget) self.leftLayout.setContentsMargins(0, 0, 0, 0) self.leftLayout.setSpacing(0) self.leftLayout.addWidget(self.nameLabel) self.leftLayout.addWidget(self.pathLabel) self.rightWidget = QtWidgets.QWidget(self) self.rightWidget.setContentsMargins(0, 0, 10, 0) self.rightLayout = QtWidgets.QVBoxLayout(self.rightWidget) self.rightLayout.setContentsMargins(0, 0, 0, 0) self.rightLayout.setSpacing(0) self.rightLayout.addWidget(self.deleteBtn) self.mainLayout = QtWidgets.QHBoxLayout(self) self.mainLayout.setContentsMargins(0, 0, 0, 0) self.mainLayout.addWidget(self.leftWidget) self.mainLayout.addWidget(self.rightWidget, 1, QtCore.Qt.AlignRight) self.setContentsMargins(0, 0, 0, 0) self.setFixedHeight(40) self.path = project
def __init__(self, project, parent=None): """ Initialize the project block. :type project: str :type parent: QtWidgets.QWidget """ super().__init__(parent) self.nameLabel = QtWidgets.QLabel(os.path.basename(project), self) self.nameLabel.setContentsMargins(20, 0, 20, 0) self.nameLabel.setProperty('class', 'name') self.nameLabel.setFont(Font('Roboto', 12, bold=True)) self.pathLabel = QtWidgets.QLabel(compressPath(shortPath(project), 34), self) self.pathLabel.setContentsMargins(20, 0, 20, 0) self.pathLabel.setProperty('class', 'path') self.pathLabel.setFont(Font('Roboto', 12)) self.deleteBtn = PHCQPushButton(self) self.deleteBtn.setIcon(QtGui.QIcon(':/icons/24/ic_delete_black')) self.deleteBtn.setVisible(not isSubPath(expandPath('@examples/'), project)) connect(self.deleteBtn.clicked, self.onDeleteButtonClicked) self.leftWidget = QtWidgets.QWidget(self) self.leftWidget.setContentsMargins(0, 0, 0, 0) self.leftLayout = QtWidgets.QVBoxLayout(self.leftWidget) self.leftLayout.setContentsMargins(0, 0, 0, 0) self.leftLayout.setSpacing(0) self.leftLayout.addWidget(self.nameLabel) self.leftLayout.addWidget(self.pathLabel) self.rightWidget = QtWidgets.QWidget(self) self.rightWidget.setContentsMargins(0, 0, 10, 0) self.rightLayout = QtWidgets.QVBoxLayout(self.rightWidget) self.rightLayout.setContentsMargins(0, 0, 0, 0) self.rightLayout.setSpacing(0) self.rightLayout.addWidget(self.deleteBtn) self.mainLayout = QtWidgets.QHBoxLayout(self) self.mainLayout.setContentsMargins(0, 0, 0, 0) self.mainLayout.addWidget(self.leftWidget) self.mainLayout.addWidget(self.rightWidget, 1, QtCore.Qt.AlignRight) self.setContentsMargins(0, 0, 0, 0) self.setFixedHeight(40) self.path = project
def __init__(self, item, name, current, importing, parent=None): """ Initialize the project dialog. :type item: Item :type name: str :type current: str :type importing: str :type parent: QWidget """ super().__init__(parent) self.item = item self.name = name ############################################# # LEFT SIDE ################################# widget = QtWidgets.QLabel(self) widget.setAlignment(QtCore.Qt.AlignCenter) widget.setFont(Font('Roboto', 14, bold=True, capitalization=Font.AllUppercase)) widget.setObjectName('current_title') widget.setText('Current') self.addWidget(widget) widget = TextField(self) widget.setFixedSize(300, 200) widget.setFocusPolicy(QtCore.Qt.NoFocus) widget.setFont(Font('Roboto', 12)) widget.setObjectName('current_documentation') widget.setReadOnly(True) widget.setValue(current) self.addWidget(widget) widget = PHCQPushButton(self) widget.setAutoDefault(False) widget.setDefault(False) widget.setProperty('class', 'flat blue') widget.setFixedWidth(32) widget.setIcon(QtGui.QIcon(':/icons/24/ic_keyboard_arrow_right_black')) widget.setIconSize(QtCore.QSize(24, 24)) widget.setObjectName('pick_current_button') widget.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding) connect(widget.clicked, self.doPickDocumentation) self.addWidget(widget) # widget = QtWidgets.QLabel(self) # widget.setFixedSize(QtCore.QSize(24, 24)) # widget.setPixmap(QtGui.QIcon(':/icons/24/ic_compare_arrows_black').pixmap(24)) # widget.setObjectName('compare_arrows_current_icon') # self.addWidget(widget) ############################################# # MIDDLE SIDE ################################# widget = QtWidgets.QLabel(self) widget.setAlignment(QtCore.Qt.AlignCenter) widget.setFont(Font('Roboto', 14, bold=True, capitalization=Font.AllUppercase)) widget.setObjectName('final_title') widget.setText('Final') self.addWidget(widget) widget = TextField(self) widget.setFixedSize(300, 200) widget.setFont(Font('Roboto', 12)) widget.setObjectName('final_documentation') self.addWidget(widget) ############################################# # RIGHT SIDE ################################# widget = QtWidgets.QLabel(self) widget.setAlignment(QtCore.Qt.AlignCenter) widget.setFont(Font('Roboto', 14, bold=True, capitalization=Font.AllUppercase)) widget.setObjectName('importing_title') widget.setText('Importing') self.addWidget(widget) widget = TextField(self) widget.setFixedSize(300, 200) widget.setFocusPolicy(QtCore.Qt.NoFocus) widget.setFont(Font('Roboto', 12)) widget.setObjectName('importing_documentation') widget.setReadOnly(True) widget.setValue(importing) self.addWidget(widget) widget = PHCQPushButton(self) widget.setAutoDefault(False) widget.setDefault(False) widget.setProperty('class', 'flat blue') widget.setFixedWidth(32) widget.setIcon(QtGui.QIcon(':/icons/24/ic_keyboard_arrow_left_black')) widget.setIconSize(QtCore.QSize(24, 24)) widget.setObjectName('pick_importing_button') widget.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding) connect(widget.clicked, self.doPickDocumentation) self.addWidget(widget) # widget = QtWidgets.QLabel(self) # widget.setFixedSize(QtCore.QSize(24, 24)) # widget.setPixmap(QtGui.QIcon(':/icons/24/ic_compare_arrows_black').pixmap(24)) # widget.setObjectName('compare_arrows_importing_icon') # self.addWidget(widget) ############################################# # CONFIRMATION AREA ################################# widget = QtWidgets.QDialogButtonBox(QtCore.Qt.Horizontal, self) widget.addButton(QtWidgets.QDialogButtonBox.Ok) widget.addButton(QtWidgets.QDialogButtonBox.Abort) widget.setContentsMargins(0, 4, 0, 0) widget.setFont(Font('Roboto', 12)) widget.setObjectName('confirmation_box') connect(widget.accepted, self.accept) connect(widget.rejected, self.reject) self.addWidget(widget) ############################################# # SETUP DIALOG LAYOUT ################################# gridWidget = QtWidgets.QWidget(self) gridLayout = QtWidgets.QGridLayout(gridWidget) gridLayout.setContentsMargins(0, 0, 0, 0) gridLayout.addWidget(self.widget('current_title'), 0, 0) gridLayout.addWidget(self.widget('current_documentation'), 1, 0) gridLayout.addWidget(self.widget('final_title'), 0, 2) gridLayout.addWidget(self.widget('final_documentation'), 1, 2) gridLayout.addWidget(self.widget('importing_title'), 0, 4) gridLayout.addWidget(self.widget('importing_documentation'), 1, 4) # gridLayout.addWidget(self.widget('compare_arrows_current_icon'), 0, 1, QtCore.Qt.AlignCenter) # gridLayout.addWidget(self.widget('compare_arrows_importing_icon'), 0, 3, QtCore.Qt.AlignCenter) gridLayout.addWidget(self.widget('pick_current_button'), 1, 1) gridLayout.addWidget(self.widget('pick_importing_button'), 1, 3) mainLayout = QtWidgets.QVBoxLayout() mainLayout.addWidget(gridWidget) mainLayout.addWidget(self.widget('confirmation_box')) mainLayout.setContentsMargins(10, 10, 10, 10) self.setLayout(mainLayout) self.setFixedSize(self.sizeHint()) self.setFont(Font('Roboto', 12)) self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy')) self.setWindowTitle("Resolve documentation conflict for {0} '{1}'...".format(self.item.shortName, self.name))
def __init__(self, collection, parent=None): """ Initialize the project dialog. :type collection: T <= list | tuple :type parent: QWidget """ super().__init__(parent) self.collection = sorted(collection, key=itemgetter(K_ITEM, K_NAME)) ############################################# # CHECKBOX WIDGETS ################################# self.marks = {K_CURRENT: {}, K_IMPORTING: {}, K_FINAL: {}} for e in self.collection: ## CREATE CURRENT CHECKBOX mark = CheckBox(self) mark.setEnabled(False) mark.setChecked(e[K_CURRENT]) if e[K_ITEM] not in self.marks[K_CURRENT]: self.marks[K_CURRENT][e[K_ITEM]] = {} if e[K_NAME] not in self.marks[K_CURRENT][e[K_ITEM]]: self.marks[K_CURRENT][e[K_ITEM]][e[K_NAME]] = {} self.marks[K_CURRENT][e[K_ITEM]][e[K_NAME]][e[K_PROPERTY]] = mark ## CREATE IMPORTING CHECKBOX mark = CheckBox(self) mark.setEnabled(False) mark.setChecked(e[K_IMPORTING]) if e[K_ITEM] not in self.marks[K_IMPORTING]: self.marks[K_IMPORTING][e[K_ITEM]] = {} if e[K_NAME] not in self.marks[K_IMPORTING][e[K_ITEM]]: self.marks[K_IMPORTING][e[K_ITEM]][e[K_NAME]] = {} self.marks[K_IMPORTING][e[K_ITEM]][e[K_NAME]][e[K_PROPERTY]] = mark ## CREATE FINAL CHECKBOX mark = CheckBox(self) mark.setEnabled(True) mark.setTristate(True) mark.setCheckState(QtCore.Qt.PartiallyChecked) connect(mark.stateChanged, self.onMarkStateChanged) if e[K_ITEM] not in self.marks[K_FINAL]: self.marks[K_FINAL][e[K_ITEM]] = {} if e[K_NAME] not in self.marks[K_FINAL][e[K_ITEM]]: self.marks[K_FINAL][e[K_ITEM]][e[K_NAME]] = {} self.marks[K_FINAL][e[K_ITEM]][e[K_NAME]][e[K_PROPERTY]] = mark ############################################# # BUTTONS & PLACEHOLDERS ################################# # widget = QtWidgets.QLabel(self) # widget.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) # widget.setFont(Font('Roboto', 14, bold=True, capitalization=Font.AllUppercase)) # widget.setObjectName('title_type') # widget.setText('Type') # self.addWidget(widget) # widget = QtWidgets.QLabel(self) # widget.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) # widget.setFont(Font('Roboto', 14, bold=True, capitalization=Font.AllUppercase)) # widget.setObjectName('title_name') # widget.setText('Name') # self.addWidget(widget) # widget = QtWidgets.QLabel(self) # widget.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) # widget.setFont(Font('Roboto', 14, bold=True, capitalization=Font.AllUppercase)) # widget.setObjectName('title_property') # widget.setText('Property') # self.addWidget(widget) widget = QtWidgets.QLabel(self) widget.setAlignment(QtCore.Qt.AlignCenter) widget.setFont(Font('Roboto', 14, bold=True, capitalization=Font.AllUppercase)) widget.setObjectName('title_current') widget.setText('Current') self.addWidget(widget) widget = QtWidgets.QLabel(self) widget.setAlignment(QtCore.Qt.AlignCenter) widget.setFont(Font('Roboto', 14, bold=True, capitalization=Font.AllUppercase)) widget.setObjectName('title_final') widget.setText('Final') self.addWidget(widget) widget = QtWidgets.QLabel(self) widget.setAlignment(QtCore.Qt.AlignCenter) widget.setFont(Font('Roboto', 14, bold=True, capitalization=Font.AllUppercase)) widget.setObjectName('title_importing') widget.setText('Importing') self.addWidget(widget) # widget = QtWidgets.QLabel(self) # widget.setFixedSize(QtCore.QSize(24, 24)) # widget.setPixmap(QtGui.QIcon(':/icons/24/ic_compare_arrows_black').pixmap(24)) # widget.setObjectName('compare_arrows_current_icon') # self.addWidget(widget) # widget = QtWidgets.QLabel(self) # widget.setFixedSize(QtCore.QSize(24, 24)) # widget.setPixmap(QtGui.QIcon(':/icons/24/ic_compare_arrows_black').pixmap(24)) # widget.setObjectName('compare_arrows_importing_icon') # self.addWidget(widget) widget = PHCQPushButton(self) widget.setAutoDefault(False) widget.setDefault(False) widget.setProperty('class', 'flat blue') widget.setFixedWidth(32) widget.setIcon(QtGui.QIcon(':/icons/24/ic_keyboard_arrow_right_black')) widget.setIconSize(QtCore.QSize(24, 24)) widget.setObjectName('pick_current_button') widget.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding) connect(widget.clicked, self.doPickBooleanSet) self.addWidget(widget) widget = PHCQPushButton(self) widget.setAutoDefault(False) widget.setDefault(False) widget.setProperty('class', 'flat blue') widget.setFixedWidth(32) widget.setIcon(QtGui.QIcon(':/icons/24/ic_keyboard_arrow_left_black')) widget.setIconSize(QtCore.QSize(24, 24)) widget.setObjectName('pick_importing_button') widget.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding) connect(widget.clicked, self.doPickBooleanSet) self.addWidget(widget) ############################################# # CONFIRMATION AREA ################################# widget = QtWidgets.QDialogButtonBox(QtCore.Qt.Horizontal, self) widget.addButton(QtWidgets.QDialogButtonBox.Ok) widget.addButton(QtWidgets.QDialogButtonBox.Abort) widget.setContentsMargins(0, 4, 0, 0) widget.setFont(Font('Roboto', 12)) widget.setObjectName('confirmation_box') widget.button(QtWidgets.QDialogButtonBox.Ok).setEnabled(False) connect(widget.accepted, self.accept) connect(widget.rejected, self.reject) self.addWidget(widget) ############################################# # SETUP DIALOG LAYOUT ################################# gridWidget = QtWidgets.QWidget(self) gridLayout = QtWidgets.QGridLayout(gridWidget) gridLayout.setContentsMargins(0, 0, 0, 0) #gridLayout.addWidget(self.widget('title_type'), 0, 0) #gridLayout.addWidget(self.widget('title_name'), 0, 1) #gridLayout.addWidget(self.widget('title_property'), 0, 2) gridLayout.addWidget(self.widget('title_current'), 0, 3) gridLayout.addWidget(self.widget('title_final'), 0, 5) gridLayout.addWidget(self.widget('title_importing'), 0, 7) #gridLayout.addWidget(self.widget('compare_arrows_current_icon'), 0, 4, QtCore.Qt.AlignCenter) #gridLayout.addWidget(self.widget('compare_arrows_importing_icon'), 0, 6, QtCore.Qt.AlignCenter) for row, e in enumerate(self.collection, start=1): w_type = QtWidgets.QLabel(self) w_type.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) w_type.setFont(Font('Roboto', 12)) w_type.setText(e[K_ITEM].shortName.title()) w_name = QtWidgets.QLabel(self) w_name.setContentsMargins(40, 0, 40, 0) w_name.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) w_name.setFont(Font('Roboto', 12, italic=True)) w_name.setText(e[K_NAME]) w_prop = QtWidgets.QLabel(self) w_prop.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) w_prop.setFont(Font('Roboto', 14, bold=True, capitalization=Font.SmallCaps)) w_prop.setText(RE_CAMEL_SPACE.sub('\g<1> \g<2>', e[K_PROPERTY]).lower()) gridLayout.addWidget(w_type, row, 0) gridLayout.addWidget(w_name, row, 1) gridLayout.addWidget(w_prop, row, 2) gridLayout.addWidget(self.marks[K_CURRENT][e[K_ITEM]][e[K_NAME]][e[K_PROPERTY]], row, 3, QtCore.Qt.AlignCenter) gridLayout.addWidget(self.marks[K_FINAL][e[K_ITEM]][e[K_NAME]][e[K_PROPERTY]], row, 5, QtCore.Qt.AlignCenter) gridLayout.addWidget(self.marks[K_IMPORTING][e[K_ITEM]][e[K_NAME]][e[K_PROPERTY]], row, 7, QtCore.Qt.AlignCenter) gridLayout.addWidget(self.widget('pick_current_button'), 1, 4, len(self.collection), 1) gridLayout.addWidget(self.widget('pick_importing_button'), 1, 6, len(self.collection), 1) mainLayout = QtWidgets.QVBoxLayout() mainLayout.addWidget(gridWidget) mainLayout.addWidget(self.widget('confirmation_box')) mainLayout.setContentsMargins(10, 10, 10, 10) self.setLayout(mainLayout) self.setFixedSize(self.sizeHint()) self.setFont(Font('Roboto', 12)) self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy')) self.setWindowTitle("Resolve conflicts...")
def __init__(self, application, parent=None): """ Initialize the workspace dialog. :type application: QApplication :type parent: QtWidgets.QWidget """ super().__init__(parent) settings = QtCore.QSettings() self.pending = False self.workspace = settings.value('workspace/home', WORKSPACE, str) ############################################# # LEFT AREA ################################# self.innerWidgetL = QtWidgets.QWidget(self) self.innerWidgetL.setProperty('class', 'inner-left') self.innerWidgetL.setContentsMargins(0, 0, 0, 0) self.innerLayoutL = QtWidgets.QVBoxLayout(self.innerWidgetL) self.innerLayoutL.setContentsMargins(0, 0, 0, 0) self.innerLayoutL.setSpacing(0) ############################################# # RIGHT AREA ################################# self.actionBugTracker = QtWidgets.QAction('Report a bug', self) self.actionBugTracker.setData(BUG_TRACKER) connect(self.actionBugTracker.triggered, self.doOpenURL) self.actionGrapholWeb = QtWidgets.QAction('Visit Graphol website', self) self.actionGrapholWeb.setData(GRAPHOL_HOME) connect(self.actionGrapholWeb.triggered, self.doOpenURL) self.actionProjectHome = QtWidgets.QAction('GitHub repository', self) self.actionProjectHome.setData(PROJECT_HOME) connect(self.actionProjectHome.triggered, self.doOpenURL) self.menuHelp = QtWidgets.QMenu(self) self.menuHelp.addAction(self.actionBugTracker) self.menuHelp.addAction(self.actionProjectHome) self.menuHelp.addAction(self.actionGrapholWeb) self.innerWidgetR = QtWidgets.QWidget(self) self.innerWidgetR.setProperty('class', 'inner-right') self.innerWidgetR.setContentsMargins(0, 30, 0, 0) self.appPix = QtWidgets.QLabel(self) self.appPix.setPixmap(QtGui.QIcon(':/icons/128/ic_eddy').pixmap(128)) self.appPix.setContentsMargins(0, 0, 0, 0) self.appName = QtWidgets.QLabel(APPNAME, self) self.appName.setFont(Font(scale=2.5, capitalization=Font.SmallCaps)) self.appName.setProperty('class', 'appname') self.appVersion = QtWidgets.QLabel('Version: {0}'.format(VERSION), self) self.appVersion.setFont( Font(scale=1.3333, capitalization=Font.SmallCaps)) self.appVersion.setProperty('class', 'version') self.buttonNewProject = PHCQPushButton(self) self.buttonNewProject.setIcon( QtGui.QIcon(':/icons/24/ic_add_document_black')) self.buttonNewProject.setIconSize(QtCore.QSize(24, 24)) self.buttonNewProject.setText('&Create new project') connect(self.buttonNewProject.clicked, self.doNewProject) self.buttonOpenProject = PHCQPushButton(self) self.buttonOpenProject.setIcon( QtGui.QIcon(':/icons/24/ic_folder_open_black')) self.buttonOpenProject.setIconSize(QtCore.QSize(24, 24)) self.buttonOpenProject.setText('&Open project') connect(self.buttonOpenProject.clicked, self.doOpen) self.buttonHelp = PHCQToolButton(self) self.buttonHelp.setIcon( QtGui.QIcon(':/icons/24/ic_help_outline_black')) self.buttonHelp.setIconSize(QtCore.QSize(24, 24)) self.buttonHelp.setText('&Help') self.buttonHelp.setMenu(self.menuHelp) self.buttonHelp.setPopupMode(PHCQToolButton.InstantPopup) self.buttonHelp.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) self.buttonLayoutRT = QtWidgets.QVBoxLayout() self.buttonLayoutRT.addWidget(self.buttonNewProject) self.buttonLayoutRT.addWidget(self.buttonOpenProject) self.buttonLayoutRT.setContentsMargins(0, 38, 0, 0) self.buttonLayoutRT.setAlignment(QtCore.Qt.AlignHCenter) self.buttonLayoutRB = QtWidgets.QHBoxLayout() self.buttonLayoutRB.addWidget(self.buttonHelp) self.buttonLayoutRB.setAlignment(QtCore.Qt.AlignBottom | QtCore.Qt.AlignRight) self.buttonLayoutRB.setContentsMargins(0, 30, 8, 0) self.innerLayoutR = QtWidgets.QVBoxLayout(self.innerWidgetR) self.innerLayoutR.setContentsMargins(0, 0, 0, 0) self.innerLayoutR.addWidget(self.appPix, 0, QtCore.Qt.AlignHCenter) self.innerLayoutR.addWidget(self.appName, 0, QtCore.Qt.AlignHCenter) self.innerLayoutR.addWidget(self.appVersion, 0, QtCore.Qt.AlignHCenter) self.innerLayoutR.addLayout(self.buttonLayoutRT) self.innerLayoutR.addLayout(self.buttonLayoutRB) ############################################# # SETUP DIALOG LAYOUT ################################# self.placeholder = QtWidgets.QLabel('No Recent Projects', self) self.placeholder.setEnabled(False) self.placeholder.setFixedSize(300, 400) self.placeholder.setFont(Font(scale=1.5)) self.placeholder.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignHCenter) self.outerWidgetL = QtWidgets.QWidget(self) self.outerWidgetL.setProperty('class', 'outer-left') self.outerWidgetL.setContentsMargins(0, 0, 0, 0) self.outerWidgetL.setFixedWidth(300) self.outerLayoutL = QtWidgets.QVBoxLayout(self.outerWidgetL) self.outerLayoutL.setContentsMargins(0, 0, 0, 0) self.outerLayoutL.addWidget(self.placeholder, 1, QtCore.Qt.AlignTop) self.outerLayoutL.addWidget(self.innerWidgetL, 0, QtCore.Qt.AlignTop) self.outerWidgetR = QtWidgets.QWidget(self) self.outerWidgetR.setProperty('class', 'outer-right') self.outerWidgetR.setContentsMargins(0, 0, 0, 0) self.outerLayoutR = QtWidgets.QVBoxLayout(self.outerWidgetR) self.outerLayoutR.setContentsMargins(0, 0, 0, 0) self.outerLayoutR.addWidget(self.innerWidgetR, 0, QtCore.Qt.AlignTop) self.mainLayout = QtWidgets.QHBoxLayout(self) self.mainLayout.setContentsMargins(0, 0, 0, 0) self.mainLayout.addWidget(self.outerWidgetL) self.mainLayout.addWidget(self.outerWidgetR) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.setFixedSize(720, 400) self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy')) self.setWindowTitle('Welcome to {0}'.format(APPNAME)) connect(self.sgnCreateSession, application.doCreateSession) connect(self.sgnCreateSessionFromScratch, application.doCreateSessionFromScratch) connect(self.sgnOpenProject, self.doOpenProject) connect(self.sgnUpdateRecentProjects, self.doUpdateRecentProjects) desktop = QtWidgets.QDesktopWidget() screen = desktop.availableGeometry(self) widget = self.geometry() x = screen.x() + (screen.width() - widget.width()) / 2 y = screen.y() + (screen.height() - widget.height()) / 2 self.move(x, y) # UPDATE RECENT PROJECTS self.sgnUpdateRecentProjects.emit()
class Welcome(QtWidgets.QDialog): """ This class is used to display the welcome screen of Eddy. """ sgnCreateSession = QtCore.pyqtSignal(str) sgnOpenProject = QtCore.pyqtSignal(str) sgnCreateSessionFromScratch = QtCore.pyqtSignal(str, str, str) sgnUpdateRecentProjects = QtCore.pyqtSignal() def __init__(self, application, parent=None): """ Initialize the workspace dialog. :type application: QApplication :type parent: QtWidgets.QWidget """ super().__init__(parent) settings = QtCore.QSettings() self.pending = False self.workspace = settings.value('workspace/home', WORKSPACE, str) ############################################# # LEFT AREA ################################# self.innerWidgetL = QtWidgets.QWidget(self) self.innerWidgetL.setProperty('class', 'inner-left') self.innerWidgetL.setContentsMargins(0, 0, 0, 0) self.innerLayoutL = QtWidgets.QVBoxLayout(self.innerWidgetL) self.innerLayoutL.setContentsMargins(0, 0, 0, 0) self.innerLayoutL.setSpacing(0) ############################################# # RIGHT AREA ################################# self.actionBugTracker = QtWidgets.QAction('Report a bug', self) self.actionBugTracker.setData(BUG_TRACKER) connect(self.actionBugTracker.triggered, self.doOpenURL) self.actionGrapholWeb = QtWidgets.QAction('Visit Graphol website', self) self.actionGrapholWeb.setData(GRAPHOL_HOME) connect(self.actionGrapholWeb.triggered, self.doOpenURL) self.actionProjectHome = QtWidgets.QAction('GitHub repository', self) self.actionProjectHome.setData(PROJECT_HOME) connect(self.actionProjectHome.triggered, self.doOpenURL) self.menuHelp = QtWidgets.QMenu(self) self.menuHelp.addAction(self.actionBugTracker) self.menuHelp.addAction(self.actionProjectHome) self.menuHelp.addAction(self.actionGrapholWeb) self.innerWidgetR = QtWidgets.QWidget(self) self.innerWidgetR.setProperty('class', 'inner-right') self.innerWidgetR.setContentsMargins(0, 30, 0, 0) self.appPix = QtWidgets.QLabel(self) self.appPix.setPixmap(QtGui.QIcon(':/icons/128/ic_eddy').pixmap(128)) self.appPix.setContentsMargins(0, 0, 0, 0) self.appName = QtWidgets.QLabel(APPNAME, self) self.appName.setFont(Font(scale=2.5, capitalization=Font.SmallCaps)) self.appName.setProperty('class', 'appname') self.appVersion = QtWidgets.QLabel('Version: {0}'.format(VERSION), self) self.appVersion.setFont( Font(scale=1.3333, capitalization=Font.SmallCaps)) self.appVersion.setProperty('class', 'version') self.buttonNewProject = PHCQPushButton(self) self.buttonNewProject.setIcon( QtGui.QIcon(':/icons/24/ic_add_document_black')) self.buttonNewProject.setIconSize(QtCore.QSize(24, 24)) self.buttonNewProject.setText('&Create new project') connect(self.buttonNewProject.clicked, self.doNewProject) self.buttonOpenProject = PHCQPushButton(self) self.buttonOpenProject.setIcon( QtGui.QIcon(':/icons/24/ic_folder_open_black')) self.buttonOpenProject.setIconSize(QtCore.QSize(24, 24)) self.buttonOpenProject.setText('&Open project') connect(self.buttonOpenProject.clicked, self.doOpen) self.buttonHelp = PHCQToolButton(self) self.buttonHelp.setIcon( QtGui.QIcon(':/icons/24/ic_help_outline_black')) self.buttonHelp.setIconSize(QtCore.QSize(24, 24)) self.buttonHelp.setText('&Help') self.buttonHelp.setMenu(self.menuHelp) self.buttonHelp.setPopupMode(PHCQToolButton.InstantPopup) self.buttonHelp.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) self.buttonLayoutRT = QtWidgets.QVBoxLayout() self.buttonLayoutRT.addWidget(self.buttonNewProject) self.buttonLayoutRT.addWidget(self.buttonOpenProject) self.buttonLayoutRT.setContentsMargins(0, 38, 0, 0) self.buttonLayoutRT.setAlignment(QtCore.Qt.AlignHCenter) self.buttonLayoutRB = QtWidgets.QHBoxLayout() self.buttonLayoutRB.addWidget(self.buttonHelp) self.buttonLayoutRB.setAlignment(QtCore.Qt.AlignBottom | QtCore.Qt.AlignRight) self.buttonLayoutRB.setContentsMargins(0, 30, 8, 0) self.innerLayoutR = QtWidgets.QVBoxLayout(self.innerWidgetR) self.innerLayoutR.setContentsMargins(0, 0, 0, 0) self.innerLayoutR.addWidget(self.appPix, 0, QtCore.Qt.AlignHCenter) self.innerLayoutR.addWidget(self.appName, 0, QtCore.Qt.AlignHCenter) self.innerLayoutR.addWidget(self.appVersion, 0, QtCore.Qt.AlignHCenter) self.innerLayoutR.addLayout(self.buttonLayoutRT) self.innerLayoutR.addLayout(self.buttonLayoutRB) ############################################# # SETUP DIALOG LAYOUT ################################# self.placeholder = QtWidgets.QLabel('No Recent Projects', self) self.placeholder.setEnabled(False) self.placeholder.setFixedSize(300, 400) self.placeholder.setFont(Font(scale=1.5)) self.placeholder.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignHCenter) self.outerWidgetL = QtWidgets.QWidget(self) self.outerWidgetL.setProperty('class', 'outer-left') self.outerWidgetL.setContentsMargins(0, 0, 0, 0) self.outerWidgetL.setFixedWidth(300) self.outerLayoutL = QtWidgets.QVBoxLayout(self.outerWidgetL) self.outerLayoutL.setContentsMargins(0, 0, 0, 0) self.outerLayoutL.addWidget(self.placeholder, 1, QtCore.Qt.AlignTop) self.outerLayoutL.addWidget(self.innerWidgetL, 0, QtCore.Qt.AlignTop) self.outerWidgetR = QtWidgets.QWidget(self) self.outerWidgetR.setProperty('class', 'outer-right') self.outerWidgetR.setContentsMargins(0, 0, 0, 0) self.outerLayoutR = QtWidgets.QVBoxLayout(self.outerWidgetR) self.outerLayoutR.setContentsMargins(0, 0, 0, 0) self.outerLayoutR.addWidget(self.innerWidgetR, 0, QtCore.Qt.AlignTop) self.mainLayout = QtWidgets.QHBoxLayout(self) self.mainLayout.setContentsMargins(0, 0, 0, 0) self.mainLayout.addWidget(self.outerWidgetL) self.mainLayout.addWidget(self.outerWidgetR) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.setFixedSize(720, 400) self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy')) self.setWindowTitle('Welcome to {0}'.format(APPNAME)) connect(self.sgnCreateSession, application.doCreateSession) connect(self.sgnCreateSessionFromScratch, application.doCreateSessionFromScratch) connect(self.sgnOpenProject, self.doOpenProject) connect(self.sgnUpdateRecentProjects, self.doUpdateRecentProjects) desktop = QtWidgets.QDesktopWidget() screen = desktop.availableGeometry(self) widget = self.geometry() x = screen.x() + (screen.width() - widget.width()) / 2 y = screen.y() + (screen.height() - widget.height()) / 2 self.move(x, y) # UPDATE RECENT PROJECTS self.sgnUpdateRecentProjects.emit() ############################################# # EVENTS ################################# def paintEvent(self, paintEvent): """ This is needed for the widget to pick the stylesheet. :type paintEvent: QPaintEvent """ option = QtWidgets.QStyleOption() option.initFrom(self) painter = QtGui.QPainter(self) style = self.style() style.drawPrimitive(QtWidgets.QStyle.PE_Widget, option, painter, self) ############################################# # SLOTS ################################# @QtCore.pyqtSlot(str) def doDeleteProject(self, path): """ Delete the given project. :type path: str """ msgbox = QtWidgets.QMessageBox(self) msgbox.setIconPixmap( QtGui.QIcon(':/icons/48/ic_help_outline_black').pixmap(48)) msgbox.setInformativeText( '<b>NOTE: This action is not reversible!</b>') msgbox.setStandardButtons(QtWidgets.QMessageBox.No | QtWidgets.QMessageBox.Yes) msgbox.setTextFormat(QtCore.Qt.RichText) msgbox.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy')) #msgbox.setWindowTitle('Remove project: {0}?'.format(os.path.basename(path))) msgbox.setWindowTitle('Remove project: {0}?'.format(path)) #msgbox.setText('Are you sure you want to remove project: <b>{0}</b>'.format(os.path.basename(path))) msgbox.setText( 'Are you sure you want to remove project: <b>{0}</b>'.format(path)) msgbox.exec_() if msgbox.result() == QtWidgets.QMessageBox.Yes: try: # REMOVE THE PROJECT FROM DISK #rmdir(path) fremove(path) except Exception as e: msgbox = QtWidgets.QMessageBox(self) msgbox.setDetailedText(format_exception(e)) msgbox.setIconPixmap( QtGui.QIcon(':/icons/48/ic_error_outline_black').pixmap( 48)) msgbox.setStandardButtons(QtWidgets.QMessageBox.Close) msgbox.setTextFormat(QtCore.Qt.RichText) msgbox.setText( 'Eddy could not remove the specified project: <b>{0}</b>!'. format(path)) msgbox.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy')) msgbox.setWindowTitle('ERROR!') msgbox.exec_() else: self.sgnUpdateRecentProjects.emit() @QtCore.pyqtSlot() def doNewProject(self): """ Bring up a modal window used to create a new project. """ form = NewProjectDialog(self) if form.exec_() == NewProjectDialog.Accepted: self.sgnCreateSessionFromScratch.emit(form.name(), form.iri(), form.prefix()) #self.sgnCreateSession.emit(expandPath(form.pathField.value())) @QtCore.pyqtSlot() def doOpen(self): """ Bring up a modal window used to open a project. """ ''' dialog = QtWidgets.QFileDialog(self) dialog.setAcceptMode(QtWidgets.QFileDialog.AcceptOpen) dialog.setDirectory(expandPath(self.workspace)) dialog.setFileMode(QtWidgets.QFileDialog.Directory) dialog.setOption(QtWidgets.QFileDialog.ShowDirsOnly, True) dialog.setViewMode(QtWidgets.QFileDialog.Detail) if dialog.exec_() == QtWidgets.QFileDialog.Accepted: self.sgnOpenProject.emit(first(dialog.selectedFiles())) ''' dialog = QtWidgets.QFileDialog(self) dialog.setAcceptMode(QtWidgets.QFileDialog.AcceptOpen) dialog.setDirectory(expandPath('~')) dialog.setFileMode(QtWidgets.QFileDialog.ExistingFiles) dialog.setViewMode(QtWidgets.QFileDialog.Detail) dialog.setNameFilters([File.Graphol.value]) if dialog.exec_() == QtWidgets.QFileDialog.Accepted: self.sgnOpenProject.emit(first(dialog.selectedFiles())) @QtCore.pyqtSlot(str) def doOpenProject(self, path): """ Open a recent project in a new session of Eddy. :type path: str """ if not self.pending: self.pending = True self.sgnCreateSession.emit(expandPath(path)) self.pending = False @QtCore.pyqtSlot() def doOpenURL(self): """ Open a URL using the operating system default browser. """ action = self.sender() weburl = action.data() if weburl: # noinspection PyTypeChecker,PyCallByClass,PyCallByClass QtGui.QDesktopServices.openUrl(QtCore.QUrl(weburl)) @QtCore.pyqtSlot(str) def doRemoveProject(self, path): """ Remove the given project from the recent list. :type path: str """ recentList = [] path = expandPath(path) settings = QtCore.QSettings() for recent in map(expandPath, settings.value('project/recent', None, str) or []): if recent != path: recentList.append(recent) settings.setValue('project/recent', recentList) settings.sync() self.sgnUpdateRecentProjects.emit() @QtCore.pyqtSlot() def doUpdateRecentProjects(self): """ Update the list of recent projects. """ # UPDATE THE RECENT PROJECT LIST recentList = [] settings = QtCore.QSettings() for path in map(expandPath, settings.value('project/recent', None, str) or []): if fexists(path): recentList.append(path) settings.setValue('project/recent', recentList) settings.sync() # CLEAR CURRENT LAYOUT for i in reversed(range(self.innerLayoutL.count())): item = self.innerLayoutL.itemAt(i) self.innerLayoutL.removeItem(item) # DISPOSE NEW PROJECT BLOCK if recentList: self.placeholder.setVisible(False) for path in recentList: project = ProjectBlock(path, self.innerWidgetL) connect(project.sgnDeleteProject, self.doDeleteProject) connect(project.sgnOpenProject, self.doOpenProject) connect(project.sgnRemoveProject, self.doRemoveProject) self.innerLayoutL.addWidget(project, 0, QtCore.Qt.AlignTop) else: self.placeholder.setVisible(True)
class ProjectBlock(QtWidgets.QWidget): """ This class implements the project block displayed in the welcome dialog. """ sgnDeleteProject = QtCore.pyqtSignal(str) sgnOpenProject = QtCore.pyqtSignal(str) sgnRemoveProject = QtCore.pyqtSignal(str) def __init__(self, project, parent=None): """ Initialize the project block. :type project: str :type parent: QtWidgets.QWidget """ super().__init__(parent) self.nameLabel = QtWidgets.QLabel(os.path.basename(project), self) self.nameLabel.setContentsMargins(20, 0, 20, 0) self.nameLabel.setProperty('class', 'name') self.nameLabel.setFont(Font(bold=True)) self.pathLabel = QtWidgets.QLabel(compressPath(shortPath(project), 34), self) self.pathLabel.setContentsMargins(20, 0, 20, 0) self.pathLabel.setProperty('class', 'path') self.removeBtn = PHCQPushButton(self) self.removeBtn.setIcon(QtGui.QIcon(':icons/24/ic_close_black')) self.removeBtn.setToolTip('Remove Project') self.removeBtn.setVisible(False) connect(self.removeBtn.clicked, self.onRemoveButtonClicked) self.deleteBtn = PHCQPushButton(self) self.deleteBtn.setToolTip('Delete Project') self.deleteBtn.setIcon(QtGui.QIcon(':/icons/24/ic_delete_black')) self.deleteBtn.setVisible(False) connect(self.deleteBtn.clicked, self.onDeleteButtonClicked) self.leftWidget = QtWidgets.QWidget(self) self.leftWidget.setContentsMargins(0, 0, 0, 0) self.leftLayout = QtWidgets.QVBoxLayout(self.leftWidget) self.leftLayout.setContentsMargins(0, 0, 0, 0) self.leftLayout.setSpacing(0) self.leftLayout.addWidget(self.nameLabel) self.leftLayout.addWidget(self.pathLabel) self.rightWidget = QtWidgets.QWidget(self) self.rightWidget.setContentsMargins(0, 0, 10, 0) self.rightLayout = QtWidgets.QHBoxLayout(self.rightWidget) self.rightLayout.setContentsMargins(0, 0, 0, 0) self.rightLayout.setSpacing(0) self.rightLayout.addWidget(self.removeBtn) self.rightLayout.addWidget(self.deleteBtn) self.mainLayout = QtWidgets.QHBoxLayout(self) self.mainLayout.setContentsMargins(0, 0, 0, 0) self.mainLayout.addWidget(self.leftWidget) self.mainLayout.addWidget(self.rightWidget, 1, QtCore.Qt.AlignRight) self.installEventFilter(self) self.setContentsMargins(0, 0, 0, 0) self.setCursor(QtCore.Qt.PointingHandCursor) self.setFixedHeight(40) self.setFocusPolicy(QtCore.Qt.TabFocus) self.setToolTip(expandPath(project)) self.path = project ############################################# # SLOTS ################################# @QtCore.pyqtSlot() def onDeleteButtonClicked(self): """ Executed when the delete button is clicked. """ self.sgnDeleteProject.emit(self.path) @QtCore.pyqtSlot() def onRemoveButtonClicked(self): """ Executed when the remove button is clicked. """ self.sgnRemoveProject.emit(self.path) ############################################# # EVENTS ################################# def eventFilter(self, source, event): """ Filters events to show remove and delete buttons only when hovered. :type source: QObject :type event: QtCore.QEvent :rtype: bool """ if event.type() == QtCore.QEvent.HoverEnter: self.removeBtn.setVisible(True) self.deleteBtn.setVisible(faccess(self.path, os.R_OK | os.W_OK)) self.setFocus() elif event.type() == QtCore.QEvent.HoverLeave: self.removeBtn.setVisible(False) self.deleteBtn.setVisible(False) self.clearFocus() elif event.type() == QtCore.QEvent.KeyPress: if event.key() in { QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return, QtCore.Qt.Key_Space }: self.sgnOpenProject.emit(self.path) return super().eventFilter(source, event) def mouseReleaseEvent(self, mouseEvent): """ Executed when a mouse button is released from this widget. :type mouseEvent: QMouseEvent """ if mouseEvent.button() == QtCore.Qt.LeftButton: self.sgnOpenProject.emit(self.path) def paintEvent(self, paintEvent): """ This is needed for the widget to pick the stylesheet. :type paintEvent: QPaintEvent """ option = QtWidgets.QStyleOption() option.initFrom(self) painter = QtGui.QPainter(self) style = self.style() style.drawPrimitive(QtWidgets.QStyle.PE_Widget, option, painter, self)
class ProjectBlock(QtWidgets.QWidget): """ This class implements the project block displayed in the welcome dialog. """ sgnDeleteProject = QtCore.pyqtSignal(str) sgnOpenProject = QtCore.pyqtSignal(str) def __init__(self, project, parent=None): """ Initialize the project block. :type project: str :type parent: QtWidgets.QWidget """ super().__init__(parent) self.nameLabel = QtWidgets.QLabel(os.path.basename(project), self) self.nameLabel.setContentsMargins(20, 0, 20, 0) self.nameLabel.setProperty('class', 'name') self.nameLabel.setFont(Font('Roboto', 12, bold=True)) self.pathLabel = QtWidgets.QLabel(compressPath(shortPath(project), 34), self) self.pathLabel.setContentsMargins(20, 0, 20, 0) self.pathLabel.setProperty('class', 'path') self.pathLabel.setFont(Font('Roboto', 12)) self.deleteBtn = PHCQPushButton(self) self.deleteBtn.setIcon(QtGui.QIcon(':/icons/24/ic_delete_black')) self.deleteBtn.setVisible( not isSubPath(expandPath('@examples/'), project)) connect(self.deleteBtn.clicked, self.onDeleteButtonClicked) self.leftWidget = QtWidgets.QWidget(self) self.leftWidget.setContentsMargins(0, 0, 0, 0) self.leftLayout = QtWidgets.QVBoxLayout(self.leftWidget) self.leftLayout.setContentsMargins(0, 0, 0, 0) self.leftLayout.setSpacing(0) self.leftLayout.addWidget(self.nameLabel) self.leftLayout.addWidget(self.pathLabel) self.rightWidget = QtWidgets.QWidget(self) self.rightWidget.setContentsMargins(0, 0, 10, 0) self.rightLayout = QtWidgets.QVBoxLayout(self.rightWidget) self.rightLayout.setContentsMargins(0, 0, 0, 0) self.rightLayout.setSpacing(0) self.rightLayout.addWidget(self.deleteBtn) self.mainLayout = QtWidgets.QHBoxLayout(self) self.mainLayout.setContentsMargins(0, 0, 0, 0) self.mainLayout.addWidget(self.leftWidget) self.mainLayout.addWidget(self.rightWidget, 1, QtCore.Qt.AlignRight) self.setContentsMargins(0, 0, 0, 0) self.setFixedHeight(40) self.path = project ############################################# # SLOTS ################################# @QtCore.pyqtSlot() def onDeleteButtonClicked(self): """ Executed when the delete button is clicked. """ self.sgnDeleteProject.emit(self.path) ############################################# # EVENTS ################################# def mouseReleaseEvent(self, mouseEvent): """ Executed when a mouse button is released from this widget. :type mouseEvent: QMouseEvent """ if mouseEvent.button() == QtCore.Qt.LeftButton: self.sgnOpenProject.emit(self.path) def paintEvent(self, paintEvent): """ This is needed for the widget to pick the stylesheet. :type paintEvent: QPaintEvent """ option = QtWidgets.QStyleOption() option.initFrom(self) painter = QtGui.QPainter(self) style = self.style() style.drawPrimitive(QtWidgets.QStyle.PE_Widget, option, painter, self)
def __init__(self, application, parent=None): """ Initialize the workspace dialog. :type application: QApplication :type parent: QtWidgets.QWidget """ super().__init__(parent) settings = QtCore.QSettings(ORGANIZATION, APPNAME) self.workspace = settings.value('workspace/home', WORKSPACE, str) ############################################# # LEFT AREA ################################# self.innerWidgetL = QtWidgets.QWidget(self) self.innerWidgetL.setProperty('class', 'inner-left') self.innerWidgetL.setContentsMargins(0, 0, 0, 0) self.innerLayoutL = QtWidgets.QVBoxLayout(self.innerWidgetL) self.innerLayoutL.setContentsMargins(0, 0, 0, 0) self.innerLayoutL.setSpacing(0) for path in settings.value('project/recent', None, str) or []: project = ProjectBlock(path, self.innerWidgetL) connect(project.sgnDeleteProject, self.doDeleteProject) connect(project.sgnOpenProject, self.doOpenRecentProject) self.innerLayoutL.addWidget(project, 0, QtCore.Qt.AlignTop) ############################################# # RIGHT AREA ################################# self.actionBugTracker = QtWidgets.QAction('Report a bug', self) self.actionBugTracker.setData(BUG_TRACKER) connect(self.actionBugTracker.triggered, self.doOpenURL) self.actionGrapholWeb = QtWidgets.QAction('Visit Graphol website', self) self.actionGrapholWeb.setData(GRAPHOL_HOME) connect(self.actionGrapholWeb.triggered, self.doOpenURL) self.actionProjectHome = QtWidgets.QAction('GitHub repository', self) self.actionProjectHome.setData(PROJECT_HOME) connect(self.actionProjectHome.triggered, self.doOpenURL) self.menuHelp = QtWidgets.QMenu(self) self.menuHelp.addAction(self.actionBugTracker) self.menuHelp.addAction(self.actionProjectHome) self.menuHelp.addAction(self.actionGrapholWeb) self.innerWidgetR = QtWidgets.QWidget(self) self.innerWidgetR.setProperty('class', 'inner-right') self.innerWidgetR.setContentsMargins(0, 30, 0, 0) self.appPix = QtWidgets.QLabel(self) self.appPix.setPixmap(QtGui.QIcon(':/icons/128/ic_eddy').pixmap(128)) self.appPix.setContentsMargins(0, 0, 0, 0) self.appName = QtWidgets.QLabel(APPNAME, self) self.appName.setFont(Font('Roboto', 30, capitalization=Font.SmallCaps)) self.appName.setProperty('class', 'appname') self.appVersion = QtWidgets.QLabel('Version: {0}'.format(VERSION), self) self.appVersion.setFont(Font('Roboto', 16)) self.appVersion.setProperty('class', 'version') self.buttonNewProject = PHCQPushButton(self) self.buttonNewProject.setFont(Font('Roboto', 13)) self.buttonNewProject.setIcon(QtGui.QIcon(':/icons/24/ic_add_document_black')) self.buttonNewProject.setIconSize(QtCore.QSize(24, 24)) self.buttonNewProject.setText('Create new project') connect(self.buttonNewProject.clicked, self.doNewProject) self.buttonOpenProject = PHCQPushButton(self) self.buttonOpenProject.setFont(Font('Roboto', 13)) self.buttonOpenProject.setIcon(QtGui.QIcon(':/icons/24/ic_folder_open_black')) self.buttonOpenProject.setIconSize(QtCore.QSize(24, 24)) self.buttonOpenProject.setText('Open project') connect(self.buttonOpenProject.clicked, self.doOpenProject) self.buttonHelp = PHCQToolButton(self) self.buttonHelp.setFont(Font('Roboto', 12)) self.buttonHelp.setIcon(QtGui.QIcon(':/icons/24/ic_help_outline_black')) self.buttonHelp.setIconSize(QtCore.QSize(24, 24)) self.buttonHelp.setText('Help') self.buttonHelp.setMenu(self.menuHelp) self.buttonHelp.setPopupMode(PHCQToolButton.InstantPopup) self.buttonHelp.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) self.buttonLayoutRT = QtWidgets.QVBoxLayout() self.buttonLayoutRT.addWidget(self.buttonNewProject) self.buttonLayoutRT.addWidget(self.buttonOpenProject) self.buttonLayoutRT.setContentsMargins(0, 38, 0, 0) self.buttonLayoutRT.setAlignment(QtCore.Qt.AlignHCenter) self.buttonLayoutRB = QtWidgets.QHBoxLayout() self.buttonLayoutRB.addWidget(self.buttonHelp) self.buttonLayoutRB.setAlignment(QtCore.Qt.AlignBottom|QtCore.Qt.AlignRight) self.buttonLayoutRB.setContentsMargins(0, 30, 8, 0) self.innerLayoutR = QtWidgets.QVBoxLayout(self.innerWidgetR) self.innerLayoutR.setContentsMargins(0, 0, 0, 0) self.innerLayoutR.addWidget(self.appPix, 0, QtCore.Qt.AlignHCenter) self.innerLayoutR.addWidget(self.appName, 0, QtCore.Qt.AlignHCenter) self.innerLayoutR.addWidget(self.appVersion, 0, QtCore.Qt.AlignHCenter) self.innerLayoutR.addLayout(self.buttonLayoutRT) self.innerLayoutR.addLayout(self.buttonLayoutRB) ############################################# # SETUP DIALOG LAYOUT ################################# self.outerWidgetL = QtWidgets.QWidget(self) self.outerWidgetL.setProperty('class', 'outer-left') self.outerWidgetL.setContentsMargins(0, 0, 0, 0) self.outerWidgetL.setFixedWidth(280) self.outerLayoutL = QtWidgets.QVBoxLayout(self.outerWidgetL) self.outerLayoutL.setContentsMargins(0, 0, 0, 0) self.outerLayoutL.addWidget(self.innerWidgetL, 0, QtCore.Qt.AlignTop) self.outerWidgetR = QtWidgets.QWidget(self) self.outerWidgetR.setProperty('class', 'outer-right') self.outerWidgetR.setContentsMargins(0, 0, 0, 0) self.outerLayoutR = QtWidgets.QVBoxLayout(self.outerWidgetR) self.outerLayoutR.setContentsMargins(0, 0, 0, 0) self.outerLayoutR.addWidget(self.innerWidgetR, 0, QtCore.Qt.AlignTop) self.mainLayout = QtWidgets.QHBoxLayout(self) self.mainLayout.setContentsMargins(0, 0, 0, 0) self.mainLayout.addWidget(self.outerWidgetL) self.mainLayout.addWidget(self.outerWidgetR) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.setFixedSize(720, 400) self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy')) self.setWindowTitle('Welcome to {0}'.format(APPNAME)) connect(self.sgnCreateSession, application.doCreateSession) desktop = QtWidgets.QDesktopWidget() screen = desktop.screenGeometry() widget = self.geometry() x = (screen.width() - widget.width()) / 2 y = (screen.height() - widget.height()) / 2 self.move(x, y)
class Welcome(QtWidgets.QWidget): """ This class is used to display the welcome screen of Eddy. """ sgnCreateSession = QtCore.pyqtSignal(str) def __init__(self, application, parent=None): """ Initialize the workspace dialog. :type application: QApplication :type parent: QtWidgets.QWidget """ super().__init__(parent) settings = QtCore.QSettings(ORGANIZATION, APPNAME) self.workspace = settings.value('workspace/home', WORKSPACE, str) ############################################# # LEFT AREA ################################# self.innerWidgetL = QtWidgets.QWidget(self) self.innerWidgetL.setProperty('class', 'inner-left') self.innerWidgetL.setContentsMargins(0, 0, 0, 0) self.innerLayoutL = QtWidgets.QVBoxLayout(self.innerWidgetL) self.innerLayoutL.setContentsMargins(0, 0, 0, 0) self.innerLayoutL.setSpacing(0) for path in settings.value('project/recent', None, str) or []: project = ProjectBlock(path, self.innerWidgetL) connect(project.sgnDeleteProject, self.doDeleteProject) connect(project.sgnOpenProject, self.doOpenRecentProject) self.innerLayoutL.addWidget(project, 0, QtCore.Qt.AlignTop) ############################################# # RIGHT AREA ################################# self.actionBugTracker = QtWidgets.QAction('Report a bug', self) self.actionBugTracker.setData(BUG_TRACKER) connect(self.actionBugTracker.triggered, self.doOpenURL) self.actionGrapholWeb = QtWidgets.QAction('Visit Graphol website', self) self.actionGrapholWeb.setData(GRAPHOL_HOME) connect(self.actionGrapholWeb.triggered, self.doOpenURL) self.actionProjectHome = QtWidgets.QAction('GitHub repository', self) self.actionProjectHome.setData(PROJECT_HOME) connect(self.actionProjectHome.triggered, self.doOpenURL) self.menuHelp = QtWidgets.QMenu(self) self.menuHelp.addAction(self.actionBugTracker) self.menuHelp.addAction(self.actionProjectHome) self.menuHelp.addAction(self.actionGrapholWeb) self.innerWidgetR = QtWidgets.QWidget(self) self.innerWidgetR.setProperty('class', 'inner-right') self.innerWidgetR.setContentsMargins(0, 30, 0, 0) self.appPix = QtWidgets.QLabel(self) self.appPix.setPixmap(QtGui.QIcon(':/icons/128/ic_eddy').pixmap(128)) self.appPix.setContentsMargins(0, 0, 0, 0) self.appName = QtWidgets.QLabel(APPNAME, self) self.appName.setFont(Font('Roboto', 30, capitalization=Font.SmallCaps)) self.appName.setProperty('class', 'appname') self.appVersion = QtWidgets.QLabel('Version: {0}'.format(VERSION), self) self.appVersion.setFont(Font('Roboto', 16)) self.appVersion.setProperty('class', 'version') self.buttonNewProject = PHCQPushButton(self) self.buttonNewProject.setFont(Font('Roboto', 13)) self.buttonNewProject.setIcon(QtGui.QIcon(':/icons/24/ic_add_document_black')) self.buttonNewProject.setIconSize(QtCore.QSize(24, 24)) self.buttonNewProject.setText('Create new project') connect(self.buttonNewProject.clicked, self.doNewProject) self.buttonOpenProject = PHCQPushButton(self) self.buttonOpenProject.setFont(Font('Roboto', 13)) self.buttonOpenProject.setIcon(QtGui.QIcon(':/icons/24/ic_folder_open_black')) self.buttonOpenProject.setIconSize(QtCore.QSize(24, 24)) self.buttonOpenProject.setText('Open project') connect(self.buttonOpenProject.clicked, self.doOpenProject) self.buttonHelp = PHCQToolButton(self) self.buttonHelp.setFont(Font('Roboto', 12)) self.buttonHelp.setIcon(QtGui.QIcon(':/icons/24/ic_help_outline_black')) self.buttonHelp.setIconSize(QtCore.QSize(24, 24)) self.buttonHelp.setText('Help') self.buttonHelp.setMenu(self.menuHelp) self.buttonHelp.setPopupMode(PHCQToolButton.InstantPopup) self.buttonHelp.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) self.buttonLayoutRT = QtWidgets.QVBoxLayout() self.buttonLayoutRT.addWidget(self.buttonNewProject) self.buttonLayoutRT.addWidget(self.buttonOpenProject) self.buttonLayoutRT.setContentsMargins(0, 38, 0, 0) self.buttonLayoutRT.setAlignment(QtCore.Qt.AlignHCenter) self.buttonLayoutRB = QtWidgets.QHBoxLayout() self.buttonLayoutRB.addWidget(self.buttonHelp) self.buttonLayoutRB.setAlignment(QtCore.Qt.AlignBottom|QtCore.Qt.AlignRight) self.buttonLayoutRB.setContentsMargins(0, 30, 8, 0) self.innerLayoutR = QtWidgets.QVBoxLayout(self.innerWidgetR) self.innerLayoutR.setContentsMargins(0, 0, 0, 0) self.innerLayoutR.addWidget(self.appPix, 0, QtCore.Qt.AlignHCenter) self.innerLayoutR.addWidget(self.appName, 0, QtCore.Qt.AlignHCenter) self.innerLayoutR.addWidget(self.appVersion, 0, QtCore.Qt.AlignHCenter) self.innerLayoutR.addLayout(self.buttonLayoutRT) self.innerLayoutR.addLayout(self.buttonLayoutRB) ############################################# # SETUP DIALOG LAYOUT ################################# self.outerWidgetL = QtWidgets.QWidget(self) self.outerWidgetL.setProperty('class', 'outer-left') self.outerWidgetL.setContentsMargins(0, 0, 0, 0) self.outerWidgetL.setFixedWidth(280) self.outerLayoutL = QtWidgets.QVBoxLayout(self.outerWidgetL) self.outerLayoutL.setContentsMargins(0, 0, 0, 0) self.outerLayoutL.addWidget(self.innerWidgetL, 0, QtCore.Qt.AlignTop) self.outerWidgetR = QtWidgets.QWidget(self) self.outerWidgetR.setProperty('class', 'outer-right') self.outerWidgetR.setContentsMargins(0, 0, 0, 0) self.outerLayoutR = QtWidgets.QVBoxLayout(self.outerWidgetR) self.outerLayoutR.setContentsMargins(0, 0, 0, 0) self.outerLayoutR.addWidget(self.innerWidgetR, 0, QtCore.Qt.AlignTop) self.mainLayout = QtWidgets.QHBoxLayout(self) self.mainLayout.setContentsMargins(0, 0, 0, 0) self.mainLayout.addWidget(self.outerWidgetL) self.mainLayout.addWidget(self.outerWidgetR) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.setFixedSize(720, 400) self.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy')) self.setWindowTitle('Welcome to {0}'.format(APPNAME)) connect(self.sgnCreateSession, application.doCreateSession) desktop = QtWidgets.QDesktopWidget() screen = desktop.screenGeometry() widget = self.geometry() x = (screen.width() - widget.width()) / 2 y = (screen.height() - widget.height()) / 2 self.move(x, y) ############################################# # EVENTS ################################# def paintEvent(self, paintEvent): """ This is needed for the widget to pick the stylesheet. :type paintEvent: QPaintEvent """ option = QtWidgets.QStyleOption() option.initFrom(self) painter = QtGui.QPainter(self) style = self.style() style.drawPrimitive(QtWidgets.QStyle.PE_Widget, option, painter, self) ############################################# # SLOTS ################################# @QtCore.pyqtSlot(str) def doDeleteProject(self, path): """ Delete the given project. :type path: str """ msgbox = QtWidgets.QMessageBox(self) msgbox.setFont(Font('Roboto', 11)) msgbox.setIconPixmap(QtGui.QIcon(':/icons/48/ic_question_outline_black').pixmap(48)) msgbox.setInformativeText('<b>NOTE: This action is not reversible!</b>') msgbox.setStandardButtons(QtWidgets.QMessageBox.No | QtWidgets.QMessageBox.Yes) msgbox.setTextFormat(QtCore.Qt.RichText) msgbox.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy')) msgbox.setWindowTitle('Remove project: {0}?'.format(os.path.basename(path))) msgbox.setText('Are you sure you want to remove project: <b>{0}</b>'.format(os.path.basename(path))) msgbox.exec_() if msgbox.result() == QtWidgets.QMessageBox.Yes: try: # REMOVE THE PROJECT FROM DISK rmdir(path) except Exception as e: msgbox = QtWidgets.QMessageBox(self) msgbox.setDetailedText(format_exception(e)) msgbox.setIconPixmap(QtGui.QIcon(':/icons/48/ic_error_outline_black').pixmap(48)) msgbox.setStandardButtons(QtWidgets.QMessageBox.Close) msgbox.setTextFormat(QtCore.Qt.RichText) msgbox.setText('Eddy could not remove the specified project: <b>{0}</b>!'.format(os.path.basename(path))) msgbox.setWindowIcon(QtGui.QIcon(':/icons/128/ic_eddy')) msgbox.setWindowTitle('ERROR!') msgbox.exec_() else: # UPDATE THE RECENT PROJECT LIST recentList = [] settings = QtCore.QSettings(ORGANIZATION, APPNAME) for path in map(expandPath, settings.value('project/recent')): if isdir(path): recentList.append(path) settings.setValue('project/recent', recentList) settings.sync() # CLEAR CURRENT LAYOUT for i in reversed(range(self.innerLayoutL.count())): item = self.innerLayoutL.itemAt(i) self.innerLayoutL.removeItem(item) # DISPOSE NEW PROJECT BLOCK for path in recentList: project = ProjectBlock(path, self.innerWidgetL) connect(project.sgnDeleteProject, self.doDeleteProject) connect(project.sgnOpenProject, self.doOpenRecentProject) self.innerLayoutL.addWidget(project, 0, QtCore.Qt.AlignTop) @QtCore.pyqtSlot() def doNewProject(self): """ Bring up a modal window used to create a new project. """ form = ProjectDialog(self) if form.exec_() == ProjectDialog.Accepted: self.sgnCreateSession.emit(expandPath(form.pathField.value())) @QtCore.pyqtSlot() def doOpenProject(self): """ Bring up a modal window used to open a project. """ dialog = QtWidgets.QFileDialog(self) dialog.setAcceptMode(QtWidgets.QFileDialog.AcceptOpen) dialog.setDirectory(expandPath(self.workspace)) dialog.setFileMode(QtWidgets.QFileDialog.Directory) dialog.setOption(QtWidgets.QFileDialog.ShowDirsOnly, True) dialog.setViewMode(QtWidgets.QFileDialog.Detail) if dialog.exec_() == QtWidgets.QFileDialog.Accepted: self.sgnCreateSession.emit(expandPath(first(dialog.selectedFiles()))) @QtCore.pyqtSlot(str) def doOpenRecentProject(self, path): """ Open a recent project in a new session of Eddy. :type path: str """ self.sgnCreateSession.emit(expandPath(path)) @QtCore.pyqtSlot() def doOpenURL(self): """ Open a URL using the operating system default browser. """ action = self.sender() weburl = action.data() if weburl: # noinspection PyTypeChecker,PyCallByClass,PyCallByClass QtGui.QDesktopServices.openUrl(QtCore.QUrl(weburl))
class ProjectBlock(QtWidgets.QWidget): """ This class implements the project block displayed in the welcome dialog. """ sgnDeleteProject = QtCore.pyqtSignal(str) sgnOpenProject = QtCore.pyqtSignal(str) def __init__(self, project, parent=None): """ Initialize the project block. :type project: str :type parent: QtWidgets.QWidget """ super().__init__(parent) self.nameLabel = QtWidgets.QLabel(os.path.basename(project), self) self.nameLabel.setContentsMargins(20, 0, 20, 0) self.nameLabel.setProperty('class', 'name') self.nameLabel.setFont(Font('Roboto', 12, bold=True)) self.pathLabel = QtWidgets.QLabel(compressPath(shortPath(project), 34), self) self.pathLabel.setContentsMargins(20, 0, 20, 0) self.pathLabel.setProperty('class', 'path') self.pathLabel.setFont(Font('Roboto', 12)) self.deleteBtn = PHCQPushButton(self) self.deleteBtn.setIcon(QtGui.QIcon(':/icons/24/ic_delete_black')) self.deleteBtn.setVisible(not isSubPath(expandPath('@examples/'), project)) connect(self.deleteBtn.clicked, self.onDeleteButtonClicked) self.leftWidget = QtWidgets.QWidget(self) self.leftWidget.setContentsMargins(0, 0, 0, 0) self.leftLayout = QtWidgets.QVBoxLayout(self.leftWidget) self.leftLayout.setContentsMargins(0, 0, 0, 0) self.leftLayout.setSpacing(0) self.leftLayout.addWidget(self.nameLabel) self.leftLayout.addWidget(self.pathLabel) self.rightWidget = QtWidgets.QWidget(self) self.rightWidget.setContentsMargins(0, 0, 10, 0) self.rightLayout = QtWidgets.QVBoxLayout(self.rightWidget) self.rightLayout.setContentsMargins(0, 0, 0, 0) self.rightLayout.setSpacing(0) self.rightLayout.addWidget(self.deleteBtn) self.mainLayout = QtWidgets.QHBoxLayout(self) self.mainLayout.setContentsMargins(0, 0, 0, 0) self.mainLayout.addWidget(self.leftWidget) self.mainLayout.addWidget(self.rightWidget, 1, QtCore.Qt.AlignRight) self.setContentsMargins(0, 0, 0, 0) self.setFixedHeight(40) self.path = project ############################################# # SLOTS ################################# @QtCore.pyqtSlot() def onDeleteButtonClicked(self): """ Executed when the delete button is clicked. """ self.sgnDeleteProject.emit(self.path) ############################################# # EVENTS ################################# def mouseReleaseEvent(self, mouseEvent): """ Executed when a mouse button is released from this widget. :type mouseEvent: QMouseEvent """ if mouseEvent.button() == QtCore.Qt.LeftButton: self.sgnOpenProject.emit(self.path) def paintEvent(self, paintEvent): """ This is needed for the widget to pick the stylesheet. :type paintEvent: QPaintEvent """ option = QtWidgets.QStyleOption() option.initFrom(self) painter = QtGui.QPainter(self) style = self.style() style.drawPrimitive(QtWidgets.QStyle.PE_Widget, option, painter, self)