diff --git a/toonz/sources/include/toonz/txshsimplelevel.h b/toonz/sources/include/toonz/txshsimplelevel.h index 2ffba7e..d502ddb 100644 --- a/toonz/sources/include/toonz/txshsimplelevel.h +++ b/toonz/sources/include/toonz/txshsimplelevel.h @@ -302,6 +302,8 @@ The oldFp is used when the current scene path change... //! must have the same size). void renumber(const std::vector &fids); + bool isFrameReadOnly(TFrameId fid); + public: // Auxiliary files management: hooks, tpl, etc. // May throw; copy and rename perform touchparentdir diff --git a/toonz/sources/tnztools/tool.cpp b/toonz/sources/tnztools/tool.cpp index 8f8e641..a0c58d4 100644 --- a/toonz/sources/tnztools/tool.cpp +++ b/toonz/sources/tnztools/tool.cpp @@ -948,16 +948,10 @@ QString TTool::updateEnabled() { // Check TTool::ImageType tools if (toolType == TTool::LevelWriteTool) { // Check level against read-only status - if (sl->isReadOnly()) { - const std::set &editableFrames = sl->getEditableRange(); - TFrameId currentFid = getCurrentFid(); - - if (editableFrames.find(currentFid) == editableFrames.end()) - return ( - enable(false), - QObject::tr( - "The current frame is locked: any editing is forbidden.")); - } + if (sl->isFrameReadOnly(getCurrentFid())) + return (enable(false), + QObject::tr( + "The current frame is locked: any editing is forbidden.")); // Check level type write support if (sl->getPath().getType() == diff --git a/toonz/sources/toonz/filmstrip.cpp b/toonz/sources/toonz/filmstrip.cpp index 301b8c5..69a9554 100644 --- a/toonz/sources/toonz/filmstrip.cpp +++ b/toonz/sources/toonz/filmstrip.cpp @@ -539,10 +539,6 @@ void FilmstripFrames::paintEvent(QPaintEvent *evt) { int frameCount = (int)fids.size(); - std::set editableFrameRange; - - if (sl) editableFrameRange = sl->getEditableRange(); - bool isReadOnly = false; if (sl) isReadOnly = sl->isReadOnly(); @@ -619,9 +615,7 @@ void FilmstripFrames::paintEvent(QPaintEvent *evt) { // Read-only frames (lock) if (0 <= i && i < frameCount) { - if ((editableFrameRange.empty() && isReadOnly) || - (isReadOnly && (!editableFrameRange.empty() && - editableFrameRange.count(fids[i]) == 0))) { + if (sl->isFrameReadOnly(fids[i])) { static QPixmap lockPixmap(":Resources/forbidden.png"); p.drawPixmap(tmp_frameRect.bottomLeft() + QPoint(3, -13), lockPixmap); } diff --git a/toonz/sources/toonzlib/txshsimplelevel.cpp b/toonz/sources/toonzlib/txshsimplelevel.cpp index e6f9886..c1c5a31 100644 --- a/toonz/sources/toonzlib/txshsimplelevel.cpp +++ b/toonz/sources/toonzlib/txshsimplelevel.cpp @@ -2251,3 +2251,24 @@ TRectD TXshSimpleLevel::getBBox(const TFrameId &fid) const { // Get the frame's dpi and traduce the bbox to inch coordinates return TScale(1.0 / dpiX, 1.0 / dpiY) * bbox; } + +bool TXshSimpleLevel::isFrameReadOnly(TFrameId fid) { + // For Raster and mesh files, check to see if files are marked as read-only at + // the OS level + if (getType() == OVL_XSHLEVEL || getType() == TZI_XSHLEVEL || + getType() == MESH_XSHLEVEL) { + TFilePath fullPath = getScene()->decodeFilePath(m_path); + TFilePath path = + fullPath.getDots() == ".." ? fullPath.withFrame(fid) : fullPath; + if (!TSystem::doesExistFileOrLevel(path)) return false; + TFileStatus fs(path); + return !fs.isWritable(); + } + + // If Level is marked read only, check for editable frames + if (m_isReadOnly && !m_editableRange.empty() && + m_editableRange.count(fid) != 0) + return false; + + return m_isReadOnly; +}