#include "tcontenthistory.h"
#include <QString>
#include <QDateTime>
#include <QStringList>
#include <QProcess>
#include <QTextStream>
#ifdef WIN32
#include <Windows.h>
#endif
#include <map>
#include <QFile>
/*
class HistoryRec
{
QDateTime m_date;
HistoryRec(const QDateTime&date QString&user, const QString&machine)
: date(date)
, m_user
};
*/
using namespace std;
//-------------------------------------------------------
TContentHistory::TContentHistory(bool isLevel)
: m_isLevel(isLevel), m_frozenHistory()
{
}
//-------------------------------------------------------
TContentHistory::~TContentHistory()
{
}
//-------------------------------------------------------
TContentHistory *TContentHistory::clone() const
{
TContentHistory *history = new TContentHistory(m_isLevel);
history->deserialize(serialize());
return history;
}
//-------------------------------------------------------
void TContentHistory::deserialize(const QString ¤tHistory)
{
m_frozenHistory = currentHistory;
}
/*
QStringList strlist = str.split("#");
//skip strlist[0], is the header
int i;
for (i=1; i<strlist.size();i++)
{
QString str = strlist.at(i);
parseLine(&str);
}
}*/
//--------------------------------------------------------------------
inline QString blanks(const QString &str, int count = 15)
{
QString res = str;
if (res.size() >= count)
res.truncate(count);
else
res += QString(count - str.size(), ' ');
return res;
}
//--------------------------------------------------------------------
inline QString getStr(const TFrameId &id)
{
if (id.getLetter() != 0)
return QString::number(id.getNumber()) + id.getLetter();
else
return QString::number(id.getNumber());
}
//--------------------------------------------------------------------
const QString Fmt = "dd MMM yy hh:mm";
QString getLine(int counter, const QDateTime &date, const set<TFrameId> &frames)
{
static QString user;
static QString machine;
if (user == "") {
QStringList list = QProcess::systemEnvironment();
int j;
for (j = 0; j < list.size(); j++) {
QString value = list.at(j);
if (value.startsWith("USERNAME="))
user = blanks(value.right(value.size() - 9));
else if (value.startsWith("COMPUTERNAME="))
machine = blanks(value.right(value.size() - 13));
}
}
if (frames.empty())
return "| #" + blanks(QString::number(counter), 4) + blanks(date.toString(Fmt), 20) + blanks(machine, 12) + user + " |";
QString framesStr;
set<TFrameId>::const_iterator it = frames.begin();
TFrameId first, last;
while (it != frames.end()) {
first = last = *it;
++it;
while (it != frames.end() &&
((*it).getNumber() == last.getNumber() || // 1a, 1b....
(*it).getNumber() == last.getNumber() + 1)) {
assert(*it > last);
last = *it, ++it;
}
framesStr += getStr(first) + ((first != last) ? "-" + getStr(last) : "");
if (it != frames.end())
framesStr += ", ";
}
return "| #" + blanks(QString::number(counter), 4) + blanks(date.toString(Fmt), 20) + blanks(machine, 12) + user + blanks(framesStr, 20) + " |";
}
//--------------------------------------------------------------------
int getCurrentCount(const QString &str)
{
if (str == "")
return 0;
int from = str.lastIndexOf('#') + 1;
assert(from != -1);
int to = str.indexOf(" ", from) - 1;
assert(to != -1);
assert(from <= to);
return (str.mid(from, to - from + 1)).toInt();
}
//--------------------------------------------------------------------
const QString TContentHistory::currentToString() const
{
if (m_records.empty())
return "";
int counter = getCurrentCount(m_frozenHistory);
if (!m_isLevel) {
assert(m_records.size() == 1);
return getLine(++counter, m_records.begin()->second, set<TFrameId>());
}
QString out;
std::multimap<QDateTime, TFrameId> dateSorted;
std::map<TFrameId, QDateTime>::const_iterator it;
for (it = m_records.begin(); it != m_records.end(); ++it)
dateSorted.insert(pair<QDateTime, TFrameId>(it->second, it->first));
std::multimap<QDateTime, TFrameId>::const_iterator it1 = dateSorted.begin();
QDateTime currDate = it1->first;
while (it1 != dateSorted.end()) {
set<TFrameId> frames;
while (it1 != dateSorted.end() && currDate == it1->first) {
frames.insert(it1->second);
++it1;
}
assert(!frames.empty());
out += getLine(++counter, currDate, frames);
if (it1 != dateSorted.end())
currDate = it1->first;
}
return out;
}
//--------------------------------------------------------------------
const QString TContentHistory::serialize() const
{
const QString currentHistory = currentToString();
if (m_frozenHistory != "")
return m_frozenHistory + currentHistory;
else if (currentHistory != "") {
if (m_isLevel)
return "| # DATE: Time: MACHINE: USER: FRAMES MODIFIED: |" + currentHistory;
else
return "| # DATE: Time: MACHINE: USER: |" + currentHistory;
} else
return "";
}
//--------------------------------------------------------------------
void TContentHistory::fixCurrentHistory()
{
m_frozenHistory = serialize();
m_records.clear();
}
//--------------------------------------------------------------------
void TContentHistory::frameRangeModifiedNow(const TFrameId &fromId, const TFrameId &toId)
{
assert(m_isLevel);
QDateTime date = QDateTime::currentDateTime();
QDateTime dateNoSecs(date.date(), date.time().addSecs(-date.time().second()));
assert(dateNoSecs.secsTo(date) == date.time().second());
int i;
m_records[fromId] = dateNoSecs;
if (fromId == toId)
return;
for (i = fromId.getNumber() + 1; i <= toId.getNumber() - 1; i++)
m_records[TFrameId(i)] = dateNoSecs;
m_records[toId] = dateNoSecs;
}
//--------------------------------------------------------------------
void TContentHistory::modifiedNow()
{
assert(!m_isLevel);
QDateTime date = QDateTime::currentDateTime();
QDateTime dateNoSecs(date.date(), date.time().addSecs(-date.time().second()));
assert(dateNoSecs.secsTo(date) == date.time().second());
m_records[0] = dateNoSecs;
}
/*
void testHistory()
{
{
TContentHistory ch(true);
ch.frameModifiedNow(TFrameId(13));
Sleep(1000);
ch.frameModifiedNow(TFrameId(3, 'c'));
ch.frameRangeModifiedNow(TFrameId(5), TFrameId(7));
ch.fixCurrentHistory();
Sleep(2000);
ch.frameRangeModifiedNow(TFrameId(6), TFrameId(9));
ch.frameModifiedNow(TFrameId(11));
QString str1 = ch.serialize();
TContentHistory ch1(true);
ch1.deserialize(str1);
ch1.frameRangeModifiedNow(TFrameId(2), TFrameId(3, 'c'));
Sleep(2000);
ch1.frameModifiedNow(TFrameId(3, 'a'));
ch1.fixCurrentHistory();
Sleep(2000);
ch1.frameModifiedNow(TFrameId(11, 'b'));
ch1.frameModifiedNow(TFrameId(12));
QString str2 = ch1.serialize();
QFile f("C:\\temp\\out.txt");
f.open(QIODevice::WriteOnly | QIODevice::Text);
QTextStream out(&f);
out << str2;
}
{
TContentHistory ch(false);
ch.modifiedNow();
Sleep(1000);
ch.modifiedNow();
ch.modifiedNow();
ch.fixCurrentHistory();
Sleep(2000);
ch.modifiedNow();
ch.modifiedNow();
QString str1 = ch.serialize();
TContentHistory ch1(false);
ch1.deserialize(str1);
ch1.modifiedNow();
Sleep(2000);
ch1.modifiedNow();
ch1.fixCurrentHistory();
Sleep(2000);
ch1.modifiedNow();
ch1.modifiedNow();
QString str2 = ch1.serialize();
QFile f("C:\\temp\\out1.txt");
f.open(QIODevice::WriteOnly | QIODevice::Text);
QTextStream out(&f);
out << str2;
}
}
*/