示例#1
0
 def random_employee(employee_type):
     if employee_type == 'developer':
         return Developer(**Developer.random_attrs())
     if employee_type == 'sales':
         return Sales(**Sales.random_attrs())
     if employee_type == 'project_manager':
         return ProjectManager(**ProjectManager.random_attrs())
     if employee_type == 'support':
         return Support(**Support.random_attrs())
     err_msg = (
         '{} employee type is not supported.\n'.format(type),
         'Allowed values are: \'developer\', \'project_manager\', \'sales\' or \'support\'',
     )
     raise ValueError(err_msg)
示例#2
0
    def make_project_book(self, book):
        self.project_panel = ProjectManager(book, 'projectinfo')
        self.project_panel.register(self)

        self.img_frame = tk.LabelFrame(self.main_frame, text='Dicom images')
        self.img_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        self.dicom_img = ImagePanel(self.img_frame, 'main_img', wl=True, toolbar=True, info=True, cb=True)
        self.dicom_img.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
示例#3
0
    @Slot()
    def exit_app(self, checked):
        QApplication.quit()

    def changed_tab(self, tab_index):
        if tab_index == 0:
            self.active_project_list.list.fill_list(True)
        elif tab_index == 1:
            self.achived_project_list.list.fill_list(False)


if __name__ == "__main__":
    app = QApplication([])

    try:
        pm = ProjectManager()
        widget = Widget()
        # QMainWindow using QWidget as central widget
        window = MainWindow(widget, pm)
        window.resize(800, 600)
        window.show()
        sys.exit(app.exec_())
    except DeckMissingError:
        msgBox = QMessageBox()
        msgBox.setWindowTitle("Missing deck error")
        msgBox.setText(
            "A stream deck couldn't be found attached to your computer. Please attach one and restart the program"
        )
        msgBox.exec_()
示例#4
0
	def __init__(self, parent=None):
		super(MainWindow, self).__init__(parent)
		
		#  Start logging
		#  ----------------------------------------
		logger = logging.getLogger("mainwindow.__init__")
		
		#  Member variables and init stuffs
		#  ----------------------------------------
		self.projdir = os.path.join(os.getcwd(), 'Downloads')
		
		if not os.path.isdir(self.projdir):
			os.makedirs(self.projdir)
		
		self.addedUsers = []
		self.currentuser = ''
		self.currentusermodel = None         # holds UserImagesModel
		self.currentthumbnailsmodel = None   # holds ThumbnailsModel
		self.currentview = 0   # 0 -> Table view, 1 -> Thumbnails view
		self.setupUi(self)
		
		#  Factory
		#  ----------------------------------------
		self.factory = Factory()
		self.factory.addClass('UserValidation', ProcessUserValidation)
		self.factory.addWorkers('UserValidation')
		self.factory.addClass('UserImages', ProcessUserImages)
		self.factory.addWorkers('UserImages')
		self.factory.addClass('ImagesFilesize', CheckImagesFilesize)
		self.factory.addWorkers('ImagesFilesize')
		
		for worker in self.factory.getWorkers('UserValidation'):
			self.connect(worker, SIGNAL('error'), self.callError)
			self.connect(worker, SIGNAL('updateList'), self.refreshUserList)
		
		for worker in self.factory.getWorkers('UserImages'):
			self.connect(worker, SIGNAL('error'), self.callError)
			self.connect(worker, SIGNAL('updateTable'), self.refreshTableView)
		
		for worker in self.factory.getWorkers('ImagesFilesize'):
			self.connect(worker, SIGNAL('updateTableModel'), self.updateTableModel)
		
		#  Users data
		#  ----------------------------------------
		self.usersdata = UsersData(self)
		self.usersdata.setProjectDir(self.projdir)
		self.usersdata.error.connect(self.callError) # SIGNAL("error()")
		self.userslistdata = UsersList(self.usersdata)
		self.userslistdata.setProjectDir(self.projdir)
		self.userslistdata.updateFromUsersData(self.usersdata)
		
		for worker in self.factory.getWorkers('UserImages'):
			self.connect(worker, SIGNAL('updateTable'), self.userslistdata.updateImagesCount)
		
		#  Project manager
		#  ----------------------------------------
		self.projman = ProjectManager(self.projdir)
		self.projman.updateWithExistingImages(self.usersdata)
		self.projman.saveData.connect(self.saveData) # SIGNAL("saveData()")
		
		#  Users list
		#  ----------------------------------------
		self.userslistmodel = UsersListModel(self.userslistdata)
		self.users_listViewWidget.setModel(self.userslistmodel)
		self.users_listViewWidget.setGridSize(QSize(20,20))
		headerstyle = "font-size: 12px;"
		self.users_listViewWidget.setStyleSheet(headerstyle)
		# Handle selection changed
		selectionmodel = self.users_listViewWidget.selectionModel()
		selectionmodel.selectionChanged.connect(self.userslistmodel.handleSelectionChanged)
		self.userslistmodel.onSelectionChanged.connect(self.onUserSelect)
		
		#  Setup layout inside stacked widget
		#  ----------------------------------------
		#  ( I can't understand how to set this up in Qt Designer,
		#    I can only create layout for one of them, then there
		#    seems to be no way to set layout for the other one )
		self.horizontalLayout_a = QHBoxLayout(self.page)
		self.horizontalLayout_a.addWidget(self.images_tableViewWidget)
		self.horizontalLayout_b = QHBoxLayout(self.page_2)
		self.horizontalLayout_b.addWidget(self.thumbnails_tableViewWidget)
		
		#  Table View
		#  ----------------------------------------
		self.gettablemodel = {}
		self.setTableModel('')
		#  Set table header's font size
		headerstyle = "QHeaderView { font-family: Segoe UI Light; font-size: 12px; }"
		self.images_tableViewWidget.horizontalHeader().setStyleSheet(headerstyle)
		self.images_tableViewWidget.verticalHeader().setStyleSheet(headerstyle)
		#  Set column width
		self.images_tableViewWidget.setColumnWidth(2,100)
		self.images_tableViewWidget.setColumnWidth(1,100)
		self.images_tableViewWidget.horizontalHeader().setResizeMode(1, QHeaderView.Fixed)
		self.images_tableViewWidget.horizontalHeader().setResizeMode(2, QHeaderView.Fixed)
		
		#  Thumbnails View
		#  ----------------------------------------
		self.getthumbnailsmodel = {}
		self.setThumbnailsModel('')
		self.thumbnails_tableViewWidget.setIconSize(QSize(64, 64))
		
		#  Table view popup menu
		#  ----------------------------------------
		self.table_popMenu = QMenu(self)
		checkSelected_Action = QAction('Check Selected', self)
		uncheckSelected_Action = QAction('Uncheck Selected', self)
		checkAll_Action = QAction('Check All', self)
		uncheckAll_Action = QAction('Uncheck All', self)
		viewFile_Action = QAction('View File', self)
		self.connect(checkAll_Action, SIGNAL("triggered()"), partial(self.checkSelected, True))
		self.connect(uncheckAll_Action, SIGNAL("triggered()"), partial(self.checkSelected, False))
		self.connect(checkAll_Action, SIGNAL("triggered()"), partial(self.checkAll, True))
		self.connect(uncheckAll_Action, SIGNAL("triggered()"), partial(self.checkAll, False))
		self.connect(viewFile_Action, SIGNAL("triggered()"), self.viewFile)
		self.table_popMenu.addAction(checkSelected_Action)
		self.table_popMenu.addAction(uncheckSelected_Action)
		self.table_popMenu.addSeparator()
		self.table_popMenu.addAction(checkAll_Action)
		self.table_popMenu.addAction(uncheckAll_Action)
		self.table_popMenu.addSeparator()
		self.table_popMenu.addAction(viewFile_Action)
		self.images_tableViewWidget.setContextMenuPolicy(Qt.CustomContextMenu)
		self.images_tableViewWidget.customContextMenuRequested.connect(self.tableviewPopup)
		
		#  Thumbnails view popup menu
		#  ----------------------------------------
		self.thumbnails_popMenu = QMenu(self)
		thumbCheckSelected_Action = QAction('Check Selected', self)
		thumbUncheckSelected_Action = QAction('Uncheck Selected', self)
		thumbCheckAll_Action = QAction('Check All', self)
		thumbUncheckAll_Action = QAction('Uncheck All', self)
		self.connect(thumbCheckSelected_Action, SIGNAL("triggered()"), partial(self.checkSelected, True))
		self.connect(thumbUncheckSelected_Action, SIGNAL("triggered()"), partial(self.checkSelected, False))
		self.connect(thumbCheckAll_Action, SIGNAL("triggered()"), partial(self.checkAll, True))
		self.connect(thumbUncheckAll_Action, SIGNAL("triggered()"), partial(self.checkAll, False))
		self.thumbnails_popMenu.addAction(thumbCheckSelected_Action)
		self.thumbnails_popMenu.addAction(thumbUncheckSelected_Action)
		self.thumbnails_popMenu.addSeparator()
		self.thumbnails_popMenu.addAction(thumbCheckAll_Action)
		self.thumbnails_popMenu.addAction(thumbUncheckAll_Action)
		self.thumbnails_tableViewWidget.setContextMenuPolicy(Qt.CustomContextMenu)
		self.thumbnails_tableViewWidget.customContextMenuRequested.connect(self.thumbnailsViewPopup)
		
		#  Users list view popup menu
		#  ----------------------------------------
		self.list_popMenu = QMenu(self)
		deleteUser_Action = QAction('Delete user', self)
		self.connect(deleteUser_Action, SIGNAL("triggered()"), self.deleteUser)
		self.list_popMenu.addAction(deleteUser_Action)
		self.users_listViewWidget.setContextMenuPolicy(Qt.CustomContextMenu)
		self.users_listViewWidget.customContextMenuRequested.connect(self.listviewPopup)
		
		#  Set project button popup menu
		#  ----------------------------------------
		self.setproject_buttonWidget.setContextMenuPolicy(Qt.CustomContextMenu)
		self.setproject_buttonWidget.customContextMenuRequested.connect(self.projectButtonPopup)
		self.project_popMenu = QMenu(self)
		openProjectDir_Action = QAction('Open Download location', self)
		self.connect(openProjectDir_Action, SIGNAL("triggered()"), partial(self.openFolder, 'project'))
		self.project_popMenu.addAction(openProjectDir_Action)
		
		#  Avatar
		#  ----------------------------------------
		self.icon = QIcon()
		#  Set default avatar
		self.loadAvatar(":no_avatar100.gif")
		self.username_labelWidget.setText(self.currentuser)
		
		#  Log Dock Widget
		#  ----------------------------------------
		logDockWidget = QDockWidget("Log", self)
		logDockWidget.setObjectName("LogDockWidget")
		logDockWidget.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
		self.logtext = LogText()
		self.log_TextBrowser = self.logtext.textbrowser
		logDockWidget.setWidget(self.log_TextBrowser)
		self.addDockWidget(Qt.RightDockWidgetArea, logDockWidget)
		self.log_TextBrowser.setStyleSheet(stylesheets.logArea)
		logDockWidget.hide()
		
		#  Menu Additions
		#  ----------------------------------------
		#  View menu
		viewDatabase_Action = self.createAction('View Database', self.openDatViewer, "Alt+D", None, None, False)
		switchView_Action = self.createAction('Switch view', self.userSwitchView, "Alt+Q", None, None, False)
		# self.menu_View.addAction(logDockWidget.toggleViewAction())
		self.view_Menu.addAction(switchView_Action)
		self.view_Menu.addSeparator()
		self.view_Menu.addAction(viewDatabase_Action)
		#  Help menu
		about_Action = self.createAction('About', self.showAboutDialog, "", None, None, False)
		# self.about_Action.activated.connect(self.showAboutDialog)
		self.help_Menu.addAction(about_Action)
		
		#  Connect Signals and Slots
		#  ----------------------------------------
		#  Main Widgets
		self.adduser_buttonWidget.pressed.connect(self.onAddUser)			# SIGNAL("pressed()")
		self.newuser_lineEditWidget.returnPressed.connect(self.onAddUser)	# SIGNAL("returnPressed()")
		self.users_listViewWidget.doubleClicked.connect(self.onUserSelect)
		
		# Note: I leave out activated signal because I not sure what it does
		# self.users_listViewWidget.activated.connect(self.onUserSelect)
		
		# Note: clicked signal is not used because we already have
		#  self.userslistmodel.onSelectionChanged.connect(self.onUserSelect).
		#  Adding both will double trigger the onUserSelect method which
		#  will cause the view be refresed twice
		# self.users_listViewWidget.clicked.connect(self.onUserSelect)
		
		#  Buttons on left panel
		self.setproject_buttonWidget.clicked.connect(self.setProjectLocation)
		self.download_buttonWidget.clicked.connect(self.downloadSelected)
		self.avatar_buttonWidget.clicked.connect(partial(self.openFolder, 'user'))
		self.tableview_buttonWidget.clicked.connect(partial(self.switchView, 0))
		self.thumbnailview_buttonWidget.clicked.connect(partial(self.switchView, 1))
		#  Actions
		self.test_action.triggered.connect(self.test)
		self.openDatViewer_action.triggered.connect(self.openDatViewer)
				
		#  Finalizing
		#  ----------------------------------------
		self.newuser_lineEditWidget.setFocus()
		self.resize(900,500)
		self.setStatus("Hello", 1.5)
		self.switchView(1)   # Set view to table view
		self.setProjectDir(os.path.join(os.getcwd(), 'Downloads'))
		QTimer.singleShot(0, self.newuser_lineEditWidget, SLOT('setFocus()'))
		
		logger.info("Finish constructing main window")
示例#5
0
class MainWindow(QMainWindow, ui_cghubdownloader.Ui_CGHubDownloader):
	def __init__(self, parent=None):
		super(MainWindow, self).__init__(parent)
		
		#  Start logging
		#  ----------------------------------------
		logger = logging.getLogger("mainwindow.__init__")
		
		#  Member variables and init stuffs
		#  ----------------------------------------
		self.projdir = os.path.join(os.getcwd(), 'Downloads')
		
		if not os.path.isdir(self.projdir):
			os.makedirs(self.projdir)
		
		self.addedUsers = []
		self.currentuser = ''
		self.currentusermodel = None         # holds UserImagesModel
		self.currentthumbnailsmodel = None   # holds ThumbnailsModel
		self.currentview = 0   # 0 -> Table view, 1 -> Thumbnails view
		self.setupUi(self)
		
		#  Factory
		#  ----------------------------------------
		self.factory = Factory()
		self.factory.addClass('UserValidation', ProcessUserValidation)
		self.factory.addWorkers('UserValidation')
		self.factory.addClass('UserImages', ProcessUserImages)
		self.factory.addWorkers('UserImages')
		self.factory.addClass('ImagesFilesize', CheckImagesFilesize)
		self.factory.addWorkers('ImagesFilesize')
		
		for worker in self.factory.getWorkers('UserValidation'):
			self.connect(worker, SIGNAL('error'), self.callError)
			self.connect(worker, SIGNAL('updateList'), self.refreshUserList)
		
		for worker in self.factory.getWorkers('UserImages'):
			self.connect(worker, SIGNAL('error'), self.callError)
			self.connect(worker, SIGNAL('updateTable'), self.refreshTableView)
		
		for worker in self.factory.getWorkers('ImagesFilesize'):
			self.connect(worker, SIGNAL('updateTableModel'), self.updateTableModel)
		
		#  Users data
		#  ----------------------------------------
		self.usersdata = UsersData(self)
		self.usersdata.setProjectDir(self.projdir)
		self.usersdata.error.connect(self.callError) # SIGNAL("error()")
		self.userslistdata = UsersList(self.usersdata)
		self.userslistdata.setProjectDir(self.projdir)
		self.userslistdata.updateFromUsersData(self.usersdata)
		
		for worker in self.factory.getWorkers('UserImages'):
			self.connect(worker, SIGNAL('updateTable'), self.userslistdata.updateImagesCount)
		
		#  Project manager
		#  ----------------------------------------
		self.projman = ProjectManager(self.projdir)
		self.projman.updateWithExistingImages(self.usersdata)
		self.projman.saveData.connect(self.saveData) # SIGNAL("saveData()")
		
		#  Users list
		#  ----------------------------------------
		self.userslistmodel = UsersListModel(self.userslistdata)
		self.users_listViewWidget.setModel(self.userslistmodel)
		self.users_listViewWidget.setGridSize(QSize(20,20))
		headerstyle = "font-size: 12px;"
		self.users_listViewWidget.setStyleSheet(headerstyle)
		# Handle selection changed
		selectionmodel = self.users_listViewWidget.selectionModel()
		selectionmodel.selectionChanged.connect(self.userslistmodel.handleSelectionChanged)
		self.userslistmodel.onSelectionChanged.connect(self.onUserSelect)
		
		#  Setup layout inside stacked widget
		#  ----------------------------------------
		#  ( I can't understand how to set this up in Qt Designer,
		#    I can only create layout for one of them, then there
		#    seems to be no way to set layout for the other one )
		self.horizontalLayout_a = QHBoxLayout(self.page)
		self.horizontalLayout_a.addWidget(self.images_tableViewWidget)
		self.horizontalLayout_b = QHBoxLayout(self.page_2)
		self.horizontalLayout_b.addWidget(self.thumbnails_tableViewWidget)
		
		#  Table View
		#  ----------------------------------------
		self.gettablemodel = {}
		self.setTableModel('')
		#  Set table header's font size
		headerstyle = "QHeaderView { font-family: Segoe UI Light; font-size: 12px; }"
		self.images_tableViewWidget.horizontalHeader().setStyleSheet(headerstyle)
		self.images_tableViewWidget.verticalHeader().setStyleSheet(headerstyle)
		#  Set column width
		self.images_tableViewWidget.setColumnWidth(2,100)
		self.images_tableViewWidget.setColumnWidth(1,100)
		self.images_tableViewWidget.horizontalHeader().setResizeMode(1, QHeaderView.Fixed)
		self.images_tableViewWidget.horizontalHeader().setResizeMode(2, QHeaderView.Fixed)
		
		#  Thumbnails View
		#  ----------------------------------------
		self.getthumbnailsmodel = {}
		self.setThumbnailsModel('')
		self.thumbnails_tableViewWidget.setIconSize(QSize(64, 64))
		
		#  Table view popup menu
		#  ----------------------------------------
		self.table_popMenu = QMenu(self)
		checkSelected_Action = QAction('Check Selected', self)
		uncheckSelected_Action = QAction('Uncheck Selected', self)
		checkAll_Action = QAction('Check All', self)
		uncheckAll_Action = QAction('Uncheck All', self)
		viewFile_Action = QAction('View File', self)
		self.connect(checkAll_Action, SIGNAL("triggered()"), partial(self.checkSelected, True))
		self.connect(uncheckAll_Action, SIGNAL("triggered()"), partial(self.checkSelected, False))
		self.connect(checkAll_Action, SIGNAL("triggered()"), partial(self.checkAll, True))
		self.connect(uncheckAll_Action, SIGNAL("triggered()"), partial(self.checkAll, False))
		self.connect(viewFile_Action, SIGNAL("triggered()"), self.viewFile)
		self.table_popMenu.addAction(checkSelected_Action)
		self.table_popMenu.addAction(uncheckSelected_Action)
		self.table_popMenu.addSeparator()
		self.table_popMenu.addAction(checkAll_Action)
		self.table_popMenu.addAction(uncheckAll_Action)
		self.table_popMenu.addSeparator()
		self.table_popMenu.addAction(viewFile_Action)
		self.images_tableViewWidget.setContextMenuPolicy(Qt.CustomContextMenu)
		self.images_tableViewWidget.customContextMenuRequested.connect(self.tableviewPopup)
		
		#  Thumbnails view popup menu
		#  ----------------------------------------
		self.thumbnails_popMenu = QMenu(self)
		thumbCheckSelected_Action = QAction('Check Selected', self)
		thumbUncheckSelected_Action = QAction('Uncheck Selected', self)
		thumbCheckAll_Action = QAction('Check All', self)
		thumbUncheckAll_Action = QAction('Uncheck All', self)
		self.connect(thumbCheckSelected_Action, SIGNAL("triggered()"), partial(self.checkSelected, True))
		self.connect(thumbUncheckSelected_Action, SIGNAL("triggered()"), partial(self.checkSelected, False))
		self.connect(thumbCheckAll_Action, SIGNAL("triggered()"), partial(self.checkAll, True))
		self.connect(thumbUncheckAll_Action, SIGNAL("triggered()"), partial(self.checkAll, False))
		self.thumbnails_popMenu.addAction(thumbCheckSelected_Action)
		self.thumbnails_popMenu.addAction(thumbUncheckSelected_Action)
		self.thumbnails_popMenu.addSeparator()
		self.thumbnails_popMenu.addAction(thumbCheckAll_Action)
		self.thumbnails_popMenu.addAction(thumbUncheckAll_Action)
		self.thumbnails_tableViewWidget.setContextMenuPolicy(Qt.CustomContextMenu)
		self.thumbnails_tableViewWidget.customContextMenuRequested.connect(self.thumbnailsViewPopup)
		
		#  Users list view popup menu
		#  ----------------------------------------
		self.list_popMenu = QMenu(self)
		deleteUser_Action = QAction('Delete user', self)
		self.connect(deleteUser_Action, SIGNAL("triggered()"), self.deleteUser)
		self.list_popMenu.addAction(deleteUser_Action)
		self.users_listViewWidget.setContextMenuPolicy(Qt.CustomContextMenu)
		self.users_listViewWidget.customContextMenuRequested.connect(self.listviewPopup)
		
		#  Set project button popup menu
		#  ----------------------------------------
		self.setproject_buttonWidget.setContextMenuPolicy(Qt.CustomContextMenu)
		self.setproject_buttonWidget.customContextMenuRequested.connect(self.projectButtonPopup)
		self.project_popMenu = QMenu(self)
		openProjectDir_Action = QAction('Open Download location', self)
		self.connect(openProjectDir_Action, SIGNAL("triggered()"), partial(self.openFolder, 'project'))
		self.project_popMenu.addAction(openProjectDir_Action)
		
		#  Avatar
		#  ----------------------------------------
		self.icon = QIcon()
		#  Set default avatar
		self.loadAvatar(":no_avatar100.gif")
		self.username_labelWidget.setText(self.currentuser)
		
		#  Log Dock Widget
		#  ----------------------------------------
		logDockWidget = QDockWidget("Log", self)
		logDockWidget.setObjectName("LogDockWidget")
		logDockWidget.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
		self.logtext = LogText()
		self.log_TextBrowser = self.logtext.textbrowser
		logDockWidget.setWidget(self.log_TextBrowser)
		self.addDockWidget(Qt.RightDockWidgetArea, logDockWidget)
		self.log_TextBrowser.setStyleSheet(stylesheets.logArea)
		logDockWidget.hide()
		
		#  Menu Additions
		#  ----------------------------------------
		#  View menu
		viewDatabase_Action = self.createAction('View Database', self.openDatViewer, "Alt+D", None, None, False)
		switchView_Action = self.createAction('Switch view', self.userSwitchView, "Alt+Q", None, None, False)
		# self.menu_View.addAction(logDockWidget.toggleViewAction())
		self.view_Menu.addAction(switchView_Action)
		self.view_Menu.addSeparator()
		self.view_Menu.addAction(viewDatabase_Action)
		#  Help menu
		about_Action = self.createAction('About', self.showAboutDialog, "", None, None, False)
		# self.about_Action.activated.connect(self.showAboutDialog)
		self.help_Menu.addAction(about_Action)
		
		#  Connect Signals and Slots
		#  ----------------------------------------
		#  Main Widgets
		self.adduser_buttonWidget.pressed.connect(self.onAddUser)			# SIGNAL("pressed()")
		self.newuser_lineEditWidget.returnPressed.connect(self.onAddUser)	# SIGNAL("returnPressed()")
		self.users_listViewWidget.doubleClicked.connect(self.onUserSelect)
		
		# Note: I leave out activated signal because I not sure what it does
		# self.users_listViewWidget.activated.connect(self.onUserSelect)
		
		# Note: clicked signal is not used because we already have
		#  self.userslistmodel.onSelectionChanged.connect(self.onUserSelect).
		#  Adding both will double trigger the onUserSelect method which
		#  will cause the view be refresed twice
		# self.users_listViewWidget.clicked.connect(self.onUserSelect)
		
		#  Buttons on left panel
		self.setproject_buttonWidget.clicked.connect(self.setProjectLocation)
		self.download_buttonWidget.clicked.connect(self.downloadSelected)
		self.avatar_buttonWidget.clicked.connect(partial(self.openFolder, 'user'))
		self.tableview_buttonWidget.clicked.connect(partial(self.switchView, 0))
		self.thumbnailview_buttonWidget.clicked.connect(partial(self.switchView, 1))
		#  Actions
		self.test_action.triggered.connect(self.test)
		self.openDatViewer_action.triggered.connect(self.openDatViewer)
				
		#  Finalizing
		#  ----------------------------------------
		self.newuser_lineEditWidget.setFocus()
		self.resize(900,500)
		self.setStatus("Hello", 1.5)
		self.switchView(1)   # Set view to table view
		self.setProjectDir(os.path.join(os.getcwd(), 'Downloads'))
		QTimer.singleShot(0, self.newuser_lineEditWidget, SLOT('setFocus()'))
		
		logger.info("Finish constructing main window")
	
	def createAction( self, text, slot=None, shortcut=None, icon=None, tip=None, checkable=False, signal="triggered()" ):
		# ( Copied from Rapid GUI Programming with Python and Qt,
		#		Chapter 6, imagechanger.py )
		action = QAction( text, self )
		if icon is not None:
			action.setIcon( QIcon(":/%s.png" % icon) )
		if shortcut is not None:
			action.setShortcut( shortcut )
		if tip is not None:
			action.setToolTip( tip )
			action.setStatusTip( tip )
		if slot is not None:
			self.connect( action, SIGNAL(signal), slot )
		if checkable:
			action.setCheckable( True )
		return action
	
	#  Non-UI methods
	#  ----------------------------------------
	def test(self):
		pass

	def logCurrentMethod(self, msg):
		methodname = inspect.stack()[1][3]
		logger = logging.getLogger("mainwindow."+methodname)
		logger.info(msg)

	def printToLog(self, msg=''):
		self.logtext.addNewMsg(msg)	
	
	def callWarning(self, msg=''):
		self.logtext.addNewMsg(msg)
		QMessageBox.warning(self, 'Warning', msg)

	def callError(self, msg=''):
		self.logtext.addNewMsg(msg)
		QMessageBox.warning(self, 'Error', msg)
	
	def setStatus(self, msg, secs=3):
		self.statusbar.showMessage(msg, secs*1000)
	
	def saveData(self):
		self.logCurrentMethod("Saving self.usersdata")
		self.usersdata.savePickle()
	
	def loadAvatar(self, avatarpath):
		self.logCurrentMethod("Loading avatar: {0}".format(avatarpath))
		self.icon.addPixmap(QPixmap(avatarpath), QIcon.Normal, QIcon.Off)
		self.avatar_buttonWidget.setIcon(self.icon)
		self.avatar_buttonWidget.setIconSize(QSize(50, 50))
	
	def setProjectDir(self, location):
		self.logCurrentMethod("Setting project dir to: {0}".format(location))
		self.projman.setProjectDir(location)
		self.setWindowTitle('CG Hub Downloader - {0}'.format(location))
	
	def switchView(self, view):
		self.logCurrentMethod("Switching view to...")
		button = None
		
		if view == 0:
			self.logCurrentMethod("Table view")
			self.tableview_buttonWidget.setEnabled(False)
			self.thumbnailview_buttonWidget.setEnabled(True)
		else:
			self.logCurrentMethod("Thumbnails view")
			self.tableview_buttonWidget.setEnabled(True)
			self.thumbnailview_buttonWidget.setEnabled(False)
		
		self.currentview = view
		self.stackedWidget.setCurrentIndex(view)
	
	def userSwitchView(self):
		self.switchView(not self.currentview)
	
	#  Direct-UI methods
	#  ----------------------------------------
	def setProjectLocation(self):
		dialog = QFileDialog()
		dialog.setFileMode(QFileDialog.Directory)
		dialogdir = self.projdir # or can use QDir.currentPath()
		directory = dialog.getExistingDirectory(self, "Set download location", \
			dialogdir, QFileDialog.ShowDirsOnly)
		
		if directory:
			self.setProjectDir(directory)
			self.usersdata.setProjectDir(directory)
			self.userslistdata.setProjectDir(directory)
			self.userslistdata.updateFromUsersData(self.usersdata)
			
			# Deselect all from users list
			for modelindex in self.users_listViewWidget.selectedIndexes():
				selectionmodel = self.users_listViewWidget.selectionModel()
				selectionmodel.select(modelindex, QItemSelectionModel.Deselect)
			
			# Clear table view
			self.clearTable()
			
			# Load default avatar
			self.loadAvatar(":no_avatar100.gif")
		
	def downloadSelected(self):
		if self.currentuser != None and self.currentuser != '':
			self.logCurrentMethod("Downloading selected images from {0}".format(self.currentuser))
			userobj = self.usersdata.getUser(self.currentuser)
			self.projman.processUser(userobj)
	
	def openFolder(self, folderType):
		self.logCurrentMethod("Opening folder")
		if folderType == 'project':
			call(["explorer.exe ", convertPathToExplorer(self.projdir)])
		elif folderType == 'user':
			if self.currentuser != None and self.currentuser != '':
				userdir = convertPathToExplorer(self.projdir+'\\'+self.currentuser)
				if os.path.isdir(userdir):
					call(["explorer.exe ", userdir])
	
	def openDatViewer( self ):
		window = datviewer2.DatViewerWindow( self )
		window.show()
	
	def showAboutDialog(self):
		aboutdialog = AboutDialog(self)
		aboutdialog.show()

	#  Table View related methods
	#  ----------------------------------------
	def onUserSelect(self, modelindex):
		self.logCurrentMethod("Loading user's images")
		username = self.userslistmodel.data(modelindex, Qt.DisplayRole)
		# Note: username will looks like -> "username (10)"
		username = username.split(' ')[0]
		userobj = self.usersdata.getUser(username)
		self.factory.addJob('UserImages', (userobj, self.projman))

	def refreshTableView(self, userobj):
		self.logCurrentMethod("Updating table view")
		self.projman.updateWithExistingImages(self.usersdata)
		
		# It might always be true, but just to be clear, please be
		# aware that both table model and thumbnails model need to
		# receive the same userobj in order to sync with each other.
		self.setTableModel(userobj.name)
		self.setThumbnailsModel(userobj.name)
		self.currentthumbnailsmodel.updateModel()

		# Load avatar
		self.loadAvatar(userobj.avatarpath)
		
		# Set current user
		self.currentuser = userobj.name
		
		# Update user name
		self.username_labelWidget.setText(self.currentuser)
		
		# Update Images filesize
		self.updateImagesFilesize()
		
		# Update/Download Thumbnails
		self.projman.processUser(userobj, thumbnails=True)
		
		# Redownload avatar if it's missing
		if userobj.avatarpath == None:
			avatarpath = self.projman.getUserAvatar(userobj, userobj.userpagehtml)
			if avatarpath:
				self.loadAvatar(avatarpath)

	def setTableModel(self, username):
		""" Attact a table model to view. If no table model found for
		the user, create a new one.
		"""
		self.logCurrentMethod("Setting table model for '{0}'".format(username))
		model = None
		
		if username not in self.gettablemodel.keys():
			model = UserImagesModel(self.usersdata, username)
			self.gettablemodel[username] = model
			
			# When projman is downloading an image, it will fires
			# 'updateModel' signal. This model will catch it and 
			# calls 'updateModel' (which is just a simple 'modelReset()')
			# to tell the view to update. This process shows the
			# download progress
			self.projman.updateModel.connect(model.updateModel)
			
		else:
			model = self.gettablemodel[username]
		
		self.images_tableViewWidget.setModel(model)
			
		# Keep self updated about the change
		self.currentusermodel = model
	
	def updateTableModel(self):
		self.logCurrentMethod("Asking table model to 'resetModel()'")
		self.currentusermodel.updateModel()
	
	def clearTable(self):
		self.logCurrentMethod("Clearing table, setting table model to empty user ('')")
		self.images_tableViewWidget.clearSpans()
		self.setTableModel('')   # Set to empty user will clear the table model

	def updateImagesFilesize(self):
		if self.currentuser != None and self.currentuser != '':
			self.logCurrentMethod("Updating images file size for '{0}'".format(self.currentuser))
			self.projman.updateWithExistingImages(self.currentusermodel._usersdata)
			self.setStatus("Checking {0}'s images file size...".format(self.currentuser), 3.5)
			self.factory.addJob('ImagesFilesize', (self.usersdata, self.currentuser))
	
	#  Thumbnails view methods
	#  ----------------------------------------
	def setThumbnailsModel(self, username):
		""" Attacth a thumbnails model to view. If no thumbnails model found for
		the user, create a new one.
		"""
		self.logCurrentMethod("Setting thumbnails model for '{0}'".format(username))
		model = None
		
		if username not in self.getthumbnailsmodel.keys():
			# Passing a UserDir to ThumbnailsModel() so that it
			# knows where to look for the thumbnails
			userdir = self.projman.getUserDir(username)
			model = ThumbnailsModel(self.usersdata, username, userdir)
			self.getthumbnailsmodel[username] = model
			
			# The thumbnails table view is an instance of MyThumbnailsView,
			# MyThumbnailsView will fires the 'columnCountChange' everytime
			# the window is resized. This will tell the model to change
			# it's column counts to fit the new size.
			self.thumbnails_tableViewWidget.columnCountChange.connect(model.setColumnCount)
			
			# When projman is downloading a thumbnails, it will fires
			# 'updateThumbnailsModel' signal. This model will catch it and 
			# calls 'updateModel' (which is just a simple 'modelReset()')
			# to tell the view to update.
			self.projman.updateThumbnailsModel.connect(model.updateModel)
			
		else:
			model = self.getthumbnailsmodel[username]

		self.thumbnails_tableViewWidget.setModel(model)
			
		# Keep self updated about the change
		self.currentthumbnailsmodel = model

	#  Table view right click context menu
	#  ----------------------------------------
	def tableviewPopup(self, point):
		self.table_popMenu.exec_(self.images_tableViewWidget.mapToGlobal(point))

	def checkSelected(self, check):
		self.logCurrentMethod("Check selected")
		view = None
		model = None
		checkstate = Qt.Checked if check else Qt.Unchecked
		
		if self.stackedWidget.currentIndex() == 0:
			view = self.images_tableViewWidget
			model = self.currentusermodel
		else:
			view = self.thumbnails_tableViewWidget
			model = self.currentthumbnailsmodel
		
		for idx in view.selectedIndexes():
			model.setData(idx, checkstate, Qt.CheckStateRole)
	
	def checkAll(self, check):
		self.logCurrentMethod("Check all")
		view = None
		model = None
		checkstate = Qt.Checked if check else Qt.Unchecked
		
		if self.stackedWidget.currentIndex() == 0:
			view = self.images_tableViewWidget
			model = self.currentusermodel
		else:
			view = self.thumbnails_tableViewWidget
			model = self.currentthumbnailsmodel
		
		view.selectAll()
		for idx in view.selectedIndexes():
			model.setData(idx, checkstate, Qt.CheckStateRole)
		view.selectionModel().clearSelection()
	
	def viewFile(self):
		# for idx in self.images_tableViewWidget.selectedIndexes():
		# 	self.currentusermodel.setData(idx, Qt.Unchecked, Qt.CheckStateRole)
		pass

	#  Thumbnails view right click context menu
	#  ----------------------------------------
	def thumbnailsViewPopup(self, point):
		self.thumbnails_popMenu.exec_(self.thumbnails_tableViewWidget.mapToGlobal(point))

	#  Users list view right click context menu
	#  ----------------------------------------
	def listviewPopup(self, point):
		self.list_popMenu.exec_(self.users_listViewWidget.mapToGlobal(point))
	
	def deleteUser(self):
		# Delete from users list
		self.userslistdata.deleteUser(self.currentuser)
		# Delete from usersdata as well
		self.usersdata.deleteUser(self.currentuser)
		self.userslistmodel.updateModel()
		
		# Selection the first item on the list
		modelindex = self.userslistmodel.index(0,0)
		if modelindex:
			self.users_listViewWidget.setCurrentIndex(modelindex)
			username = self.userslistmodel.data(modelindex, Qt.DisplayRole)
			self.refreshTableView(self.usersdata.getUser(username))
	
	#  Set project button right click context menu
	#  -------------------------------------------
	def projectButtonPopup(self, point):
		self.project_popMenu.exec_(self.setproject_buttonWidget.mapToGlobal(point))

	#  User lists related methods
	#  ----------------------------------------
	def onAddUser( self ):
		user = self.newuser_lineEditWidget.text()
		user = str(user).lower()
		self.logCurrentMethod("Adding '{0}' to list".format(user))
		if len( user ) > 0:
			if user not in self.addedUsers:
				self.usersdata.addNewUser(user)
				userobj = self.usersdata.getUser(user)
				self.setStatus("Adding '{0}'...".format(user), 3)
				self.factory.addJob('UserValidation', userobj)
	
	def refreshUserList(self, userobj, html):
		self.logCurrentMethod("Refreshing users list")
		if userobj.exists and userobj.viewImageUrl == False:
			# need to mark user empty???
			self.callWarning("{0}'s gallery is empty".format(userobj.name))
			logger.warning("{0}'s gallery is empty".format(userobj.name))
		else:
			self.userslistdata.addUser(userobj)
			self.userslistmodel.updateModel()
			# Select new user
			idx = self.userslistdata.getUserIndex(userobj.name)
			if idx != None:
				modelindex = self.userslistmodel.index(idx, 0)
				self.users_listViewWidget.setCurrentIndex(modelindex)
			avatarpath = self.projman.getUserAvatar(userobj, html)
			if avatarpath != None:
				self.loadAvatar(avatarpath)
示例#6
0
import os
import sys
from projectmanager import ProjectManager
from angularsetup import AngularSetup
from cordovasetup import CordovaSetup
import constants

src = constants.DEFAULT_PROJECT_SRC

if sys.argv.__len__() == 2:
    src = sys.argv[1]

projectManager = ProjectManager(src)

if sys.argv.__len__() > 2:
    directory = sys.argv[2]

else:
    directory = "../" + projectManager.getProjectName()

projectManager.cloneProject(directory)

angularSetup = AngularSetup(directory)
cordovaSetup = CordovaSetup(directory)

angularSetup.setup()
cordovaSetup.setup()

os.chdir(directory)

angularSetup.build()
示例#7
0
#
# Setup configurations
#
rootPath = pathlib.Path(os.path.dirname(os.path.abspath(__file__)))
templateRootPath = rootPath / config['templateSettings']['path']
dataRootPath = rootPath / config['userdataSettings']['path']
outputRootPath = rootPath / config['outputSettings']['path']

#
# Handle commands
#
print()
args = docopt(__doc__, version='Glide v0.1')

if args['show-projects']:
    ProjectManager.showProjects(dataRootPath)

elif args['create-project']:
    ProjectManager.createProject(dataRootPath, outputRootPath,
                                 args['<project_name>'])

elif args['select-project']:
    ProjectManager.selectProject(dataRootPath, outputRootPath,
                                 args['<project_name>'])

elif args['show-themes']:
    ProjectManager.showThemes()

elif args['show-layouts']:
    ProjectManager.showLayouts(args['<theme_name>'])
示例#8
0
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        #  Start logging
        #  ----------------------------------------
        logger = logging.getLogger("mainwindow.__init__")

        #  Member variables and init stuffs
        #  ----------------------------------------
        self.projdir = os.path.join(os.getcwd(), 'Downloads')

        if not os.path.isdir(self.projdir):
            os.makedirs(self.projdir)

        self.addedUsers = []
        self.currentuser = ''
        self.currentusermodel = None  # holds UserImagesModel
        self.currentthumbnailsmodel = None  # holds ThumbnailsModel
        self.currentview = 0  # 0 -> Table view, 1 -> Thumbnails view
        self.setupUi(self)

        #  Factory
        #  ----------------------------------------
        self.factory = Factory()
        self.factory.addClass('UserValidation', ProcessUserValidation)
        self.factory.addWorkers('UserValidation')
        self.factory.addClass('UserImages', ProcessUserImages)
        self.factory.addWorkers('UserImages')
        self.factory.addClass('ImagesFilesize', CheckImagesFilesize)
        self.factory.addWorkers('ImagesFilesize')

        for worker in self.factory.getWorkers('UserValidation'):
            self.connect(worker, SIGNAL('error'), self.callError)
            self.connect(worker, SIGNAL('updateList'), self.refreshUserList)

        for worker in self.factory.getWorkers('UserImages'):
            self.connect(worker, SIGNAL('error'), self.callError)
            self.connect(worker, SIGNAL('updateTable'), self.refreshTableView)

        for worker in self.factory.getWorkers('ImagesFilesize'):
            self.connect(worker, SIGNAL('updateTableModel'),
                         self.updateTableModel)

        #  Users data
        #  ----------------------------------------
        self.usersdata = UsersData(self)
        self.usersdata.setProjectDir(self.projdir)
        self.usersdata.error.connect(self.callError)  # SIGNAL("error()")
        self.userslistdata = UsersList(self.usersdata)
        self.userslistdata.setProjectDir(self.projdir)
        self.userslistdata.updateFromUsersData(self.usersdata)

        for worker in self.factory.getWorkers('UserImages'):
            self.connect(worker, SIGNAL('updateTable'),
                         self.userslistdata.updateImagesCount)

        #  Project manager
        #  ----------------------------------------
        self.projman = ProjectManager(self.projdir)
        self.projman.updateWithExistingImages(self.usersdata)
        self.projman.saveData.connect(self.saveData)  # SIGNAL("saveData()")

        #  Users list
        #  ----------------------------------------
        self.userslistmodel = UsersListModel(self.userslistdata)
        self.users_listViewWidget.setModel(self.userslistmodel)
        self.users_listViewWidget.setGridSize(QSize(20, 20))
        headerstyle = "font-size: 12px;"
        self.users_listViewWidget.setStyleSheet(headerstyle)
        # Handle selection changed
        selectionmodel = self.users_listViewWidget.selectionModel()
        selectionmodel.selectionChanged.connect(
            self.userslistmodel.handleSelectionChanged)
        self.userslistmodel.onSelectionChanged.connect(self.onUserSelect)

        #  Setup layout inside stacked widget
        #  ----------------------------------------
        #  ( I can't understand how to set this up in Qt Designer,
        #    I can only create layout for one of them, then there
        #    seems to be no way to set layout for the other one )
        self.horizontalLayout_a = QHBoxLayout(self.page)
        self.horizontalLayout_a.addWidget(self.images_tableViewWidget)
        self.horizontalLayout_b = QHBoxLayout(self.page_2)
        self.horizontalLayout_b.addWidget(self.thumbnails_tableViewWidget)

        #  Table View
        #  ----------------------------------------
        self.gettablemodel = {}
        self.setTableModel('')
        #  Set table header's font size
        headerstyle = "QHeaderView { font-family: Segoe UI Light; font-size: 12px; }"
        self.images_tableViewWidget.horizontalHeader().setStyleSheet(
            headerstyle)
        self.images_tableViewWidget.verticalHeader().setStyleSheet(headerstyle)
        #  Set column width
        self.images_tableViewWidget.setColumnWidth(2, 100)
        self.images_tableViewWidget.setColumnWidth(1, 100)
        self.images_tableViewWidget.horizontalHeader().setResizeMode(
            1, QHeaderView.Fixed)
        self.images_tableViewWidget.horizontalHeader().setResizeMode(
            2, QHeaderView.Fixed)

        #  Thumbnails View
        #  ----------------------------------------
        self.getthumbnailsmodel = {}
        self.setThumbnailsModel('')
        self.thumbnails_tableViewWidget.setIconSize(QSize(64, 64))

        #  Table view popup menu
        #  ----------------------------------------
        self.table_popMenu = QMenu(self)
        checkSelected_Action = QAction('Check Selected', self)
        uncheckSelected_Action = QAction('Uncheck Selected', self)
        checkAll_Action = QAction('Check All', self)
        uncheckAll_Action = QAction('Uncheck All', self)
        viewFile_Action = QAction('View File', self)
        self.connect(checkAll_Action, SIGNAL("triggered()"),
                     partial(self.checkSelected, True))
        self.connect(uncheckAll_Action, SIGNAL("triggered()"),
                     partial(self.checkSelected, False))
        self.connect(checkAll_Action, SIGNAL("triggered()"),
                     partial(self.checkAll, True))
        self.connect(uncheckAll_Action, SIGNAL("triggered()"),
                     partial(self.checkAll, False))
        self.connect(viewFile_Action, SIGNAL("triggered()"), self.viewFile)
        self.table_popMenu.addAction(checkSelected_Action)
        self.table_popMenu.addAction(uncheckSelected_Action)
        self.table_popMenu.addSeparator()
        self.table_popMenu.addAction(checkAll_Action)
        self.table_popMenu.addAction(uncheckAll_Action)
        self.table_popMenu.addSeparator()
        self.table_popMenu.addAction(viewFile_Action)
        self.images_tableViewWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.images_tableViewWidget.customContextMenuRequested.connect(
            self.tableviewPopup)

        #  Thumbnails view popup menu
        #  ----------------------------------------
        self.thumbnails_popMenu = QMenu(self)
        thumbCheckSelected_Action = QAction('Check Selected', self)
        thumbUncheckSelected_Action = QAction('Uncheck Selected', self)
        thumbCheckAll_Action = QAction('Check All', self)
        thumbUncheckAll_Action = QAction('Uncheck All', self)
        self.connect(thumbCheckSelected_Action, SIGNAL("triggered()"),
                     partial(self.checkSelected, True))
        self.connect(thumbUncheckSelected_Action, SIGNAL("triggered()"),
                     partial(self.checkSelected, False))
        self.connect(thumbCheckAll_Action, SIGNAL("triggered()"),
                     partial(self.checkAll, True))
        self.connect(thumbUncheckAll_Action, SIGNAL("triggered()"),
                     partial(self.checkAll, False))
        self.thumbnails_popMenu.addAction(thumbCheckSelected_Action)
        self.thumbnails_popMenu.addAction(thumbUncheckSelected_Action)
        self.thumbnails_popMenu.addSeparator()
        self.thumbnails_popMenu.addAction(thumbCheckAll_Action)
        self.thumbnails_popMenu.addAction(thumbUncheckAll_Action)
        self.thumbnails_tableViewWidget.setContextMenuPolicy(
            Qt.CustomContextMenu)
        self.thumbnails_tableViewWidget.customContextMenuRequested.connect(
            self.thumbnailsViewPopup)

        #  Users list view popup menu
        #  ----------------------------------------
        self.list_popMenu = QMenu(self)
        deleteUser_Action = QAction('Delete user', self)
        self.connect(deleteUser_Action, SIGNAL("triggered()"), self.deleteUser)
        self.list_popMenu.addAction(deleteUser_Action)
        self.users_listViewWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.users_listViewWidget.customContextMenuRequested.connect(
            self.listviewPopup)

        #  Set project button popup menu
        #  ----------------------------------------
        self.setproject_buttonWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.setproject_buttonWidget.customContextMenuRequested.connect(
            self.projectButtonPopup)
        self.project_popMenu = QMenu(self)
        openProjectDir_Action = QAction('Open Download location', self)
        self.connect(openProjectDir_Action, SIGNAL("triggered()"),
                     partial(self.openFolder, 'project'))
        self.project_popMenu.addAction(openProjectDir_Action)

        #  Avatar
        #  ----------------------------------------
        self.icon = QIcon()
        #  Set default avatar
        self.loadAvatar(":no_avatar100.gif")
        self.username_labelWidget.setText(self.currentuser)

        #  Log Dock Widget
        #  ----------------------------------------
        logDockWidget = QDockWidget("Log", self)
        logDockWidget.setObjectName("LogDockWidget")
        logDockWidget.setAllowedAreas(Qt.LeftDockWidgetArea
                                      | Qt.RightDockWidgetArea)
        self.logtext = LogText()
        self.log_TextBrowser = self.logtext.textbrowser
        logDockWidget.setWidget(self.log_TextBrowser)
        self.addDockWidget(Qt.RightDockWidgetArea, logDockWidget)
        self.log_TextBrowser.setStyleSheet(stylesheets.logArea)
        logDockWidget.hide()

        #  Menu Additions
        #  ----------------------------------------
        #  View menu
        viewDatabase_Action = self.createAction('View Database',
                                                self.openDatViewer, "Alt+D",
                                                None, None, False)
        switchView_Action = self.createAction('Switch view',
                                              self.userSwitchView, "Alt+Q",
                                              None, None, False)
        # self.menu_View.addAction(logDockWidget.toggleViewAction())
        self.view_Menu.addAction(switchView_Action)
        self.view_Menu.addSeparator()
        self.view_Menu.addAction(viewDatabase_Action)
        #  Help menu
        about_Action = self.createAction('About', self.showAboutDialog, "",
                                         None, None, False)
        # self.about_Action.activated.connect(self.showAboutDialog)
        self.help_Menu.addAction(about_Action)

        #  Connect Signals and Slots
        #  ----------------------------------------
        #  Main Widgets
        self.adduser_buttonWidget.pressed.connect(
            self.onAddUser)  # SIGNAL("pressed()")
        self.newuser_lineEditWidget.returnPressed.connect(
            self.onAddUser)  # SIGNAL("returnPressed()")
        self.users_listViewWidget.doubleClicked.connect(self.onUserSelect)

        # Note: I leave out activated signal because I not sure what it does
        # self.users_listViewWidget.activated.connect(self.onUserSelect)

        # Note: clicked signal is not used because we already have
        #  self.userslistmodel.onSelectionChanged.connect(self.onUserSelect).
        #  Adding both will double trigger the onUserSelect method which
        #  will cause the view be refresed twice
        # self.users_listViewWidget.clicked.connect(self.onUserSelect)

        #  Buttons on left panel
        self.setproject_buttonWidget.clicked.connect(self.setProjectLocation)
        self.download_buttonWidget.clicked.connect(self.downloadSelected)
        self.avatar_buttonWidget.clicked.connect(
            partial(self.openFolder, 'user'))
        self.tableview_buttonWidget.clicked.connect(partial(
            self.switchView, 0))
        self.thumbnailview_buttonWidget.clicked.connect(
            partial(self.switchView, 1))
        #  Actions
        self.test_action.triggered.connect(self.test)
        self.openDatViewer_action.triggered.connect(self.openDatViewer)

        #  Finalizing
        #  ----------------------------------------
        self.newuser_lineEditWidget.setFocus()
        self.resize(900, 500)
        self.setStatus("Hello", 1.5)
        self.switchView(1)  # Set view to table view
        self.setProjectDir(os.path.join(os.getcwd(), 'Downloads'))
        QTimer.singleShot(0, self.newuser_lineEditWidget, SLOT('setFocus()'))

        logger.info("Finish constructing main window")
示例#9
0
class MainWindow(QMainWindow, ui_cghubdownloader.Ui_CGHubDownloader):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        #  Start logging
        #  ----------------------------------------
        logger = logging.getLogger("mainwindow.__init__")

        #  Member variables and init stuffs
        #  ----------------------------------------
        self.projdir = os.path.join(os.getcwd(), 'Downloads')

        if not os.path.isdir(self.projdir):
            os.makedirs(self.projdir)

        self.addedUsers = []
        self.currentuser = ''
        self.currentusermodel = None  # holds UserImagesModel
        self.currentthumbnailsmodel = None  # holds ThumbnailsModel
        self.currentview = 0  # 0 -> Table view, 1 -> Thumbnails view
        self.setupUi(self)

        #  Factory
        #  ----------------------------------------
        self.factory = Factory()
        self.factory.addClass('UserValidation', ProcessUserValidation)
        self.factory.addWorkers('UserValidation')
        self.factory.addClass('UserImages', ProcessUserImages)
        self.factory.addWorkers('UserImages')
        self.factory.addClass('ImagesFilesize', CheckImagesFilesize)
        self.factory.addWorkers('ImagesFilesize')

        for worker in self.factory.getWorkers('UserValidation'):
            self.connect(worker, SIGNAL('error'), self.callError)
            self.connect(worker, SIGNAL('updateList'), self.refreshUserList)

        for worker in self.factory.getWorkers('UserImages'):
            self.connect(worker, SIGNAL('error'), self.callError)
            self.connect(worker, SIGNAL('updateTable'), self.refreshTableView)

        for worker in self.factory.getWorkers('ImagesFilesize'):
            self.connect(worker, SIGNAL('updateTableModel'),
                         self.updateTableModel)

        #  Users data
        #  ----------------------------------------
        self.usersdata = UsersData(self)
        self.usersdata.setProjectDir(self.projdir)
        self.usersdata.error.connect(self.callError)  # SIGNAL("error()")
        self.userslistdata = UsersList(self.usersdata)
        self.userslistdata.setProjectDir(self.projdir)
        self.userslistdata.updateFromUsersData(self.usersdata)

        for worker in self.factory.getWorkers('UserImages'):
            self.connect(worker, SIGNAL('updateTable'),
                         self.userslistdata.updateImagesCount)

        #  Project manager
        #  ----------------------------------------
        self.projman = ProjectManager(self.projdir)
        self.projman.updateWithExistingImages(self.usersdata)
        self.projman.saveData.connect(self.saveData)  # SIGNAL("saveData()")

        #  Users list
        #  ----------------------------------------
        self.userslistmodel = UsersListModel(self.userslistdata)
        self.users_listViewWidget.setModel(self.userslistmodel)
        self.users_listViewWidget.setGridSize(QSize(20, 20))
        headerstyle = "font-size: 12px;"
        self.users_listViewWidget.setStyleSheet(headerstyle)
        # Handle selection changed
        selectionmodel = self.users_listViewWidget.selectionModel()
        selectionmodel.selectionChanged.connect(
            self.userslistmodel.handleSelectionChanged)
        self.userslistmodel.onSelectionChanged.connect(self.onUserSelect)

        #  Setup layout inside stacked widget
        #  ----------------------------------------
        #  ( I can't understand how to set this up in Qt Designer,
        #    I can only create layout for one of them, then there
        #    seems to be no way to set layout for the other one )
        self.horizontalLayout_a = QHBoxLayout(self.page)
        self.horizontalLayout_a.addWidget(self.images_tableViewWidget)
        self.horizontalLayout_b = QHBoxLayout(self.page_2)
        self.horizontalLayout_b.addWidget(self.thumbnails_tableViewWidget)

        #  Table View
        #  ----------------------------------------
        self.gettablemodel = {}
        self.setTableModel('')
        #  Set table header's font size
        headerstyle = "QHeaderView { font-family: Segoe UI Light; font-size: 12px; }"
        self.images_tableViewWidget.horizontalHeader().setStyleSheet(
            headerstyle)
        self.images_tableViewWidget.verticalHeader().setStyleSheet(headerstyle)
        #  Set column width
        self.images_tableViewWidget.setColumnWidth(2, 100)
        self.images_tableViewWidget.setColumnWidth(1, 100)
        self.images_tableViewWidget.horizontalHeader().setResizeMode(
            1, QHeaderView.Fixed)
        self.images_tableViewWidget.horizontalHeader().setResizeMode(
            2, QHeaderView.Fixed)

        #  Thumbnails View
        #  ----------------------------------------
        self.getthumbnailsmodel = {}
        self.setThumbnailsModel('')
        self.thumbnails_tableViewWidget.setIconSize(QSize(64, 64))

        #  Table view popup menu
        #  ----------------------------------------
        self.table_popMenu = QMenu(self)
        checkSelected_Action = QAction('Check Selected', self)
        uncheckSelected_Action = QAction('Uncheck Selected', self)
        checkAll_Action = QAction('Check All', self)
        uncheckAll_Action = QAction('Uncheck All', self)
        viewFile_Action = QAction('View File', self)
        self.connect(checkAll_Action, SIGNAL("triggered()"),
                     partial(self.checkSelected, True))
        self.connect(uncheckAll_Action, SIGNAL("triggered()"),
                     partial(self.checkSelected, False))
        self.connect(checkAll_Action, SIGNAL("triggered()"),
                     partial(self.checkAll, True))
        self.connect(uncheckAll_Action, SIGNAL("triggered()"),
                     partial(self.checkAll, False))
        self.connect(viewFile_Action, SIGNAL("triggered()"), self.viewFile)
        self.table_popMenu.addAction(checkSelected_Action)
        self.table_popMenu.addAction(uncheckSelected_Action)
        self.table_popMenu.addSeparator()
        self.table_popMenu.addAction(checkAll_Action)
        self.table_popMenu.addAction(uncheckAll_Action)
        self.table_popMenu.addSeparator()
        self.table_popMenu.addAction(viewFile_Action)
        self.images_tableViewWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.images_tableViewWidget.customContextMenuRequested.connect(
            self.tableviewPopup)

        #  Thumbnails view popup menu
        #  ----------------------------------------
        self.thumbnails_popMenu = QMenu(self)
        thumbCheckSelected_Action = QAction('Check Selected', self)
        thumbUncheckSelected_Action = QAction('Uncheck Selected', self)
        thumbCheckAll_Action = QAction('Check All', self)
        thumbUncheckAll_Action = QAction('Uncheck All', self)
        self.connect(thumbCheckSelected_Action, SIGNAL("triggered()"),
                     partial(self.checkSelected, True))
        self.connect(thumbUncheckSelected_Action, SIGNAL("triggered()"),
                     partial(self.checkSelected, False))
        self.connect(thumbCheckAll_Action, SIGNAL("triggered()"),
                     partial(self.checkAll, True))
        self.connect(thumbUncheckAll_Action, SIGNAL("triggered()"),
                     partial(self.checkAll, False))
        self.thumbnails_popMenu.addAction(thumbCheckSelected_Action)
        self.thumbnails_popMenu.addAction(thumbUncheckSelected_Action)
        self.thumbnails_popMenu.addSeparator()
        self.thumbnails_popMenu.addAction(thumbCheckAll_Action)
        self.thumbnails_popMenu.addAction(thumbUncheckAll_Action)
        self.thumbnails_tableViewWidget.setContextMenuPolicy(
            Qt.CustomContextMenu)
        self.thumbnails_tableViewWidget.customContextMenuRequested.connect(
            self.thumbnailsViewPopup)

        #  Users list view popup menu
        #  ----------------------------------------
        self.list_popMenu = QMenu(self)
        deleteUser_Action = QAction('Delete user', self)
        self.connect(deleteUser_Action, SIGNAL("triggered()"), self.deleteUser)
        self.list_popMenu.addAction(deleteUser_Action)
        self.users_listViewWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.users_listViewWidget.customContextMenuRequested.connect(
            self.listviewPopup)

        #  Set project button popup menu
        #  ----------------------------------------
        self.setproject_buttonWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.setproject_buttonWidget.customContextMenuRequested.connect(
            self.projectButtonPopup)
        self.project_popMenu = QMenu(self)
        openProjectDir_Action = QAction('Open Download location', self)
        self.connect(openProjectDir_Action, SIGNAL("triggered()"),
                     partial(self.openFolder, 'project'))
        self.project_popMenu.addAction(openProjectDir_Action)

        #  Avatar
        #  ----------------------------------------
        self.icon = QIcon()
        #  Set default avatar
        self.loadAvatar(":no_avatar100.gif")
        self.username_labelWidget.setText(self.currentuser)

        #  Log Dock Widget
        #  ----------------------------------------
        logDockWidget = QDockWidget("Log", self)
        logDockWidget.setObjectName("LogDockWidget")
        logDockWidget.setAllowedAreas(Qt.LeftDockWidgetArea
                                      | Qt.RightDockWidgetArea)
        self.logtext = LogText()
        self.log_TextBrowser = self.logtext.textbrowser
        logDockWidget.setWidget(self.log_TextBrowser)
        self.addDockWidget(Qt.RightDockWidgetArea, logDockWidget)
        self.log_TextBrowser.setStyleSheet(stylesheets.logArea)
        logDockWidget.hide()

        #  Menu Additions
        #  ----------------------------------------
        #  View menu
        viewDatabase_Action = self.createAction('View Database',
                                                self.openDatViewer, "Alt+D",
                                                None, None, False)
        switchView_Action = self.createAction('Switch view',
                                              self.userSwitchView, "Alt+Q",
                                              None, None, False)
        # self.menu_View.addAction(logDockWidget.toggleViewAction())
        self.view_Menu.addAction(switchView_Action)
        self.view_Menu.addSeparator()
        self.view_Menu.addAction(viewDatabase_Action)
        #  Help menu
        about_Action = self.createAction('About', self.showAboutDialog, "",
                                         None, None, False)
        # self.about_Action.activated.connect(self.showAboutDialog)
        self.help_Menu.addAction(about_Action)

        #  Connect Signals and Slots
        #  ----------------------------------------
        #  Main Widgets
        self.adduser_buttonWidget.pressed.connect(
            self.onAddUser)  # SIGNAL("pressed()")
        self.newuser_lineEditWidget.returnPressed.connect(
            self.onAddUser)  # SIGNAL("returnPressed()")
        self.users_listViewWidget.doubleClicked.connect(self.onUserSelect)

        # Note: I leave out activated signal because I not sure what it does
        # self.users_listViewWidget.activated.connect(self.onUserSelect)

        # Note: clicked signal is not used because we already have
        #  self.userslistmodel.onSelectionChanged.connect(self.onUserSelect).
        #  Adding both will double trigger the onUserSelect method which
        #  will cause the view be refresed twice
        # self.users_listViewWidget.clicked.connect(self.onUserSelect)

        #  Buttons on left panel
        self.setproject_buttonWidget.clicked.connect(self.setProjectLocation)
        self.download_buttonWidget.clicked.connect(self.downloadSelected)
        self.avatar_buttonWidget.clicked.connect(
            partial(self.openFolder, 'user'))
        self.tableview_buttonWidget.clicked.connect(partial(
            self.switchView, 0))
        self.thumbnailview_buttonWidget.clicked.connect(
            partial(self.switchView, 1))
        #  Actions
        self.test_action.triggered.connect(self.test)
        self.openDatViewer_action.triggered.connect(self.openDatViewer)

        #  Finalizing
        #  ----------------------------------------
        self.newuser_lineEditWidget.setFocus()
        self.resize(900, 500)
        self.setStatus("Hello", 1.5)
        self.switchView(1)  # Set view to table view
        self.setProjectDir(os.path.join(os.getcwd(), 'Downloads'))
        QTimer.singleShot(0, self.newuser_lineEditWidget, SLOT('setFocus()'))

        logger.info("Finish constructing main window")

    def createAction(self,
                     text,
                     slot=None,
                     shortcut=None,
                     icon=None,
                     tip=None,
                     checkable=False,
                     signal="triggered()"):
        # ( Copied from Rapid GUI Programming with Python and Qt,
        #		Chapter 6, imagechanger.py )
        action = QAction(text, self)
        if icon is not None:
            action.setIcon(QIcon(":/%s.png" % icon))
        if shortcut is not None:
            action.setShortcut(shortcut)
        if tip is not None:
            action.setToolTip(tip)
            action.setStatusTip(tip)
        if slot is not None:
            self.connect(action, SIGNAL(signal), slot)
        if checkable:
            action.setCheckable(True)
        return action

    #  Non-UI methods
    #  ----------------------------------------
    def test(self):
        pass

    def logCurrentMethod(self, msg):
        methodname = inspect.stack()[1][3]
        logger = logging.getLogger("mainwindow." + methodname)
        logger.info(msg)

    def printToLog(self, msg=''):
        self.logtext.addNewMsg(msg)

    def callWarning(self, msg=''):
        self.logtext.addNewMsg(msg)
        QMessageBox.warning(self, 'Warning', msg)

    def callError(self, msg=''):
        self.logtext.addNewMsg(msg)
        QMessageBox.warning(self, 'Error', msg)

    def setStatus(self, msg, secs=3):
        self.statusbar.showMessage(msg, secs * 1000)

    def saveData(self):
        self.logCurrentMethod("Saving self.usersdata")
        self.usersdata.savePickle()

    def loadAvatar(self, avatarpath):
        self.logCurrentMethod("Loading avatar: {0}".format(avatarpath))
        self.icon.addPixmap(QPixmap(avatarpath), QIcon.Normal, QIcon.Off)
        self.avatar_buttonWidget.setIcon(self.icon)
        self.avatar_buttonWidget.setIconSize(QSize(50, 50))

    def setProjectDir(self, location):
        self.logCurrentMethod("Setting project dir to: {0}".format(location))
        self.projman.setProjectDir(location)
        self.setWindowTitle('CG Hub Downloader - {0}'.format(location))

    def switchView(self, view):
        self.logCurrentMethod("Switching view to...")
        button = None

        if view == 0:
            self.logCurrentMethod("Table view")
            self.tableview_buttonWidget.setEnabled(False)
            self.thumbnailview_buttonWidget.setEnabled(True)
        else:
            self.logCurrentMethod("Thumbnails view")
            self.tableview_buttonWidget.setEnabled(True)
            self.thumbnailview_buttonWidget.setEnabled(False)

        self.currentview = view
        self.stackedWidget.setCurrentIndex(view)

    def userSwitchView(self):
        self.switchView(not self.currentview)

    #  Direct-UI methods
    #  ----------------------------------------
    def setProjectLocation(self):
        dialog = QFileDialog()
        dialog.setFileMode(QFileDialog.Directory)
        dialogdir = self.projdir  # or can use QDir.currentPath()
        directory = dialog.getExistingDirectory(self, "Set download location", \
         dialogdir, QFileDialog.ShowDirsOnly)

        if directory:
            self.setProjectDir(directory)
            self.usersdata.setProjectDir(directory)
            self.userslistdata.setProjectDir(directory)
            self.userslistdata.updateFromUsersData(self.usersdata)

            # Deselect all from users list
            for modelindex in self.users_listViewWidget.selectedIndexes():
                selectionmodel = self.users_listViewWidget.selectionModel()
                selectionmodel.select(modelindex, QItemSelectionModel.Deselect)

            # Clear table view
            self.clearTable()

            # Load default avatar
            self.loadAvatar(":no_avatar100.gif")

    def downloadSelected(self):
        if self.currentuser != None and self.currentuser != '':
            self.logCurrentMethod(
                "Downloading selected images from {0}".format(
                    self.currentuser))
            userobj = self.usersdata.getUser(self.currentuser)
            self.projman.processUser(userobj)

    def openFolder(self, folderType):
        self.logCurrentMethod("Opening folder")
        if folderType == 'project':
            call(["explorer.exe ", convertPathToExplorer(self.projdir)])
        elif folderType == 'user':
            if self.currentuser != None and self.currentuser != '':
                userdir = convertPathToExplorer(self.projdir + '\\' +
                                                self.currentuser)
                if os.path.isdir(userdir):
                    call(["explorer.exe ", userdir])

    def openDatViewer(self):
        window = datviewer2.DatViewerWindow(self)
        window.show()

    def showAboutDialog(self):
        aboutdialog = AboutDialog(self)
        aboutdialog.show()

    #  Table View related methods
    #  ----------------------------------------
    def onUserSelect(self, modelindex):
        self.logCurrentMethod("Loading user's images")
        username = self.userslistmodel.data(modelindex, Qt.DisplayRole)
        # Note: username will looks like -> "username (10)"
        username = username.split(' ')[0]
        userobj = self.usersdata.getUser(username)
        self.factory.addJob('UserImages', (userobj, self.projman))

    def refreshTableView(self, userobj):
        self.logCurrentMethod("Updating table view")
        self.projman.updateWithExistingImages(self.usersdata)

        # It might always be true, but just to be clear, please be
        # aware that both table model and thumbnails model need to
        # receive the same userobj in order to sync with each other.
        self.setTableModel(userobj.name)
        self.setThumbnailsModel(userobj.name)
        self.currentthumbnailsmodel.updateModel()

        # Load avatar
        self.loadAvatar(userobj.avatarpath)

        # Set current user
        self.currentuser = userobj.name

        # Update user name
        self.username_labelWidget.setText(self.currentuser)

        # Update Images filesize
        self.updateImagesFilesize()

        # Update/Download Thumbnails
        self.projman.processUser(userobj, thumbnails=True)

        # Redownload avatar if it's missing
        if userobj.avatarpath == None:
            avatarpath = self.projman.getUserAvatar(userobj,
                                                    userobj.userpagehtml)
            if avatarpath:
                self.loadAvatar(avatarpath)

    def setTableModel(self, username):
        """ Attact a table model to view. If no table model found for
		the user, create a new one.
		"""
        self.logCurrentMethod("Setting table model for '{0}'".format(username))
        model = None

        if username not in self.gettablemodel.keys():
            model = UserImagesModel(self.usersdata, username)
            self.gettablemodel[username] = model

            # When projman is downloading an image, it will fires
            # 'updateModel' signal. This model will catch it and
            # calls 'updateModel' (which is just a simple 'modelReset()')
            # to tell the view to update. This process shows the
            # download progress
            self.projman.updateModel.connect(model.updateModel)

        else:
            model = self.gettablemodel[username]

        self.images_tableViewWidget.setModel(model)

        # Keep self updated about the change
        self.currentusermodel = model

    def updateTableModel(self):
        self.logCurrentMethod("Asking table model to 'resetModel()'")
        self.currentusermodel.updateModel()

    def clearTable(self):
        self.logCurrentMethod(
            "Clearing table, setting table model to empty user ('')")
        self.images_tableViewWidget.clearSpans()
        self.setTableModel('')  # Set to empty user will clear the table model

    def updateImagesFilesize(self):
        if self.currentuser != None and self.currentuser != '':
            self.logCurrentMethod("Updating images file size for '{0}'".format(
                self.currentuser))
            self.projman.updateWithExistingImages(
                self.currentusermodel._usersdata)
            self.setStatus(
                "Checking {0}'s images file size...".format(self.currentuser),
                3.5)
            self.factory.addJob('ImagesFilesize',
                                (self.usersdata, self.currentuser))

    #  Thumbnails view methods
    #  ----------------------------------------
    def setThumbnailsModel(self, username):
        """ Attacth a thumbnails model to view. If no thumbnails model found for
		the user, create a new one.
		"""
        self.logCurrentMethod(
            "Setting thumbnails model for '{0}'".format(username))
        model = None

        if username not in self.getthumbnailsmodel.keys():
            # Passing a UserDir to ThumbnailsModel() so that it
            # knows where to look for the thumbnails
            userdir = self.projman.getUserDir(username)
            model = ThumbnailsModel(self.usersdata, username, userdir)
            self.getthumbnailsmodel[username] = model

            # The thumbnails table view is an instance of MyThumbnailsView,
            # MyThumbnailsView will fires the 'columnCountChange' everytime
            # the window is resized. This will tell the model to change
            # it's column counts to fit the new size.
            self.thumbnails_tableViewWidget.columnCountChange.connect(
                model.setColumnCount)

            # When projman is downloading a thumbnails, it will fires
            # 'updateThumbnailsModel' signal. This model will catch it and
            # calls 'updateModel' (which is just a simple 'modelReset()')
            # to tell the view to update.
            self.projman.updateThumbnailsModel.connect(model.updateModel)

        else:
            model = self.getthumbnailsmodel[username]

        self.thumbnails_tableViewWidget.setModel(model)

        # Keep self updated about the change
        self.currentthumbnailsmodel = model

    #  Table view right click context menu
    #  ----------------------------------------
    def tableviewPopup(self, point):
        self.table_popMenu.exec_(
            self.images_tableViewWidget.mapToGlobal(point))

    def checkSelected(self, check):
        self.logCurrentMethod("Check selected")
        view = None
        model = None
        checkstate = Qt.Checked if check else Qt.Unchecked

        if self.stackedWidget.currentIndex() == 0:
            view = self.images_tableViewWidget
            model = self.currentusermodel
        else:
            view = self.thumbnails_tableViewWidget
            model = self.currentthumbnailsmodel

        for idx in view.selectedIndexes():
            model.setData(idx, checkstate, Qt.CheckStateRole)

    def checkAll(self, check):
        self.logCurrentMethod("Check all")
        view = None
        model = None
        checkstate = Qt.Checked if check else Qt.Unchecked

        if self.stackedWidget.currentIndex() == 0:
            view = self.images_tableViewWidget
            model = self.currentusermodel
        else:
            view = self.thumbnails_tableViewWidget
            model = self.currentthumbnailsmodel

        view.selectAll()
        for idx in view.selectedIndexes():
            model.setData(idx, checkstate, Qt.CheckStateRole)
        view.selectionModel().clearSelection()

    def viewFile(self):
        # for idx in self.images_tableViewWidget.selectedIndexes():
        # 	self.currentusermodel.setData(idx, Qt.Unchecked, Qt.CheckStateRole)
        pass

    #  Thumbnails view right click context menu
    #  ----------------------------------------
    def thumbnailsViewPopup(self, point):
        self.thumbnails_popMenu.exec_(
            self.thumbnails_tableViewWidget.mapToGlobal(point))

    #  Users list view right click context menu
    #  ----------------------------------------
    def listviewPopup(self, point):
        self.list_popMenu.exec_(self.users_listViewWidget.mapToGlobal(point))

    def deleteUser(self):
        # Delete from users list
        self.userslistdata.deleteUser(self.currentuser)
        # Delete from usersdata as well
        self.usersdata.deleteUser(self.currentuser)
        self.userslistmodel.updateModel()

        # Selection the first item on the list
        modelindex = self.userslistmodel.index(0, 0)
        if modelindex:
            self.users_listViewWidget.setCurrentIndex(modelindex)
            username = self.userslistmodel.data(modelindex, Qt.DisplayRole)
            self.refreshTableView(self.usersdata.getUser(username))

    #  Set project button right click context menu
    #  -------------------------------------------
    def projectButtonPopup(self, point):
        self.project_popMenu.exec_(
            self.setproject_buttonWidget.mapToGlobal(point))

    #  User lists related methods
    #  ----------------------------------------
    def onAddUser(self):
        user = self.newuser_lineEditWidget.text()
        user = str(user).lower()
        self.logCurrentMethod("Adding '{0}' to list".format(user))
        if len(user) > 0:
            if user not in self.addedUsers:
                self.usersdata.addNewUser(user)
                userobj = self.usersdata.getUser(user)
                self.setStatus("Adding '{0}'...".format(user), 3)
                self.factory.addJob('UserValidation', userobj)

    def refreshUserList(self, userobj, html):
        self.logCurrentMethod("Refreshing users list")
        if userobj.exists and userobj.viewImageUrl == False:
            # need to mark user empty???
            self.callWarning("{0}'s gallery is empty".format(userobj.name))
            logger.warning("{0}'s gallery is empty".format(userobj.name))
        else:
            self.userslistdata.addUser(userobj)
            self.userslistmodel.updateModel()
            # Select new user
            idx = self.userslistdata.getUserIndex(userobj.name)
            if idx != None:
                modelindex = self.userslistmodel.index(idx, 0)
                self.users_listViewWidget.setCurrentIndex(modelindex)
            avatarpath = self.projman.getUserAvatar(userobj, html)
            if avatarpath != None:
                self.loadAvatar(avatarpath)
示例#10
0
        text = input("paste reference id: ")
        if text == "revert":
            env.prepare_working_dir()
            continue
        elif text == "exit":
            if env.starting_branch is not None:
                if 'y' == input(
                        "we've not retuned to the working branch exit anyway? (y/n)"
                ):
                    break
            else:
                break
        elif text == "help":
            print(howto)
        else:
            env.switch_to(text)


if __name__ == "__main__":
    config = JsonConfigManager(os.path.expanduser(CONFIG_FOLDER), CONFIG_NAME)
    if I_AM_EVAN:
        old_school()
    else:
        pm = ProjectManager(config)
        root = Tk()
        my_gui = TkGui(root, pm)
        root.update()
        root.mainloop()
        logger.info("Exiting")
        config.save_to_file()
示例#11
0
class Gellies(GUIFramework):
    menuitems = (
        'File- &Exit/Ctrl+q/self.quit',
    )
    def __init__(self, root):
        GUIFramework.__init__(self, root)
        self.root = root
        self.build_GUI()
        self.r2mapsID = None

    def build_GUI(self):
        books = ('Project', 'R2map', 'Calibration')
        self.left_frame = tk.Frame(self.root)
        self.left_frame.pack(side=tk.LEFT, fill=tk.Y, expand=0)

        self.right_frame = tk.Frame(self.root)
        self.right_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)

        self.notebook = ttk.Notebook(self.left_frame)
        self.notebook.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        self.book1 = tk.Frame(self.notebook)
        self.notebook.add(self.book1, text='Project')
        self.book2 = tk.Frame(self.notebook)
        self.notebook.add(self.book2, text='R2map')
        self.book3 = tk.Frame(self.notebook)
        self.notebook.add(self.book3, text='Calibration')
        self.notebook.bind('<<NotebookTabChanged>>', self.notebook_changed)

        self.main_frame = tk.Frame(self.right_frame)
        self.main_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=1)

        self.make_project_book(self.book1)
        self.make_r2map_book(self.book2)
        self.make_calibration_book(self.book3)

        self.message_box_frame = tk.LabelFrame(self.right_frame, text='Messages')
        self.message_box_frame.pack(side=tk.BOTTOM, fill=tk.BOTH, expand=1)
        self.messagebox = MessageBox(self.message_box_frame)
        self.messagebox.pack(side=tk.TOP, fill=tk.BOTH, expand=1)

        self.r2value = []
        self.dose = []


    def make_project_book(self, book):
        self.project_panel = ProjectManager(book, 'projectinfo')
        self.project_panel.register(self)

        self.img_frame = tk.LabelFrame(self.main_frame, text='Dicom images')
        self.img_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        self.dicom_img = ImagePanel(self.img_frame, 'main_img', wl=True, toolbar=True, info=True, cb=True)
        self.dicom_img.pack(side=tk.TOP, fill=tk.BOTH, expand=1)

    def make_r2map_book(self, book):
        #toolbaritems = ('Save$icons/Save$tk.FLAT$self.saveR2$tk.LEFT$Save R2 parameters',
        #                'Exit$icons/Exit$tk.FLAT$self.quit$tk.RIGHT$Exit')
        #button_bar = self.make_button_bar(book, toolbaritems, tk.TOP)
        #button_bar.pack(side=tk.TOP, fill=tk.X, expand=0)

        self.r2map_panel = R2MapPanel(book, self.project_panel, 'r2mappanel')
        self.r2map_panel.pack(side=tk.TOP, fill=tk.Y, expand=1)
        self.r2map_panel.register(self)

        self.r2map_dicom_frame = tk.LabelFrame(self.main_frame, text='Dicom image')
        self.r2map_dicom_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
        self.r2map_dicom_img = ImagePanel(self.r2map_dicom_frame, 'r2map_dicom_frame', wl=True, toolbar=True, info=False, cb=True)
        self.r2map_dicom_img.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        self.r2map_dicom_img.register(self)

        self.r2map_frame = tk.LabelFrame(self.main_frame, text='R2map')
        self.r2map_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
        self.r2map_img = ImagePanel(self.r2map_frame, 'r2map_frame', wl=True, toolbar=True, info=False, cb=True)
        self.r2map_img.pack(side=tk.TOP, fill=tk.BOTH, expand=1)

    def make_calibration_book(self, book):
        self.calibration_panel = CalibrationPanel(book, 'calibrationpanel')
        self.calibration_panel.pack(side=tk.TOP, fill=tk.Y, expand=1)
        self.calibration_panel.register(self)

        self.calibration_r2map_frame = tk.LabelFrame(self.main_frame, text='R2map')
        self.calibration_r2map_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
        self.calibration_r2map_img = ImagePanel(self.calibration_r2map_frame, 'calr2mapimg', wl=True, toolbar=True, info=False, cb=True)
        self.calibration_r2map_img.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        self.calibration_r2map_img.register(self)

        self.calibration_dosemap_frame = tk.LabelFrame(self.main_frame, text='Dose map')
        self.calibration_dosemap_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
        self.calibration_dosemap_img = ImagePanel(self.calibration_dosemap_frame, 'caldosemapimg', wl=True, toolbar=True, info=False, cb=True)
        self.calibration_dosemap_img.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        self.calibration_dosemap_img.register(self)

    def notebook_changed(self, event):
        book = self.notebook.index(self.notebook.select())
        print(book)
        if book == 0:
            print('Book 1')
            for child in self.main_frame.winfo_children():
                child.pack_forget()
            self.img_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        if book == 1:
            print('Book 2')
            for child in self.main_frame.winfo_children()[:-1]:
                child.pack_forget()
            self.r2map_dicom_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
            self.r2map_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)

        if book == 2:
            print('Book 3')
            for child in self.main_frame.winfo_children():
                child.pack_forget()
            self.calibration_r2map_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
            self.calibration_dosemap_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)

    def quit(self):
        self.root.quit()

    def update_(self, name, event):
        print(name, event)
        if name == 'projectinfo':
            if event == 'NewProject':
                self.messagebox.config(state=tk.NORMAL)
                self.messagebox.delete(1.0,tk.END)
                self.messagebox.insert(tk.END, '>> ')
                self.messagebox.config(state=tk.DISABLED)
                for item in self.r2map_panel.r2map_tree.get_children():
                    for child in self.r2map_panel.r2map_tree.children(item):
                        self.r2map_panel.r2map_tree.delete(child)
                    self.r2map_panel.r2map_tree.delete(item)
            if event == 'OpenProject':
                self.messagebox.config(state=tk.NORMAL)
                self.messagebox.delete(1.0,tk.END)
                self.messagebox.insert(tk.END, '>> Open ')
                self.messagebox.insert(tk.END, self.project_panel.get_project_name())
                self.messagebox.insert(tk.END, ' project.')
                self.messagebox.config(state=tk.DISABLED)
                for item in self.r2map_panel.r2map_tree.get_children():
                    for child in self.r2map_panel.r2map_tree.children(item):
                        self.r2map_panel.r2map_tree.delete(child)
                    self.r2map_panel.r2map_tree.delete(item)
                for key in sorted(self.project_panel.dicom_files):
                    id = self.r2map_panel.r2map_tree.insert('', 'end', text=key)
                    i=0
                    for item in self.project_panel.dicom_files[key]:
                        self.r2map_panel.r2map_tree.insert(id, 'end', text=str(i), values=(item.SeriesNumber, item.SeriesDescription, item.EchoTime))
                        i += 1
                if self.project_panel.meta_data['r2maps']:
                    self.r2mapsID = self.r2map_panel.r2map_tree.insert('', 'end', text='R2maps')
                    for key in self.project_panel.meta_data['r2maps']:
                        i=0
                        id = self.r2map_panel.r2map_tree.insert(self.r2mapsID, 'end', text=key)
                        self.r2maps = np.load(self.project_panel.project_dir+'/r2map'+'key')
                        for item in self.project_panel.meta_data['r2maps'][key]:
                            self.r2map_panel.r2map_tree.insert(id, 'end', text = str(i))
                            i += 1
            if event == 'ReadDicom':
                self.messagebox.config(state=tk.NORMAL)
                self.messagebox.insert(tk.END, '\n>> Read dicom files.')
                self.messagebox.config(state=tk.DISABLED)
        if name == 'projectinfo.treepanel':
            project_tree = self.project_panel.get_project_tree()
            if event == '<<TreeviewSelect>>':
                selection = project_tree.selection()[0]
                parent = project_tree.parent(selection)
                print(name, event, selection, parent)
                if parent:
                    self.dicom_img.set_images(self.project_panel.get_dicom_images()[parent])
                    self.dicom_img.set_indexOfImg(int(project_tree.item(project_tree.selection())['text']))
                    self.dicom_img.show_images()
                else:
                    self.dicom_img.set_images(self.project_panel.get_dicom_images()[selection])
            if event == 'delete_item':
                temp = {}
                for item in project_tree.get_children():
                    key = project_tree.item(item)['text']
                    temp[key] = self.project_panel.get_dicom_path()[key]
                self.project_panel.set_meta_data('dicom_dict', temp)

        if name == 'projectinfo.projectinfo':
            if event == 'Save':
                self.messagebox.config(state=tk.NORMAL)
                self.messagebox.insert(tk.END, '\n>> Save project data.')
                self.messagebox.config(state=tk.DISABLED)
            if event == 'Modify':
                self.messagebox.config(state=tk.NORMAL)
                self.messagebox.insert(tk.END, '\n>> Modify project data.')
                self.messagebox.config(state=tk.DISABLED)

        if name == 'r2projectpanel':
            if event == '<<TreeviewSelect>>':
                selection = self.r2map_panel.r2map_tree.selection()[0]
                parent = self.r2map_panel.r2map_tree.parent(selection)
                if parent:
                    self.r2map_dicom_img.set_images(self.project_panel.get_dicom_images()[parent])
                    self.r2map_dicom_img.set_indexOfImg(int(self.r2map_panel.r2map_tree.item(self.r2map_panel.r2map_tree.selection())['text']))
                    self.r2map_dicom_img.show_images()
                else:
                    self.r2map_dicom_img.set_images(self.project_panel.get_dicom_images()[selection])

        if name == 'r2mappanel':
            if event == 'r2mapping':
                if self.r2map_panel.map_algoritm.get() == 'Polyfit':
                    self.r2maping()
        if name == 'r2map_dicom_frame':
            if event == '<DrawRectangle>':
                print('OK')
                points = self.r2map_dicom_img.getRectanglePoints()
                self.r2map_panel.lx0.set(int(points[0]))
                self.r2map_panel.lx1.set(int(points[1]))
                self.r2map_panel.ly0.set(int(points[2]))
                self.r2map_panel.ly1.set(int(points[3]))

        if name == 'calibrationpanel':
            if event == 'calr2maptree.<<TreeviewSelect>>':
                selection = self.calibration_panel.r2maptree.selection()[0]
                self.calibration_r2map_img.set_images(self.r2maps)
            if event == 'addvalue':
                x0 = int(self.calibration_r2map_img.x0)
                x1 = int(self.calibration_r2map_img.x1)
                y0 = int(self.calibration_r2map_img.y0)
                y1 = int(self.calibration_r2map_img.y1)
                print(x0,x1,y1,y0)
                id = self.calibration_r2map_img.indexOfImg
                average = np.median(self.r2maps[id, y1:y0,x0:x1])
                print(self.r2maps[id, x0:x1,y1:y0])
                #sd = np.std(self.r2maps[id, x0:x1,y1:y0])
                print('Mean = '+str(average))
                #print('Std = '+str(sd))
                i = len(self.r2value)
                self.calibration_panel.spreadsheet.cells['R2'+str(i+1)].insert(0, average)
                self.r2value.append(average)
                self.calibration_dosemap_img.set_images(self.r2maps[:, x1:x0,y0:y1])
                self.calibration_dosemap_img.set_indexOfImg(id)
                self.calibration_dosemap_img.show_images()


    def r2maping(self):
        self.pixels = []
        self.te = []
        for item in self.r2map_panel.r2map_tree.get_children():
            self.pixels.append(self.project_panel.dicom_images[item])
            self.te.append(self.project_panel.project_tree.item(item)['text'])
        print(self.te)

        row = np.shape(self.pixels[0][0])[0]
        column = np.shape(self.pixels[0][0])[0]
        nSlice = np.shape(self.pixels[0])[0]
        print('Slice ' + str(nSlice))
        r2maps = []
        sigma = []
        images = self.pixels

        col0 = int(self.r2map_dicom_img.x0)
        col1 = int(self.r2map_dicom_img.x1)
        row0 = int(self.r2map_dicom_img.y0)
        row1 = int(self.r2map_dicom_img.y1)
        for s in range(0,nSlice):
            print(s)
            r2map = np.zeros((row, column))
            for i in range(row0,row1):
                for j in range(col0,col1):
                    temp = []
                    for item in self.pixels:
                        if item[s][i,j]!=0:
                            temp.append(np.log(item[s][i,j]))
                        else: temp.append(0)
                    slope = np.polyfit(self.te, temp,1)
                    r2map[i,j] = -slope[0]

            r2maps.append(r2map)

        #self.project_panel.meta_data['r2maps']['key'] = self.project_panel.project_dir+'/r2map'+'key'
        #with open(self.project_panel.project_dir+'/'+self.project_panel.project_name+'.dat', 'wb') as outfile:
        #    pickle.dump(self.project_panel.meta_data, outfile, protocol=pickle.HIGHEST_PROTOCOL)
        self.r2maps = np.array(r2maps)
        np.save(self.project_panel.project_dir+'/r2map'+'key', self.r2maps)
        self.r2map_img.set_images(self.r2maps)
        self.r2map_img.show_images()
        n = len(self.calibration_panel.r2maptree.get_children())
        self.calibration_panel.r2maptree.insert('', 'end', text=str(n+1), value=('', 'Polyfit'))