# # # patch "res/forms/nodeinfo.ui" # from [137190ad5b2b72d2f9cbda862e05d3b9a63ea8da] # to [e4c6043616ed5f5f0406523d128a4c43517bbb05] # # patch "src/monotone/MonotoneUtil.cpp" # from [187a0a485688e4154ccd36cae9047fdc32696e58] # to [5c86539c718460b571f9d6ca3516ff82caf7d8c7] # # patch "src/monotone/MonotoneUtil.h" # from [13e7aebbd695979af145534728db918ab6effa2c] # to [6d598f1f7692ade5b5ecf4f1072d1f6040cba5f7] # # patch "src/view/panels/NodeInfo.cpp" # from [3751bf8e0640277bfe1454231f3c983ecb8013fc] # to [4ce3573fa203783d551d2b370cd45e723918cce5] # ============================================================ --- res/forms/nodeinfo.ui 137190ad5b2b72d2f9cbda862e05d3b9a63ea8da +++ res/forms/nodeinfo.ui e4c6043616ed5f5f0406523d128a4c43517bbb05 @@ -1,523 +1,501 @@ - + + NodeInfo - - + + 0 0 - 311 - 477 + 337 + 444 - - + + 0 0 - + 250 420 - + Node information - + - - - QFrame::Panel + + + 0 - - true - - - + + 0 0 - 301 - 467 + 313 + 315 - - - - - 0 + + Last Change + + + + + + Revision: - - - - 0 - 0 - 283 - 356 - - - - Last Change - - - - - - Revision: - - - - - - - - 0 - 0 - - - - %1 - - - - - - - Author: - - - - - - - Date: - - - - - - - - 0 - 0 - - - - %1 - - - - - - - Changelog: - - - - - - - - 0 - 0 - - - - Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - - 0 - 0 - - - - %1 - - - - - label - label_2 - label_6 - label_4 - lastChange_Date - lastChange_Revision - lastChange_Changelog - lastChange_Author - - - - Node Information - - - - - - Old Path: - - - - - - - New Path: - - - - - - - - 0 - 0 - - - - %1 - - - - - - - Old Node Type: - - - - - - - - 0 - 0 - - - - %1 - - - - - - - New Node Type: - - - - - - - - 0 - 0 - - - - %1 - - - - - - - Qt::Vertical - - - - 65 - 147 - - - - - - - - - 0 - 0 - - - - %1 - - - - - - - %1 - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - Added in: - - - - - - - %1 - - - true - - - - - - - Status: - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - Path: - - - - - - - - 0 - 0 - - - - %1 - - - - - - - Type: - - - - - - - - 0 - 0 - - - - %1 - - - - - - - - - 0 - 0 - 283 - 356 - - - - Filesystem Information - - - - - - - 0 - 0 - - - - %1 - - - - - - - - 0 - 0 - - - - %1 - - - - - - - %1 - - - - - - - %1 - - - - - - - %1 - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - Group: - - - - - - - Permissions: - - - - - - - Owner: - - - - - - - Size: - - - - - - - Last modified: - - - - - - - Symlink target: - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - %1 - - - - - - - Qt::Horizontal - - - - - + + + + + 0 + 0 + + + + %1 + + + + + + + Author: + + + + + + + + 0 + 0 + + + + %1 + + + + + + + Date: + + + + + + + + 0 + 0 + + + + %1 + + + + + + + Changelog: + + + + + + + + 0 + 0 + + + + Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + label + label_2 + label_6 + label_4 + lastChangeDate + lastChangeRevision + lastChangeLog + lastChangeAuthor + + + + 0 + 0 + 313 + 315 + + + + Node Information + + + + + + Old Path: + + + + + + + New Path: + + + + + + + + 0 + 0 + + + + %1 + + + + + + + Old Node Type: + + + + + + + + 0 + 0 + + + + %1 + + + + + + + New Node Type: + + + + + + + + 0 + 0 + + + + %1 + + + + + + + + 0 + 0 + + + + %1 + + + + + + + %1 + + + + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + + + + + Added in: + + + + + + + %1 + + + true + + + + + + + Status: + + + + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + + + + + Path: + + + + + + + + 0 + 0 + + + + %1 + + + + + + + + 0 + 0 + + + + %1 + + + + + + + Type: + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + 0 + 0 + 313 + 315 + + + + Filesystem Information + + + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + + + + + Symlink target: + + + + + + + Permissions: + + + + + + + Group: + + + + + + + Owner: + + + + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + + + + + %1 + + + + + + + %1 + + + + + + + %1 + + + + + + + %1 + + + + + + + Size: + + + + + + + Last modified: + + + + + + + + 0 + 0 + + + + %1 + + + + + + + + 0 + 0 + + + + %1 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + - scrollArea - fileSymlinkTarget ============================================================ --- src/monotone/MonotoneUtil.cpp 187a0a485688e4154ccd36cae9047fdc32696e58 +++ src/monotone/MonotoneUtil.cpp 5c86539c718460b571f9d6ca3516ff82caf7d8c7 @@ -350,6 +350,34 @@ QString MonotoneUtil::getFileId(const Da return data; } +QStringList MonotoneUtil::getPreviousContentMarks(const DatabaseFile & db, const QString & file, const QString & startRev) +{ + QStringList args; + args << "get_content_changed" << file << startRev; + MonotoneTask in(args); + MonotoneTask out = runSynchronousDatabaseTask(db, in); + if (!out.isFinished()) F("task aborted"); + + QStringList revs; + + QString data = out.getDecodedOutput(); + if (out.getReturnCode() > 0) + { + C(QString("Couldn't query content marks for '%1' (%2)").arg(file).arg(startRev)); + return revs; + } + + BasicIOParser parser(data); + I(parser.parse()); + foreach (const Stanza & st, parser.getStanzas()) + { + I(st.size() == 1); + revs.push_back(st.at(0).hash); + } + return revs; +} + + QStringList MonotoneUtil::topsortRevisions(const DatabaseFile & db, const QStringList & revs) { QStringList args; ============================================================ --- src/monotone/MonotoneUtil.h 13e7aebbd695979af145534728db918ab6effa2c +++ src/monotone/MonotoneUtil.h 6d598f1f7692ade5b5ecf4f1072d1f6040cba5f7 @@ -39,6 +39,7 @@ public: static RevisionCerts getRevisionCerts(const DatabaseFile &, const QString &); static FileEntryList getRevisionManifest(const DatabaseFile &, const QString &); static QStringList getPrivateKeyList(const DatabaseFile &); + static QStringList getPreviousContentMarks(const DatabaseFile &, const QString &, const QString &); static QString getFileId(const DatabaseFile &, const QString &); static QStringList topsortRevisions(const DatabaseFile &, const QStringList &); static bool getAttribute(const WorkspacePath &, const QString &, const QString &, QPair &); ============================================================ --- src/view/panels/NodeInfo.cpp 3751bf8e0640277bfe1454231f3c983ecb8013fc +++ src/view/panels/NodeInfo.cpp 4ce3573fa203783d551d2b370cd45e723918cce5 @@ -17,9 +17,9 @@ ***************************************************************************/ #include "NodeInfo.h" +#include "MonotoneUtil.h" #include -#include #include NodeInfo::NodeInfo(QWidget * parent) : QDockWidget(parent) @@ -35,6 +35,10 @@ NodeInfo::NodeInfo(QWidget * parent) : Q this, SIGNAL(showSelectRevision(const QString &)) ); + connect( + lastChangeRevision, SIGNAL(linkActivated(const QString &)), + this, SIGNAL(showSelectRevision(const QString &)) + ); resetInfo(); setWindowTitle(tr("Node information")); @@ -54,79 +58,142 @@ void NodeInfo::readAndSetInfo(const Inve I(item); I(!workspacePath.isEmpty()); - QString strFileSize("-"); - QString strFileLastModified("-"); + QString strLastChangeRevision("-"), + strLastChangeAuthor("-"), + strLastChangeDate("-"), + strLastChangelog(""); - IconProvider * ourIconProvider = IconProvider::singleton(); - if (item->isDirectory()) + if (item->isTracked()) { - fileIcon->setPixmap(ourIconProvider->getPlainFolderIcon().pixmap(64, 64)); - } - else - { - if (item->getFSType() == InventoryItem::File) + DatabaseFile db = MonotoneUtil::getDatabaseFile(workspacePath); + QStringList revs = MonotoneUtil::getPreviousContentMarks( + db, + item->getPath(), + MonotoneUtil::getBaseWorkspaceRevision(workspacePath) + ); + + // FIXME: for now we only handle the first returned content + // mark; its not clear if merges would really pop up here + if (revs.size() > 1) { - QFileInfo fileInfo(workspacePath + "/" + item->getPath()); - I(fileInfo.exists()); - strFileSize = QString("%1 KB").arg(fileInfo.size() / 1024); - // FIXME: use Qt::DefaultLocaleShortDate if support for Qt 4.3 is dropped - strFileLastModified = fileInfo.lastModified().toString(Qt::LocaleDate); - QFileIconProvider iconProvider; - fileIcon->setPixmap(iconProvider.icon(fileInfo).pixmap(64, 64)); + W(QString("multiple content marks returned, only using the first")); } - else + + strLastChangeRevision = QObject::tr("%2...") + .arg(revs.at(0)) + .arg(revs.at(0).left(12)); + + RevisionCerts certs = MonotoneUtil::getRevisionCerts(db, revs.at(0)); + + // FIXME: we do not handle merge revisions here + foreach (const RevisionCert & cert, certs) { - fileIcon->setPixmap(ourIconProvider->getPlainFileIcon().pixmap(64, 64)); + if (cert.first == "author") strLastChangeAuthor = cert.second; + if (cert.first == "changelog") strLastChangelog = cert.second; + if (cert.first == "date") + { + QDateTime dt = QDateTime::fromString(cert.second); + strLastChangeDate = dt.toString(Qt::LocaleDate); + } } } - filePath->setText(tr("Current Path: %1").arg(item->getPath())); - fileStatus->setText(tr("Status: %1").arg(item->getStatusString())); + lastChangeRevision->setText(strLastChangeRevision); + lastChangeAuthor->setText(strLastChangeAuthor); + lastChangeDate->setText(strLastChangeDate); + lastChangeLog->setPlainText(strLastChangelog); + QString strFileSize("-"), + strFileLastModified("-"), + strFileOwner("-"), + strFileGroup("-"), + strFilePermissions("-"), + strFileSymlinkTarget("-"); + + if (item->getFSType() != InventoryItem::None) + { + QFileInfo fileInfo(workspacePath + "/" + item->getPath()); + I(fileInfo.exists()); + strFileSize = QString("%1 KB").arg(fileInfo.size() / 1024); + // FIXME: use Qt::DefaultLocaleShortDate if support for Qt 4.3 is dropped + strFileLastModified = fileInfo.lastModified().toString(Qt::LocaleDate); + +#ifdef Q_OS_UNIX + strFileOwner = QString("%1 (UID %2)").arg(fileInfo.owner()).arg(fileInfo.ownerId()); + strFileGroup = QString("%1 (GID %2)").arg(fileInfo.group()).arg(fileInfo.groupId()); + QFile::Permissions perms = fileInfo.permissions(); + strFilePermissions = QString("%1%2%3 %4%5%6 %7%8%9") + .arg((perms & QFile::ReadUser) == QFile::ReadUser ? "r" : "-") + .arg((perms & QFile::WriteUser) == QFile::WriteUser ? "w" : "-") + .arg((perms & QFile::ExeUser) == QFile::ExeUser ? "x" : "-") + .arg((perms & QFile::ReadGroup) == QFile::ReadGroup ? "r" : "-") + .arg((perms & QFile::WriteGroup) == QFile::WriteGroup ? "w" : "-") + .arg((perms & QFile::ExeGroup) == QFile::ExeGroup ? "x" : "-") + .arg((perms & QFile::ReadOther) == QFile::ReadOther ? "r" : "-") + .arg((perms & QFile::WriteOther) == QFile::WriteOther ? "w" : "-") + .arg((perms & QFile::ExeOther) == QFile::ExeOther ? "x" : "-"); +#endif + + if (fileInfo.isSymLink()) + strFileSymlinkTarget = fileInfo.symLinkTarget(); + } + + fileSize->setText(strFileSize); + fileLastModified->setText(strFileLastModified); + fileOwner->setText(strFileOwner); + fileGroup->setText(strFileGroup); + filePermissions->setText(strFilePermissions); + fileSymlinkTarget->setText(strFileSymlinkTarget); + + filePath->setText(item->getPath()); + fileStatus->setText(item->getStatusString()); + QString renameSource = item->getRenameSource(); if (renameSource.isEmpty()) renameSource = "-"; - fileOldPath->setText(tr("Old Path: %1").arg(renameSource)); + fileOldPath->setText(renameSource); QString renameTarget = item->getRenameTarget(); if (renameTarget.isEmpty()) renameTarget = "-"; - fileNewPath->setText(tr("New Path: %1").arg(renameTarget)); + fileNewPath->setText(renameTarget); QString birthRev = item->getBirthRevision(); if (!birthRev.isEmpty()) { - fileBirthRev->setText(tr("Added in: %2..."). + fileBirthRev->setText(tr("%2..."). arg(birthRev). arg(birthRev.left(12))); } else { - fileBirthRev->setText(tr("Added in: %1").arg("-")); + fileBirthRev->setText("-"); } - fileSize->setText(tr("%1").arg(strFileSize)); - fileBaseType->setText(tr("Old Node Type: %1"). - arg(InventoryItem::translateFileType(item->getOldType()))); - fileNewType->setText(tr("New Node Type: %1"). - arg(InventoryItem::translateFileType(item->getNewType()))); - fileDiskType->setText(tr("Current Node Type: %1"). - arg(InventoryItem::translateFileType(item->getFSType()))); - fileLastModified->setText(tr("Last Modified: %1").arg(strFileLastModified)); + fileBaseType->setText(InventoryItem::translateFileType(item->getOldType())); + fileNewType->setText(InventoryItem::translateFileType(item->getNewType())); + fileDiskType->setText(InventoryItem::translateFileType(item->getFSType())); } void NodeInfo::resetInfo() { - IconProvider * ourIconProvider = IconProvider::singleton(); - fileIcon->setPixmap(ourIconProvider->getPlainFileIcon().pixmap(64, 64)); + lastChangeRevision->setText("-"); + lastChangeAuthor->setText("-"); + lastChangeDate->setText("-"); + lastChangeLog->setPlainText(""); - filePath->setText(tr("Current Path: %1").arg("-")); - fileStatus->setText(tr("Status: %1").arg("-")); - fileOldPath->setText(tr("Old Path: %1").arg("-")); - fileNewPath->setText(tr("New Path: %1").arg("-")); - fileBirthRev->setText(tr("Added in: %1").arg("-")); - fileSize->setText(tr("%1").arg("-")); - fileBaseType->setText(tr("Old Node Type: %1").arg("-")); - fileNewType->setText(tr("New Node Type: %1").arg("-")); - fileDiskType->setText(tr("Current Node Type: %1").arg("-")); - fileLastModified->setText(tr("Last Modified: %1").arg("-")); + filePath->setText("-"); + fileStatus->setText("-"); + fileOldPath->setText("-"); + fileNewPath->setText("-"); + fileBirthRev->setText("-"); + fileBaseType->setText("-"); + fileNewType->setText("-"); + fileDiskType->setText("-"); + + fileLastModified->setText("-"); + fileSize->setText("-"); + fileOwner->setText("-"); + fileGroup->setText("-"); + filePermissions->setText("-"); + fileSymlinkTarget->setText("-"); }