示例#1
0
def get_or_create_shotgun_menu(menu_name):
    app = NatronGui.natron.getActiveInstance()
    app_id = app.getAppID()
    app_gui = NatronGui.natron.getGuiInstance(app_id)
    fake_panel = NatronGui.PyPanel("shotgun.software.engine", "tk-natron",
                                   True, app_gui)
    main_window = fake_panel.parent()
    del fake_panel

    menu_bar = None
    for m in main_window.findChildren(QtGui.QMenuBar):
        menu_bar = m
        break

    for action in menu_bar.actions():
        if action.text() == menu_name:
            return action.menu()

    help_action = None
    for action in menu_bar.actions():
        if action.text() == "Help":
            shotgun_menu = QtGui.QMenu(menu_name)
            menu_bar.insertMenu(action, shotgun_menu)
            return shotgun_menu

    return None
示例#2
0
    def add_command_to_menu(self, menu):
        """
        Adds an app command to the menu
        """

        # create menu sub-tree if need to:
        # Support menu items seperated by '/'
        parent_menu = menu
        parts = self.name.split("/")
        for item_label in parts[:-1]:

            # see if there is already a sub-menu item
            sub_menu = self._find_sub_menu_item(parent_menu, item_label)
            if sub_menu:
                # already have sub menu
                parent_menu = sub_menu
            else:
                new_sub_menu = QtGui.QMenu(item_label)
                parent_menu.addMenu(new_sub_menu)
                parent_menu = new_sub_menu

        # finally create the command menu item:
        menu_action = parent_menu.addAction(parts[-1])
        #menu_action.triggered.connect(self.callback)
        menu_action.triggered.connect(lambda: menu_callback(self.callback))
        if "tooltip" in self.properties:
            menu_action.setToolTip(self.properties["tooltip"])

        if "enable_callback" in self.properties:
            menu_action.setEnabled(self.properties["enable_callback"]())
示例#3
0
    def _add_app_menu(self, commands_by_app):
        """
        Add all apps to the main menu, process them one by one.
        """
        for app_name in sorted(commands_by_app.keys()):

            if len(commands_by_app[app_name]) > 1:
                # more than one menu entry fort his app
                # make a sub menu and put all items in the sub menu
                app_menu = QtGui.QMenu(app_name)
                self._menu_handle.addMenu(app_menu)

                # get the list of menu cmds for this app
                cmds = commands_by_app[app_name]
                # make sure it is in alphabetical order
                cmds.sort(key=lambda x: x.name)

                for cmd in cmds:
                    cmd.add_command_to_menu(app_menu)

            else:

                # this app only has a single entry.
                # display that on the menu
                # todo: Should this be labelled with the name of the app
                # or the name of the menu item? Not sure.
                cmd_obj = commands_by_app[app_name][0]
                if not cmd_obj.favourite:
                    # skip favourites since they are alreay on the menu
                    cmd_obj.add_command_to_menu(self._menu_handle)
    def __init__(self, engine, menu_name):
        self._engine = engine
        self._menu_name = menu_name
        self._dialogs = []

        self._widget = QtGui.QWidget()
        self._handle = QtGui.QMenu(self._menu_name, self._widget)
        self._ui_cache = []
        self.logger = self._engine.logger
示例#5
0
def get_or_create_shotgun_menu(menu_name):
    """
    Creates or retrieves the Shotgun Menu entry in the Menu bar.
    """
    menu_bar = get_menubar()
    if menu_bar:
        for action in menu_bar.actions():
            if action.text().replace("&", "") == menu_name:
                return action.menu()

        for action in menu_bar.actions():
            if action.text().replace("&", "") == "Help":
                shotgun_menu = QtGui.QMenu(menu_name, menu_bar)
                menu_bar.insertMenu(action, shotgun_menu)
                return shotgun_menu
    def __init__(self, parent):
        """
        Constructor
        """
        QtGui.QWidget.__init__(self, parent)

        # make sure this widget isn't shown
        self.setVisible(False)

        # set up the UI
        self.ui = Ui_ListWidget()
        self.ui.setupUi(self)

        # set up action menu
        self._menu = QtGui.QMenu()
        self._actions = []
        self.ui.button.setMenu(self._menu)
        self.ui.button.setVisible(False)
示例#7
0
    def clear_app_uis(self):
        # empty the project commands
        self._project_command_model.clear()

        # hide the pipeline configuration bar
        self.ui.configuration_frame.hide()

        # hide the setup project ui if it is shown
        self.setup_project_widget.hide()
        self.update_project_config_widget.hide()
        self.setup_new_os_widget.hide()

        # clear the project specific menu
        self.project_menu = QtGui.QMenu(self)
        self.project_menu.triggered.connect(self._on_project_menu_triggered)
        self.project_menu.addAction(self.ui.actionProject_Filesystem_Folder)
        self.ui.project_menu.setMenu(self.project_menu)
        self.__pipeline_configuration_separator = None
示例#8
0
    def _add_context_menu(self):
        """
        Adds a context menu which displays the current context
        """

        ctx = self._engine.context
        ctx_name = str(ctx)

        # # create the menu object

        ctx_menu = QtGui.QMenu(ctx_name)
        self._menu_handle.addMenu(ctx_menu)

        action_reload = ctx_menu.addAction("Reload Shotgun", self._reload_sg)
        action_reload = ctx_menu.addAction("Jump to Shotgun", self._jump_to_sg)
        action_reload = ctx_menu.addAction("Jump to File System",
                                           self._jump_to_fs)
        ctx_menu.addSeparator()

        return ctx_menu
示例#9
0
    def reset(self):
        """
        Clears the project specific related QT menu and add basic menu actions
        and pipeline configuration section divider.
        """
        if self._project_menu:
            self._pipeline_configuration_separator = None
            self._project_menu.clear()

        self._project_menu = QtGui.QMenu(self._parent)

        self._project_menu.aboutToShow.connect(
            self._on_project_menu_about_to_show)
        self._project_menu.triggered.connect(self._on_project_menu_triggered)
        self._parent.ui.actionProject_Filesystem_Folder.setVisible(True)
        self._project_menu.addAction(
            self._parent.ui.actionProject_Filesystem_Folder)
        self._parent.ui.project_menu.setMenu(self._project_menu)

        # Add a section separator that will be above the pipeline configurations.
        # The context menu actions will be inserted above this saparator.
        self._pipeline_configuration_separator = self._project_menu.addSeparator(
        )
    def __init__(self, parent):
        """
        Constructor
        """
        QtGui.QWidget.__init__(self, parent)

        # make sure this widget isn't shown
        self.setVisible(False)

        # set up the UI
        self.ui = Ui_ThumbWidget()
        self.ui.setupUi(self)

        # set up an event filter to ensure that the thumbnails
        # are scaled in a square fashion.
        filter = ResizeEventFilter(self.ui.thumbnail)
        filter.resized.connect(self.__on_thumb_resized)
        self.ui.thumbnail.installEventFilter(filter)

        # set up action menu
        self._menu = QtGui.QMenu()
        self._actions = []
        self.ui.button.setMenu(self._menu)
        self.ui.button.setVisible(False)
示例#11
0
def get_or_create_shotgun_menu(menu_name):
    """
    Creates or retrieves the Shotgun Menu entry in the Menu bar.
    """
    ctx = sd.getContext()
    app = ctx.getSDApplication()
    uiMgr = app.getQtForPythonUIMgr()

    menu_id = "Pfx.Editor.Menu.%s" % menu_name
    menu = uiMgr.findMenuFromObjectName(menu_id)

    if not menu:
        help_menu = uiMgr.findMenuFromObjectName("Pfx.Editor.Menu.Help")
        main_window = uiMgr.getMainWindow()

        menu_bar = main_window.menuBar()
        menu = QtGui.QMenu(menu_name, menu_bar)
        menu.setObjectName(menu_id)
        if help_menu:
            menu_bar.insertMenu(help_menu.menuAction(), menu)
        else:
            menu_bar.addMenu(menu)

    return menu
 def _add_sub_menu(self, menu_name, parent_menu):
     sub_menu = QtGui.QMenu(title=menu_name, parent=parent_menu)
     parent_menu.addMenu(sub_menu)
     return sub_menu
示例#13
0
    def _create_hiero_menu(self, add_commands=True, commands=None):
        """
        Creates the "Shotgun" menu in Hiero.

        :param bool add_commands: If True, menu commands will be added to the
            newly-created menu. If False, the menu will be created, but no
            contents will be added. Defaults to True.
        :param dict commands: The engine commands to add to the various menus.
            The dictionary is structured the same as engine.commands is, where
            the key is the name of the command, and the value is a dictionary
            of command properties.
        """
        import hiero

        if self._menu_handle is not None:
            self.destroy_menu()

        from sgtk.platform.qt import QtGui

        self._menu_handle = QtGui.QMenu("Shotgun")
        help = hiero.ui.findMenuAction("Cache")
        menuBar = hiero.ui.menuBar()
        menuBar.insertMenu(help, self._menu_handle)

        self._menu_handle.clear()

        # If we were asked not to add any commands to the menu,
        # then bail out.
        if not add_commands:
            return

        # Now add the context item on top of the main menu.
        self._context_menu = self._add_context_menu()
        self._menu_handle.addSeparator()

        if not commands:
            return

        # Now enumerate all items and create menu objects for them.
        menu_items = []
        for (cmd_name, cmd_details) in commands.items():
            menu_items.append(
                HieroAppCommand(self.engine, cmd_name, cmd_details))

        # Now add favourites.
        for fav in self.engine.get_setting("menu_favourites"):
            app_instance_name = fav["app_instance"]
            menu_name = fav["name"]
            # Scan through all menu items.
            for cmd in menu_items:
                if cmd.app_instance_name == app_instance_name and cmd.name == menu_name:
                    # Found our match!
                    cmd.add_command_to_menu(self._menu_handle)
                    # Mark as a favourite item.
                    cmd.favourite = True

        # Get the apps for the various context menus.
        self._context_menus_to_apps = {
            "bin_context_menu": [],
            "timeline_context_menu": [],
            "spreadsheet_context_menu": [],
        }

        remove = set()
        for (key, apps) in self._context_menus_to_apps.iteritems():
            items = self.engine.get_setting(key)
            for item in items:
                app_instance_name = item["app_instance"]
                menu_name = item["name"]
                # Scan through all menu items.
                for (i, cmd) in enumerate(menu_items):
                    if (cmd.app_instance_name == app_instance_name
                            and cmd.name == menu_name):
                        # Found the match.
                        apps.append(cmd)
                        cmd.requires_selection = item["requires_selection"]
                        if not item["keep_in_menu"]:
                            remove.add(i)
                        break

        for index in sorted(remove, reverse=True):
            del menu_items[index]

        # Register for the interesting events.
        hiero.core.events.registerInterest(
            "kShowContextMenu/kBin",
            self.eventHandler,
        )
        hiero.core.events.registerInterest(
            "kShowContextMenu/kTimeline",
            self.eventHandler,
        )
        # Note that the kViewer works differently than the other things
        # (returns a hiero.ui.Viewer object: http://docs.thefoundry.co.uk/hiero/10/hieropythondevguide/api/api_ui.html#hiero.ui.Viewer)
        # so we cannot support this easily using the same principles as for the other things.
        hiero.core.events.registerInterest(
            "kShowContextMenu/kSpreadsheet",
            self.eventHandler,
        )
        self._menu_handle.addSeparator()

        # Now go through all of the menu items.
        # Separate them out into various sections.
        commands_by_app = {}

        for cmd in menu_items:
            if cmd.type == "context_menu":
                cmd.add_command_to_menu(self._context_menu)
            else:
                # Normal menu.
                app_name = cmd.app_name
                if app_name is None:
                    # Unparented app.
                    app_name = "Other Items"
                if not app_name in commands_by_app:
                    commands_by_app[app_name] = []
                commands_by_app[app_name].append(cmd)

        # Now add all apps to main menu.
        self._add_app_menu(commands_by_app)
示例#14
0
	def __init__(self, app):
		"""
		main UI for the Maya Create Ocean options
		"""
		QtGui.QWidget.__init__(self)
		self.app = app
		tk = sgtk.sgtk_from_path("T:/software/bubblebathbay")
		self.editor = self._getEditor()
		 ## To get the step
		context = self.app.context
		debug(self.app, method = 'run_app', message = 'Context Step: %s' % context.step['name'], verbose = False)

		if context.step['name'] == 'FX' or context.step['name'] == 'Additional FX':
			self.editor = 'modelPanel4'

		if self.editor:
			debug(self.app, method = 'Main_UI', message = 'Lauching UI', verbose = False)

			## Setup the paths for the presets and defaults etc...
			scene_path = os.path.abspath(cmds.file(query=True, sn= True))
			debug(self.app, method = 'Main_UI', message = 'scene_path: %s' % scene_path, verbose = False)

			epName = scene_path.split('\\')[3]

			###NOTE NO UNDERSCORES ARE ALLOWED HERE OR THE F*****G THING FAILS MISERABLY!!! FOR ***HOURS*** OF YOUR PRECIOUS LIFE!!
			wakePreset =            'newOceanWakeTexture'
			foamPreset =            'newOceanWakeFoamTexture'
			oceanDefaultPreset =    'oceanDefaultPreset'
			wakeEmitterPreset =     'wakeEmitter.mel'
			foamEmitterPreset =     'foamEmitter.mel'
			hullEmitterPreset =     'hullEmitter.mel'

			## Now work out the published animation fx folder to get the ocean preset from for the published animation so our maya ocean matches after rebuild.
			entity = self.app.context.entity
			debug(self.app, method = 'Main_UI', message = 'entity: %s' % entity, verbose = False)
			debug(self.app, method = 'Main_UI', message = 'context.step["name"]: %s' % context.step['name'], verbose = False)

			## Now get the templates from the shot_step.yml
			## ocean_preset_template: maya_shot_oceanPresets
			## ocean_publish_template: maya_shot_publishOceanCache

			oceanPublishTemplate                = self.app.get_template('ocean_publish_template')
			## maya_shot_oceanPresets: '@presetsRoot/ocean/{presetName}.mel'
			oceanWakePresetTemplate             = self.app.get_template('ocean_preset_template')
			oceanFoamPresetTemplate             = self.app.get_template('ocean_preset_template')
			oceanDefaultPresetTemplate          = self.app.get_template('ocean_preset_template')
			animOceanPublishedPresetTemplate    = self.app.get_template('shotfx_publish_template')
			## maya_shot_publishOceanCache: '@shot_root/publish/fluids/{name}.v{version}.abc'
			debug(self.app, method = 'Main_UI', message = 'ocean_publish_template: %s' % oceanPublishTemplate, verbose = False)
			debug(self.app, method = 'Main_UI', message = 'oceanWakePresetTemplate: %s' % oceanWakePresetTemplate, verbose = False)
			debug(self.app, method = 'Main_UI', message = 'oceanFoamPresetTemplate: %s' % oceanFoamPresetTemplate, verbose = False)
			debug(self.app, method = 'Main_UI', message = 'oceanDefaultPresetTemplate: %s' % oceanDefaultPresetTemplate, verbose = False)
			debug(self.app, method = 'Main_UI', message = 'animOceanPublishedPresetTemplate: %s' % animOceanPublishedPresetTemplate, verbose = False)
			print

			## Now get ready to convert these to / pathing using the r approach
			## CONVERT WAKE TO A PROPER PATH
			self.wakePresetPath = r'%s' % oceanWakePresetTemplate.apply_fields({'presetName' : wakePreset})
			debug(self.app, method = 'Main_UI', message = 'self.wakePresetPath: %s' % self.wakePresetPath.replace('\\', '/'), verbose = False)

			## CONVERT FOAM TO A PROPER PATH
			self.foamPresetPath = r'%s' % oceanFoamPresetTemplate.apply_fields({'presetName' : foamPreset})
			debug(self.app, method = 'Main_UI', message = 'self.foamPresetPath: %s' % self.foamPresetPath.replace('\\', '/'), verbose = False)

			##############################################################
			################ Process ocean preset path for Anim or FX step |  Animation will use default preset, FX will use published preset.
			##############################################################
			isFX = False
			if cmds.objExists('fxNugget'):
				debug(self.app, method = 'Main_UI', message = 'fxNugget found...', verbose = False)

				# getAnimVersionFolders = tk.paths_from_template(animOceanPublishedPresetTemplate, {'id' : entity["id"], 'Shot' : entity["name"]})
				getAnimVersionFolders = tk.paths_from_template(animOceanPublishedPresetTemplate, {'Step' : 'Anm', 'id' : entity["id"], 'Shot' : entity["name"]})
				debug(self.app, method = 'Main_UI', message = 'getAnimVersionFolders: %s' % getAnimVersionFolders, verbose = False)

				highestAnimVerFolder = max(getAnimVersionFolders)
				debug(self.app, method = 'Main_UI', message = 'Path to highest oceanPreset AnimVerFolder: %s' % highestAnimVerFolder, verbose = False)
				if not highestAnimVerFolder:
					cmds.warning('THERE IS NO PUBLISHED OCEAN PRESET FROM ANIMAITON! PLEASE FIX THIS NOW!')

				isFX = True
			else:
				cmds.warning('NO FX NUGGET FOUND!')
				getAnimVersNum = None
				isFX = False

			##############################################################
			################ Now set the preset path properly
			##############################################################
			self.oceanPublishedPresetPath = None
			debug(self.app, method = 'Main_UI', message = 'Figuring out the ocean preset path now...', verbose = False)
			debug(self.app, method = 'Main_UI', message = 'isFX: %s' % isFX, verbose = False)
			if context.step['name'] == 'Anm' or context.step['name'] == 'FX' or context.step['name'] == 'Additional FX' or context.step['name'] == 'Blocking':
				if isFX:
					getMelPreset = [eachMel for eachMel in os.listdir(highestAnimVerFolder) if eachMel.endswith('.mel')]
					debug(self.app, method = 'Main_UI', message = 'getMelPreset: %s' % getMelPreset, verbose = False)

					if not getMelPreset:
						cmds.warning('NO ANIMATION OCEAN PRESET FOUND, USING THE DEFAULT.')
						debug(self.app, method = 'Main_UI', message = 'No published animation ocean preset found!!! Using default! NOT GOOD!', verbose = False)
						self.oceanPublishedPresetPath = r'%s' % oceanDefaultPresetTemplate.apply_fields({'presetName' : oceanDefaultPreset})
						debug(self.app, method = 'Main_UI', message = 'self.oceanPublishedPresetPath: %s'  % self.oceanPublishedPresetPath, verbose = False)
					else:
						presetPath = r'%s\%s' % (highestAnimVerFolder, getMelPreset[0])
						debug(self.app, method = 'Main_UI', message = 'Using published ocean preset: %s' % presetPath, verbose = False)
						self.oceanPublishedPresetPath = presetPath
						debug(self.app, method = 'Main_UI', message = 'self.oceanPublishedPresetPath: %s'  % self.oceanPublishedPresetPath, verbose = False)

				else:
					debug(self.app, method = 'Main_UI', message = 'No getAnimVersionFolders found... must be an animation scene or blocking scene setting default ocean preset template now', verbose = False)
					self.oceanPublishedPresetPath = r'%s' % oceanDefaultPresetTemplate.apply_fields({'presetName' : oceanDefaultPreset})
					debug(self.app, method = 'Main_UI', message = 'self.oceanPublishedPresetPath: %s'  % self.oceanPublishedPresetPath, verbose = False)
			else:
				debug(self.app, method = 'Main_UI', message = 'Context step is %s.' % context.step['name'], verbose = False)
				self.oceanPublishedPresetPath = r'%s' % oceanDefaultPresetTemplate.apply_fields({'presetName' : oceanDefaultPreset})
				debug(self.app, method = 'Main_UI', message = 'self.oceanPublishedPresetPath: %s'  % self.oceanPublishedPresetPath, verbose = False)

			## Now build the UI
			self.mainLayout = QtGui.QVBoxLayout(self)
			## High and Low Tide layout
			self.lowhiLayout = QtGui.QHBoxLayout(self)
			self.highTide = QtGui.QRadioButton('High Tide')
			self.highTide.setChecked(True)
			self.highTide.setEnabled(False)
			self.highTide.hide()
			self.lowTide = QtGui.QRadioButton('Low Tide')
			self.lowTide.setChecked(False)
			self.lowTide.setEnabled(False)
			self.lowTide.hide()
			## Now parent these tot the layout
			self.lowhiLayout.addWidget(self.highTide)
			self.lowhiLayout.addWidget(self.lowTide)
			self.lowhiLayout.addStretch(1)
			debug(self.app, method = 'Main_UI', message = 'lowhiLayout built successfully...', verbose = False)

			## Animation ocean setup
			self.animGroupBox = QtGui.QGroupBox(self)
			self.animGroupBox.setTitle('Animation Ocean Setup:')
			debug(self.app, method = 'Main_UI', message = 'animGroupBox built successfully...', verbose = False)

			self.animLayout = QtGui.QVBoxLayout(self.animGroupBox)
			debug(self.app, method = 'Main_UI', message = 'animLayout built successfully...', verbose = False)

			## Build Base Animation Ocean Setup Button
			self.buildOceanButton = QtGui.QPushButton('Setup Animation Ocean')
			self.buildOceanButton.setStyleSheet("QPushButton {text-align: center; background: dark green; color: white}")
			self.buildOceanButton.pressed.connect(partial(oceanBuilder.buildAnimOcean, self.editor, self.oceanPublishedPresetPath,  self.foamPresetPath.replace('\\', '/'), self.wakePresetPath.replace('\\', '/'), self.highTide.isChecked()))
			debug(self.app, method = 'Main_UI', message = 'self.buildOceanButton connected..', verbose = False)

			## Fetch FX Cache for interactive wake referencing
			self.fetchWakeFromFXButton = QtGui.QPushButton('Fetch Cache from FX')
			self.fetchWakeFromFXButton.setStyleSheet("QPushButton {text-align: center; background: dark orange; color: black}")
			self.fetchWakeFromFXButton.pressed.connect(self.get_shotfx_publish_dirs)
			debug(self.app, method = 'Main_UI', message = 'self.fetchWakeFromFXButton connected..', verbose = False)

			# ## Setup Interactive Ocean On Selected world_ctrl button
			# self.buildInteractiveOceanButton = QtGui.QPushButton('Setup Interactive Ocean On Sel world_ctrl')
			# self.buildInteractiveOceanButton.pressed.connect(self.setupInteractionOcean)
			# self.buildInteractiveOceanButton.setEnabled(False)
			# debug(self.app, method = 'Main_UI', message = 'self.buildInteractiveOceanButton connected..', verbose = False)
			#
			# ## Apply Fluid Emitter Presets button
			# self.buildInteractivePresetsButton = QtGui.QPushButton('Apply Fluid Emitter Presets')
			# self.buildInteractivePresetsButton.pressed.connect(partial(fluidLib._setFluidEmitterPresets, wakeEmitterPreset, foamEmitterPreset, hullEmitterPreset))
			# self.buildInteractivePresetsButton.setEnabled(False)
			# debug(self.app, method = 'Main_UI', message = 'self.buildInteractivePresetsButton connected..', verbose = False)

			self.animLayout.addWidget(self.buildOceanButton)
			self.animLayout.addWidget(self.fetchWakeFromFXButton)
			# self.animLayout.addWidget(self.buildInteractiveOceanButton)
			# self.animLayout.addWidget(self.buildInteractivePresetsButton)
			debug(self.app, method = 'Main_UI', message = 'animLayout built successfully...', verbose = False)

			######################################
			##### FX STUFF
			if context.step['name'] == 'FX' or context.step['name'] == 'Additional FX':
				###############################
				## BUILD THE MAIN BUILD BUTTONS
				###############################
				self.FXBuildGroupBox = QtGui.QGroupBox(self)
				self.FXBuildGroupBox.setTitle('FX Build Stuff:')
				self.mainFXBuildLayout = QtGui.QVBoxLayout(self.FXBuildGroupBox)

				self.hLayout = QtGui.QHBoxLayout(self)
				self.buildFXOceanSetupButton = QtGui.QPushButton('1. Setup FX Ocean')
				self.buildFXOceanSetupButton.pressed.connect(partial(self.setupFXOcean, highestAnimVerFolder))
				self.buildFXOceanSetupButton.setStyleSheet("QPushButton {text-align: center; background: dark green}")

				self.buildPresetsButton = QtGui.QPushButton('2. Apply All Fluid Emitter Presets')
				self.buildPresetsButton.pressed.connect(partial(fluidLib._setFluidEmitterPresets, wakeEmitterPreset, foamEmitterPreset, hullEmitterPreset))
				self.buildPresetsButton.setStyleSheet("QPushButton {text-align: center; background: dark green}")

				# self.buildParticlesPresetsButton = QtGui.QPushButton('3. Apply All Particle Presets')
				# self.buildParticlesPresetsButton.pressed.connect(self._setPresets)
				# self.buildParticlesPresetsButton.setStyleSheet("QPushButton {text-align: center; background: dark green}")

				## Add the buttons to the hLayout
				self.hLayout.addWidget(self.buildFXOceanSetupButton)
				self.hLayout.addWidget(self.buildPresetsButton)
				# self.hLayout.addWidget(self.buildParticlesPresetsButton)
				debug(self.app, method = 'Main_UI', message = 'Added widgets to hLayout', verbose = False)
				self.mainFXBuildLayout.addLayout(self.hLayout)

				###############################
				## BUILD THE MAIN VIEW SWITCHING BUTTONS
				###############################
				self.FXViewGroupBox = QtGui.QGroupBox(self)
				self.FXViewGroupBox.setTitle('Change FX Scene Settings:')
				self.mainFXViewLayout = QtGui.QVBoxLayout(self.FXViewGroupBox)

				self.h2Layout = QtGui.QHBoxLayout(self)
				self._setForRenderButton = QtGui.QPushButton('Apply Render View Settings')
				self._setForRenderButton.pressed.connect(partial(self._setForRender))
				self._setForRenderButton.setStyleSheet("QPushButton {text-align: center; background: dark grey}")

				self._setForFluidsButton = QtGui.QPushButton('Apply Fluid View Settings')
				self._setForFluidsButton.pressed.connect(partial(self._setForFluids))
				self._setForFluidsButton.setStyleSheet("QPushButton {text-align: center; background: dark grey}")

				# self._fetchAnimAlembicButton = QtGui.QPushButton(Icon('alembic.png'), 'Fetch Alembic Anim Caches', self)
				# self._fetchAnimAlembicButton.pressed.connect(partial(self._fetchAlembicCaches, highestAnimVerFolder))
				# self._fetchAnimAlembicButton.setStyleSheet("QPushButton {text-align: center; background: dark grey}")

				## Add the buttons to the h2Layout
				self.h2Layout.addWidget(self._setForRenderButton)
				self.h2Layout.addWidget(self._setForFluidsButton)
				# self.h2Layout.addWidget(self._fetchAnimAlembicButton)
				debug(self.app, method = 'Main_UI', message = 'Added widgets to h2Layout', verbose = False)

				self.mainFXViewLayout.addLayout(self.h2Layout)

				##############################
				##### MAIN SETTINGS UI
				##############################
				self.FXSettingsGroupBox = QtGui.QGroupBox(self)
				self.FXSettingsGroupBox.setTitle('FX Build Settings:')
				self.mainFXLayout = QtGui.QVBoxLayout(self.FXSettingsGroupBox)
				self.optionsVBoxLayout = QtGui.QVBoxLayout(self)

				self.nurbsPreviewOptionsLayout = QtGui.QHBoxLayout()
				##xRes of the NURBSPlane
				self.xResLabel = QtGui.QLabel('zRes')
				self.xRes = QtGui.QDoubleSpinBox()
				self.xRes.setRange(0, 100)
				self.xRes.setSingleStep(1)
				self.xRes.setValue(20)
				##zRes of the NURBSPlane
				self.zResLabel = QtGui.QLabel('zRes')
				self.zRes = QtGui.QDoubleSpinBox()
				self.zRes.setRange(0, 100)
				self.zRes.setSingleStep(1)
				self.zRes.setValue(20)
				debug(self.app, method = 'Main_UI', message = 'Nurbs Preview options built...', verbose = False)

				self.mistPresetLabel = QtGui.QLabel('mist_ParticlePreset')
				self.mistPreset_pullDownMenu = QtGui.QComboBox (self)
				self.mistPreset_pullDownMenu.setMinimumWidth(250)
				self.mistPreset_pullDownMenu.setMaximumHeight(25)

				self.sprayPresetLabel = QtGui.QLabel('spray_ParticlePreset')
				self.sprayPreset_pullDownMenu = QtGui.QComboBox (self)
				self.sprayPreset_pullDownMenu.setMinimumWidth(250)
				self.sprayPreset_pullDownMenu.setMaximumHeight(25)

				self.rearPresetLabel = QtGui.QLabel('rear_ParticlePreset')
				self.rearPreset_pullDownMenu = QtGui.QComboBox (self)
				self.rearPreset_pullDownMenu.setMinimumWidth(250)
				self.rearPreset_pullDownMenu.setMaximumHeight(25)

				## Add the res to the layout
				self.nurbsPreviewOptionsLayout.addWidget(self.xResLabel)
				self.nurbsPreviewOptionsLayout.addWidget(self.xRes)
				self.nurbsPreviewOptionsLayout.addWidget(self.zResLabel)
				self.nurbsPreviewOptionsLayout.addWidget(self.zRes)
				self.nurbsPreviewOptionsLayout.addWidget(self.mistPresetLabel)
				self.nurbsPreviewOptionsLayout.addWidget(self.mistPreset_pullDownMenu)
				self.nurbsPreviewOptionsLayout.addWidget(self.sprayPresetLabel)
				self.nurbsPreviewOptionsLayout.addWidget(self.sprayPreset_pullDownMenu)
				self.nurbsPreviewOptionsLayout.addWidget(self.rearPresetLabel)
				self.nurbsPreviewOptionsLayout.addWidget(self.rearPreset_pullDownMenu)
				self.nurbsPreviewOptionsLayout.addStretch(1)
				debug(self.app, method = 'Main_UI', message = 'Added widgets to nurbsPreviewOptionsLayout', verbose = False)

				self.optionsVBoxLayout .addLayout(self.nurbsPreviewOptionsLayout)


				self.mainFXLayout.addLayout(self.optionsVBoxLayout)
				debug(self.app, method = 'Main_UI', message = 'FXSettingsGroupBox built successfully...', verbose = False)

			#################################
			##############################
			##### OPTIONS BOX BUILD
			self.FXOptionsGroupBox = QtGui.QGroupBox(self)
			self.FXOptionsGroupBox.setTitle('FX Ocean Manual Hookups:')
			self.FXOptionsMainLayout = QtGui.QVBoxLayout(self.FXOptionsGroupBox)

			### MANUAL BUILD BUTTONS
			self.optionshLayout = QtGui.QHBoxLayout()

			# self.connectAllWithOceanButton = QtGui.QPushButton('FX / Connect Height Locks To Ocean')
			# self.connectAllWithOceanButton.pressed.connect(partial(connOH.connectAllWithOceanHeightAttr))
			# debug(self.app, method = 'Main_UI', message = 'self.connectAllWithOceanButton built...', verbose = False)

			#############################################################
			self.connectToOceanButton = QtGui.QToolButton(self)
			self.connectToOceanButton.setPopupMode(QtGui.QToolButton.MenuButtonPopup)
			self.connectToOceanButton.setStyleSheet("QToolButton {text-align: center; background: rgb(100, 100, 100); color: white}")
			connectToOceanButtonStretchPolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed)
			self.connectToOceanButton.setSizePolicy(connectToOceanButtonStretchPolicy)
			self.connectToOceanButton.setText('All Ocean Hookup')
			self.connectToOceanButton.setMenu( QtGui.QMenu(self.connectToOceanButton) )
			self.connectToOceanButton.clicked.connect(self.connectOceanHeights)

			self.connectToOceanListWidget = QtGui.QListWidget()
			self.connectToOceanListWidget.setFixedHeight(60)
			self.connectToOceanListWidget.addItem('Dock')
			self.connectToOceanListWidget.addItem('Boat')
			self.connectToOceanListWidget.addItem('Prop')
			self.connectToOceanListWidget.addItem('All')
			self.connectToOceanListWidget.clicked.connect(self.connectToOceanButtonText)

			self.connectToOceanAction = QtGui.QWidgetAction(self.connectToOceanButton)
			self.connectToOceanAction.setDefaultWidget(self.connectToOceanListWidget)
			self.connectToOceanButton.menu().addAction(self.connectToOceanAction)
			#############################################################

			if context.step['name'] == 'FX' or context.step['name'] == 'Additional FX':
				self.animShaderIntersectButton = QtGui.QPushButton('Anim Intersect')
				self.animShaderIntersectButton.pressed.connect( partial( fluidLib._intersect_animShader_expression ) )
				debug(self.app, method = 'Main_UI', message = 'self.animShaderIntersectButton built...', verbose = False)

				self.dispShaderIntersectButton = QtGui.QPushButton('Disp Intersect')
				self.dispShaderIntersectButton.pressed.connect( partial( fluidLib._intersect_dispShader_expression ) )
				debug(self.app, method = 'Main_UI', message = 'self.dispShaderIntersectButton built...', verbose = False)

				self.linkEmittersButton = QtGui.QPushButton('FX / Link Emitters To Ocean')
				self.linkEmittersButton.pressed.connect(partial(fluidLib._linkWakeEmitters))
				debug(self.app, method = 'Main_UI', message = 'self.linkEmittersButton built...', verbose = False)

			self.optionshLayout.addWidget(self.connectToOceanButton)

			## Add the buttons to the optionshLayout
			if context.step['name'] == 'FX' or context.step['name'] == 'Additional FX':
				self.optionshLayout.addWidget(self.animShaderIntersectButton)
				self.optionshLayout.addWidget(self.dispShaderIntersectButton)
				self.optionshLayout.addWidget(self.linkEmittersButton)

			### Now parent the FXOption layouts to the options main VBoxLayout
			self.FXOptionsMainLayout.addLayout(self.optionshLayout)

			###############################
			## FX INTERACTIVE SECTION
			###############################

			if context.step['name'] == 'FX' or context.step['name'] == 'Additional FX':
				## MAIN SECTION
				self.FXInteractiveGroupBox = QtGui.QGroupBox(self)
				self.FXInteractiveGroupBox.setTitle('FX Interactive:')
				self.FXInteractiveMainLayout = QtGui.QVBoxLayout(self.FXInteractiveGroupBox)

				## MAIN LAYOUT
				self.FXInteractiveLayout = QtGui.QHBoxLayout()

				## SETUP BUTTONS
				self.cacheFluidsButton = QtGui.QPushButton('Cache fluids')
				self.cacheFluidsButton.pressed.connect(fc.cacheFluidsToCTemp)
				self.cacheFluidsButton.setStyleSheet("QPushButton {text-align: center; background: dark orange; color: black}")
				# self.cacheFluidsButton.setEnabled(False)

				self.previewInteractiveButton = QtGui.QPushButton('Preview Interactive')
				self.previewInteractiveButton.pressed.connect(fc.previewInteractiveCaches)
				self.previewInteractiveButton.setStyleSheet("QPushButton {text-align: center; background: dark orange; color: black}")
				# self.previewInteractiveButton.setEnabled(False)

				self.cleanupCacheFilesButton = QtGui.QPushButton('Cleanup fluids caches')
				self.cleanupCacheFilesButton.setStyleSheet("QPushButton {text-align: center; background: dark orange; color: black}")
				self.cleanupCacheFilesButton.pressed.connect(fc.deleteCaches)
				# self.cleanupCacheFilesButton.setEnabled(False)

				self.cleanupICacheFilesButton = QtGui.QPushButton('Cleanup interactive caches')
				self.cleanupICacheFilesButton.setStyleSheet("QPushButton {text-align: center; background: dark orange; color: black}")
				self.cleanupICacheFilesButton.pressed.connect(fc.deleteInteractiveCaches)
				# self.cleanupICacheFilesButton.setEnabled(False)

				## ADD BUTTON TO LAYOUT
				self.FXInteractiveLayout.addWidget(self.cacheFluidsButton)
				self.FXInteractiveLayout.addWidget(self.previewInteractiveButton)
				self.FXInteractiveLayout.addWidget(self.cleanupCacheFilesButton)
				self.FXInteractiveLayout.addWidget(self.cleanupICacheFilesButton)

				## Now parent the FXOption layouts to the options main VBoxLayout
				self.FXInteractiveMainLayout.addLayout(self.FXInteractiveLayout)

			###############################
			## BUILD THE FX LIBRARY STUFFS
			###############################

			if context.step['name'] == 'FX' or context.step['name'] == 'Additional FX':
				self.FXLibGroupBox = QtGui.QGroupBox(self)
				self.FXLibGroupBox.setTitle('FX Library:')
				self.FXLibMainLayout = QtGui.QVBoxLayout(self.FXLibGroupBox)

				### HORIZONTAL BOX LAYOUT
				self.fxLibshLayout = QtGui.QGridLayout()

				j = 0
				pos =   [
						(0, 0), (0, 1), (0, 2), (0, 3), (0, 4),
						(1, 0), (1, 1), (1, 2), (1, 3), (1, 4),
						(2, 0), (2, 1), (2, 2), (2, 3), (2, 4),
						(3, 0), (3, 1), (3, 2), (3, 3), (3, 4),
						(4, 0), (4, 1), (4, 2), (4, 3), (4, 4),
						]

				fxNames = [('Boat Splash', fxLib.splashRigger, 'Creates a spherical volumetric emitter that emits sprite as splashes'),
						   ('Splash Tool v1.0', self.openSplashTool,'working'),
						   ('Bubble on selected Mesh(s)', fxLib.bubbleSetup, 'Creates bubble setup on selected mesh'),
						   ('Kill Field', fxLib.nParticle_killField, 'How it works?\n    - Creates a uniform field (change-able) volume shapes that kills any particles when in contact.\n    - LifespanPP expression line added into runtime after dynamics of nParticleShape.\n    - Lifespan mode needs to be changed to lifespanPP in order to work.\n\nUsage\n    - Select nParticle(s) and click button.'),
						   ('Wake / Foam Emitter', fluidLib._addWakeEmitter),
						   ('-', fxLib._underConstruction),
						   ('-', fxLib._underConstruction),
						   ('-', fxLib._underConstruction),
						   ('-', fxLib._underConstruction),
						   ('-', fxLib._underConstruction),
						   ]

				for fxName in fxNames:
					buttonName = fxName[0]
					buttonFunc = fxName[1]
					buttonToolTip = fxName[2] if len(fxName) == 3 else None

					button = QtGui.QPushButton(buttonName)
					button.pressed.connect( partial(buttonFunc) )
					if buttonToolTip:
						button.setToolTip(buttonToolTip)

					self.fxLibshLayout.addWidget(button, pos[j][0], pos[j][1])
					j += 1

				### Now parent the FXOption layouts to the options main VBoxLayout
				self.FXLibMainLayout.addLayout(self.fxLibshLayout)

			###############################

			## Delete Ocean Setup
			self.deleteButton = QtGui.QPushButton('Delete Ocean Setup!')
			self.deleteButton.setFlat(False)
			self.deleteButton.pressed.connect(partial(fxLib.removeOceanSetup, context.step["name"]))
			self.deleteButton.setStyleSheet("QPushButton {text-align: center; background: dark red; color: black}")

			## Now add to the mainLayout
			debug(self.app, method = 'Main_UI', message = 'Parenting widgets....', verbose = False)
			self.mainLayout.addLayout(self.lowhiLayout)
			self.mainLayout.addWidget(self.animGroupBox)

			if context.step['name'] == 'FX' or context.step['name'] == 'Additional FX':
				self.mainLayout.addWidget(self.FXBuildGroupBox)
				self.mainLayout.addWidget(self.FXViewGroupBox)
				self.mainLayout.addWidget(self.FXSettingsGroupBox)
				self.mainLayout.addWidget(self.FXLibGroupBox)
				self.mainLayout.addWidget(self.FXInteractiveGroupBox)
				## Hide the build settings atm because we're not using them
				self.FXSettingsGroupBox.hide()

			self.mainLayout.addWidget(self.FXOptionsGroupBox)
			self.mainLayout.addWidget(self.deleteButton)
			self.mainLayout.addStretch(1)
			self.resize(50,120)

			if context.step['name'] == 'FX' or context.step['name'] == 'Additional FX':
				self.animGroupBox.hide()
				self.populatePulldowns()
				debug(app = self.app, method = 'Main_UI', message= 'self.xRes.value(): %s' % self.xRes.value(), verbose = False)
				debug(app = self.app, method = 'Main_UI', message= 'self.zRes.value(): %s' % self.zRes.value(), verbose = False)
			debug(self.app, method = 'Main_UI', message = 'UI Build SUCCESS.', verbose = False)
		else:
			QtGui.QMessageBox.information(None, "Aborted...", 'You must have active a current 3D viewport! \nRight click the viewport to build from as we need to use the camera information.')
			self.parent.close()
示例#15
0
    def process_result(self, result):
        """
        Process list of tasks retrieved by get_data on the main thread
        
        :param result:  Dictionary containing the various display & grouping options required to build the
                        file list as well as the list of files organised by task.        
        """
        if FileListView.DEBUG_GET_DATA_IN_MAIN_THREAD:
            # gathering of data was not done in the get_data stage so we
            # should do it here instead - this method gets called in the 
            # main thread
            result = self._get_data(result)
        
        task_groups = result["task_groups"]
        task_name_order = result["task_name_order"]
        task_order = result["task_order"]
        current_task_name = result["current_task_name"]
        self._current_filter = result["filter"]
        
        self._update_title()
        
        if not task_groups:
            # build a useful error message using the info we have available:
            msg = ""
            if not result["can_change_work_area"]:
                if not result["have_valid_workarea"]:
                    msg = "The current Work Area is not valid!"
                elif not result["have_valid_configuration"]:
                    msg = ("Shotgun File Manager has not been configured for the environment "
                           "being used by the selected Work Area!")
                elif not result["can_do_new_file"]:
                    msg = "Couldn't find any files in this Work Area!"
                else:
                    msg = "Couldn't find any files!\nClick the New file button to start work."
            else:
                if not result["have_valid_workarea"]:
                    msg = "The current Work Area is not valid!"
                elif not result["have_valid_configuration"]:
                    msg = ("Shotgun File Manager has not been configured for the environment "
                           "being used by the selected Work Area!\n"
                           "Please choose a different Work Area to continue.")
                elif not result["can_do_new_file"]:
                    msg = "Couldn't find any files in this Work Area!\nTry selecting a different Work Area."
                else:
                    msg = "Couldn't find any files!\nClick the New file button to start work."
            self.set_message(msg)
            return
        
        for task_name in task_order:
            name_groups = task_groups[task_name]
        
            if (len(task_groups) > 1 
                or (task_name != current_task_name
                    and task_name != FileListView.NO_TASK_NAME 
                    and current_task_name == None)):
                # add header for task:
                h = self.add_item(browser_widget.ListHeader)
                h.set_title("%s" % (task_name))
            
            ordered_names = task_name_order[task_name]
            for name in ordered_names:
                details = name_groups[name]
                
                files = details["files"]
                highest_local_file = details.get("highest_local_file")
                highest_publish_file = details.get("highest_publish_file")
                thumbnail = details["thumbnail"]
                
                # add new item to list:
                item = self._add_file_item(highest_publish_file, highest_local_file)
                if not item:
                    continue
                
                # set thumbnail if have one:
                if thumbnail:
                    item.set_thumbnail(thumbnail)
                
                # add context menu:
                item.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)

                # if it's a publish then add 'View In Shotgun' item:
                if highest_publish_file:
                    action = QtGui.QAction("View latest Publish in Shotgun", item)
                    # (AD) - the '[()]' syntax in action.triggered[()].connect looks weird right!
                    # 'triggered' is a QtCore.SignalInstance which actually defines multiple
                    # signals: triggered() & triggered(bool).  PySide will correctly determine which
                    # one to use but PyQt gets confused and calls the (bool) version instead which
                    # causes problems for us...  Luckily, Qt lets us use the argument list () to 
                    # index into the SignalInstance object to force the use of the non-bool version - yay!
                    action.triggered[()].connect(lambda f=highest_publish_file: self._on_show_in_shotgun_action_triggered(f))
                    item.addAction(action)

                # build context menu for all publish versions:                
                published_versions = [f.version for f in files.values() if f.is_published and isinstance(f.version, int)]
                if published_versions:
                    
                    published_versions.sort(reverse=True)
                    
                    publishes_action = QtGui.QAction("Open Publish Read-Only", item)
                    publishes_sm = QtGui.QMenu(item)
                    publishes_action.setMenu(publishes_sm)
                    item.addAction(publishes_action)    
                     
                    for v in published_versions[:20]:
                        f = files[v]
                        msg = ("v%03d" % f.version)
                        action = QtGui.QAction(msg, publishes_sm)
                        # see above for explanation of [()] syntax in action.triggered[()].connect...
                        action.triggered[()].connect(lambda f=f: self._on_open_publish_action_triggered(f))
                        publishes_sm.addAction(action)
                     
                # build context menu for all work files:
                wf_versions = [f.version for f in files.values() if f.is_local and isinstance(f.version, int)]
                if wf_versions:
                    
                    wf_versions.sort(reverse=True)
                    
                    wf_action = QtGui.QAction("Open Work File", item)
                    wf_sm = QtGui.QMenu(item)
                    wf_action.setMenu(wf_sm)
                    item.addAction(wf_action)    
                     
                    for v in wf_versions[:20]:
                        f = files[v]
                        msg = ("v%03d" % f.version)
                        action = QtGui.QAction(msg, wf_sm)
                        # see above for explanation of [()] syntax in action.triggered[()].connect...
                        action.triggered[()].connect(lambda f=f: self._on_open_workfile_action_triggered(f))
                        wf_sm.addAction(action)                
示例#16
0
    def __init__(self, parent=None):
        SystrayWindow.__init__(self, parent)

        # initialize member variables
        self.current_project = None
        self.__activation_hotkey = None
        self.__pipeline_configuration_separator = None
        self._settings_manager = settings.UserSettings(
            sgtk.platform.current_bundle())

        # setup the window
        self.ui = desktop_window.Ui_DesktopWindow()
        self.ui.setupUi(self)
        self.project_overlay = overlay_widget.ShotgunOverlayWidget(
            self.ui.project_commands)
        self.setup_project_widget = SetupProject(self.ui.project_commands)
        self.setup_project_widget.setup_finished.connect(
            self._on_setup_finished)
        self.update_project_config_widget = UpdateProjectConfig(
            self.ui.project_commands)
        self.update_project_config_widget.update_finished.connect(
            self._on_update_finished)
        self.setup_new_os_widget = SetupNewOS(self.ui.project_commands)

        # setup systray behavior
        self.set_content_layout(self.ui.border_layout)
        self.set_drag_widgets([self.ui.header, self.ui.footer])

        self.systray_state_changed.connect(self.handle_systray_state_changed)
        QtGui.QApplication.instance().setQuitOnLastWindowClosed(False)

        # Setup header buttons
        self.ui.apps_button.setProperty("active", True)
        self.ui.apps_button.style().unpolish(self.ui.apps_button)
        self.ui.apps_button.style().polish(self.ui.apps_button)

        engine = sgtk.platform.current_engine()

        connection = engine.get_current_user().create_sg_connection()

        # Setup the console
        self.__console = Console()
        self.__console_handler = ConsoleLogHandler(self.__console)
        engine.add_logging_handler(self.__console_handler)

        # User menu
        ###########################
        user = engine.get_current_login()
        current_user = connection.find_one("HumanUser",
                                           [["id", "is", user["id"]]],
                                           ["image", "name"])
        self._current_user_id = user["id"]
        thumbnail_url = current_user.get("image")
        if thumbnail_url is not None:
            (_, thumbnail_file) = tempfile.mkstemp(suffix=".jpg")
            try:
                shotgun.download_url(connection, thumbnail_url, thumbnail_file)
                pixmap = QtGui.QPixmap(thumbnail_file)
                self.ui.user_button.setIcon(QtGui.QIcon(pixmap))
            except Exception:
                # if it fails for any reason, that's alright
                pass
            finally:
                try:
                    os.remove(thumbnail_file)
                except Exception:
                    pass

        # populate user menu
        self.user_menu = QtGui.QMenu(self)
        name_action = self.user_menu.addAction(current_user["name"])
        url_action = self.user_menu.addAction(
            connection.base_url.split("://")[1])
        self.user_menu.addSeparator()
        self.user_menu.addAction(self.ui.actionPin_to_Menu)
        self.user_menu.addAction(self.ui.actionKeep_on_Top)
        self.user_menu.addAction(self.ui.actionShow_Console)
        self.user_menu.addAction(self.ui.actionRefresh_Projects)
        about_action = self.user_menu.addAction("About...")
        self.user_menu.addSeparator()
        self.user_menu.addAction(self.ui.actionSign_Out)
        self.user_menu.addAction(self.ui.actionQuit)

        name_action.triggered.connect(self.open_site_in_browser)
        url_action.triggered.connect(self.open_site_in_browser)
        about_action.triggered.connect(self.handle_about)

        QtGui.QApplication.instance().aboutToQuit.connect(
            self.handle_quit_action)

        self.ui.actionPin_to_Menu.triggered.connect(self.toggle_pinned)
        self.ui.actionKeep_on_Top.triggered.connect(self.toggle_keep_on_top)
        self.ui.actionShow_Console.triggered.connect(
            self.__console.show_and_raise)
        self.ui.actionRefresh_Projects.triggered.connect(
            self.handle_project_refresh_action)
        self.ui.actionSign_Out.triggered.connect(self.sign_out)
        self.ui.actionQuit.triggered.connect(self.handle_quit_action)

        self.ui.user_button.setMenu(self.user_menu)

        # Initialize the model to track project commands
        self._project_command_model = ProjectCommandModel(self)
        self._project_command_proxy = ProjectCommandProxyModel(self)
        self._project_command_proxy.setSourceModel(self._project_command_model)
        self._project_command_proxy.sort(0)
        self.ui.project_commands.setModel(self._project_command_proxy)

        # limit how many recent commands are shown
        self._project_command_proxy.set_recents_limit(6)

        self._project_command_delegate = ProjectCommandDelegate(
            self.ui.project_commands)
        self.ui.project_commands.setItemDelegate(
            self._project_command_delegate)
        self.ui.project_commands.expanded_changed.connect(
            self.handle_project_command_expanded_changed)

        # fix for floating delegate bug
        # see discussion at https://stackoverflow.com/questions/15331256
        self.ui.project_commands.verticalScrollBar().valueChanged.connect(
            self.ui.project_commands.updateEditorGeometries)

        self._project_command_model.command_triggered.connect(
            engine._handle_button_command_triggered)

        # load and initialize cached projects
        self._project_model = SgProjectModel(self, self.ui.projects)
        self._project_proxy = SgProjectModelProxy(self)

        # hook up sorting/filtering GUI
        self._project_proxy.setSourceModel(self._project_model)
        self._project_proxy.sort(0)
        self.ui.projects.setModel(self._project_proxy)

        # tell our project view to use a custom delegate to produce widgets
        self._project_delegate = \
            SgProjectDelegate(self.ui.projects, QtCore.QSize(130, 150))
        self.ui.projects.setItemDelegate(self._project_delegate)

        # handle project selection change
        self._project_selection_model = self.ui.projects.selectionModel()
        self._project_selection_model.selectionChanged.connect(
            self._on_project_selection)

        # handle project data updated
        self._project_model.data_refreshed.connect(
            self._handle_project_data_changed)

        self.ui.actionProject_Filesystem_Folder.triggered.connect(
            self.on_project_filesystem_folder_triggered)

        # setup project search
        self._search_x_icon = QtGui.QIcon(":/tk-desktop/icon_inbox_clear.png")
        self._search_magnifier_icon = QtGui.QIcon(
            ":/tk-desktop/search_transparent.png")
        self.ui.search_button.clicked.connect(self.search_button_clicked)
        self.ui.search_text.textChanged.connect(self.search_text_changed)
        self.search_button_clicked()

        self.project_carat_up = QtGui.QIcon(":tk-desktop/up_carat.png")
        self.project_carat_down = QtGui.QIcon(":tk-desktop/down_carat.png")
        self.down_arrow = QtGui.QIcon(":tk-desktop/down_arrow.png")
        self.right_arrow = QtGui.QIcon(":tk-desktop/right_arrow.png")

        self.ui.project_arrow.clicked.connect(
            self._on_back_to_projects_clicked)

        self.clear_app_uis()

        self.ui.shotgun_button.clicked.connect(self.open_site_in_browser)
        self.ui.shotgun_button.setToolTip("Open Shotgun in browser.\n%s" %
                                          connection.base_url)

        self._project_model.thumbnail_updated.connect(
            self.handle_project_thumbnail_updated)

        self._load_settings()
示例#17
0
 def __init__(self, engine, menu_name):
     self._engine = engine
     self._menu_name = menu_name
     self._handle = QtGui.QMenu(self._menu_name)