def on_show_prompt_instance_delay_menu(self):
        prompt_instance_state = cmds.optionVar(query='MTT_prompt_instance_state')

        if prompt_instance_state == PROMPT_INSTANCE_WAIT:
            elapsed_time = time() - cmds.optionVar(query='MTT_prompt_instance_suspend')
            if elapsed_time > PROMPT_INSTANCE_WAIT_DURATION:
                prompt_instance_state = PROMPT_INSTANCE_ASK
                cmds.optionVar(iv=['MTT_prompt_instance_state', prompt_instance_state])
            else:
                mtt_log('Remaining %.2fs' % (PROMPT_INSTANCE_WAIT_DURATION - elapsed_time))
        elif prompt_instance_state == PROMPT_INSTANCE_SESSION:
            if 'mtt_prompt_session' not in __main__.__dict__:
                prompt_instance_state = PROMPT_INSTANCE_ASK
                cmds.optionVar(iv=['MTT_prompt_instance_state', prompt_instance_state])

        self.instance_menu.clear()

        prompt_delay = QActionGroup(self)
        prompt_delay.setExclusive(True)
        for i in range(len(PROMPT_INSTANCE_STATE.keys())):
            current_delay_action = QAction(PROMPT_INSTANCE_STATE[i], prompt_delay)
            current_delay_action.setCheckable(True)
            current_delay_action.setChecked(prompt_instance_state == i)
            current_delay_action.triggered.connect(
                partial(self.view.on_choose_instance_delay, i, prompt=i != 0))
            self.instance_menu.addAction(current_delay_action)
示例#2
0
    def rename_maya_node(self, node_name, wanted_name, deferred=False):
        """ Rename node and return new name

        :param node_name:
        :param wanted_name:
        :param deferred:
        :return:
        """

        if cmds.lockNode(node_name, query=True, lock=True)[0] \
                or cmds.referenceQuery(node_name, isNodeReferenced=True):
            mtt_log('%s is locked, cannot perform rename' % node_name,
                    verbose=False)
            return node_name

        wanted_name = self.validate_node_name(wanted_name)

        # get node namespace if exists and prefix wanted name
        if ':' in node_name:
            namespace = '{}:'.format(node_name.rsplit(':', 1)[0])
            if not wanted_name.startswith(namespace):
                wanted_name = namespace + wanted_name

        if deferred:
            cmd = 'import maya.cmds as cmds;cmds.rename("%s", "%s")' % (
                node_name, wanted_name)
            return cmds.evalDeferred(cmd)
        else:
            return cmds.rename(node_name, wanted_name)
    def on_show_prompt_instance_delay_menu(self):
        prompt_instance_state = cmds.optionVar(
            query='MTT_prompt_instance_state')

        if prompt_instance_state == PROMPT_INSTANCE_WAIT:
            elapsed_time = time() - cmds.optionVar(
                query='MTT_prompt_instance_suspend')
            if elapsed_time > PROMPT_INSTANCE_WAIT_DURATION:
                prompt_instance_state = PROMPT_INSTANCE_ASK
                cmds.optionVar(
                    iv=['MTT_prompt_instance_state', prompt_instance_state])
            else:
                mtt_log('Remaining %.2fs' %
                        (PROMPT_INSTANCE_WAIT_DURATION - elapsed_time))
        elif prompt_instance_state == PROMPT_INSTANCE_SESSION:
            if 'mtt_prompt_session' not in __main__.__dict__:
                prompt_instance_state = PROMPT_INSTANCE_ASK
                cmds.optionVar(
                    iv=['MTT_prompt_instance_state', prompt_instance_state])

        self.instance_menu.clear()

        prompt_delay = QActionGroup(self)
        prompt_delay.setExclusive(True)
        for i in range(len(PROMPT_INSTANCE_STATE.keys())):
            current_delay_action = QAction(PROMPT_INSTANCE_STATE[i],
                                           prompt_delay)
            current_delay_action.setCheckable(True)
            current_delay_action.setChecked(prompt_instance_state == i)
            current_delay_action.triggered.connect(
                partial(self.view.on_choose_instance_delay, i, prompt=i != 0))
            self.instance_menu.addAction(current_delay_action)
示例#4
0
    def rename_maya_node(self, node_name, wanted_name, deferred=False):
        """ Rename node and return new name

        :param node_name:
        :param wanted_name:
        :param deferred:
        :return:
        """

        if cmds.lockNode(node_name, query=True, lock=True)[0] \
                or cmds.referenceQuery(node_name, isNodeReferenced=True):
            mtt_log('%s is locked, cannot perform rename' % node_name,
                    verbose=False)
            return node_name

        wanted_name = self.validate_node_name(wanted_name)

        # get node namespace if exists and prefix wanted name
        if ':' in node_name:
            namespace = '{}:'.format(node_name.rsplit(':', 1)[0])
            if not wanted_name.startswith(namespace):
                wanted_name = namespace + wanted_name

        if deferred:
            cmd = 'import maya.cmds as cmds;cmds.rename("%s", "%s")' % (
                node_name, wanted_name)
            return cmds.evalDeferred(cmd)
        else:
            return cmds.rename(node_name, wanted_name)
示例#5
0
 def database_dump_sql(self):
     sql_file = os.path.join(os.path.dirname(__file__), 'debug_db.sql')
     with open(sql_file, 'w') as f:
         for line in self.db.iterdump():
             f.write('%s\n' % line)
     mtt_log('SQL Dump write into : %s' % sql_file, add_tag='DEBUG',
             verbose=False)
     cmds.launchImageEditor(viewImageFile=os.path.dirname(__file__))
示例#6
0
 def database_dump_sql(self):
     sql_file = os.path.join(os.path.dirname(__file__), 'debug_db.sql')
     with open(sql_file, 'w') as f:
         for line in self.db.iterdump():
             f.write('%s\n' % line)
     mtt_log('SQL Dump write into : %s' % sql_file,
             add_tag='DEBUG',
             verbose=False)
     cmds.launchImageEditor(viewImageFile=os.path.dirname(__file__))
示例#7
0
 def show_image(self, texture_path):
     if os.path.isfile(texture_path):
         self.texture_path = texture_path
         self.graphics_view.is_loading_fail = False
         self.update_status(is_loading=True)
         QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
         self.graphics_view.show_texture(texture_path)
         QApplication.restoreOverrideCursor()
     else:
         self.texture_path = None
         mtt_log('File not found.', add_tag='VIEWER', msg_type='warning', verbose=False)
         self.graphics_view.is_loading_fail = True
         self.graphics_view.reset_image()
 def show_image(self, texture_path):
     if os.path.isfile(texture_path):
         self.texture_path = texture_path
         self.graphics_view.is_loading_fail = False
         self.update_status(is_loading=True)
         QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
         self.graphics_view.show_texture(texture_path)
         QApplication.restoreOverrideCursor()
     else:
         self.texture_path = None
         mtt_log('File not found.',
                 add_tag='VIEWER',
                 msg_type='warning',
                 verbose=False)
         self.graphics_view.is_loading_fail = True
         self.graphics_view.reset_image()
示例#9
0
    def database_dump_csv(self):
        c = self.db.cursor()
        c.execute('SELECT * FROM NodesTable as N '
                  'LEFT JOIN FilesTable as F ON N.FileId=F.FileId '
                  'LEFT JOIN RefTable as R ON N.RefName=R.RefName')

        import csv
        file_path = os.path.join(os.path.dirname(__file__), 'debug_db.csv')
        csv_file = open(file_path, "w")
        csv_file_writer = csv.writer(csv_file, delimiter=';')
        csv_file_writer.writerows(c.fetchall())
        csv_file.close()
        mtt_log('CSV Dump write into : %s' % file_path,
                add_tag='DEBUG',
                verbose=False)
        cmds.launchImageEditor(viewImageFile=os.path.dirname(__file__))
示例#10
0
    def database_dump_csv(self):
        c = self.db.cursor()
        c.execute(
            'SELECT * FROM NodesTable as N '
            'LEFT JOIN FilesTable as F ON N.FileId=F.FileId '
            'LEFT JOIN RefTable as R ON N.RefName=R.RefName')

        import csv
        file_path = os.path.join(os.path.dirname(__file__), 'debug_db.csv')
        csv_file = open(file_path, "w")
        csv_file_writer = csv.writer(csv_file, delimiter=';')
        csv_file_writer.writerows(c.fetchall())
        csv_file.close()
        mtt_log('CSV Dump write into : %s' % file_path, add_tag='DEBUG',
                verbose=False)
        cmds.launchImageEditor(viewImageFile=os.path.dirname(__file__))
示例#11
0
    def export_as_csv(self):
        """ Export texture listing in csv file """
        file_content = self.get_database_content_as_csv()

        # check if current scene is empty
        if not file_content:
            mtt_log('Nothing to save. Operation aborted.',
                    msg_type='warning',
                    verbose=False)
            return

        # clean output
        convert_nicename = {n: t for t, n, a in MTTSettings.SUPPORTED_TYPE}
        for i, row in enumerate(file_content):
            node_type = convert_nicename[row[1]]
            ref_str = 'True' if row[2] == 1 else ''
            missing_str = 'True' if row[3] == -1 else ''
            file_content[i] = (row[0], node_type, ref_str, missing_str, row[4],
                               row[5])

        # query file to write
        scene_name = os.path.basename(cmds.file(query=True, sceneName=True))
        file_path = os.path.join(
            cmds.workspace(query=True, rootDirectory=True), scene_name)
        csv_path = cmds.fileDialog2(fileFilter='Texture List (*.csv)',
                                    caption='Save Texture List',
                                    startingDirectory=file_path,
                                    fileMode=0)

        # fill file
        if csv_path is not None:
            import csv
            file_path = csv_path[0]
            scene_name = cmds.file(q=True, sceneName=True) or 'Scene UNTITLED'
            with open(file_path, "w") as csv_file:
                csv_file_writer = csv.writer(csv_file, delimiter=';')
                csv_file_writer.writerow([scene_name])
                csv_file_writer.writerow([
                    'NODE NAME', 'NODE TYPE', 'IS REF', 'MISSING',
                    'INSTANCE COUNT', 'FILE PATH'
                ])
                csv_file_writer.writerows(file_content)
                csv_file.close()
                mtt_log('CSV file saved to %s' % file_path, verbose=False)
                cmds.launchImageEditor(
                    viewImageFile=os.path.dirname(file_path))
def create_nodes(define_path='', define_type=None):
    dialog = MTTFilterFileDialog(
        define_path=define_path, define_type=define_type)

    if dialog.exec_():
        files = dialog.get_selected_files()
        node_type = dialog.get_node_type()
        node_attr = [
            attr
            for (n_type, nice, attr) in MTTSettings.SUPPORTED_TYPE
            if node_type == n_type][0]

        current_selection = cmds.ls(selection=True)
        MTTSettings.set_value('suspendRenameCallbacks', True)

        nodes = list()
        for f in files:
            n_name = os.path.basename(f).rsplit('.')[0]
            node_name = n_name if not n_name[0].isdigit() else '_%s' % n_name
            new_node = cmds.shadingNode(node_type, name=node_name, asTexture=1)
            convert = MTTSettings.value('forceRelativePath')

            if convert:
                f = convert_to_relative_path(f)

            set_attr(new_node, node_attr, f, attr_type='string')

            if MTTSettings.IMPORT_POLICY:
                try:
                    exec MTTSettings.IMPORT_POLICY
                    exec_import_policy(
                        current_selection, node_name, os.path.basename(f)
                    )

                except RuntimeError:
                    mtt_log('Fail to run import policy.', msg_type='error',
                            verbose=False)

            nodes.append(new_node)

        MTTSettings.set_value('suspendRenameCallbacks', False)
        MTTSettings.remove('suspendRenameCallbacks')
        if nodes:
            cmds.select(nodes, replace=True)

    dialog.deleteLater()
def create_nodes(define_path='', define_type=None):
    dialog = MTTFilterFileDialog(define_path=define_path,
                                 define_type=define_type)

    if dialog.exec_():
        files = dialog.get_selected_files()
        node_type = dialog.get_node_type()
        node_attr = [
            attr for (n_type, nice, attr) in MTTSettings.SUPPORTED_TYPE
            if node_type == n_type
        ][0]

        current_selection = cmds.ls(selection=True)
        MTTSettings.set_value('suspendRenameCallbacks', True)

        nodes = list()
        for f in files:
            n_name = os.path.basename(f).rsplit('.')[0]
            node_name = n_name if not n_name[0].isdigit() else '_%s' % n_name
            new_node = cmds.shadingNode(node_type, name=node_name, asTexture=1)
            convert = MTTSettings.value('forceRelativePath')

            if convert:
                f = convert_to_relative_path(f)

            set_attr(new_node, node_attr, f, attr_type='string')

            if MTTSettings.IMPORT_POLICY:
                try:
                    exec MTTSettings.IMPORT_POLICY
                    exec_import_policy(current_selection, node_name,
                                       os.path.basename(f))

                except RuntimeError:
                    mtt_log('Fail to run import policy.',
                            msg_type='error',
                            verbose=False)

            nodes.append(new_node)

        MTTSettings.set_value('suspendRenameCallbacks', False)
        MTTSettings.remove('suspendRenameCallbacks')
        if nodes:
            cmds.select(nodes, replace=True)

    dialog.deleteLater()
示例#14
0
 def __init__(self, watcher=None):
     """ Init model """
     QAbstractTableModel.__init__(self)
     self.table_view = None
     self.watcher = watcher
     self.watcher.fileChanged.connect(self.file_watch_file_change)
     self.watcher.directoryChanged.connect(self.file_watch_directory_change)
     self.is_reloading_file = False
     self.suspend_force_sort = False
     self.supported_format_dict = dict(
         [(n_type, nodeAttr) for n_type, nice, nodeAttr in MTTSettings.SUPPORTED_TYPE])
     self.db = None
     # create database table
     try:
         self._database_create_table()
     except sqlite3.Error, e:
         mtt_log('Error init DB :\n\t>> %s <<\n' % e, msg_type='error',
                 verbose=False)
         sys.exit(1)
示例#15
0
    def export_as_csv(self):
        """ Export texture listing in csv file """
        file_content = self.get_database_content_as_csv()

        # check if current scene is empty
        if not file_content:
            mtt_log('Nothing to save. Operation aborted.', msg_type='warning',
                    verbose=False)
            return

        # clean output
        convert_nicename = {n: t for t, n, a in MTTSettings.SUPPORTED_TYPE}
        for i, row in enumerate(file_content):
            node_type = convert_nicename[row[1]]
            ref_str = 'True' if row[2] == 1 else ''
            missing_str = 'True' if row[3] == -1 else ''
            file_content[i] = (row[0], node_type, ref_str, missing_str, row[4], row[5])

        # query file to write
        scene_name = os.path.basename(cmds.file(query=True, sceneName=True))
        file_path = os.path.join(cmds.workspace(query=True, rootDirectory=True), scene_name)
        csv_path = cmds.fileDialog2(
            fileFilter='Texture List (*.csv)',
            caption='Save Texture List',
            startingDirectory=file_path,
            fileMode=0)

        # fill file
        if csv_path is not None:
            import csv
            file_path = csv_path[0]
            scene_name = cmds.file(q=True, sceneName=True) or 'Scene UNTITLED'
            with open(file_path, "w") as csv_file:
                csv_file_writer = csv.writer(csv_file, delimiter=';')
                csv_file_writer.writerow([scene_name])
                csv_file_writer.writerow(['NODE NAME', 'NODE TYPE', 'IS REF', 'MISSING', 'INSTANCE COUNT', 'FILE PATH'])
                csv_file_writer.writerows(file_content)
                csv_file.close()
                mtt_log('CSV file saved to %s' % file_path, verbose=False)
                cmds.launchImageEditor(viewImageFile=os.path.dirname(file_path))
示例#16
0
 def __init__(self, watcher=None):
     """ Init model """
     QAbstractTableModel.__init__(self)
     self.table_view = None
     self.watcher = watcher
     self.watcher.fileChanged.connect(self.file_watch_file_change)
     self.watcher.directoryChanged.connect(self.file_watch_directory_change)
     self.is_reloading_file = False
     self.suspend_force_sort = False
     self.supported_format_dict = dict([
         (n_type, nodeAttr)
         for n_type, nice, nodeAttr in MTTSettings.SUPPORTED_TYPE
     ])
     self.db = None
     # create database table
     try:
         self._database_create_table()
     except sqlite3.Error, e:
         mtt_log('Error init DB :\n\t>> %s <<\n' % e,
                 msg_type='error',
                 verbose=False)
         sys.exit(1)
示例#17
0
    def change_node_attribute(self, node_name, new_attribute_value):
        if cmds.lockNode(node_name, query=True, lock=True)[0] \
                or cmds.referenceQuery(node_name, isNodeReferenced=True):

            mtt_log('%s is locked, cannot perform changePath\n' % node_name,
                    verbose=False)
            return False

        if self.is_reloading_file:
            return False

        # get original data for current node
        c = self.db.cursor()
        c.execute(
            'SELECT Attribute, FilePath, InstanceCount, FileId '
            'FROM NodesTable LEFT JOIN FilesTable USING (FileId) '
            'WHERE Name=?',
            (node_name, ))
        node_attr, node_file_path, instance_count, old_file_id = c.fetchone()

        new_absolute_attr_value = self.get_attribute_absolute_file_path(
            node_name, new_attribute_value)
        key_path = self.convert_to_key_path(new_absolute_attr_value)
        # check if new_attribute_value already exist
        c.execute('SELECT EXISTS (SELECT 1 FROM FilesTable WHERE KeyPath=?)',
                  (key_path, ))

        if c.fetchone()[0] > 0:
            # instance found
            c.execute('SELECT FileId FROM FilesTable WHERE KeyPath=?',
                      (key_path, ))
            new_file_id = c.fetchone()[0]

        else:
            # new entry
            c.execute(
                'INSERT '
                'INTO FilesTable(KeyPath, FilePath, State, InstanceCount) '
                'VALUES (?, ?, ?, ?)',
                (key_path, new_absolute_attr_value,
                 self.get_file_state(new_absolute_attr_value), 0)
            )
            new_file_id = c.lastrowid
            self.file_watch_add_path(new_absolute_attr_value)

        # update old file instance count and state
        c.execute('SELECT InstanceCount FROM FilesTable WHERE FileId=?',
                  (old_file_id, ))
        if c.fetchone()[0] == 1 and node_file_path != new_absolute_attr_value:
                c.execute('DELETE FROM FilesTable WHERE FileId=?',
                          (old_file_id, ))
        else:
            c.execute(
                'UPDATE FilesTable SET InstanceCount=InstanceCount - 1 '
                'WHERE FileId=?',
                (old_file_id, ))
            c.execute(
                'UPDATE FilesTable SET State=? '
                'WHERE FileId=?',
                (self.get_file_state(node_file_path), old_file_id))

        # set new values
        c.execute('UPDATE NodesTable SET Attribute=? WHERE Name=?',
                  (new_attribute_value, node_name))
        c.execute('UPDATE NodesTable SET FileId=? WHERE Name=?',
                  (new_file_id, node_name))
        c.execute('UPDATE FilesTable SET InstanceCount=InstanceCount + 1 '
                  'WHERE FileId=?', (new_file_id, ))
        c.execute('UPDATE FilesTable SET State=? WHERE FileId=?',
                  (self.get_file_state(new_absolute_attr_value), new_file_id))

        self.db.commit()

        # notify data changed
        index = self.get_node_model_id(node_name)
        self.dataChanged.emit(index, index)

        return True
示例#18
0
    def show_texture(self, texture_path):
        # create pointers
        width_util = om.MScriptUtil()
        width_util.createFromInt(0)
        width_ptr = width_util.asUintPtr()

        height_util = om.MScriptUtil()
        height_util.createFromInt(0)
        height_ptr = height_util.asUintPtr()

        # create Maya native MImage
        maya_texture = om.MImage()
        maya_texture.readFromFile(texture_path)
        maya_texture.verticalFlip()
        maya_texture.getSize(width_ptr, height_ptr)

        # get texture info
        width_value = width_util.getUint(width_ptr)
        height_value = height_util.getUint(height_ptr)
        texture_size = width_value * height_value * 4

        # convert to Qt format
        image_format = QImage.Format_ARGB32_Premultiplied \
            if MTTSettings.value('Viewer/premultiply') \
            else QImage.Format_RGB32

        show_default = False
        qt_image = None

        try:
            self.image_buffer = ctypes.c_ubyte * texture_size
            self.image_buffer = self.image_buffer.from_address(long(maya_texture.pixels()))
            qt_image = QImage(self.image_buffer, width_value, height_value, image_format).rgbSwapped()

            self.is_loading_fail = False
            mtt_log('%s loaded' % os.path.basename(texture_path), add_tag='VIEWER', verbose=False)
        except Exception as e:
            mtt_log('%s\n%s' % (type(e), e), add_tag='VIEWER', msg_type='error', verbose=False)
            mtt_log('Fail to load %s' % os.path.basename(texture_path), add_tag='VIEWER', msg_type='error', verbose=False)
            self.is_loading_fail = True
            if MTTSettings.value('Viewer/recoverMode'):
                try:
                    import time

                    start = time.clock()
                    qt_image = QImage(width_value, height_value, QImage.Format_ARGB32)
                    pixel_ptr = maya_texture.pixels()
                    for y in xrange(height_value):
                        for x in xrange(1, width_value):
                            i = (y * width_value) + x
                            i = 4 * (i - 1)
                            r = om.MScriptUtil.getUcharArrayItem(pixel_ptr, i)
                            g = om.MScriptUtil.getUcharArrayItem(pixel_ptr, i + 1)
                            b = om.MScriptUtil.getUcharArrayItem(pixel_ptr, i + 2)
                            a = om.MScriptUtil.getUcharArrayItem(pixel_ptr, i + 3)
                            qt_image.setPixel(x, y, QColor(r, g, b, a).rgba())
                    end = time.clock()
                    mtt_log('Image read in %.3fs' % (end - start), verbose=False)
                except Exception as e:
                    mtt_log(e, add_tag='VIEWER', msg_type='error', verbose=False)
                    show_default = True
            else:
                show_default = True
        except RuntimeError as e:
            mtt_log('%s\n%s' % (type(e), e), add_tag='VIEWER', msg_type='error', verbose=False)
            mtt_log('Fail to load %s' % os.path.basename(texture_path), add_tag='VIEWER', msg_type='error', verbose=False)
            self.is_loading_fail = True
            show_default = True

        if show_default:
            self.reset_image()
            return

        self.current_texture = QPixmap.fromImage(qt_image)

        # display texture in QGraphicsView
        self.__add_texture_item(False)
        self.update_status()
示例#19
0
    def change_node_attribute(self, node_name, new_attribute_value):
        if cmds.lockNode(node_name, query=True, lock=True)[0] \
                or cmds.referenceQuery(node_name, isNodeReferenced=True):

            mtt_log('%s is locked, cannot perform changePath\n' % node_name,
                    verbose=False)
            return False

        if self.is_reloading_file:
            return False

        # get original data for current node
        c = self.db.cursor()
        c.execute(
            'SELECT Attribute, FilePath, InstanceCount, FileId '
            'FROM NodesTable LEFT JOIN FilesTable USING (FileId) '
            'WHERE Name=?', (node_name, ))
        node_attr, node_file_path, instance_count, old_file_id = c.fetchone()

        new_absolute_attr_value = self.get_attribute_absolute_file_path(
            node_name, new_attribute_value)
        key_path = self.convert_to_key_path(new_absolute_attr_value)
        # check if new_attribute_value already exist
        c.execute('SELECT EXISTS (SELECT 1 FROM FilesTable WHERE KeyPath=?)',
                  (key_path, ))

        if c.fetchone()[0] > 0:
            # instance found
            c.execute('SELECT FileId FROM FilesTable WHERE KeyPath=?',
                      (key_path, ))
            new_file_id = c.fetchone()[0]

        else:
            # new entry
            c.execute(
                'INSERT '
                'INTO FilesTable(KeyPath, FilePath, State, InstanceCount) '
                'VALUES (?, ?, ?, ?)',
                (key_path, new_absolute_attr_value,
                 self.get_file_state(new_absolute_attr_value), 0))
            new_file_id = c.lastrowid
            self.file_watch_add_path(new_absolute_attr_value)

        # update old file instance count and state
        c.execute('SELECT InstanceCount FROM FilesTable WHERE FileId=?',
                  (old_file_id, ))
        if c.fetchone()[0] == 1 and node_file_path != new_absolute_attr_value:
            c.execute('DELETE FROM FilesTable WHERE FileId=?', (old_file_id, ))
        else:
            c.execute(
                'UPDATE FilesTable SET InstanceCount=InstanceCount - 1 '
                'WHERE FileId=?', (old_file_id, ))
            c.execute('UPDATE FilesTable SET State=? '
                      'WHERE FileId=?',
                      (self.get_file_state(node_file_path), old_file_id))

        # set new values
        c.execute('UPDATE NodesTable SET Attribute=? WHERE Name=?',
                  (new_attribute_value, node_name))
        c.execute('UPDATE NodesTable SET FileId=? WHERE Name=?',
                  (new_file_id, node_name))
        c.execute(
            'UPDATE FilesTable SET InstanceCount=InstanceCount + 1 '
            'WHERE FileId=?', (new_file_id, ))
        c.execute('UPDATE FilesTable SET State=? WHERE FileId=?',
                  (self.get_file_state(new_absolute_attr_value), new_file_id))

        self.db.commit()

        # notify data changed
        index = self.get_node_model_id(node_name)
        self.dataChanged.emit(index, index)

        return True
    def show_texture(self, texture_path):
        # create pointers
        width_util = om.MScriptUtil()
        width_util.createFromInt(0)
        width_ptr = width_util.asUintPtr()

        height_util = om.MScriptUtil()
        height_util.createFromInt(0)
        height_ptr = height_util.asUintPtr()

        # create Maya native MImage
        maya_texture = om.MImage()
        maya_texture.readFromFile(texture_path)
        maya_texture.verticalFlip()
        maya_texture.getSize(width_ptr, height_ptr)

        # get texture info
        width_value = width_util.getUint(width_ptr)
        height_value = height_util.getUint(height_ptr)
        texture_size = width_value * height_value * 4

        # convert to Qt format
        image_format = QImage.Format_ARGB32_Premultiplied \
            if MTTSettings.value('Viewer/premultiply') \
            else QImage.Format_RGB32

        show_default = False
        qt_image = None

        try:
            self.image_buffer = ctypes.c_ubyte * texture_size
            self.image_buffer = self.image_buffer.from_address(
                long(maya_texture.pixels()))
            qt_image = QImage(self.image_buffer, width_value, height_value,
                              image_format).rgbSwapped()

            self.is_loading_fail = False
            mtt_log('%s loaded' % os.path.basename(texture_path),
                    add_tag='VIEWER',
                    verbose=False)
        except Exception as e:
            mtt_log('%s\n%s' % (type(e), e),
                    add_tag='VIEWER',
                    msg_type='error',
                    verbose=False)
            mtt_log('Fail to load %s' % os.path.basename(texture_path),
                    add_tag='VIEWER',
                    msg_type='error',
                    verbose=False)
            self.is_loading_fail = True
            if MTTSettings.value('Viewer/recoverMode'):
                try:
                    import time

                    start = time.clock()
                    qt_image = QImage(width_value, height_value,
                                      QImage.Format_ARGB32)
                    pixel_ptr = maya_texture.pixels()
                    for y in xrange(height_value):
                        for x in xrange(1, width_value):
                            i = (y * width_value) + x
                            i = 4 * (i - 1)
                            r = om.MScriptUtil.getUcharArrayItem(pixel_ptr, i)
                            g = om.MScriptUtil.getUcharArrayItem(
                                pixel_ptr, i + 1)
                            b = om.MScriptUtil.getUcharArrayItem(
                                pixel_ptr, i + 2)
                            a = om.MScriptUtil.getUcharArrayItem(
                                pixel_ptr, i + 3)
                            qt_image.setPixel(x, y, QColor(r, g, b, a).rgba())
                    end = time.clock()
                    mtt_log('Image read in %.3fs' % (end - start),
                            verbose=False)
                except Exception as e:
                    mtt_log(e,
                            add_tag='VIEWER',
                            msg_type='error',
                            verbose=False)
                    show_default = True
            else:
                show_default = True
        except RuntimeError as e:
            mtt_log('%s\n%s' % (type(e), e),
                    add_tag='VIEWER',
                    msg_type='error',
                    verbose=False)
            mtt_log('Fail to load %s' % os.path.basename(texture_path),
                    add_tag='VIEWER',
                    msg_type='error',
                    verbose=False)
            self.is_loading_fail = True
            show_default = True

        if show_default:
            self.reset_image()
            return

        self.current_texture = QPixmap.fromImage(qt_image)

        # display texture in QGraphicsView
        self.__add_texture_item(False)
        self.update_status()