/* * This file is part of muCommander, http://www.mucommander.com * Copyright (C) 2002-2016 Maxence Bernard * * muCommander is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * muCommander is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.mucommander.job; import com.mucommander.job.impl.TransferFileJob; import com.mucommander.text.DurationFormat; import com.mucommander.text.Translator; /** * Contains information about job progress. * */ public class JobProgress { private FileJob job; private TransferFileJob transferFileJob; private long effectiveJobTime; private long lastTime; private int totalPercentInt; private String totalProgressText; private int filePercentInt; private String fileProgressText; private long currentBps; private long bytesTotal; private long totalBps; private long lastBytesTotal; private String jobStatusString; private long jobPauseStartDate; public JobProgress(FileJob job) { this.job = job; if (job instanceof TransferFileJob) { this.transferFileJob = (TransferFileJob) job; } lastBytesTotal = 0; lastTime = System.currentTimeMillis(); } /** * Calculates the job progress status. This method calculates variables used * to show job progress information. It can update information only on a * processed file (when <code>labelOnly</code> is <code>true</code>). If * <code>labelOnly</code> is false it will try to update full information on * a job progress (e.g. percent completed, bytes per second, etc.). * * @param fullUpdate * <code>true</code> update all information about processed file.<br/> * <code>false</code> update only label of a processed file.<br/> * Note that if a job has just finished this flag is ignored * and all variables are recalulated. * @return <code>true</code> if full job progress has been updated, * <code>false</code> if only label has been updated. */ public boolean calcJobProgress(boolean fullUpdate) { FileJobState jobState = job.getState(); jobPauseStartDate = job.getPauseStartDate(); if (jobState == FileJobState.FINISHED || jobState == FileJobState.INTERRUPTED) { jobStatusString = Translator.get("progress_dialog.job_finished"); // Job just finished, let's loop one more time to ensure that // components (progress bar in particular) // reflect job completion fullUpdate = true; } else { jobStatusString = job.getStatusString(); } if (!fullUpdate) { return false; } // Do not refresh progress information is job is paused, simply sleep if (jobState == FileJobState.PAUSED) { return false; } // Now is updated with current time, or job end date if job has finished // already. long now = job.getEndDate(); if (now == 0) { // job hasn't finished yet now = System.currentTimeMillis(); } long currentFileRemainingTime = 0; long totalRemainingTime; effectiveJobTime = job.getEffectiveJobTime(); if (effectiveJobTime == 0) { effectiveJobTime = 1; // To avoid potential zero divisions } if (transferFileJob != null) { bytesTotal = transferFileJob.getTotalByteCount() - transferFileJob.getTotalSkippedByteCount(); totalBps = (long) (bytesTotal * 1000d / effectiveJobTime); if (now - lastTime > 0) { // To avoid divisions by zero currentBps = (long) ((bytesTotal - lastBytesTotal) * 1000d / (now - lastTime)); } else { currentBps = 0; } // Update current file progress bar float filePercentFloat = transferFileJob.getFilePercentDone(); filePercentInt = (int) (100 * filePercentFloat); fileProgressText = filePercentInt + "%"; // Append estimated remaining time (ETA) if current file transfer is // not already finished (100%) if (filePercentFloat < 1) { fileProgressText += " - "; long currentFileSize = transferFileJob.getCurrentFileSize(); // If current file size is not available, ETA cannot be // calculated if (currentFileSize == -1) { fileProgressText += "?"; } // Avoid potential divisions by zero else if (totalBps == 0) { currentFileRemainingTime = -1; fileProgressText += DurationFormat.getInfiniteSymbol(); } else { currentFileRemainingTime = (long) ((1000 * (currentFileSize - transferFileJob.getCurrentFileByteCount())) / (float) totalBps); fileProgressText += DurationFormat.format(currentFileRemainingTime); } } lastBytesTotal = bytesTotal; lastTime = now; } // Update total progress bar // Total job percent is based on the *number* of files remaining, not // their actual size. // So this is very approximate. float totalPercentFloat = job.getTotalPercentDone(); totalPercentInt = (int) (100 * totalPercentFloat); totalProgressText = totalPercentInt + "%"; // Add a rough estimate of the total remaining time (ETA): // total remaining time is based on the total job percent completed // which itself is based on the *number* // of files remaining, not their actual size. So this is very // approximate. // Do not add ETA if job is already finished (100%) if (totalPercentFloat < 1) { totalProgressText += " - "; // Avoid potential divisions by zero if (totalPercentFloat == 0) { totalProgressText += "?"; } else { // Make sure that total ETA is never smaller than current file // ETA totalRemainingTime = (long) ((1 - totalPercentFloat) * (effectiveJobTime / totalPercentFloat)); totalRemainingTime = Math.max(totalRemainingTime, currentFileRemainingTime); totalProgressText += DurationFormat.format(totalRemainingTime); } } return true; } public String getJobStatusString() { return jobStatusString; } public boolean isTransferFileJob() { return transferFileJob != null; } public int getFilePercentInt() { return filePercentInt; } public String getFileProgressText() { return fileProgressText; } public long getBytesTotal() { return bytesTotal; } public long getTotalBps() { return totalBps; } public long getLastTime() { return lastTime; } public long getCurrentBps() { return currentBps; } public int getTotalPercentInt() { return totalPercentInt; } public String getTotalProgressText() { return totalProgressText; } public long getEffectiveJobTime() { return effectiveJobTime; } public long getJobPauseStartDate() { return jobPauseStartDate; } }