Merge pull request #2619 from manongjohn/fix_version_control

Fix version control issues
This commit is contained in:
Rodney 2019-08-26 03:14:46 -05:00 committed by GitHub
commit ec5bd26a54
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 231 additions and 7723 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -110,7 +110,8 @@ QComboBox {
} }
} }
QLineEdit { QPlainTextEdit
,QLineEdit {
&:extend(.LineEdit all); &:extend(.LineEdit all);
} }

File diff suppressed because one or more lines are too long

View file

@ -302,6 +302,8 @@ The oldFp is used when the current scene path change...
//! must have the same size). //! must have the same size).
void renumber(const std::vector<TFrameId> &fids); void renumber(const std::vector<TFrameId> &fids);
bool isFrameReadOnly(TFrameId fid);
public: public:
// Auxiliary files management: hooks, tpl, etc. // Auxiliary files management: hooks, tpl, etc.
// May throw; copy and rename perform touchparentdir // May throw; copy and rename perform touchparentdir

View file

@ -948,16 +948,10 @@ QString TTool::updateEnabled() {
// Check TTool::ImageType tools // Check TTool::ImageType tools
if (toolType == TTool::LevelWriteTool) { if (toolType == TTool::LevelWriteTool) {
// Check level against read-only status // Check level against read-only status
if (sl->isReadOnly()) { if (sl->isFrameReadOnly(getCurrentFid()))
const std::set<TFrameId> &editableFrames = sl->getEditableRange(); return (enable(false),
TFrameId currentFid = getCurrentFid(); QObject::tr(
"The current frame is locked: any editing is forbidden."));
if (editableFrames.find(currentFid) == editableFrames.end())
return (
enable(false),
QObject::tr(
"The current frame is locked: any editing is forbidden."));
}
// Check level type write support // Check level type write support
if (sl->getPath().getType() == if (sl->getPath().getType() ==

View file

@ -367,6 +367,9 @@ DvDirTreeView::DvDirTreeView(QWidget *parent)
assert(ret); assert(ret);
setAcceptDrops(true); setAcceptDrops(true);
if (Preferences::instance()->isAutomaticSVNFolderRefreshEnabled())
setRefreshVersionControlEnabled(true);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -1373,11 +1376,11 @@ void DvDirTreeView::onRefreshStatusError(const QString &text) {
void DvDirTreeView::checkPartialLock(const QString &workingDir, void DvDirTreeView::checkPartialLock(const QString &workingDir,
const QStringList &files) { const QStringList &files) {
QStringList args; QStringList args;
args << "propget"; args << "proplist";
args << "partial-lock";
int filesCount = files.count(); int filesCount = files.count();
for (int i = 0; i < filesCount; i++) args << files.at(i); for (int i = 0; i < filesCount; i++) args << files.at(i);
args << "--xml"; args << "--xml";
args << "-v";
m_thread.disconnect(SIGNAL(done(const QString &))); m_thread.disconnect(SIGNAL(done(const QString &)));
m_thread.disconnect(SIGNAL(error(const QString &))); m_thread.disconnect(SIGNAL(error(const QString &)));
@ -1470,18 +1473,11 @@ DvItemListModel::Status DvDirTreeView::getItemVersionControlStatus(
if (s.m_item == "missing" || if (s.m_item == "missing" ||
s.m_item == "none" && s.m_repoStatus == "added") s.m_item == "none" && s.m_repoStatus == "added")
return DvItemListModel::VC_Missing; return DvItemListModel::VC_Missing;
if (s.m_isLocked) {
DvDirVersionControlRootNode *rootNode = node->getVersionControlRootNode();
if (rootNode) {
if (QString::fromStdWString(rootNode->getUserName()) != s.m_lockOwner ||
TSystem::getHostName() != s.m_lockHostName)
return DvItemListModel::VC_Locked;
else if (s.m_item == "normal" && s.m_repoStatus == "none")
return DvItemListModel::VC_Edited;
}
}
if (s.m_item == "unversioned") return DvItemListModel::VC_Unversioned; if (s.m_item == "unversioned") return DvItemListModel::VC_Unversioned;
// If, for some errors, there is some item added locally but not committed
// yet, use the modified status
if (s.m_item == "modified" || s.m_item == "added")
return DvItemListModel::VC_Modified;
if (s.m_isPartialEdited) { if (s.m_isPartialEdited) {
QString from = QString::number(s.m_editFrom); QString from = QString::number(s.m_editFrom);
QString to = QString::number(s.m_editTo); QString to = QString::number(s.m_editTo);
@ -1500,15 +1496,21 @@ DvItemListModel::Status DvDirTreeView::getItemVersionControlStatus(
return DvItemListModel::VC_PartialEdited; return DvItemListModel::VC_PartialEdited;
} }
if (s.m_isPartialLocked) return DvItemListModel::VC_PartialLocked; if (s.m_isPartialLocked) return DvItemListModel::VC_PartialLocked;
if (s.m_isLocked) {
DvDirVersionControlRootNode *rootNode = node->getVersionControlRootNode();
if (rootNode) {
if (QString::fromStdWString(rootNode->getUserName()) != s.m_lockOwner ||
TSystem::getHostName() != s.m_lockHostName)
return DvItemListModel::VC_Locked;
else if (s.m_item == "normal" && s.m_repoStatus == "none")
return DvItemListModel::VC_Edited;
}
}
// Pay attention: "ToUpdate" is more important than "ReadOnly" // Pay attention: "ToUpdate" is more important than "ReadOnly"
if (s.m_item == "normal" && s.m_repoStatus == "modified") if (s.m_item == "normal" && s.m_repoStatus == "modified")
return DvItemListModel::VC_ToUpdate; return DvItemListModel::VC_ToUpdate;
if (!fs.isWritable() || s.m_item == "normal") if (!fs.isWritable() || s.m_item == "normal")
return DvItemListModel::VC_ReadOnly; return DvItemListModel::VC_ReadOnly;
// If, for some errors, there is some item added locally but not committed
// yet, use the modified status
if (s.m_item == "modified" || s.m_item == "added")
return DvItemListModel::VC_Modified;
} else if (fp.getDots() == "..") { } else if (fp.getDots() == "..") {
// Get the files list to control its status... // Get the files list to control its status...
QStringList levelNames = getLevelFileNames(fp); QStringList levelNames = getLevelFileNames(fp);

View file

@ -1149,6 +1149,9 @@ void DvItemViewerPanel::paintTableItem(QPainter &p, int index) {
Qt::AlignLeft | Qt::AlignVCenter, Qt::AlignLeft | Qt::AlignVCenter,
elideText(value, p.font(), lx)); elideText(value, p.font(), lx));
x += lx; x += lx;
// If status icon is show, shift the next column left by the width of the
// icon
if (i == 0 && !statusPixmap.isNull()) x -= 15;
} }
if (n > 1) { if (n > 1) {
p.setPen(QColor(0, 0, 0, 100)); // column line p.setPen(QColor(0, 0, 0, 100)); // column line
@ -1730,15 +1733,15 @@ void DvItemViewerTitleBar::paintEvent(QPaintEvent *) {
m_itemViewer->getPanel()->getColumns(columns); m_itemViewer->getPanel()->getColumns(columns);
QRect rect(0, 0, width(), height()); QRect rect(0, 0, width(), height());
QBrush nb = QBrush(Qt::NoBrush); QBrush nb = QBrush(Qt::NoBrush);
QPalette pal = QPalette pal = QPalette(nb, nb, QBrush(QColor(255, 255, 255, 30)),
QPalette(nb, nb, QBrush(QColor(255, 255, 255, 30)), QBrush(QColor(0, 0, 0, 110)), QBrush(QColor(0, 0, 0, 110)),
QBrush(QColor(Qt::gray)), nb, nb, nb, nb); QBrush(QColor(Qt::gray)), nb, nb, nb, nb);
p.fillRect(rect, QColor(0, 0, 0, 90)); // bg color p.fillRect(rect, QColor(0, 0, 0, 90)); // bg color
p.setPen(QColor(200, 200, 200, 255)); // text color p.setPen(QColor(200, 200, 200, 255)); // text color
int h = 0; // fontMetrics().descent(); int h = 0; // fontMetrics().descent();
int y = rect.top(); int y = rect.top();
int ly = rect.height(); int ly = rect.height();
int lx = rect.width(); int lx = rect.width();

View file

@ -1350,6 +1350,10 @@ QMenu *FileBrowser::getContextMenu(QWidget *parent, int index) {
} }
if (status == DvItemListModel::VC_Locked && files.size() == 1) { if (status == DvItemListModel::VC_Locked && files.size() == 1) {
action = vcMenu->addAction(tr("Unlock"));
ret = ret && connect(action, SIGNAL(triggered()), this,
SLOT(unlockVersionControl()));
action = vcMenu->addAction(tr("Edit Info")); action = vcMenu->addAction(tr("Edit Info"));
ret = ret && connect(action, SIGNAL(triggered()), this, ret = ret && connect(action, SIGNAL(triggered()), this,
SLOT(showLockInformation())); SLOT(showLockInformation()));

View file

@ -539,10 +539,6 @@ void FilmstripFrames::paintEvent(QPaintEvent *evt) {
int frameCount = (int)fids.size(); int frameCount = (int)fids.size();
std::set<TFrameId> editableFrameRange;
if (sl) editableFrameRange = sl->getEditableRange();
bool isReadOnly = false; bool isReadOnly = false;
if (sl) isReadOnly = sl->isReadOnly(); if (sl) isReadOnly = sl->isReadOnly();
@ -619,9 +615,7 @@ void FilmstripFrames::paintEvent(QPaintEvent *evt) {
// Read-only frames (lock) // Read-only frames (lock)
if (0 <= i && i < frameCount) { if (0 <= i && i < frameCount) {
if ((editableFrameRange.empty() && isReadOnly) || if (sl->isFrameReadOnly(fids[i])) {
(isReadOnly && (!editableFrameRange.empty() &&
editableFrameRange.count(fids[i]) == 0))) {
static QPixmap lockPixmap(":Resources/forbidden.png"); static QPixmap lockPixmap(":Resources/forbidden.png");
p.drawPixmap(tmp_frameRect.bottomLeft() + QPoint(3, -13), lockPixmap); p.drawPixmap(tmp_frameRect.bottomLeft() + QPoint(3, -13), lockPixmap);
} }

View file

@ -469,7 +469,8 @@ void SVNCommitDialog::onResourcesStatusRetrieved(const QString &xmlResponse) {
void SVNCommitDialog::onStatusRetrieved(const QString &xmlResponse) { void SVNCommitDialog::onStatusRetrieved(const QString &xmlResponse) {
SVNStatusReader sr(xmlResponse); SVNStatusReader sr(xmlResponse);
m_status = sr.getStatus(); m_status = sr.getStatus();
int height = 160;
m_thread.disconnect(SIGNAL(statusRetrieved(const QString &))); m_thread.disconnect(SIGNAL(statusRetrieved(const QString &)));
@ -508,6 +509,10 @@ void SVNCommitDialog::onStatusRetrieved(const QString &xmlResponse) {
} }
} }
if (m_treeWidget->isVisible()) height += (filesToPutCount * 25);
setMinimumSize(350, min(height, 350));
m_waitingLabel->hide(); m_waitingLabel->hide();
m_commentLabel->show(); m_commentLabel->show();
m_commentTextEdit->show(); m_commentTextEdit->show();
@ -531,6 +536,10 @@ void SVNCommitDialog::onStatusRetrieved(const QString &xmlResponse) {
m_selectionLabel->show(); m_selectionLabel->show();
} }
if (m_treeWidget->isVisible()) height += (m_items.size() * 25);
setMinimumSize(350, min(height, 350));
m_waitingLabel->hide(); m_waitingLabel->hide();
m_textLabel->hide(); m_textLabel->hide();
m_commentLabel->show(); m_commentLabel->show();
@ -630,7 +639,7 @@ void SVNCommitDialog::addUnversionedItem(const QString &relativePath) {
item = new QTreeWidgetItem(m_treeWidget, QStringList(list.at(i))); item = new QTreeWidgetItem(m_treeWidget, QStringList(list.at(i)));
if (fi.isDir()) item->setIcon(0, folderIcon); if (fi.isDir()) item->setIcon(0, folderIcon);
if (relativePath == tempString) { if ((i + 1) == levelCount) {
item->setCheckState(0, m_folderOnly ? Qt::Unchecked : Qt::Checked); item->setCheckState(0, m_folderOnly ? Qt::Unchecked : Qt::Checked);
item->setData(0, Qt::UserRole, tempString); item->setData(0, Qt::UserRole, tempString);
item->setData(0, Qt::UserRole + 1, true); item->setData(0, Qt::UserRole + 1, true);
@ -916,7 +925,7 @@ SVNCommitFrameRangeDialog::SVNCommitFrameRangeDialog(QWidget *parent,
setWindowTitle(tr("Version Control: Put")); setWindowTitle(tr("Version Control: Put"));
setMinimumSize(300, 150); setMinimumSize(350, 150);
QWidget *container = new QWidget; QWidget *container = new QWidget;
QVBoxLayout *mainLayout = new QVBoxLayout; QVBoxLayout *mainLayout = new QVBoxLayout;
@ -1041,10 +1050,10 @@ void SVNCommitFrameRangeDialog::onLockDone() {
// Step 3: propget // Step 3: propget
QStringList args; QStringList args;
args << "propget"; args << "proplist";
args << "partial-lock";
args << m_file; args << m_file;
args << "--xml"; args << "--xml";
args << "-v";
m_thread.disconnect(SIGNAL(done(const QString &))); m_thread.disconnect(SIGNAL(done(const QString &)));
connect(&m_thread, SIGNAL(done(const QString &)), this, connect(&m_thread, SIGNAL(done(const QString &)), this,

View file

@ -169,8 +169,15 @@ SVNDeleteDialog::SVNDeleteDialog(QWidget *parent, const QString &workingDir,
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void SVNDeleteDialog::showEvent(QShowEvent *e) { void SVNDeleteDialog::showEvent(QShowEvent *e) {
if (!m_isFolder) {
initTreeWidget();
int height = 50;
if (m_treeWidget->isVisible()) height += (m_files.size() * 50);
setMinimumSize(300, min(height, 350));
}
QDialog::showEvent(e); QDialog::showEvent(e);
if (!m_isFolder) initTreeWidget();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -261,6 +268,10 @@ void SVNDeleteDialog::onDeleteServerButtonClicked() {
m_deleteServerButton->setText(tr("Delete")); m_deleteServerButton->setText(tr("Delete"));
connect(m_deleteServerButton, SIGNAL(clicked()), this, SLOT(deleteFiles())); connect(m_deleteServerButton, SIGNAL(clicked()), this, SLOT(deleteFiles()));
int height = 175;
if (m_treeWidget->isVisible()) height += (m_files.size() * 50);
setMinimumSize(300, min(height, 350));
m_textLabel->setText( m_textLabel->setText(
tr("You are deleting items also on repository. Are you sure ?")); tr("You are deleting items also on repository. Are you sure ?"));
m_commentLabel->show(); m_commentLabel->show();

View file

@ -160,7 +160,7 @@ SVNLockDialog::SVNLockDialog(QWidget *parent, const QString &workingDir,
// 1. Getting status // 1. Getting status
connect(&m_thread, SIGNAL(statusRetrieved(const QString &)), this, connect(&m_thread, SIGNAL(statusRetrieved(const QString &)), this,
SLOT(onStatusRetrieved(const QString &))); SLOT(onStatusRetrieved(const QString &)));
m_thread.getSVNStatus(m_workingDir); m_thread.getSVNStatus(m_workingDir, true);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -185,20 +185,24 @@ void SVNLockDialog::onStatusRetrieved(const QString &xmlResponse) {
switchToCloseButton(); switchToCloseButton();
} else { } else {
int height = m_lock ? 160 : 50;
if (m_treeWidget->isVisible())
height += (m_filesToEdit.size() * (m_lock ? 25 : 50));
setMinimumSize(300, min(height, 350));
m_waitingLabel->hide(); m_waitingLabel->hide();
if (m_lock) if (m_lock)
m_textLabel->setText( m_textLabel->setText(
tr("%1 items to edit.") tr("%1 items to edit.")
.arg(m_filesToEdit.size() == 1 .arg(m_filesToEdit.size() == 1 ? 1 : m_filesToEdit.size() -
? 1 m_sceneIconAdded));
: m_filesToEdit.size() - m_sceneIconAdded));
else else
m_textLabel->setText( m_textLabel->setText(
tr("%1 items to unlock.") tr("%1 items to unlock.")
.arg(m_filesToEdit.size() == 1 .arg(m_filesToEdit.size() == 1 ? 1 : m_filesToEdit.size() -
? 1 m_sceneIconAdded));
: m_filesToEdit.size() - m_sceneIconAdded));
m_lockButton->show(); m_lockButton->show();
} }
@ -267,15 +271,13 @@ void SVNLockDialog::executeCommand() {
if (m_lock) if (m_lock)
m_textLabel->setText( m_textLabel->setText(
tr("Editing %1 items...") tr("Editing %1 items...")
.arg(m_filesToEdit.size() == 1 .arg(m_filesToEdit.size() == 1 ? 1 : m_filesToEdit.size() -
? 1 m_sceneIconAdded));
: m_filesToEdit.size() - m_sceneIconAdded));
else else
m_textLabel->setText( m_textLabel->setText(
tr("Unlocking %1 items...") tr("Unlocking %1 items...")
.arg(m_filesToEdit.size() == 1 .arg(m_filesToEdit.size() == 1 ? 1 : m_filesToEdit.size() -
? 1 m_sceneIconAdded));
: m_filesToEdit.size() - m_sceneIconAdded));
QStringList args; QStringList args;
if (m_lock) if (m_lock)

View file

@ -185,6 +185,10 @@ void SVNLockFrameRangeDialog::onPropGetDone(const QString &xmlResponse) {
} }
} }
int height =
180 + (m_lockInfos.isEmpty() ? 0 : ((m_lockInfos.size() - 1) * 25));
setMinimumSize(300, height);
m_lockButton->show(); m_lockButton->show();
m_cancelButton->show(); m_cancelButton->show();
@ -304,10 +308,10 @@ void SVNLockFrameRangeDialog::onLockDone() {
// Step 2: propget // Step 2: propget
QStringList args; QStringList args;
args << "propget"; args << "proplist";
args << "partial-lock";
args << m_file; args << m_file;
args << "--xml"; args << "--xml";
args << "-v";
m_thread.disconnect(SIGNAL(done(const QString &))); m_thread.disconnect(SIGNAL(done(const QString &)));
connect(&m_thread, SIGNAL(done(const QString &)), this, connect(&m_thread, SIGNAL(done(const QString &)), this,
@ -531,6 +535,10 @@ void SVNLockMultiFrameRangeDialog::onStatusRetrieved(
m_textLabel->setText(temp); m_textLabel->setText(temp);
} }
int height =
180 + (m_lockInfos.isEmpty() ? 0 : ((m_lockInfos.size() - 1) * 25));
setMinimumSize(300, height);
m_lockButton->show(); m_lockButton->show();
m_cancelButton->show(); m_cancelButton->show();
@ -736,10 +744,10 @@ void SVNUnlockFrameRangeDialog::onLockDone() {
// Step 3: propget // Step 3: propget
QStringList args; QStringList args;
args << "propget"; args << "proplist";
args << "partial-lock";
args << m_file; args << m_file;
args << "--xml"; args << "--xml";
args << "-v";
m_thread.disconnect(SIGNAL(done(const QString &))); m_thread.disconnect(SIGNAL(done(const QString &)));
connect(&m_thread, SIGNAL(done(const QString &)), this, connect(&m_thread, SIGNAL(done(const QString &)), this,
@ -1074,10 +1082,10 @@ SVNFrameRangeLockInfoDialog::SVNFrameRangeLockInfoDialog(
// 1. propget // 1. propget
QStringList args; QStringList args;
args << "propget"; args << "proplist";
args << "partial-lock";
args << m_file; args << m_file;
args << "--xml"; args << "--xml";
args << "-v";
connect(&m_thread, SIGNAL(done(const QString &)), this, connect(&m_thread, SIGNAL(done(const QString &)), this,
SLOT(onPropGetDone(const QString &))); SLOT(onPropGetDone(const QString &)));
@ -1115,6 +1123,9 @@ void SVNFrameRangeLockInfoDialog::onPropGetDone(const QString &xmlResponse) {
.arg(lock.m_from) .arg(lock.m_from)
.arg(lock.m_to)); .arg(lock.m_to));
} }
int height = 100 + ((lockInfos.size() - 1) * 25);
setMinimumSize(300, height);
m_textLabel->setText(temp); m_textLabel->setText(temp);
} }
} }
@ -1224,6 +1235,9 @@ void SVNMultiFrameRangeLockInfoDialog::onStatusRetrieved(
.arg(lock.m_from) .arg(lock.m_from)
.arg(lock.m_to)); .arg(lock.m_to));
} }
int height = 100 + ((lockInfos.size() - 1) * 25);
setMinimumSize(300, height);
m_textLabel->setText(temp); m_textLabel->setText(temp);
} }
} }

View file

@ -121,7 +121,8 @@ SVNRevertDialog::SVNRevertDialog(QWidget *parent, const QString &workingDir,
void SVNRevertDialog::onStatusRetrieved(const QString &xmlResponse) { void SVNRevertDialog::onStatusRetrieved(const QString &xmlResponse) {
SVNStatusReader sr(xmlResponse); SVNStatusReader sr(xmlResponse);
m_status = sr.getStatus(); m_status = sr.getStatus();
int height = 50;
checkFiles(); checkFiles();
@ -140,6 +141,10 @@ void SVNRevertDialog::onStatusRetrieved(const QString &xmlResponse) {
m_textLabel->setText(msg); m_textLabel->setText(msg);
switchToCloseButton(); switchToCloseButton();
} else { } else {
if (m_treeWidget->isVisible()) height += (m_filesToRevert.size() * 50);
setMinimumSize(300, min(height, 350));
QString msg = QString(tr("%1 items to revert.")) QString msg = QString(tr("%1 items to revert."))
.arg(m_filesToRevert.size() == 1 .arg(m_filesToRevert.size() == 1
? 1 ? 1

View file

@ -156,6 +156,8 @@ void SVNUpdateAndLockDialog::onStatusRetrieved(const QString &xmlResponse) {
m_commentLabel->show(); m_commentLabel->show();
switchToCloseButton(); switchToCloseButton();
} else { } else {
setMinimumSize(300, 150);
m_waitingLabel->hide(); m_waitingLabel->hide();
m_textLabel->setText( m_textLabel->setText(

View file

@ -257,6 +257,8 @@ void SVNUpdateDialog::updateFiles() {
return; return;
} }
setMinimumSize(300, 200);
if (m_updateSceneContentsCheckBox) m_updateSceneContentsCheckBox->hide(); if (m_updateSceneContentsCheckBox) m_updateSceneContentsCheckBox->hide();
m_updateButton->setEnabled(false); m_updateButton->setEnabled(false);
m_waitingLabel->hide(); m_waitingLabel->hide();

View file

@ -15,9 +15,11 @@
#include "toonz/palettecontroller.h" #include "toonz/palettecontroller.h"
#include "toonz/tpalettehandle.h" #include "toonz/tpalettehandle.h"
#include "toonz/tscenehandle.h" #include "toonz/tscenehandle.h"
#include "toonz/tproject.h"
#include "tsystem.h" #include "tsystem.h"
#include "tenv.h" #include "tenv.h"
#include "tapp.h" #include "tapp.h"
#include "permissionsmanager.h"
#include <QFile> #include <QFile>
#include <QDir> #include <QDir>
@ -316,6 +318,18 @@ VersionControlManager *VersionControlManager::instance() {
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void setVersionControlCredentials(QString currentPath) {
VersionControl *vc = VersionControl::instance();
QList<SVNRepository> repositories = vc->getRepositories();
int repoCount = repositories.size();
for (int i = 0; i < repoCount; i++) {
SVNRepository r = repositories.at(i);
if (!currentPath.startsWith(r.m_localPath)) continue;
vc->setUserName(r.m_username);
vc->setPassword(r.m_password);
return;
}
}
void VersionControlManager::setFrameRange(TLevelSet *levelSet, void VersionControlManager::setFrameRange(TLevelSet *levelSet,
bool deleteLater) { bool deleteLater) {
@ -327,8 +341,7 @@ void VersionControlManager::setFrameRange(TLevelSet *levelSet,
m_deleteLater = deleteLater; m_deleteLater = deleteLater;
QStringList args; QStringList args;
args << "propget"; args << "proplist";
args << "partial-lock";
bool checkVersionControl = false; bool checkVersionControl = false;
bool filesAddedToArgs = false; bool filesAddedToArgs = false;
@ -341,8 +354,10 @@ void VersionControlManager::setFrameRange(TLevelSet *levelSet,
TFilePath parentDir = TFilePath parentDir =
sl->getScene()->decodeFilePath(sl->getPath().getParentDir()); sl->getScene()->decodeFilePath(sl->getPath().getParentDir());
if (VersionControl::instance()->isFolderUnderVersionControl( if (VersionControl::instance()->isFolderUnderVersionControl(
toQString(parentDir))) toQString(parentDir))) {
checkVersionControl = true; checkVersionControl = true;
setVersionControlCredentials(toQString(parentDir));
}
} }
if (sl && sl->isReadOnly()) { if (sl && sl->isReadOnly()) {
@ -379,6 +394,7 @@ void VersionControlManager::setFrameRange(TLevelSet *levelSet,
} }
args << "--xml"; args << "--xml";
args << "-v";
TFilePath path = m_scene->getScenePath(); TFilePath path = m_scene->getScenePath();
path = m_scene->decodeFilePath(path); path = m_scene->decodeFilePath(path);
@ -435,6 +451,8 @@ void VersionControlManager::onFrameRangeDone(const QString &text) {
} }
} }
setVersionControlCredentials(toQString(currentPath));
QString username = VersionControl::instance()->getUserName(); QString username = VersionControl::instance()->getUserName();
QString hostName = TSystem::getHostName(); QString hostName = TSystem::getHostName();
@ -612,7 +630,15 @@ bool VersionControl::testSetup() {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool VersionControl::isFolderUnderVersionControl(const QString &folderPath) { bool VersionControl::isFolderUnderVersionControl(const QString &folderPath) {
QDir dir(folderPath); QDir dir(folderPath);
return dir.entryList(QDir::AllDirs | QDir::Hidden).contains(".svn"); if (dir.entryList(QDir::AllDirs | QDir::Hidden).contains(".svn")) return true;
// For SVN 1.7 and greater, check parent directories to see if it's under
// version control
while (dir.cdUp()) {
if (dir.entryList(QDir::AllDirs | QDir::Hidden).contains(".svn"))
return true;
}
return false;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View file

@ -50,9 +50,7 @@ TimelineWidget::TimelineWidget(QWidget *parent) : QWidget(parent) {
QLabel *label = new QLabel(tr("Recent Version")); QLabel *label = new QLabel(tr("Recent Version"));
label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
label->setAlignment(Qt::AlignHCenter); label->setAlignment(Qt::AlignHCenter);
label->setStyleSheet( label->setStyleSheet("border: 1px solid rgb(150,150,150);");
"background-color: rgb(220,220,220); border: 1px solid "
"rgb(150,150,150);");
mainLayout->addWidget(label); mainLayout->addWidget(label);
@ -72,9 +70,7 @@ TimelineWidget::TimelineWidget(QWidget *parent) : QWidget(parent) {
label = new QLabel(tr("Older Version")); label = new QLabel(tr("Older Version"));
label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
label->setAlignment(Qt::AlignHCenter); label->setAlignment(Qt::AlignHCenter);
label->setStyleSheet( label->setStyleSheet("border: 1px solid rgb(150,150,150); ");
"background-color: rgb(220,220,220); border: 1px solid "
"rgb(150,150,150); ");
mainLayout->addWidget(label); mainLayout->addWidget(label);
@ -93,7 +89,7 @@ int TimelineWidget::getCurrentIndex() const {
SVNTimeline::SVNTimeline(QWidget *parent, const QString &workingDir, SVNTimeline::SVNTimeline(QWidget *parent, const QString &workingDir,
const QString &fileName, const QStringList &auxFiles) const QString &fileName, const QStringList &auxFiles)
: Dialog(TApp::instance()->getMainWindow(), true, true) : Dialog(TApp::instance()->getMainWindow(), true, false)
, m_workingDir(workingDir) , m_workingDir(workingDir)
, m_auxFiles(auxFiles) , m_auxFiles(auxFiles)
, m_fileName(fileName) , m_fileName(fileName)
@ -121,9 +117,7 @@ SVNTimeline::SVNTimeline(QWidget *parent, const QString &workingDir,
hLayout->addStretch(); hLayout->addStretch();
m_timelineWidget = new TimelineWidget; m_timelineWidget = new TimelineWidget;
m_timelineWidget->setStyleSheet( m_timelineWidget->setStyleSheet("QListWidget:item { margin: 5px; }");
"QListWidget { background-color: white; } QListWidget:item { margin: "
"5px; }");
m_timelineWidget->hide(); m_timelineWidget->hide();
connect(m_timelineWidget->getListWidget(), SIGNAL(itemSelectionChanged()), connect(m_timelineWidget->getListWidget(), SIGNAL(itemSelectionChanged()),
this, SLOT(onSelectionChanged())); this, SLOT(onSelectionChanged()));
@ -185,7 +179,7 @@ SVNTimeline::SVNTimeline(QWidget *parent, const QString &workingDir,
SVNTimeline::~SVNTimeline() { SVNTimeline::~SVNTimeline() {
removeTempFiles(); removeTempFiles();
// Delete, if exist the sceneIcons folder // Delete, if exist the sceneIcons folder
QDir d; QDir d(QDir::tempPath());
d.rmdir("sceneIcons"); d.rmdir("sceneIcons");
} }
@ -269,8 +263,10 @@ void SVNTimeline::onLogDone(const QString &xmlResponse) {
lwi->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); lwi->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
lwi->setToolTip(tooltip); lwi->setToolTip(tooltip);
lwi->setTextAlignment(Qt::AlignLeft); lwi->setTextAlignment(Qt::AlignLeft);
m_tempFiles.append(new QTemporaryFile("svn_temp_img_" + QString::number(i) + QString tmpFileName = QDir::tempPath() + "/svn_temp_img_" +
"." + fileNameType)); QString::number(i) + "." + fileNameType;
m_tempFiles.append(new QTemporaryFile());
m_tempFiles.last()->setFileName(tmpFileName);
// Add also auxiliary files // Add also auxiliary files
TFilePath fp(TFilePath(m_workingDir.toStdWString()) + TFilePath fp(TFilePath(m_workingDir.toStdWString()) +
@ -283,10 +279,13 @@ void SVNTimeline::onLogDone(const QString &xmlResponse) {
TFilePathSet::iterator it; TFilePathSet::iterator it;
for (it = fpset.begin(); it != fpset.end(); ++it) { for (it = fpset.begin(); it != fpset.end(); ++it) {
TFilePath fp = *it; TFilePath fp = *it;
if (fp.getType() == "tpl") if (fp.getType() == "tpl") {
m_auxTempFiles.append( QString tmpFileName = QDir::tempPath() + "/svn_temp_img_" +
new QTemporaryFile("svn_temp_img_" + QString::number(i) + "." + QString::number(i) + "." +
QString::fromStdString(fp.getType()))); QString::fromStdString(fp.getType());
m_auxTempFiles.append(new QTemporaryFile());
m_auxTempFiles.last()->setFileName(tmpFileName);
}
} }
} }
// Add sceneIcon (only for scene files) // Add sceneIcon (only for scene files)
@ -296,17 +295,20 @@ void SVNTimeline::onLogDone(const QString &xmlResponse) {
QDir dir(toQString(fp.getParentDir())); QDir dir(toQString(fp.getParentDir()));
// Create the sceneIcons folder // Create the sceneIcons folder
QDir d; QDir d(QDir::tempPath());
d.mkdir("sceneIcons"); d.mkdir("sceneIcons");
m_auxTempFiles.append( QString tmpFileName = QDir::tempPath() + QString("/sceneicons/") +
new QTemporaryFile(QDir::tempPath() + QString("/sceneicons/") + "svn_temp_img_" + QString::number(i) + " .png";
"svn_temp_img_" + QString::number(i) + " .png")); m_auxTempFiles.append(new QTemporaryFile());
m_auxTempFiles.at(m_auxTempFiles.size() - 1)->setFileName(tmpFileName);
} }
} }
m_listWidgetitems.append(lwi); m_listWidgetitems.append(lwi);
} }
setMinimumSize(430, 450);
m_timelineWidget->getListWidget()->update(); m_timelineWidget->getListWidget()->update();
m_timelineWidget->show(); m_timelineWidget->show();
@ -389,14 +391,13 @@ void SVNTimeline::exportToTemporaryFile(int index, bool isAuxFile) {
// SceneIcons (pay attention to add a space at the fileName end) // SceneIcons (pay attention to add a space at the fileName end)
if (isAuxFile && fi.completeSuffix() == "png") { if (isAuxFile && fi.completeSuffix() == "png") {
args << "sceneIcons/" + fileName + " ." + extension + "@" + args << "sceneIcons/" + fileName + " .png@" + m_log.at(index).m_revision;
m_log.at(index).m_revision;
args << fi.absoluteFilePath(); args << fi.absoluteFilePath();
} else { } else {
args << fileName + "." + fi.completeSuffix() + "@" + args << m_fileName + "@" + m_log.at(index).m_revision;
m_log.at(index).m_revision;
args << fi.absoluteFilePath(); args << fi.absoluteFilePath();
} }
args << "--force";
// Export to temporary file... // Export to temporary file...
m_thread.executeCommand(m_workingDir, "svn", args, true); m_thread.executeCommand(m_workingDir, "svn", args, true);

View file

@ -579,6 +579,13 @@ void StudioPalette::setStylesGlobalNames(TPalette *palette) {
//------------------------------------------------------------------- //-------------------------------------------------------------------
void StudioPalette::save(const TFilePath &path, TPalette *palette) { void StudioPalette::save(const TFilePath &path, TPalette *palette) {
TFileStatus fs(path);
if (fs.doesExist() && !fs.isWritable()) {
throw TSystemException(path,
"The studio palette cannot be saved: it is a read "
"only studio palette.");
}
TOStream os(path); TOStream os(path);
std::map<std::string, std::string> attr; std::map<std::string, std::string> attr;
attr["name"] = ::to_string(palette->getGlobalName()); attr["name"] = ::to_string(palette->getGlobalName());

View file

@ -160,7 +160,15 @@ TFilePath searchProjectPath(TFilePath folder) {
bool isFolderUnderVersionControl(const TFilePath &folderPath) { bool isFolderUnderVersionControl(const TFilePath &folderPath) {
QDir dir(QString::fromStdWString(folderPath.getWideString())); QDir dir(QString::fromStdWString(folderPath.getWideString()));
return dir.entryList(QDir::AllDirs | QDir::Hidden).contains(".svn"); if (dir.entryList(QDir::AllDirs | QDir::Hidden).contains(".svn")) return true;
// For SVN 1.7 and greater, check parent directories to see if it's under
// version control
while (dir.cdUp()) {
if (dir.entryList(QDir::AllDirs | QDir::Hidden).contains(".svn"))
return true;
}
return false;
} }
//=================================================================== //===================================================================

View file

@ -101,6 +101,11 @@ void TXshPaletteLevel::load() {
void TXshPaletteLevel::save() { void TXshPaletteLevel::save() {
TFilePath path = getScene()->decodeFilePath(m_path); TFilePath path = getScene()->decodeFilePath(m_path);
if (TSystem::doesExistFileOrLevel(path) && m_palette) { if (TSystem::doesExistFileOrLevel(path) && m_palette) {
TFileStatus fs(path);
if (!fs.isWritable()) {
throw TSystemException(
path, "The palette cannot be saved: it is a read only palette.");
}
TOStream os(path); TOStream os(path);
os << m_palette; os << m_palette;
} }

View file

@ -1431,8 +1431,11 @@ void TXshSimpleLevel::save(const TFilePath &fp, const TFilePath &oldFp,
sl->setPalette(getPalette()); sl->setPalette(getPalette());
sl->setPath(getScene()->codeFilePath(app)); sl->setPath(getScene()->codeFilePath(app));
sl->setType(getType()); sl->setType(getType());
sl->setDirtyFlag(getDirtyFlag());
sl->addRef(); // Needed so levelUpdater doesn't destroy it right away
// when its done writing
std::set<TFrameId>::iterator eft, efEnd; std::set<TFrameId>::iterator eft, efEnd = m_editableRange.end();
for (eft = m_editableRange.begin(); eft != efEnd; ++eft) { for (eft = m_editableRange.begin(); eft != efEnd; ++eft) {
const TFrameId &fid = *eft; const TFrameId &fid = *eft;
sl->setFrame(fid, getFrame(fid, false)); sl->setFrame(fid, getFrame(fid, false));
@ -1450,6 +1453,8 @@ void TXshSimpleLevel::save(const TFilePath &fp, const TFilePath &oldFp,
hookSet->eraseFrame(fid); hookSet->eraseFrame(fid);
} }
sl->setRenumberTable();
// Copy mesh level // Copy mesh level
sl->save(app); sl->save(app);
@ -2200,9 +2205,8 @@ TFilePath TXshSimpleLevel::getExistingHookFile(
} }
assert(h >= 0); assert(h >= 0);
return (h < 0) ? TFilePath() return (h < 0) ? TFilePath() : decodedLevelPath.getParentDir() +
: decodedLevelPath.getParentDir() + TFilePath(hookFiles[h].toStdWString());
TFilePath(hookFiles[h].toStdWString());
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -2249,3 +2253,24 @@ TRectD TXshSimpleLevel::getBBox(const TFrameId &fid) const {
// Get the frame's dpi and traduce the bbox to inch coordinates // Get the frame's dpi and traduce the bbox to inch coordinates
return TScale(1.0 / dpiX, 1.0 / dpiY) * bbox; 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;
}

View file

@ -22,6 +22,7 @@
// TnzCore includes // TnzCore includes
#include "tconvert.h" #include "tconvert.h"
#include "tsystem.h"
// Qt includes // Qt includes
#include <QVBoxLayout> #include <QVBoxLayout>
@ -903,8 +904,15 @@ void PaletteViewer::saveStudioPalette() {
int ret = DVGui::MsgBox(question, QObject::tr("Overwrite"), int ret = DVGui::MsgBox(question, QObject::tr("Overwrite"),
QObject::tr("Don't Overwrite"), 0); QObject::tr("Don't Overwrite"), 0);
if (ret == 2 || ret == 0) return; if (ret == 2 || ret == 0) return;
StudioPalette::instance()->save(palettePath, palette); try {
palette->setDirtyFlag(false); StudioPalette::instance()->save(palettePath, palette);
palette->setDirtyFlag(false);
} catch (TSystemException se) {
QApplication::restoreOverrideCursor();
DVGui::warning(QString::fromStdWString(se.getMessage()));
return;
} catch (...) {
}
} }
} }
return; return;