This commit is contained in:
Igor Pavlov
2015-06-15 00:00:00 +00:00
committed by Kornel Lesiński
parent 0713a3ab80
commit 54490d51d5
591 changed files with 34932 additions and 16390 deletions
+279 -86
View File
@@ -2,112 +2,305 @@
#include "StdAfx.h"
#include <stdio.h>
#include "../../../Common/IntToString.h"
#include "../../../Common/StringConvert.h"
#include "FarUtils.h"
#include "ProgressBox.h"
static void CopySpaces(char *dest, int numSpaces)
void CPercentPrinterState::ClearCurState()
{
int i;
for (i = 0; i < numSpaces; i++)
dest[i] = ' ';
dest[i] = '\0';
Completed = 0;
Total = ((UInt64)(Int64)-1);
Files = 0;
FilesTotal = 0;
Command.Empty();
FileName.Empty();
}
void ConvertUInt64ToStringAligned(UInt64 value, char *s, int alignSize)
{
char temp[32];
ConvertUInt64ToString(value, temp);
int len = (int)strlen(temp);
int numSpaces = 0;
if (len < alignSize)
{
numSpaces = alignSize - len;
CopySpaces(s, numSpaces);
}
strcpy(s + numSpaces, temp);
}
// ---------- CMessageBox ----------
static const int kMaxLen = 255;
void CMessageBox::Init(const AString &title, int width)
void CProgressBox::Init(const AString &title)
{
_title = title;
_width = MyMin(width, kMaxLen);
_wasPrinted = false;
StartTick = GetTickCount();
_prevTick = StartTick;
_prevElapsedSec = 0;
}
void CMessageBox::ShowMessages(const char *strings[], int numStrings)
static unsigned GetPower32(UInt32 val)
{
const int kNumStaticStrings = 1;
const int kNumStringsMax = 10;
if (numStrings > kNumStringsMax)
numStrings = kNumStringsMax;
const char *msgItems[kNumStaticStrings + kNumStringsMax];
msgItems[0] = _title;
char formattedMessages[kNumStringsMax][kMaxLen + 1];
for (int i = 0; i < numStrings; i++)
const unsigned kStart = 32;
UInt32 mask = ((UInt32)1 << (kStart - 1));
for (unsigned i = kStart;; i--)
{
char *formattedMessage = formattedMessages[i];
const char *s = strings[i];
int len = (int)strlen(s);
if (len < kMaxLen)
if (i == 0 || (val & mask) != 0)
return i;
mask >>= 1;
}
}
static unsigned GetPower64(UInt64 val)
{
UInt32 high = (UInt32)(val >> 32);
if (high == 0)
return GetPower32((UInt32)val);
return GetPower32(high) + 32;
}
static UInt64 MyMultAndDiv(UInt64 mult1, UInt64 mult2, UInt64 divider)
{
unsigned pow1 = GetPower64(mult1);
unsigned pow2 = GetPower64(mult2);
while (pow1 + pow2 > 64)
{
if (pow1 > pow2) { pow1--; mult1 >>= 1; }
else { pow2--; mult2 >>= 1; }
divider >>= 1;
}
UInt64 res = mult1 * mult2;
if (divider != 0)
res /= divider;
return res;
}
#define UINT_TO_STR_2(val) { s[0] = (char)('0' + (val) / 10); s[1] = (char)('0' + (val) % 10); s += 2; }
static void GetTimeString(UInt64 timeValue, char *s)
{
UInt64 hours = timeValue / 3600;
UInt32 seconds = (UInt32)(timeValue - hours * 3600);
UInt32 minutes = seconds / 60;
seconds %= 60;
if (hours > 99)
{
ConvertUInt64ToString(hours, s);
for (; *s != 0; s++);
}
else
{
UInt32 hours32 = (UInt32)hours;
UINT_TO_STR_2(hours32);
}
*s++ = ':'; UINT_TO_STR_2(minutes);
*s++ = ':'; UINT_TO_STR_2(seconds);
*s = 0;
}
void CProgressBox::ReduceString(const UString &src, AString &dest)
{
UnicodeStringToMultiByte2(dest, src, CP_OEMCP);
if (dest.Len() <= MaxLen)
return;
unsigned len = FileName.Len();
for (; len != 0;)
{
unsigned delta = len / 8;
if (delta == 0)
delta = 1;
len -= delta;
_tempU = FileName;
_tempU.Delete(len / 2, FileName.Len() - len);
_tempU.Insert(len / 2, L" . ");
UnicodeStringToMultiByte2(dest, _tempU, CP_OEMCP);
if (dest.Len() <= MaxLen)
return;
}
dest.Empty();
}
static void Print_UInt64_and_String(AString &s, UInt64 val, const char *name)
{
char temp[32];
ConvertUInt64ToString(val, temp);
s += temp;
s.Add_Space();
s += name;
}
static void PrintSize_bytes_Smart(AString &s, UInt64 val)
{
// Print_UInt64_and_String(s, val, "bytes");
{
char temp[32];
ConvertUInt64ToString(val, temp);
s += temp;
}
if (val == 0)
return;
unsigned numBits = 10;
char c = 'K';
char temp[4] = { 'K', 'i', 'B', 0 };
if (val >= ((UInt64)10 << 30)) { numBits = 30; c = 'G'; }
else if (val >= ((UInt64)10 << 20)) { numBits = 20; c = 'M'; }
temp[0] = c;
s += " (";
Print_UInt64_and_String(s, ((val + ((UInt64)1 << numBits) - 1) >> numBits), temp);
s += ')';
}
static const unsigned kPercentsSize = 4;
void CProgressBox::Print()
{
DWORD tick = GetTickCount();
DWORD elapsedTicks = tick - StartTick;
DWORD elapsedSec = elapsedTicks / 1000;
if (_wasPrinted)
{
if (elapsedSec == _prevElapsedSec)
{
int size = MyMax(_width, len);
int startPos = (size - len) / 2;
CopySpaces(formattedMessage, startPos);
strcpy(formattedMessage + startPos, s);
CopySpaces(formattedMessage + startPos + len, size - startPos - len);
if ((UInt32)(tick - _prevTick) < _tickStep)
return;
if (_printedState.IsEqualTo((const CPercentPrinterState &)*this))
return;
}
}
UInt64 cur = Completed;
UInt64 total = Total;
if (!UseBytesForPercents)
{
cur = Files;
total = FilesTotal;
}
{
_timeStr.Empty();
_timeStr = "Elapsed time: ";
char s[40];
GetTimeString(elapsedSec, s);
_timeStr += s;
if (cur != 0)
{
UInt64 remainingTime = 0;
if (cur < total)
remainingTime = MyMultAndDiv(elapsedTicks, total - cur, cur);
UInt64 remainingSec = remainingTime / 1000;
_timeStr += " Remaining time: ";
GetTimeString(remainingSec, s);
_timeStr += s;
}
}
{
_perc.Empty();
char s[32];
unsigned size;
{
UInt64 val = 0;
if (total != (UInt64)(Int64)-1 && total != 0)
val = cur * 100 / Total;
ConvertUInt64ToString(val, s);
size = (unsigned)strlen(s);
s[size++] = '%';
s[size] = 0;
}
unsigned len = size;
while (len < kPercentsSize)
len = kPercentsSize;
len++;
if (len < MaxLen)
{
unsigned numChars = MaxLen - len;
unsigned filled = 0;
if (total != (UInt64)(Int64)-1 && total != 0)
filled = (unsigned)(cur * numChars / total);
unsigned i = 0;
if (filled < numChars)
{
for (i = 0; i < filled; i++)
_perc += '=';
}
for (; i < numChars; i++)
_perc += '.';
}
_perc.Add_Space();
while (size < kPercentsSize)
{
_perc.Add_Space();
size++;
}
_perc += s;
}
_files.Empty();
if (Files != 0 || FilesTotal != 0)
{
_files += "Files: ";
char s[32];
// if (Files != 0)
{
ConvertUInt64ToString(Files, s);
_files += s;
}
if (FilesTotal != 0)
{
_files += " / ";
ConvertUInt64ToString(FilesTotal, s);
_files += s;
}
}
_sizesStr.Empty();
if (Total != 0)
{
_sizesStr += "Size: ";
PrintSize_bytes_Smart(_sizesStr, Completed);
if (Total != 0 && Total != (UInt64)(Int64)-1)
{
_sizesStr += " / ";
PrintSize_bytes_Smart(_sizesStr, Total);
}
}
_name1.Empty();
_name2.Empty();
if (!FileName.IsEmpty())
{
_name1U.Empty();
_name2U.Empty();
/*
if (_isDir)
s1 = _filePath;
else
*/
{
strncpy(formattedMessage, s, kMaxLen);
formattedMessage[kMaxLen] = 0;
int slashPos = FileName.ReverseFind_PathSepar();
if (slashPos >= 0)
{
_name1U.SetFrom(FileName, slashPos + 1);
_name2U = FileName.Ptr(slashPos + 1);
}
else
_name2U = FileName;
}
msgItems[kNumStaticStrings + i] = formattedMessage;
ReduceString(_name1U, _name1);
ReduceString(_name2U, _name2);
}
NFar::g_StartupInfo.ShowMessage(0, NULL, msgItems, kNumStaticStrings + numStrings, 0);
}
// ---------- CProgressBox ----------
void CProgressBox::Init(const AString &title, int width)
{
CMessageBox::Init(title, width);
_prevMessage.Empty();
_prevPercentMessage.Empty();
_wasShown = false;
}
void CProgressBox::Progress(const UInt64 *total, const UInt64 *completed, const AString &message)
{
AString percentMessage;
if (total != 0 && completed != 0)
{
UInt64 totalVal = *total;
if (totalVal == 0)
totalVal = 1;
char buf[32];
ConvertUInt64ToStringAligned(*completed * 100 / totalVal, buf, 3);
strcat(buf, "%");
percentMessage = buf;
}
if (message != _prevMessage || percentMessage != _prevPercentMessage || !_wasShown)
{
_prevMessage = message;
_prevPercentMessage = percentMessage;
const char *strings[] = { message, percentMessage };
ShowMessages(strings, ARRAY_SIZE(strings));
_wasShown = true;
const char *strings[] = { _title, _timeStr, _files, _sizesStr, Command, _name1, _name2, _perc };
NFar::g_StartupInfo.ShowMessage(FMSG_LEFTALIGN, NULL, strings, ARRAY_SIZE(strings), 0);
}
_wasPrinted = true;
_printedState = *this;
_prevTick = tick;
_prevElapsedSec = elapsedSec;
}