Index: changelog.txt
===================================================================
diff -u
--- changelog.txt	(revision 0)
+++ changelog.txt	(revision 814b694086d5dc450efb6a5e5c6902145ddc07fd)
@@ -0,0 +1,24 @@
+1.50
+User feedback improvements:
+* Added possibility to define automatic responses to user-feedback dialogs (file already exists, not enough space, error) for fully unattended operations
+* Added possibility to rename file when file already exists
+
+Better filtering support:
+* Added regex-based file and path filtering options
+* Added glob-based path filtering options
+
+GUI:
+* Simplified task edit and user-feedback dialogs
+* Adjusted the look of mini-view dialog
+* Added context menus to both status dialog and mini-view
+
+Other:
+* Task definition xml files now uses human-readable attribute values instead of numeric ones
+
+Breaking changes:
+* Multiple filters are now separated with semicolon instead of vertical line
+* Removed support for Windows XP and Windows Vista
+* Removed support for outdated html help
+
+Development changes:
+* Updated toolsets used to build binaries - InnoSetup to 6.0, Visual Studio to 2019
Index: src/ch/GuiOptions.cpp
===================================================================
diff -u
--- src/ch/GuiOptions.cpp	(revision 0)
+++ src/ch/GuiOptions.cpp	(revision 814b694086d5dc450efb6a5e5c6902145ddc07fd)
@@ -0,0 +1,130 @@
+// ============================================================================
+//  Copyright (C) 2001-2020 by Jozef Starosczyk
+//  ixen {at} copyhandler [dot] com
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU Library General Public License
+//  (version 2) as published by the Free Software Foundation;
+//
+//  This program 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 Library General Public
+//  License along with this program; if not, write to the
+//  Free Software Foundation, Inc.,
+//  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+// ============================================================================
+#include "stdafx.h"
+#include "GuiOptions.h"
+
+using namespace chengine;
+
+bool GuiOptions::IsPauseAvailable(chengine::ETaskCurrentState eState)	//ok
+{
+	switch(eState)
+	{
+	case eTaskState_None:
+	case eTaskState_Max:
+	case eTaskState_LoadError:
+	case eTaskState_Finished:
+	case eTaskState_Cancelled:
+	case eTaskState_Paused:
+		return false;
+
+	default:
+		return true;
+	}
+}
+
+bool GuiOptions::IsResumeAvailable(chengine::ETaskCurrentState eState)	//ok
+{
+	switch(eState)
+	{
+	case eTaskState_None:
+	case eTaskState_Max:
+	case eTaskState_LoadError:
+	case eTaskState_Finished:
+	case eTaskState_Cancelled:
+	case eTaskState_Processing:
+	case eTaskState_Error:
+		return false;
+
+	case eTaskState_Paused:
+	case eTaskState_Waiting:
+	default:
+		return true;
+	}
+}
+
+bool GuiOptions::IsRestartAvailable(chengine::ETaskCurrentState eState)	//ok
+{
+	switch(eState)
+	{
+	case eTaskState_None:
+	case eTaskState_Max:
+	case eTaskState_LoadError:
+		return false;
+
+	default:
+		return true;
+	}
+}
+
+bool GuiOptions::IsCancelAvailable(chengine::ETaskCurrentState eState)	//ok
+{
+	switch(eState)
+	{
+	case eTaskState_None:
+	case eTaskState_Max:
+	case eTaskState_LoadError:
+	case eTaskState_Finished:
+	case eTaskState_Cancelled:
+		return false;
+
+	default:
+		return true;
+	}
+}
+
+bool GuiOptions::IsDeleteAvailable(chengine::ETaskCurrentState eState)	//ok
+{
+	switch(eState)
+	{
+	case eTaskState_None:
+	case eTaskState_Max:
+	case eTaskState_LoadError:
+		return false;
+
+	default:
+		return true;
+	}
+}
+
+bool GuiOptions::IsShowLogAvailable(chengine::ETaskCurrentState eState)	//ok
+{
+	switch(eState)
+	{
+	case eTaskState_None:
+	case eTaskState_Max:
+		return false;
+
+	default:
+		return true;
+	}
+}
+
+bool GuiOptions::IsResetUserFeedbackAvailable(chengine::ETaskCurrentState eState)
+{
+	switch(eState)
+	{
+	case eTaskState_None:
+	case eTaskState_Max:
+	case eTaskState_LoadError:
+		return false;
+
+	default:
+		return true;
+	}
+}
Index: src/ch/GuiOptions.h
===================================================================
diff -u
--- src/ch/GuiOptions.h	(revision 0)
+++ src/ch/GuiOptions.h	(revision 814b694086d5dc450efb6a5e5c6902145ddc07fd)
@@ -0,0 +1,34 @@
+// ============================================================================
+//  Copyright (C) 2001-2020 by Jozef Starosczyk
+//  ixen {at} copyhandler [dot] com
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU Library General Public License
+//  (version 2) as published by the Free Software Foundation;
+//
+//  This program 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 Library General Public
+//  License along with this program; if not, write to the
+//  Free Software Foundation, Inc.,
+//  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+// ============================================================================
+#pragma once
+
+#include "../libchengine/ETaskCurrentState.h"
+
+class GuiOptions
+{
+public:
+	static bool IsPauseAvailable(chengine::ETaskCurrentState eState);
+	static bool IsResumeAvailable(chengine::ETaskCurrentState eState);
+	static bool IsRestartAvailable(chengine::ETaskCurrentState eState);
+	static bool IsCancelAvailable(chengine::ETaskCurrentState eState);
+	static bool IsDeleteAvailable(chengine::ETaskCurrentState eState);
+
+	static bool IsShowLogAvailable(chengine::ETaskCurrentState eState);
+	static bool IsResetUserFeedbackAvailable(chengine::ETaskCurrentState eState);
+};
Index: src/ch/MiniViewDlg.cpp
===================================================================
diff -u -r547f865c69434c14c6f16e4b529d4198f6fe2040 -r814b694086d5dc450efb6a5e5c6902145ddc07fd
--- src/ch/MiniViewDlg.cpp	(.../MiniViewDlg.cpp)	(revision 547f865c69434c14c6f16e4b529d4198f6fe2040)
+++ src/ch/MiniViewDlg.cpp	(.../MiniViewDlg.cpp)	(revision 814b694086d5dc450efb6a5e5c6902145ddc07fd)
@@ -1,21 +1,21 @@
-/***************************************************************************
-*   Copyright (C) 2001-2008 by Jozef Starosczyk                           *
-*   ixen@copyhandler.com                                                  *
-*                                                                         *
-*   This program is free software; you can redistribute it and/or modify  *
-*   it under the terms of the GNU Library General Public License          *
-*   (version 2) as published by the Free Software Foundation;             *
-*                                                                         *
-*   This program 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 Library General Public     *
-*   License along with this program; if not, write to the                 *
-*   Free Software Foundation, Inc.,                                       *
-*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
-***************************************************************************/
+// ============================================================================
+//  Copyright (C) 2001-2020 by Jozef Starosczyk
+//  ixen {at} copyhandler [dot] com
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU Library General Public License
+//  (version 2) as published by the Free Software Foundation;
+//
+//  This program 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 Library General Public
+//  License along with this program; if not, write to the
+//  Free Software Foundation, Inc.,
+//  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+// ============================================================================
 #include "stdafx.h"
 #include "MiniViewDlg.h"
 #include "ch.h"
@@ -24,6 +24,7 @@
 #include "resource.h"
 #include "../libchengine/TTaskManager.h"
 #include "../libchengine/TTask.h"
+#include "GuiOptions.h"
 
 #ifdef _DEBUG
 #define new DEBUG_NEW
@@ -33,272 +34,10 @@
 
 #define WM_INITDATA				WM_USER+5
 
-static const int sg_iMargin = 8;
+using namespace chengine;
 
-#define ROUND(val) ( ( (val)-static_cast<int>(val) > 0.5 ) ? static_cast<int>(val)+1 : static_cast<int>(val) )
-#undef ROUNDUP	// from other module
-#define ROUNDUP(val, to) ( (static_cast<int>((val)/(to))+1 )*(to) )
-
 bool CMiniViewDlg::m_bLock=false;
 
-void OnPause(CMiniViewDlg* pDlg, UINT uiMsg, CMiniViewDlg::_BTNDATA_* pData, CDC* pDC)
-{
-	switch (uiMsg)
-	{
-	case MSG_DRAWBUTTON:
-	{
-		CRect rcCopy = pData->rcButton;
-		rcCopy.DeflateRect(2, 2, 2, 2);
-
-		// frame drawing
-		if (!pData->bPressed || pDlg->m_ctlStatus.GetCurSel() == LB_ERR)
-			pDC->Draw3dRect(&rcCopy, GetSysColor(COLOR_BTNHIGHLIGHT), GetSysColor(COLOR_BTNSHADOW));
-		else
-			pDC->Draw3dRect(&rcCopy, GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_BTNHIGHLIGHT));
-
-		// fill the background
-		rcCopy.DeflateRect(1, 1, 1, 1);
-		pDC->FillSolidRect(&rcCopy, GetSysColor(COLOR_3DFACE));
-
-		// pause
-		CPen pen;
-		int iPenWidth = rcCopy.Width() / 10 + 1;
-		pen.CreatePen(PS_SOLID, iPenWidth, pData->bEnabled ? GetSysColor(COLOR_BTNTEXT) : GetSysColor(COLOR_BTNSHADOW));
-		CPen* pOld = pDC->SelectObject(&pen);
-
-		int iOffset = rcCopy.Width() / 3;
-		pDC->MoveTo(rcCopy.left + iOffset - ROUND(0.66*iPenWidth) + pData->bPressed, rcCopy.top + 1 * iPenWidth + pData->bPressed);
-		pDC->LineTo(rcCopy.left + iOffset - ROUND(0.66*iPenWidth) + pData->bPressed, rcCopy.bottom - ROUND(1.5*iPenWidth) + pData->bPressed);
-		pDC->MoveTo(rcCopy.right - iOffset - ROUND(0.66*iPenWidth) + pData->bPressed, rcCopy.top + 1 * iPenWidth + pData->bPressed);
-		pDC->LineTo(rcCopy.right - iOffset - ROUND(0.66*iPenWidth) + pData->bPressed, rcCopy.bottom - ROUND(1.5*iPenWidth) + pData->bPressed);
-
-		pDC->SelectObject(pOld);
-		break;
-	}
-	case MSG_ONCLICK:
-	{
-		int iSel = pDlg->m_ctlStatus.GetCurSel();
-		if (iSel == LB_ERR || (size_t)iSel >= pDlg->m_ctlStatus.m_vItems.size())
-			return;
-
-		chengine::TTaskPtr spTask = pDlg->m_pTasks->GetTaskByTaskID(pDlg->m_ctlStatus.m_vItems.at(iSel)->m_tTaskID);
-		if (spTask)
-			spTask->PauseProcessing();
-		else
-			pDlg->m_pTasks->TasksPauseProcessing();
-
-		break;
-	}
-	}
-}
-
-void OnCloseBtn(CMiniViewDlg* pDlg, UINT uiMsg, CMiniViewDlg::_BTNDATA_* pData, CDC* pDC)
-{
-	switch (uiMsg)
-	{
-	case MSG_DRAWBUTTON:
-	{
-		CRect rcCopy = pData->rcButton;
-		rcCopy.DeflateRect(2, 2, 2, 2);
-
-		// frame
-		if (!pData->bPressed)
-			pDC->Draw3dRect(&rcCopy, GetSysColor(COLOR_BTNHIGHLIGHT), GetSysColor(COLOR_BTNSHADOW));
-		else
-			pDC->Draw3dRect(&rcCopy, GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_BTNHIGHLIGHT));
-
-		// background
-		rcCopy.DeflateRect(1, 1, 1, 1);
-		pDC->FillSolidRect(&rcCopy, GetSysColor(COLOR_3DFACE));
-
-		// close
-		CPen pen;
-		int iPenSize = rcCopy.Width() / 10 + 1;
-		pen.CreatePen(PS_SOLID | PS_INSIDEFRAME, iPenSize, GetSysColor(COLOR_BTNTEXT));
-		CPen* pOld = pDC->SelectObject(&pen);
-
-		switch (iPenSize)
-		{
-		case 1:
-			pDC->MoveTo(rcCopy.left + pData->bPressed + ROUND(1.4*iPenSize), rcCopy.top + pData->bPressed + ROUND(1.4*iPenSize));
-			pDC->LineTo(rcCopy.right + pData->bPressed - ROUND(1.4*iPenSize), rcCopy.bottom + pData->bPressed - ROUND(1.6*iPenSize));
-			pDC->MoveTo(rcCopy.left + pData->bPressed + ROUND(1.4*iPenSize), rcCopy.bottom + pData->bPressed - ROUND(2.6*iPenSize));
-			pDC->LineTo(rcCopy.right + pData->bPressed - ROUND(1.4*iPenSize), rcCopy.top + pData->bPressed + ROUND(0.4*iPenSize));
-			break;
-		default:
-			pDC->MoveTo(rcCopy.left + pData->bPressed + ROUND(1.4*iPenSize), rcCopy.top + pData->bPressed + ROUND(1.4*iPenSize));
-			pDC->LineTo(rcCopy.right + pData->bPressed - ROUND(2.0*iPenSize), rcCopy.bottom + pData->bPressed - ROUND(2.0*iPenSize));
-			pDC->MoveTo(rcCopy.left + pData->bPressed + ROUND(1.4*iPenSize), rcCopy.bottom + pData->bPressed - ROUND(2.0*iPenSize));
-			pDC->LineTo(rcCopy.right + pData->bPressed - ROUND(2.0*iPenSize), rcCopy.top + pData->bPressed + ROUND(1.4*iPenSize));
-			break;
-		}
-
-		pDC->SelectObject(pOld);
-		break;
-	}
-	case MSG_ONCLICK:
-		pDlg->SendMessage(WM_CLOSE, 0, 0);
-		break;
-	}
-}
-
-void OnResume(CMiniViewDlg* pDlg, UINT uiMsg, CMiniViewDlg::_BTNDATA_* pData, CDC* pDC)
-{
-	switch (uiMsg)
-	{
-	case MSG_DRAWBUTTON:
-	{
-		CRect rcCopy = pData->rcButton;
-		rcCopy.DeflateRect(2, 2, 2, 2);
-
-		// frame
-		if (!pData->bPressed || pDlg->m_ctlStatus.GetCurSel() == LB_ERR)
-			pDC->Draw3dRect(&rcCopy, GetSysColor(COLOR_BTNHIGHLIGHT), GetSysColor(COLOR_BTNSHADOW));
-		else
-			pDC->Draw3dRect(&rcCopy, GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_BTNHIGHLIGHT));
-
-		// bkgnd
-		rcCopy.DeflateRect(1, 1, 1, 1);
-		pDC->FillSolidRect(&rcCopy, GetSysColor(COLOR_3DFACE));
-
-		// triangle
-		int iOffset = rcCopy.Width() / 4;
-		int iHeight = rcCopy.Width() / 10 + 1;
-		POINT pt[3] = { {rcCopy.left + iOffset - 1 + pData->bPressed, rcCopy.top + 1 * iHeight + pData->bPressed}, {rcCopy.left + iOffset - 1 + pData->bPressed, rcCopy.bottom - ROUND(1.625*iHeight) + pData->bPressed},
-						{rcCopy.right - iOffset - 1 + pData->bPressed, rcCopy.top + 1 * iHeight + pData->bPressed + (rcCopy.Height() - 3 * iHeight + 1) / 2} };
-
-		CBrush brs;
-		brs.CreateSolidBrush(pData->bEnabled ? GetSysColor(COLOR_BTNTEXT) : GetSysColor(COLOR_BTNSHADOW));
-		CBrush* pOld = pDC->SelectObject(&brs);
-
-		CPen pen;
-		pen.CreatePen(PS_SOLID, 1, pData->bEnabled ? GetSysColor(COLOR_BTNTEXT) : GetSysColor(COLOR_BTNSHADOW));
-		CPen *pOldPen = pDC->SelectObject(&pen);
-		pDC->SetPolyFillMode(WINDING);
-
-		pDC->Polygon(pt, 3);
-
-		pDC->SelectObject(pOld);
-		pDC->SelectObject(pOldPen);
-
-		break;
-	}
-	case MSG_ONCLICK:
-	{
-		int iSel = pDlg->m_ctlStatus.GetCurSel();
-		if (iSel == LB_ERR || (size_t)iSel >= pDlg->m_ctlStatus.m_vItems.size())
-			return;
-
-		chengine::TTaskPtr spTask = pDlg->m_pTasks->GetTaskByTaskID(pDlg->m_ctlStatus.m_vItems.at(iSel)->m_tTaskID);
-		if (spTask)
-		{
-			if (spTask->GetTaskState() == chengine::eTaskState_Waiting)
-				spTask->SetForceFlag(true);
-			else
-				spTask->ResumeProcessing();
-		}
-		else
-			pDlg->m_pTasks->TasksResumeProcessing();
-		break;
-	}
-	}
-}
-
-void OnCancelBtn(CMiniViewDlg* pDlg, UINT uiMsg, CMiniViewDlg::_BTNDATA_* pData, CDC* pDC)
-{
-	switch (uiMsg)
-	{
-	case MSG_DRAWBUTTON:
-	{
-		CRect rcCopy = pData->rcButton;
-		rcCopy.DeflateRect(2, 2, 2, 2);
-
-		// frame
-		if (!pData->bPressed || pDlg->m_ctlStatus.GetCurSel() == LB_ERR)
-			pDC->Draw3dRect(&rcCopy, GetSysColor(COLOR_BTNHIGHLIGHT), GetSysColor(COLOR_BTNSHADOW));
-		else
-			pDC->Draw3dRect(&rcCopy, GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_BTNHIGHLIGHT));
-
-		// bkgnd
-		rcCopy.DeflateRect(1, 1, 1, 1);
-		pDC->FillSolidRect(&rcCopy, GetSysColor(COLOR_3DFACE));
-
-		// square
-		int iWidth = rcCopy.Width() / 10 + 1;
-		rcCopy.DeflateRect(1 * iWidth + pData->bPressed, 1 * iWidth + pData->bPressed, ROUND(1.6*iWidth) - pData->bPressed, 1 * iWidth - pData->bPressed);
-		pDC->FillSolidRect(&rcCopy, pData->bEnabled ? GetSysColor(COLOR_BTNTEXT) : GetSysColor(COLOR_BTNSHADOW));
-		break;
-	}
-	case MSG_ONCLICK:
-		int iSel = pDlg->m_ctlStatus.GetCurSel();
-		if (iSel == LB_ERR || (size_t)iSel >= pDlg->m_ctlStatus.m_vItems.size())
-			return;
-
-		chengine::TTaskPtr spTask = pDlg->m_pTasks->GetTaskByTaskID(pDlg->m_ctlStatus.m_vItems.at(iSel)->m_tTaskID);
-		if (spTask)
-			spTask->CancelProcessing();
-		else
-			pDlg->m_pTasks->TasksCancelProcessing();
-		break;
-	}
-}
-
-void OnRestartBtn(CMiniViewDlg* pDlg, UINT uiMsg, CMiniViewDlg::_BTNDATA_* pData, CDC* pDC)
-{
-	switch (uiMsg)
-	{
-	case MSG_DRAWBUTTON:
-	{
-		CRect rcCopy = pData->rcButton;
-		rcCopy.DeflateRect(2, 2, 2, 2);
-
-		// frame
-		if (!pData->bPressed || pDlg->m_ctlStatus.GetCurSel() == LB_ERR)
-			pDC->Draw3dRect(&rcCopy, GetSysColor(COLOR_BTNHIGHLIGHT), GetSysColor(COLOR_BTNSHADOW));
-		else
-			pDC->Draw3dRect(&rcCopy, GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_BTNHIGHLIGHT));
-
-		// bkgnd
-		rcCopy.DeflateRect(1, 1, 1, 1);
-		pDC->FillSolidRect(&rcCopy, GetSysColor(COLOR_3DFACE));
-
-		// triangle in a square
-		int iOffset = rcCopy.Width() / 4;
-		int iHeight = rcCopy.Width() / 10 + 1;
-		POINT pt[3] = { {rcCopy.left + iOffset - 1 + pData->bPressed, rcCopy.top + 1 * iHeight + pData->bPressed}, {rcCopy.left + iOffset - 1 + pData->bPressed, rcCopy.bottom - ROUND(1.625*iHeight) + pData->bPressed},
-						{rcCopy.right - iOffset - 1 + pData->bPressed, rcCopy.top + 1 * iHeight + pData->bPressed + (rcCopy.Height() - 3 * iHeight + 1) / 2} };
-
-		CBrush brs;
-		brs.CreateSolidBrush(pData->bEnabled ? RGB(255, 0, 0) : GetSysColor(COLOR_BTNSHADOW));
-		CBrush* pOld = pDC->SelectObject(&brs);
-
-		CPen pen;
-		pen.CreatePen(PS_SOLID, 1, pData->bEnabled ? RGB(255, 0, 0) : GetSysColor(COLOR_BTNSHADOW));
-		CPen *pOldPen = pDC->SelectObject(&pen);
-
-		pDC->SetPolyFillMode(WINDING);
-		pDC->Polygon(pt, 3);
-		pDC->SelectObject(pOld);
-		pDC->SelectObject(pOldPen);
-
-		break;
-	}
-	case MSG_ONCLICK:
-	{
-		int iSel = pDlg->m_ctlStatus.GetCurSel();
-		if (iSel == LB_ERR || (size_t)iSel >= pDlg->m_ctlStatus.m_vItems.size())
-			return;
-
-		chengine::TTaskPtr spTask = pDlg->m_pTasks->GetTaskByTaskID(pDlg->m_ctlStatus.m_vItems.at(iSel)->m_tTaskID);
-		if (spTask)
-			spTask->RestartProcessing();
-		else
-			pDlg->m_pTasks->TasksRestartProcessing();
-		break;
-	}
-	}
-}
-
 /////////////////////////////////////////////////////////////////////////////
 // CMiniViewDlg dialog
 
@@ -311,68 +50,32 @@
 	m_pbHide(pbHide),
 	m_iIndex(-1)
 {
-	COLORREF cr3DFace = GetSysColor(COLOR_3DFACE);
-	m_brBackground.CreateSolidBrush(cr3DFace);
 }
 
 void CMiniViewDlg::DoDataExchange(CDataExchange* pDX)
 {
 	CLanguageDialog::DoDataExchange(pDX);
-	//{{AFX_DATA_MAP(CMiniViewDlg)
 	DDX_Control(pDX, IDC_PROGRESS_LIST, m_ctlStatus);
-	//}}AFX_DATA_MAP
 }
 
 BEGIN_MESSAGE_MAP(CMiniViewDlg,ictranslate::CLanguageDialog)
-	//{{AFX_MSG_MAP(CMiniViewDlg)
-	ON_WM_CTLCOLOR()
 	ON_WM_TIMER()
 	ON_LBN_SELCHANGE(IDC_PROGRESS_LIST, OnSelchangeProgressList)
-	ON_WM_NCLBUTTONDOWN()
-	ON_WM_LBUTTONUP()
-	ON_WM_NCPAINT()
-	ON_WM_NCACTIVATE()
 	ON_LBN_SETFOCUS(IDC_PROGRESS_LIST, OnSetfocusProgressList)
 	ON_LBN_SELCANCEL(IDC_PROGRESS_LIST, OnSelcancelProgressList)
-	ON_WM_MOUSEMOVE()
 	ON_WM_SETTINGCHANGE()
 	ON_LBN_DBLCLK(IDC_PROGRESS_LIST, OnDblclkProgressList)
-	//}}AFX_MSG_MAP
+	ON_MESSAGE(WM_TASK_RCLICK, OnTaskRClick)
 END_MESSAGE_MAP()
 
 /////////////////////////////////////////////////////////////////////////////
 // CMiniViewDlg message handlers
 
-HBRUSH CMiniViewDlg::OnCtlColor(CDC*, CWnd*, UINT) 
-{
-	return m_brBackground;
-}
-
 BOOL CMiniViewDlg::OnInitDialog() 
 {
 	CLanguageDialog::OnInitDialog();
 
-	// fill the buttons' structure
-	m_bdButtons[0].pfnCallbackFunc=&OnPause;
-	m_bdButtons[0].iPosition=4;
-	m_bdButtons[0].bPressed=false;
-	m_bdButtons[0].bEnabled=false;
-	m_bdButtons[1].pfnCallbackFunc=&OnResume;
-	m_bdButtons[1].iPosition=3;
-	m_bdButtons[1].bPressed=false;
-	m_bdButtons[1].bEnabled=false;
-	m_bdButtons[2].pfnCallbackFunc=&OnCancelBtn;
-	m_bdButtons[2].iPosition=2;
-	m_bdButtons[2].bPressed=false;
-	m_bdButtons[2].bEnabled=false;
-	m_bdButtons[3].pfnCallbackFunc=&OnRestartBtn;
-	m_bdButtons[3].iPosition=1;
-	m_bdButtons[3].bPressed=false;
-	m_bdButtons[3].bEnabled=false;
-	m_bdButtons[4].pfnCallbackFunc=&OnCloseBtn;
-	m_bdButtons[4].iPosition=0;
-	m_bdButtons[4].bPressed=false;
-	m_bdButtons[4].bEnabled=true;
+	m_menuContext.Load();
 
 	ResizeDialog();
 	PostMessage(WM_INITDATA);
@@ -396,6 +99,13 @@
 
 void CMiniViewDlg::RecalcSize(int nHeight, bool bInitial)
 {
+	CRect rcMargins(0, 0, 5, 3);
+
+	MapDialogRect(&rcMargins);
+
+	const int XMargin = rcMargins.Width();
+	const int YMargin = rcMargins.Height();
+
 	// set listbox size
 	CRect rcList;
 	m_ctlStatus.GetWindowRect(&rcList);
@@ -411,26 +121,18 @@
 	m_iLastHeight = nHeight;
 
 	CRect rcNewDlgPos(rcList);
+	rcNewDlgPos.InflateRect(XMargin, YMargin);
+
+	CRect rcNewDlgPosClient = rcNewDlgPos;
+
 	AdjustWindowRectEx(&rcNewDlgPos, GetStyle(), FALSE, GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE));
 
 	// use dynamic margin
 	int iWidth = rcNewDlgPos.Width();
 	int iHeight = rcNewDlgPos.Height();
 
-	int iListXOffset = 0;
-	int iXMargin = (rcNewDlgPos.Width() - rcList.Width()) / 2;
-	if(iXMargin < sg_iMargin)
-	{
-		iListXOffset = (sg_iMargin - iXMargin);
-		iWidth += (sg_iMargin - iXMargin) * 2;
-	}
-	
-	int iYMargin = rcNewDlgPos.bottom - rcList.bottom;
-	if(iYMargin < sg_iMargin)
-		iHeight += (sg_iMargin - iYMargin);
-
 	// place listbox in the best place
-	m_ctlStatus.SetWindowPos(nullptr, iListXOffset, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
+	m_ctlStatus.SetWindowPos(nullptr, XMargin, YMargin / 2, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
 
 	// size of a dialog and screen
 	CRect rcDialog, rcScreen;
@@ -474,7 +176,7 @@
 				if(eTaskState == chengine::eTaskState_Error)
 					pItem->m_crColor=RGB(255, 0, 0);
 				else if(eTaskState == chengine::eTaskState_Paused)
-					pItem->m_crColor=RGB(255, 255, 0);
+					pItem->m_crColor=RGB(255, 201, 14);
 				else if(eTaskState == chengine::eTaskState_Waiting)
 					pItem->m_crColor=RGB(0, 0, 255);
 				else
@@ -564,168 +266,13 @@
 	return ictranslate::CLanguageDialog::WindowProc(message, wParam, lParam);
 }
 
-void CMiniViewDlg::OnNcPaint() 
-{
-	int iCXBorder=GetSystemMetrics(SM_CXBORDER);
-	int iCYBorder=GetSystemMetrics(SM_CYBORDER);
-	int iWidth=GetSystemMetrics(SM_CXSMSIZE);
-	int iHeight=GetSystemMetrics(SM_CYSMSIZE);
-	int iFrameHeight=GetSystemMetrics(SM_CYDLGFRAME);
-	int iFrameWidth=GetSystemMetrics(SM_CXDLGFRAME);
-	bool bEnabled=(m_ctlStatus.GetCurSel() != LB_ERR);
-
-	// NC coordinates
-	CRect rcWindow;
-	GetWindowRect(&rcWindow);
-	rcWindow.OffsetRect(-rcWindow.left, -rcWindow.top);
-
-	// device context
-	CWindowDC ncdc(this);
-
-	// frame
-	ncdc.DrawEdge(&rcWindow, EDGE_RAISED, BF_RECT);
-	rcWindow.DeflateRect(iFrameWidth-iCXBorder, iFrameHeight-iCYBorder, iFrameWidth-iCXBorder, iFrameHeight-iCYBorder);
-
-	CPen pen, pen2;
-	pen.CreatePen(PS_SOLID, iCXBorder, GetSysColor(COLOR_3DFACE));
-	pen2.CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DFACE));
-
-	ncdc.SelectObject(&pen);
-	ncdc.SelectObject(m_brBackground);
-	
-	ncdc.Rectangle(&rcWindow);
-
-	// caption bar
-	rcWindow.DeflateRect(iCXBorder, iCXBorder, iCXBorder, 0);
-	rcWindow.bottom=rcWindow.top+iHeight;	// caption pos
-
-	// additional horz bar
-	ncdc.SelectObject(&pen2);
-	ncdc.MoveTo(rcWindow.left, rcWindow.bottom);
-	ncdc.LineTo(rcWindow.right, rcWindow.bottom);
-
-	// memdc
-	CMemDC dc(ncdc, &rcWindow);
-
-	COLORREF crLeft=GetSysColor(m_bActive ? COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION);
-	dc.GetDC().FillSolidRect(&rcWindow, crLeft);
-
-	// caption text
-	CString strWindow;
-	GetWindowText(strWindow);
-//	TRACE("DRAWING TEXT: "+strWindow+"\n");
-
-	rcWindow.DeflateRect(5, 0, BTN_COUNT*iWidth+iFrameWidth+5, 0);
-	
-	// caption font
-	NONCLIENTMETRICS ncm;
-	memset(&ncm, 0, sizeof(NONCLIENTMETRICS));
-	ncm.cbSize=sizeof(NONCLIENTMETRICS);
-	SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0);
-	
-	CFont font;
-	font.CreateFontIndirect(&ncm.lfSmCaptionFont);
-	dc.GetDC().SelectObject(&font);
-	
-	dc.GetDC().SetTextColor(GetSysColor(COLOR_CAPTIONTEXT));
-	dc.GetDC().SetBkMode(TRANSPARENT);
-	dc.GetDC().DrawText(strWindow, &rcWindow, DT_END_ELLIPSIS | DT_VCENTER | DT_LEFT | DT_NOCLIP | DT_SINGLELINE);
-	// button drawing
-	GetClientRect(&rcWindow);
-	
-	for (int i=0;i<BTN_COUNT;i++)
-	{
-		if (m_bdButtons[i].iPosition == 0)
-		{
-			m_bdButtons[i].rcButton.left=rcWindow.right-iWidth+2;
-			m_bdButtons[i].bEnabled=true;
-		}
-		else
-		{
-			m_bdButtons[i].rcButton.left=rcWindow.right-(m_bdButtons[i].iPosition+1)*iWidth-iFrameWidth;
-			m_bdButtons[i].bEnabled=bEnabled;
-		}
-
-		m_bdButtons[i].rcButton.top=iFrameHeight;
-		m_bdButtons[i].rcButton.right=m_bdButtons[i].rcButton.left+iWidth;
-		m_bdButtons[i].rcButton.bottom=m_bdButtons[i].rcButton.top+iHeight;
-		
-		m_bdButtons[i].pfnCallbackFunc(this, MSG_DRAWBUTTON, &m_bdButtons[i], &dc.GetDC());
-	}
-}
-
 void CMiniViewDlg::OnSelchangeProgressList() 
 {
 	RefreshStatus();
 	RedrawWindow(nullptr, nullptr, RDW_INVALIDATE | RDW_FRAME);
 //	PostMessage(WM_NCPAINT);
 }
 
-void CMiniViewDlg::OnNcLButtonDown(UINT nHitTest, CPoint point) 
-{
-	bool bEnabled=false;
-	CRect rcBtn;
-	int iNCHeight=GetSystemMetrics(SM_CYSMCAPTION)+GetSystemMetrics(SM_CYDLGFRAME);
-		
-	// has been button pressed ?
-	for (int i=0;i<BTN_COUNT;i++)
-	{
-		// translate coordinates
-		rcBtn=m_bdButtons[i].rcButton;
-		ClientToScreen(rcBtn);
-		rcBtn.top-=iNCHeight;
-		rcBtn.bottom-=iNCHeight;
-			
-		// check
-		if (rcBtn.PtInRect(point))
-		{
-			bEnabled=true;
-			if (m_bdButtons[i].bEnabled)
-			{
-				m_iIndex=i;
-				m_bdButtons[i].bPressed=true;
-				SetCapture();
-				RedrawWindow(nullptr, nullptr, RDW_INVALIDATE | RDW_FRAME);
-//				PostMessage(WM_NCPAINT, nullptr, nullptr);
-				return;
-			}
-		}
-	}
-
-	if (!bEnabled)
-		CLanguageDialog::OnNcLButtonDown(nHitTest, point);
-}
-
-void CMiniViewDlg::OnLButtonUp(UINT nFlags, CPoint point) 
-{
-	ReleaseCapture();
-	bool bProcessed=false;
-
-	if (m_iIndex != -1 && m_bdButtons[m_iIndex].bPressed)
-	{
-		m_bdButtons[m_iIndex].bPressed=false;
-		RedrawWindow(nullptr, nullptr, RDW_INVALIDATE | RDW_FRAME);
-//		PostMessage(WM_NCPAINT, nullptr, nullptr);
-		m_bdButtons[m_iIndex].pfnCallbackFunc(this, MSG_ONCLICK, &m_bdButtons[m_iIndex], nullptr);
-		bProcessed=true;
-	}
-
-	if (!bProcessed)
-		m_ctlStatus.SetCurrentSelection(-1);
-
-	m_iIndex=-1;
-
-	CLanguageDialog::OnLButtonUp(nFlags, point);
-}
-
-BOOL CMiniViewDlg::OnNcActivate(BOOL bActive) 
-{
-	m_bActive=bActive != 0;
-	RedrawWindow(nullptr, nullptr, RDW_INVALIDATE | RDW_FRAME);
-//	PostMessage(WM_NCPAINT);	
-	return TRUE/*bResult*/;
-}
-
 void CMiniViewDlg::OnSetfocusProgressList() 
 {
 	RedrawWindow(nullptr, nullptr, RDW_INVALIDATE | RDW_FRAME);
@@ -739,35 +286,6 @@
 //	PostMessage(WM_NCPAINT);	
 }
 
-void CMiniViewDlg::OnMouseMove(UINT nFlags, CPoint point) 
-{
-//	int iNCHeight=GetSystemMetrics(SM_CYSMCAPTION)+GetSystemMetrics(SM_CYDLGFRAME);
-
-	if (m_iIndex != -1)
-	{
-		point.x+=GetSystemMetrics(SM_CYDLGFRAME);
-		point.y+=GetSystemMetrics(SM_CYSMCAPTION)+GetSystemMetrics(SM_CYDLGFRAME);
-		if (m_bdButtons[m_iIndex].rcButton.PtInRect(point))
-		{
-			if (!m_bdButtons[m_iIndex].bPressed)
-			{
-				m_bdButtons[m_iIndex].bPressed=true;
-				SendMessage(WM_NCPAINT);
-			}
-		}
-		else
-		{
-			if (m_bdButtons[m_iIndex].bPressed)
-			{
-				m_bdButtons[m_iIndex].bPressed=false;
-				SendMessage(WM_NCPAINT);
-			}
-		}
-	}
-	
-	CLanguageDialog::OnMouseMove(nFlags, point);
-}
-
 void CMiniViewDlg::OnSettingChange(UINT uFlags, LPCTSTR lpszSection) 
 {
 	CLanguageDialog::OnSettingChange(uFlags, lpszSection);
@@ -798,12 +316,102 @@
 
 void CMiniViewDlg::OnDblclkProgressList() 
 {
-	int iSel = m_ctlStatus.GetCurSel();
-	if(iSel == LB_ERR || (size_t)iSel >= m_ctlStatus.m_vItems.size())
+	chengine::taskid_t tTaskID = m_ctlStatus.GetSelectedTaskId();
+	GetParent()->PostMessage(WM_MINIVIEWDBLCLK, 0, boost::numeric_cast<LPARAM>(tTaskID));
+}
+
+LRESULT CMiniViewDlg::OnTaskRClick(WPARAM /*wParam*/, LPARAM lParam)
+{
+	TASK_CLICK_NOTIFICATION* pNotify = (TASK_CLICK_NOTIFICATION*)lParam;
+	m_currentTaskId = pNotify->taskId;
+
+	ETaskCurrentState eState = eTaskState_None;
+
+	TTaskPtr spTask = m_pTasks->GetTaskByTaskID(m_currentTaskId);
+	if(spTask)
+		eState = spTask->GetTaskState();
+	spTask.reset();
+
+	int iMenuItem = m_menuContext.TrackPopupMenu(eState, TPM_RIGHTALIGN | TPM_BOTTOMALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, pNotify->point.x, pNotify->point.y, this);
+	switch(iMenuItem)
+	{
+	case ID_TASK_MENU_PAUSE:
+	case ID_TASK_MENU_RESUME:
+	case ID_TASK_MENU_RESTART:
+	case ID_TASK_MENU_CANCEL:
+	case ID_TASK_MENU_REMOVE:
+	case ID_TASK_MENU_RESET_FEEDBACK:
+		ExecTaskCommand(iMenuItem);
+		break;
+
+	case ID_TASK_MENU_PAUSE_ALL:
+		m_pTasks->TasksPauseProcessing();
+		break;
+	case ID_TASK_MENU_RESUME_ALL:
+		m_pTasks->TasksResumeProcessing();
+		break;
+	case ID_TASK_MENU_RESTART_ALL:
+		m_pTasks->TasksRestartProcessing();
+		break;
+	case ID_TASK_MENU_CANCEL_ALL:
+		m_pTasks->TasksCancelProcessing();
+		break;
+	case ID_TASK_MENU_REMOVE_INACTIVE:
+		m_pTasks->RemoveAllFinished();
+		break;
+	}
+
+	return 0;
+}
+
+void CMiniViewDlg::ExecTaskCommand(int idCmd)
+{
+	TTaskPtr spTask = m_pTasks->GetTaskByTaskID(m_currentTaskId);
+	if(!spTask)
 		return;
 
-	chengine::taskid_t tTaskID = m_ctlStatus.m_vItems.at(iSel)->m_tTaskID;
-	GetParent()->PostMessage(WM_MINIVIEWDBLCLK, 0, boost::numeric_cast<LPARAM>(tTaskID));
+	ETaskCurrentState eState = spTask->GetTaskState();
+
+	switch(idCmd)
+	{
+	case ID_TASK_MENU_PAUSE:
+		spTask->PauseProcessing();
+		break;
+	case ID_TASK_MENU_RESUME:
+		if(eState == chengine::eTaskState_Waiting)
+			spTask->SetForceFlag(true);
+		else
+			spTask->ResumeProcessing();
+		break;
+	case ID_TASK_MENU_RESTART:
+		spTask->RestartProcessing();
+		break;
+	case ID_TASK_MENU_CANCEL:
+		spTask->CancelProcessing();
+		break;
+	case ID_TASK_MENU_REMOVE:
+	{
+		switch(eState)
+		{
+		case chengine::eTaskState_Finished:
+		case chengine::eTaskState_Cancelled:
+		case chengine::eTaskState_LoadError:
+			break;
+
+		default:
+			if(MsgBox(IDS_CONFIRMCANCEL_STRING, MB_OKCANCEL | MB_ICONQUESTION) == IDOK)
+				spTask->CancelProcessing();
+			else
+				return;
+		}
+
+		m_pTasks->RemoveFinished(spTask);
+		break;
+	}
+	case ID_TASK_MENU_RESET_FEEDBACK:
+		spTask->RestoreFeedbackDefaults();
+		break;
+	}
 }
 
 void CMiniViewDlg::OnLanguageChanged()
Index: src/ch/MiniViewDlg.h
===================================================================
diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r814b694086d5dc450efb6a5e5c6902145ddc07fd
--- src/ch/MiniViewDlg.h	(.../MiniViewDlg.h)	(revision 0d5b67ee96b435d63f7bf075dc8e28603793b187)
+++ src/ch/MiniViewDlg.h	(.../MiniViewDlg.h)	(revision 814b694086d5dc450efb6a5e5c6902145ddc07fd)
@@ -1,28 +1,28 @@
-/***************************************************************************
-*   Copyright (C) 2001-2008 by J�zef Starosczyk                           *
-*   ixen@copyhandler.com                                                  *
-*                                                                         *
-*   This program is free software; you can redistribute it and/or modify  *
-*   it under the terms of the GNU Library General Public License          *
-*   (version 2) as published by the Free Software Foundation;             *
-*                                                                         *
-*   This program 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 Library General Public     *
-*   License along with this program; if not, write to the                 *
-*   Free Software Foundation, Inc.,                                       *
-*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
-***************************************************************************/
-#ifndef __MINIVIEWDLG_H__
-#define __MINIVIEWDLG_H__
+// ============================================================================
+//  Copyright (C) 2001-2020 by Jozef Starosczyk
+//  ixen {at} copyhandler [dot] com
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU Library General Public License
+//  (version 2) as published by the Free Software Foundation;
+//
+//  This program 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 Library General Public
+//  License along with this program; if not, write to the
+//  Free Software Foundation, Inc.,
+//  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+// ============================================================================
+#pragma once
 
 /////////////////////////////////////////////////////////////////////////////
 // CMiniViewDlg dialog
 #include "ProgressListBox.h"
 #include <array>
+#include "TaskContextMenu.h"
 
 namespace chengine {
 	class TTaskManager;
@@ -33,41 +33,16 @@
 	class TTaskManager;
 }
 
-#define BTN_COUNT 5
-
-#define MSG_DRAWBUTTON	1
-#define MSG_ONCLICK		2
-
 #define WM_MINIVIEWDBLCLK		WM_USER+14
 
 class CMiniViewDlg : public ictranslate::CLanguageDialog
 {
-// internal struct
 public:
-	struct _BTNDATA_
-	{
-		void (*pfnCallbackFunc)(CMiniViewDlg*, UINT, _BTNDATA_*, CDC*) = nullptr;		// callback - click
-		int iPosition = 0;		// button pos counting from right
-		bool bPressed = false;		// is it pressed ?
-		bool bEnabled = false;		// is it enabled ?
-
-		CRect rcButton;		// filled in OnNCPaint
-	};
-
-	std::array<_BTNDATA_, BTN_COUNT> m_bdButtons;
-
-// Construction
-public:
 	CMiniViewDlg(chengine::TTaskManager* pArray, bool* pbHide, CWnd* pParent = nullptr);   // standard constructor
 
 	void ShowWindow();
 	void HideWindow();
 	void ResizeDialog();
-	friend void OnRestartBtn(CMiniViewDlg* pDlg, UINT uiMsg, CMiniViewDlg::_BTNDATA_* pData, CDC* pDC=nullptr);
-	friend void OnCancelBtn(CMiniViewDlg* pDlg, UINT uiMsg, CMiniViewDlg::_BTNDATA_* pData, CDC* pDC=nullptr);
-	friend void OnResume(CMiniViewDlg* pDlg, UINT uiMsg, CMiniViewDlg::_BTNDATA_* pData, CDC* pDC=nullptr);
-	friend void OnPause(CMiniViewDlg* pDlg, UINT uiMsg, CMiniViewDlg::_BTNDATA_* pData, CDC* pDC=nullptr);
-	friend void OnCloseBtn(CMiniViewDlg* pDlg, UINT uiMsg, CMiniViewDlg::_BTNDATA_* pData, CDC* pDC);
 
 	void RefreshStatus();
 	void RecalcSize(int nHeight, bool bInitial);
@@ -79,20 +54,17 @@
 	void DoDataExchange(CDataExchange* pDX) override;    // DDX/DDV support
 	LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam) override;
 
-	afx_msg HBRUSH OnCtlColor(CDC*, CWnd*, UINT);
 	BOOL OnInitDialog() override;
 	afx_msg void OnTimer(UINT_PTR nIDEvent);
 	afx_msg void OnSelchangeProgressList();
-	afx_msg void OnNcLButtonDown(UINT nHitTest, CPoint point);
-	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
-	afx_msg void OnNcPaint();
-	afx_msg BOOL OnNcActivate(BOOL bActive);
 	afx_msg void OnSetfocusProgressList();
 	afx_msg void OnSelcancelProgressList();
-	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
 	afx_msg void OnSettingChange(UINT uFlags, LPCTSTR lpszSection);
 	afx_msg void OnDblclkProgressList();
+	afx_msg LRESULT OnTaskRClick(WPARAM wParam, LPARAM lParam);
 
+	void ExecTaskCommand(int idCmd);
+
 	DECLARE_MESSAGE_MAP()
 
 public:
@@ -102,7 +74,6 @@
 	// from CMainWnd
 	chengine::TTaskManager *m_pTasks;
 
-	CBrush m_brBackground;
 	int m_iLastHeight;
 	bool m_bShown;
 
@@ -115,7 +86,7 @@
 	// in onmousemove points to last pressed button
 	int m_iIndex;
 
-	CProgressListBox	m_ctlStatus;
+	CProgressListBox m_ctlStatus;
+	TaskContextMenu m_menuContext;
+	chengine::taskid_t m_currentTaskId = chengine::NoTaskID;
 };
-
-#endif
Index: src/ch/ProgressListBox.cpp
===================================================================
diff -u -r547f865c69434c14c6f16e4b529d4198f6fe2040 -r814b694086d5dc450efb6a5e5c6902145ddc07fd
--- src/ch/ProgressListBox.cpp	(.../ProgressListBox.cpp)	(revision 547f865c69434c14c6f16e4b529d4198f6fe2040)
+++ src/ch/ProgressListBox.cpp	(.../ProgressListBox.cpp)	(revision 814b694086d5dc450efb6a5e5c6902145ddc07fd)
@@ -1,21 +1,21 @@
-/***************************************************************************
-*   Copyright (C) 2001-2008 by J�zef Starosczyk                           *
-*   ixen@copyhandler.com                                                  *
-*                                                                         *
-*   This program is free software; you can redistribute it and/or modify  *
-*   it under the terms of the GNU Library General Public License          *
-*   (version 2) as published by the Free Software Foundation;             *
-*                                                                         *
-*   This program 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 Library General Public     *
-*   License along with this program; if not, write to the                 *
-*   Free Software Foundation, Inc.,                                       *
-*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
-***************************************************************************/
+// ============================================================================
+//  Copyright (C) 2001-2020 by Jozef Starosczyk
+//  ixen {at} copyhandler [dot] com
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU Library General Public License
+//  (version 2) as published by the Free Software Foundation;
+//
+//  This program 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 Library General Public
+//  License along with this program; if not, write to the
+//  Free Software Foundation, Inc.,
+//  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+// ============================================================================
 #include "stdafx.h"
 #include "ProgressListBox.h"
 
@@ -25,15 +25,10 @@
 static char THIS_FILE[] = __FILE__;
 #endif
 
-//#define USE_SMOOTH_PROGRESS
+using namespace chengine;
 
-/////////////////////////////////////////////////////////////////////////////
-// CProgressListBox
-
 CProgressListBox::CProgressListBox()
 {
-	m_bShowCaptions=true;
-	m_bSmoothProgress=false;
 }
 
 CProgressListBox::~CProgressListBox()
@@ -46,11 +41,11 @@
 
 
 BEGIN_MESSAGE_MAP(CProgressListBox, CListBox)
-	//{{AFX_MSG_MAP(CProgressListBox)
 	ON_WM_PAINT()
 	ON_WM_ERASEBKGND()
 	ON_CONTROL_REFLECT(LBN_KILLFOCUS, OnKillfocus)
-	//}}AFX_MSG_MAP
+	ON_WM_RBUTTONDOWN()
+	ON_WM_RBUTTONUP()
 END_MESSAGE_MAP()
 
 /////////////////////////////////////////////////////////////////////////////
@@ -78,45 +73,58 @@
 	}
 
 	// draw text
-	if (m_bShowCaptions)
+	if(m_bShowCaptions)
 	{
-		CRect rcText(lpDrawItemStruct->rcItem.left, lpDrawItemStruct->rcItem.top+2,
-			lpDrawItemStruct->rcItem.right, lpDrawItemStruct->rcItem.bottom-(9+2));
+		CRect rcText(
+			lpDrawItemStruct->rcItem.left,
+			lpDrawItemStruct->rcItem.top + m_iTopMargin,
+			lpDrawItemStruct->rcItem.right,
+			lpDrawItemStruct->rcItem.bottom - (m_iProgressHeight + m_iMidMargin + m_iBottomMargin));
 		pDC->SetTextColor(GetSysColor(COLOR_BTNTEXT));
 		pDC->DrawText(pItem->m_strText, &rcText,
 			DT_PATH_ELLIPSIS | DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);
 	}
 
 	// frame sizes
-	int iEdgeWidth=1/*GetSystemMetrics(SM_CXEDGE)*/;
-	int iEdgeHeight=1/*GetSystemMetrics(SM_CYEDGE)*/;
+	int iEdgeWidth = 1/*GetSystemMetrics(SM_CXEDGE)*/;
+	int iEdgeHeight = 1/*GetSystemMetrics(SM_CYEDGE)*/;
 
 	// progress like drawing
-	int iBoxWidth=static_cast<int>(static_cast<double>(((9+2)-2*iEdgeWidth))*(2.0/3.0))+1;
-	CRect rcProgress(lpDrawItemStruct->rcItem.left, lpDrawItemStruct->rcItem.bottom-(9+2), 
-		lpDrawItemStruct->rcItem.left+2*iEdgeWidth+((lpDrawItemStruct->rcItem.right-lpDrawItemStruct->rcItem.left-2*iEdgeWidth)/iBoxWidth)*iBoxWidth,
-		lpDrawItemStruct->rcItem.bottom);
+	int iBoxWidth = static_cast<int>(static_cast<double>(((9 + 2) - 2 * iEdgeWidth)) * (2.0 / 3.0)) + 1;
+	CRect rcProgress(
+		lpDrawItemStruct->rcItem.left,
+		lpDrawItemStruct->rcItem.bottom - m_iProgressHeight - m_iBottomMargin,
+		lpDrawItemStruct->rcItem.left + 2 * iEdgeWidth + ((lpDrawItemStruct->rcItem.right - lpDrawItemStruct->rcItem.left - 2 * iEdgeWidth) / iBoxWidth) * iBoxWidth,
+		lpDrawItemStruct->rcItem.bottom - m_iBottomMargin);
 
 	// edge
 	pDC->Draw3dRect(&rcProgress, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_3DHIGHLIGHT));
 
-	if (!m_bSmoothProgress)
+	if(!m_bSmoothProgress)
 	{
 		// boxes within edge
-		double dCount=static_cast<int>(static_cast<double>(((rcProgress.Width()-2*iEdgeHeight)/iBoxWidth))
-			*(static_cast<double>(pItem->m_uiPos)/static_cast<double>(pItem->m_uiRange)));
-		int iBoxCount=((dCount-static_cast<int>(dCount)) > 0.2) ? static_cast<int>(dCount)+1 : static_cast<int>(dCount);
+		double dCount = static_cast<int>(static_cast<double>(((rcProgress.Width() - 2 * iEdgeHeight) / iBoxWidth))
+			* (static_cast<double>(pItem->m_uiPos) / static_cast<double>(pItem->m_uiRange)));
+		int iBoxCount = ((dCount - static_cast<int>(dCount)) > 0.2) ? static_cast<int>(dCount) + 1 : static_cast<int>(dCount);
 
-		for (int i=0;i<iBoxCount;i++)
-			pDC->FillSolidRect(lpDrawItemStruct->rcItem.left+i*iBoxWidth+iEdgeWidth+1,
-			lpDrawItemStruct->rcItem.bottom-(9+2)+iEdgeHeight+1,
-			iBoxWidth-2, rcProgress.Height()-2*iEdgeHeight-2, pItem->m_crColor);
+		for(int i = 0; i < iBoxCount; i++)
+		{
+			pDC->FillSolidRect(
+				lpDrawItemStruct->rcItem.left + i * iBoxWidth + iEdgeWidth + m_iProgressContentXMargin / 2,
+				lpDrawItemStruct->rcItem.bottom - m_iProgressHeight - m_iBottomMargin + iEdgeHeight + m_iProgressContentYMargin / 2,
+				iBoxWidth - m_iProgressContentXMargin,
+				rcProgress.Height() - 2 * iEdgeHeight - m_iProgressContentYMargin,
+				pItem->m_crColor);
+		}
 	}
 	else
 	{
-		pDC->FillSolidRect(lpDrawItemStruct->rcItem.left+iEdgeWidth+1, lpDrawItemStruct->rcItem.bottom-(9+2)+iEdgeHeight+1,
-			static_cast<int>((rcProgress.Width()-2*iEdgeHeight-3)*(static_cast<double>(pItem->m_uiPos)/static_cast<double>(pItem->m_uiRange))),
-			rcProgress.Height()-2*iEdgeHeight-2, pItem->m_crColor);
+		pDC->FillSolidRect(
+			lpDrawItemStruct->rcItem.left + iEdgeWidth + m_iProgressContentXMargin / 2,
+			lpDrawItemStruct->rcItem.bottom - m_iProgressHeight -m_iBottomMargin + iEdgeHeight + m_iProgressContentYMargin / 2,
+			static_cast<int>((rcProgress.Width() - 2 * iEdgeHeight - 3) * (static_cast<double>(pItem->m_uiPos) / static_cast<double>(pItem->m_uiRange))),
+			rcProgress.Height() - 2 * iEdgeHeight - m_iProgressContentYMargin,
+			pItem->m_crColor);
 	}
 }
 
@@ -129,20 +137,9 @@
 {
 	if (bShow != m_bShowCaptions)
 	{
-		m_bShowCaptions=bShow;
-		if (bShow)
-		{
-			CClientDC dc(this);
-			dc.SelectObject(GetFont());
-			TEXTMETRIC tm;
-			dc.GetTextMetrics(&tm);
-			int iHeight=MulDiv(tm.tmHeight+tm.tmExternalLeading, dc.GetDeviceCaps(LOGPIXELSY), tm.tmDigitizedAspectY);
+		m_bShowCaptions = bShow;
+		Init();
 
-			SetItemHeight(0, 9+2+2+iHeight);
-		}
-		else
-			SetItemHeight(0, 9+2+2);
-
 		RecalcHeight();
 	}
 }
@@ -158,14 +155,35 @@
 	this->SetWindowPos(nullptr, 0, 0, rcCtl.Width(), iCtlHeight, SWP_NOZORDER | SWP_NOMOVE);
 }
 
+chengine::taskid_t CProgressListBox::GetSelectedTaskId() const
+{
+	int iSel = GetCurSel();
+	if(iSel == LB_ERR || (size_t)iSel >= m_vItems.size())
+		return NoTaskID;
+
+	return m_vItems.at(iSel)->m_tTaskID;
+}
+
 void CProgressListBox::Init()
 {
-	// set new height of an item
 	CClientDC dc(this);
+	dc.SelectObject(GetFont());
 	TEXTMETRIC tm;
 	dc.GetTextMetrics(&tm);
-	int iHeight=MulDiv(tm.tmHeight+tm.tmExternalLeading, dc.GetDeviceCaps(LOGPIXELSY), tm.tmDigitizedAspectY);
-	SetItemHeight(0, m_bShowCaptions ? iHeight+2+9+2 : 2+9+2);
+	int iHeight = MulDiv(tm.tmHeight + tm.tmExternalLeading, dc.GetDeviceCaps(LOGPIXELSY), tm.tmDigitizedAspectY);
+
+	m_iProgressHeight = std::max(9, int(iHeight * 0.6));
+	m_iTopMargin = std::max(2, int(iHeight / 6));
+	m_iMidMargin = std::max(2, int(iHeight / 8));
+	m_iBottomMargin = std::max(2, int(iHeight / 6));;
+	m_iProgressContentXMargin = m_iProgressContentYMargin = std::max(1, m_iProgressHeight / 9);
+
+	if(m_bShowCaptions)
+	{
+		SetItemHeight(0, m_iProgressHeight + m_iTopMargin + m_iMidMargin + m_iBottomMargin + iHeight);
+	}
+	else
+		SetItemHeight(0, m_iProgressHeight + m_iTopMargin + m_iMidMargin + m_iBottomMargin);
 }
 
 _PROGRESSITEM_* CProgressListBox::GetItemAddress(int iIndex)
@@ -214,10 +232,13 @@
 	CRect rcClip;
 	dc.GetClipBox(&rcClip);
 
-	CMemDC memDC(dc, &rcClip);
-	memDC.GetDC().FillSolidRect(&rcClip, GetSysColor(COLOR_3DFACE));
+	if(!rcClip.IsRectEmpty())
+	{
+		CMemDC memDC(dc, &rcClip);
+		memDC.GetDC().FillSolidRect(&rcClip, GetSysColor(COLOR_3DFACE));
 
-	DefWindowProc(WM_PAINT, reinterpret_cast<WPARAM>(memDC.GetDC().m_hDC), 0);
+		DefWindowProc(WM_PAINT, reinterpret_cast<WPARAM>(memDC.GetDC().m_hDC), 0);
+	}
 }
 
 BOOL CProgressListBox::OnEraseBkgnd(CDC*) 
@@ -239,6 +260,27 @@
 	SetCurrentSelection(-1);
 }
 
+void CProgressListBox::OnRButtonDown(UINT /*nFlags*/, CPoint point)
+{
+	BOOL bOutside = FALSE;
+	UINT uiIndex = ItemFromPoint(point, bOutside);
+	if(!bOutside && uiIndex < m_vItems.size())
+		SetCurrentSelection(uiIndex);
+}
+
+void CProgressListBox::OnRButtonUp(UINT /*nFlags*/, CPoint point)
+{
+	chengine::taskid_t taskId = GetSelectedTaskId();
+	CWnd* pWnd = GetParent();
+	if(pWnd)
+	{
+		ClientToScreen(&point);
+
+		TASK_CLICK_NOTIFICATION notify = { point, taskId };
+		pWnd->SendMessage(WM_TASK_RCLICK, 0, (LPARAM)&notify);
+	}
+}
+
 void CProgressListBox::SetSmoothProgress(bool bSmoothProgress)
 {
 	m_bSmoothProgress=bSmoothProgress;
Index: src/ch/ProgressListBox.h
===================================================================
diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r814b694086d5dc450efb6a5e5c6902145ddc07fd
--- src/ch/ProgressListBox.h	(.../ProgressListBox.h)	(revision 0d5b67ee96b435d63f7bf075dc8e28603793b187)
+++ src/ch/ProgressListBox.h	(.../ProgressListBox.h)	(revision 814b694086d5dc450efb6a5e5c6902145ddc07fd)
@@ -1,26 +1,27 @@
-/***************************************************************************
-*   Copyright (C) 2001-2008 by J�zef Starosczyk                           *
-*   ixen@copyhandler.com                                                  *
-*                                                                         *
-*   This program is free software; you can redistribute it and/or modify  *
-*   it under the terms of the GNU Library General Public License          *
-*   (version 2) as published by the Free Software Foundation;             *
-*                                                                         *
-*   This program 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 Library General Public     *
-*   License along with this program; if not, write to the                 *
-*   Free Software Foundation, Inc.,                                       *
-*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
-***************************************************************************/
-#ifndef __PROGRESSLISTBOX_H__
-#define __PROGRESSLISTBOX_H__
+// ============================================================================
+//  Copyright (C) 2001-2020 by Jozef Starosczyk
+//  ixen {at} copyhandler [dot] com
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU Library General Public License
+//  (version 2) as published by the Free Software Foundation;
+//
+//  This program 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 Library General Public
+//  License along with this program; if not, write to the
+//  Free Software Foundation, Inc.,
+//  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+// ============================================================================
+#pragma once
 
 #include "../libchengine/TaskID.h"
 
+constexpr int WM_TASK_RCLICK = WM_USER + 13;
+
 /////////////////////////////////////////////////////////////////////////////
 // CProgressListBox window
 struct _PROGRESSITEM_
@@ -35,60 +36,55 @@
 	chengine::taskid_t m_tTaskID;
 };
 
+struct TASK_CLICK_NOTIFICATION
+{
+	CPoint point;
+	chengine::taskid_t taskId = chengine::NoTaskID;
+};
+
 class CProgressListBox : public CListBox
 {
-// Construction
 public:
 	CProgressListBox();
+	virtual ~CProgressListBox();
 
-// Attributes
 public:
+	void SetSmoothProgress(bool bSmoothProgress);
+	int SetCurrentSelection(int nSelect);
+	chengine::taskid_t GetSelectedTaskId() const;
 
-// Operations
-public:
-	std::vector<_PROGRESSITEM_*> m_vItems;
+	_PROGRESSITEM_* GetItemAddress(int iIndex);
+	std::vector<_PROGRESSITEM_*>& GetItems() { return m_vItems; }
 
-protected:
-	bool m_bShowCaptions;
-	bool m_bSmoothProgress;
+	void UpdateItems(int nLimit, bool bUpdateSize);		// updates items in listbox
 
-// Overrides
-	// ClassWizard generated virtual function overrides
-	//{{AFX_VIRTUAL(CProgressListBox)
-public:
-	void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) override;
-	//}}AFX_VIRTUAL
-
-// Implementation
-public:
-	void SetSmoothProgress(bool bSmoothProgress);
-	int SetCurrentSelection( int nSelect );
 	void Init();
 
-	void UpdateItems(int nLimit, bool bUpdateSize);		// updates items in listbox
-	void RecalcHeight();	// sets size of a listbox by counting szie of the items
-
-	_PROGRESSITEM_* GetItemAddress(int iIndex);
-
-	void SetShowCaptions(bool bShow=true);
+	void SetShowCaptions(bool bShow = true);
 	bool GetShowCaptions();
 
-	virtual ~CProgressListBox();
-
-	// Generated message map functions
 protected:
-	//{{AFX_MSG(CProgressListBox)
+	void RecalcHeight();	// sets size of a listbox by counting size of the items
+
+	void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) override;
+
 	afx_msg void OnPaint();
 	afx_msg BOOL OnEraseBkgnd(CDC*);
 	afx_msg void OnKillfocus();
-	//}}AFX_MSG
+	afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
+	afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
 
 	DECLARE_MESSAGE_MAP()
-};
 
-/////////////////////////////////////////////////////////////////////////////
+private:
+	std::vector<_PROGRESSITEM_*> m_vItems;
+	bool m_bShowCaptions = true;
+	bool m_bSmoothProgress = false;
 
-//{{AFX_INSERT_LOCATION}}
-// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
-
-#endif
+	int m_iTopMargin = 5;
+	int m_iProgressHeight = 10;
+	int m_iMidMargin = 2;
+	int m_iBottomMargin = 0;
+	int m_iProgressContentXMargin = 2;
+	int m_iProgressContentYMargin = 2;
+};
Index: src/ch/StatusDlg.cpp
===================================================================
diff -u -rc88853d744d42c9d0d18d14f920190d535bb714a -r814b694086d5dc450efb6a5e5c6902145ddc07fd
--- src/ch/StatusDlg.cpp	(.../StatusDlg.cpp)	(revision c88853d744d42c9d0d18d14f920190d535bb714a)
+++ src/ch/StatusDlg.cpp	(.../StatusDlg.cpp)	(revision 814b694086d5dc450efb6a5e5c6902145ddc07fd)
@@ -27,13 +27,16 @@
 #include "CfgProperties.h"
 #include "../libchengine/TTaskManager.h"
 #include "../libchengine/TLocalFilesystem.h"
+#include "GuiOptions.h"
 
 #ifdef _DEBUG
 #define new DEBUG_NEW
 #undef THIS_FILE
 static char THIS_FILE[] = __FILE__;
 #endif
 
+using namespace chengine;
+
 bool CStatusDlg::m_bLock=false;
 
 /////////////////////////////////////////////////////////////////////////////
@@ -80,6 +83,7 @@
 	ON_BN_CLICKED(IDC_REMOVE_FINISHED_BUTTON, OnRemoveFinishedButton)
 	ON_NOTIFY(LVN_KEYDOWN, IDC_STATUS_LIST, OnKeydownStatusList)
 	ON_NOTIFY(LVN_CHANGEDSELECTION, IDC_STATUS_LIST, OnSelectionChanged)
+	ON_NOTIFY(NM_RCLICK, IDC_STATUS_LIST, OnStatusListRClick)
 	ON_BN_CLICKED(IDC_SHOW_LOG_BUTTON, OnShowLogButton)
 	ON_BN_CLICKED(IDC_STICK_BUTTON, OnStickButton)
 	ON_BN_CLICKED(IDC_RESUME_BUTTON, OnResumeButton)
@@ -151,10 +155,11 @@
 	m_ctlTaskCountProgress.SetRange32(0, 100);
 	m_ctlProgressAll.SetRange32(0, 100);
 
+	// load menu
+	m_menuContext.Load();
+
 	// change the size of a dialog
 	StickDialogToScreenEdge();
-//	ApplyButtonsState();
-//	EnableControls(false);
 
 	// refresh data
 	RefreshStatus();
@@ -322,59 +327,14 @@
 	chengine::TTaskPtr spSelectedTask = GetSelectedItemPointer();
 
 	// set status of buttons pause/resume/cancel
-	if (spSelectedTask != nullptr)
-	{
-		if(spSelectedTask->GetTaskState() == chengine::eTaskState_LoadError)
-		{
-			GetDlgItem(IDC_SHOW_LOG_BUTTON)->EnableWindow(true);
-			GetDlgItem(IDC_PAUSE_BUTTON)->EnableWindow(false);
-			GetDlgItem(IDC_RESUME_BUTTON)->EnableWindow(false);
-			GetDlgItem(IDC_RESTART_BUTTON)->EnableWindow(false);
-			GetDlgItem(IDC_CANCEL_BUTTON)->EnableWindow(false);
-			GetDlgItem(IDC_DELETE_BUTTON)->EnableWindow(true);
-		}
-		else
-		{
-			GetDlgItem(IDC_RESTART_BUTTON)->EnableWindow(true);
-			GetDlgItem(IDC_SHOW_LOG_BUTTON)->EnableWindow(true);
-			GetDlgItem(IDC_DELETE_BUTTON)->EnableWindow(true);
+	ETaskCurrentState eState = spSelectedTask != nullptr ? spSelectedTask->GetTaskState() : eTaskState_None;
 
-			if (spSelectedTask->GetTaskState() == chengine::eTaskState_Finished || spSelectedTask->GetTaskState() == chengine::eTaskState_Cancelled)
-			{
-				GetDlgItem(IDC_CANCEL_BUTTON)->EnableWindow(false);
-				GetDlgItem(IDC_PAUSE_BUTTON)->EnableWindow(false);
-				GetDlgItem(IDC_RESUME_BUTTON)->EnableWindow(false);
-			}
-			else
-			{
-				// pause/resume
-				if (spSelectedTask->GetTaskState() == chengine::eTaskState_Paused)
-				{
-					GetDlgItem(IDC_PAUSE_BUTTON)->EnableWindow(false);
-					GetDlgItem(IDC_RESUME_BUTTON)->EnableWindow(true);
-				}
-				else
-				{
-					GetDlgItem(IDC_PAUSE_BUTTON)->EnableWindow(true);
-					if (spSelectedTask->GetTaskState() == chengine::eTaskState_Waiting)
-						GetDlgItem(IDC_RESUME_BUTTON)->EnableWindow(true);
-					else
-						GetDlgItem(IDC_RESUME_BUTTON)->EnableWindow(false);
-				}
-
-				GetDlgItem(IDC_CANCEL_BUTTON)->EnableWindow(true);
-			}
-		}
-	}
-	else
-	{
-		GetDlgItem(IDC_SHOW_LOG_BUTTON)->EnableWindow(false);
-		GetDlgItem(IDC_PAUSE_BUTTON)->EnableWindow(false);
-		GetDlgItem(IDC_RESUME_BUTTON)->EnableWindow(false);
-		GetDlgItem(IDC_RESTART_BUTTON)->EnableWindow(false);
-		GetDlgItem(IDC_CANCEL_BUTTON)->EnableWindow(false);
-		GetDlgItem(IDC_DELETE_BUTTON)->EnableWindow(false);
-	}
+	GetDlgItem(IDC_SHOW_LOG_BUTTON)->EnableWindow(GuiOptions::IsShowLogAvailable(eState));
+	GetDlgItem(IDC_PAUSE_BUTTON)->EnableWindow(GuiOptions::IsPauseAvailable(eState));
+	GetDlgItem(IDC_RESUME_BUTTON)->EnableWindow(GuiOptions::IsResumeAvailable(eState));
+	GetDlgItem(IDC_RESTART_BUTTON)->EnableWindow(GuiOptions::IsRestartAvailable(eState));
+	GetDlgItem(IDC_CANCEL_BUTTON)->EnableWindow(GuiOptions::IsCancelAvailable(eState));
+	GetDlgItem(IDC_DELETE_BUTTON)->EnableWindow(GuiOptions::IsDeleteAvailable(eState));
 }
 
 void CStatusDlg::OnSetPriorityButton() 
@@ -467,18 +427,20 @@
 		}
 		else if(LOWORD(wParam) == ID_POPUP_RESET_APPLY_TO_ALL)
 		{
-			// processing priority
-			chengine::TTaskPtr spSelectedTask = GetSelectedItemPointer();
-
-			if(spSelectedTask == nullptr)
-				return ictranslate::CLanguageDialog::OnCommand(wParam, lParam);
-
-			spSelectedTask->RestoreFeedbackDefaults();
+			OnResetUserFeedback();
 		}
 	}
 	return ictranslate::CLanguageDialog::OnCommand(wParam, lParam);
 }
 
+void CStatusDlg::OnResetUserFeedback()
+{
+	chengine::TTaskPtr spSelectedTask = GetSelectedItemPointer();
+
+	if(spSelectedTask)
+		spSelectedTask->RestoreFeedbackDefaults();
+}
+
 void CStatusDlg::OnPauseButton() 
 {
 	chengine::TTaskPtr spTask = GetSelectedItemPointer();
@@ -721,6 +683,62 @@
 	RefreshStatus();
 }
 
+void CStatusDlg::OnStatusListRClick(NMHDR* pNMHDR, LRESULT* /*pResult*/)
+{
+	NMITEMACTIVATE* pData = (NMITEMACTIVATE*)pNMHDR;
+	if(!pData)
+		return;
+
+	ETaskCurrentState eState = eTaskState_None;
+
+	TTaskPtr spTask = GetSelectedItemPointer();
+	if(spTask)
+		eState = spTask->GetTaskState();
+	spTask.reset();
+
+	CPoint pt = pData->ptAction;
+	m_ctlStatusList.ClientToScreen(&pt);
+
+	int iMenuItem = m_menuContext.TrackPopupMenu(eState, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, this);
+	switch(iMenuItem)
+	{
+	case ID_TASK_MENU_PAUSE:
+		OnPauseButton();
+		break;
+	case ID_TASK_MENU_RESUME:
+		OnResumeButton();
+		break;
+	case ID_TASK_MENU_RESTART:
+		OnRestartButton();
+		break;
+	case ID_TASK_MENU_CANCEL:
+		OnCancelButton();
+		break;
+	case ID_TASK_MENU_REMOVE:
+		OnDeleteButton();
+		break;
+	case ID_TASK_MENU_RESET_FEEDBACK:
+		OnResetUserFeedback();
+		break;
+
+	case ID_TASK_MENU_PAUSE_ALL:
+		m_pTasks->TasksPauseProcessing();
+		break;
+	case ID_TASK_MENU_RESUME_ALL:
+		m_pTasks->TasksResumeProcessing();
+		break;
+	case ID_TASK_MENU_RESTART_ALL:
+		m_pTasks->TasksRestartProcessing();
+		break;
+	case ID_TASK_MENU_CANCEL_ALL:
+		m_pTasks->TasksCancelProcessing();
+		break;
+	case ID_TASK_MENU_REMOVE_INACTIVE:
+		m_pTasks->RemoveAllFinished();
+		break;
+	}
+}
+
 void CStatusDlg::OnCancel() 
 {
 	PostCloseMessage();
Index: src/ch/StatusDlg.h
===================================================================
diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r814b694086d5dc450efb6a5e5c6902145ddc07fd
--- src/ch/StatusDlg.h	(.../StatusDlg.h)	(revision 0d5b67ee96b435d63f7bf075dc8e28603793b187)
+++ src/ch/StatusDlg.h	(.../StatusDlg.h)	(revision 814b694086d5dc450efb6a5e5c6902145ddc07fd)
@@ -24,6 +24,7 @@
 #include "TExplorerTaskBarProgress.h"
 #include "../libchengine/TTask.h"
 #include "../libchengine/TTaskManager.h"
+#include "TaskContextMenu.h"
 
 namespace chengine {
 	class TTaskManager;
@@ -56,6 +57,9 @@
 protected:
 	void DoDataExchange(CDataExchange* pDX) override;    // DDX/DDV support
 	BOOL OnCommand(WPARAM wParam, LPARAM lParam) override;
+
+	void OnResetUserFeedback();
+
 	LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam) override;
 
 	void OnLanguageChanged() override;
@@ -98,6 +102,7 @@
 	afx_msg void OnRemoveFinishedButton();
 	afx_msg void OnKeydownStatusList(NMHDR* pNMHDR, LRESULT* pResult);
 	afx_msg void OnSelectionChanged(NMHDR* /*pNMHDR*/, LRESULT* /*pResult*/);
+	afx_msg void OnStatusListRClick(NMHDR* pNMHDR, LRESULT* pResult);
 	void OnCancel() override;
 	afx_msg void OnShowLogButton();
 	afx_msg void OnStickButton();
@@ -123,6 +128,9 @@
 	TProgressCtrlEx m_ctlSubTaskSizeProgress;
 	TProgressCtrlEx	m_ctlProgressAll;
 
+	TaskContextMenu m_menuContext;
+	chengine::taskid_t m_currentTaskId = chengine::NoTaskID;
+
 	chengine::TTaskManagerStatsSnapshotPtr m_spTaskMgrStats;
 	TExplorerTaskBarProgress m_taskBarProgress;
 };
Index: src/ch/TaskContextMenu.cpp
===================================================================
diff -u
--- src/ch/TaskContextMenu.cpp	(revision 0)
+++ src/ch/TaskContextMenu.cpp	(revision 814b694086d5dc450efb6a5e5c6902145ddc07fd)
@@ -0,0 +1,26 @@
+#include "stdafx.h"
+#include "TaskContextMenu.h"
+#include "ch.h"
+#include "resource.h"
+#include "GuiOptions.h"
+
+void TaskContextMenu::Load()
+{
+	HMENU hMenu = GetResManager().LoadMenu(MAKEINTRESOURCE(IDR_TASK_MENU));
+	Attach(hMenu);
+}
+
+BOOL TaskContextMenu::TrackPopupMenu(chengine::ETaskCurrentState eState, UINT nFlags, int x, int y, CWnd* pWnd)
+{
+	CMenu* pSubMenu = GetSubMenu(0);
+
+	pSubMenu->EnableMenuItem(ID_TASK_MENU_PAUSE, MF_BYCOMMAND | (GuiOptions::IsPauseAvailable(eState) ? MF_ENABLED : MF_GRAYED));
+	pSubMenu->EnableMenuItem(ID_TASK_MENU_RESUME, MF_BYCOMMAND | (GuiOptions::IsResumeAvailable(eState) ? MF_ENABLED : MF_GRAYED));
+	pSubMenu->EnableMenuItem(ID_TASK_MENU_RESTART, MF_BYCOMMAND | (GuiOptions::IsRestartAvailable(eState) ? MF_ENABLED : MF_GRAYED));
+	pSubMenu->EnableMenuItem(ID_TASK_MENU_CANCEL, MF_BYCOMMAND | (GuiOptions::IsCancelAvailable(eState) ? MF_ENABLED : MF_GRAYED));
+	pSubMenu->EnableMenuItem(ID_TASK_MENU_REMOVE, MF_BYCOMMAND | (GuiOptions::IsDeleteAvailable(eState) ? MF_ENABLED : MF_GRAYED));
+	pSubMenu->EnableMenuItem(ID_TASK_MENU_RESET_FEEDBACK, MF_BYCOMMAND | (GuiOptions::IsResetUserFeedbackAvailable(eState) ? MF_ENABLED : MF_GRAYED));
+
+	return pSubMenu->TrackPopupMenu(nFlags, x, y, pWnd);
+}
+
Index: src/ch/TaskContextMenu.h
===================================================================
diff -u
--- src/ch/TaskContextMenu.h	(revision 0)
+++ src/ch/TaskContextMenu.h	(revision 814b694086d5dc450efb6a5e5c6902145ddc07fd)
@@ -0,0 +1,29 @@
+// ============================================================================
+//  Copyright (C) 2001-2020 by Jozef Starosczyk
+//  ixen {at} copyhandler [dot] com
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU Library General Public License
+//  (version 2) as published by the Free Software Foundation;
+//
+//  This program 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 Library General Public
+//  License along with this program; if not, write to the
+//  Free Software Foundation, Inc.,
+//  59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+// ============================================================================
+#pragma once
+#include "../libchengine/ETaskCurrentState.h"
+
+class TaskContextMenu : public CMenu
+{
+public:
+	void Load();
+
+	BOOL TrackPopupMenu(chengine::ETaskCurrentState eState, UINT nFlags, int x, int y, CWnd* pWnd);
+
+};
Index: src/ch/ch.rc
===================================================================
diff -u -r95ca5963512a664baa8dcb491e63f5cea1dc5f23 -r814b694086d5dc450efb6a5e5c6902145ddc07fd
--- src/ch/ch.rc	(.../ch.rc)	(revision 95ca5963512a664baa8dcb491e63f5cea1dc5f23)
+++ src/ch/ch.rc	(.../ch.rc)	(revision 814b694086d5dc450efb6a5e5c6902145ddc07fd)
@@ -101,13 +101,13 @@
     LTEXT           "Alternate file:",IDC_DST_NAME_STATIC,45,52,54,8
 END
 
-IDD_MINIVIEW_DIALOG DIALOGEX 0, 0, 91, 23
-STYLE DS_ABSALIGN | DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | WS_POPUP | WS_CAPTION
+IDD_MINIVIEW_DIALOG DIALOGEX 0, 0, 105, 23
+STYLE DS_ABSALIGN | DS_SYSMODAL | DS_SETFONT | DS_SETFOREGROUND | WS_POPUP | WS_CAPTION | WS_SYSMENU
 EXSTYLE WS_EX_TOOLWINDOW
 CAPTION "Status"
 FONT 8, "Tahoma", 0, 0, 0x1
 BEGIN
-    LISTBOX         IDC_PROGRESS_LIST,7,7,77,9,LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | NOT WS_BORDER | WS_TABSTOP
+    LISTBOX         IDC_PROGRESS_LIST,7,7,91,9,LBS_OWNERDRAWFIXED | LBS_NOINTEGRALHEIGHT | NOT WS_BORDER | WS_TABSTOP
 END
 
 IDD_OPTIONS_DIALOG DIALOGEX 0, 0, 397, 214
@@ -589,7 +589,7 @@
     IDD_MINIVIEW_DIALOG, DIALOG
     BEGIN
         LEFTMARGIN, 7
-        RIGHTMARGIN, 84
+        RIGHTMARGIN, 98
         TOPMARGIN, 7
         BOTTOMMARGIN, 16
     END
@@ -855,7 +855,12 @@
     0
 END
 
+IDD_MINIVIEW_DIALOG AFX_DIALOG_LAYOUT
+BEGIN
+    0
+END
 
+
 /////////////////////////////////////////////////////////////////////////////
 //
 // Icon
@@ -1051,7 +1056,27 @@
     END
 END
 
+IDR_TASK_MENU MENU
+BEGIN
+    POPUP "_POPUP_"
+    BEGIN
+        MENUITEM "&Pause",                      ID_TASK_MENU_PAUSE
+        MENUITEM "&Resume",                     ID_TASK_MENU_RESUME
+        MENUITEM "R&estart",                    ID_TASK_MENU_RESTART
+        MENUITEM "&Cancel",                     ID_TASK_MENU_CANCEL
+        MENUITEM "Re&move",                     ID_TASK_MENU_REMOVE
+        MENUITEM SEPARATOR
+        MENUITEM "Reset user-feedback state",   ID_TASK_MENU_RESET_FEEDBACK
+        MENUITEM SEPARATOR
+        MENUITEM "Pause all",                   ID_TASK_MENU_PAUSE_ALL
+        MENUITEM "Resume all",                  ID_TASK_MENU_RESUME_ALL
+        MENUITEM "Restart all",                 ID_TASK_MENU_RESTART_ALL
+        MENUITEM "Cancel all",                  ID_TASK_MENU_CANCEL_ALL
+        MENUITEM "Remove inactive",             ID_TASK_MENU_REMOVE_INACTIVE
+    END
+END
 
+
 #ifdef APSTUDIO_INVOKED
 /////////////////////////////////////////////////////////////////////////////
 //
Index: src/ch/ch.vc140.vcxproj
===================================================================
diff -u -r9250a0229add10f4315e76848c755f337a16ae95 -r814b694086d5dc450efb6a5e5c6902145ddc07fd
--- src/ch/ch.vc140.vcxproj	(.../ch.vc140.vcxproj)	(revision 9250a0229add10f4315e76848c755f337a16ae95)
+++ src/ch/ch.vc140.vcxproj	(.../ch.vc140.vcxproj)	(revision 814b694086d5dc450efb6a5e5c6902145ddc07fd)
@@ -563,6 +563,7 @@
     <ClInclude Include="FeedbackHandler.h" />
     <ClInclude Include="FeedbackHandlerFactory.h" />
     <ClInclude Include="FilterTypesMenuWrapper.h" />
+    <ClInclude Include="GuiOptions.h" />
     <ClInclude Include="RuleEditAlreadyExistsDlg.h" />
     <ClInclude Include="RuleEditDlg.h" />
     <ClInclude Include="RuleEditErrorDlg.h" />
@@ -573,6 +574,7 @@
     <ClInclude Include="ClipboardMonitor.h" />
     <ClInclude Include="shortcuts.h" />
     <ClInclude Include="StringHelpers.h" />
+    <ClInclude Include="TaskContextMenu.h" />
     <ClInclude Include="TExplorerTaskBarProgress.h" />
     <ClInclude Include="TMsgBox.h" />
     <ClInclude Include="TPathProcessor.h" />
@@ -645,6 +647,7 @@
     <ClCompile Include="FeedbackHandler.cpp" />
     <ClCompile Include="FeedbackHandlerFactory.cpp" />
     <ClCompile Include="FilterTypesMenuWrapper.cpp" />
+    <ClCompile Include="GuiOptions.cpp" />
     <ClCompile Include="RuleEditAlreadyExistsDlg.cpp" />
     <ClCompile Include="RuleEditDlg.cpp" />
     <ClCompile Include="RuleEditErrorDlg.cpp" />
@@ -654,6 +657,7 @@
     <ClCompile Include="ClipboardMonitor.cpp" />
     <ClCompile Include="shortcuts.cpp" />
     <ClCompile Include="StringHelpers.cpp" />
+    <ClCompile Include="TaskContextMenu.cpp" />
     <ClCompile Include="TExplorerTaskBarProgress.cpp" />
     <ClCompile Include="TMsgBox.cpp" />
     <ClCompile Include="TPathProcessor.cpp" />
Index: src/ch/ch.vc140.vcxproj.filters
===================================================================
diff -u -r63369021254e8b67ffeef5a9ece1b5a70df881c4 -r814b694086d5dc450efb6a5e5c6902145ddc07fd
--- src/ch/ch.vc140.vcxproj.filters	(.../ch.vc140.vcxproj.filters)	(revision 63369021254e8b67ffeef5a9ece1b5a70df881c4)
+++ src/ch/ch.vc140.vcxproj.filters	(.../ch.vc140.vcxproj.filters)	(revision 814b694086d5dc450efb6a5e5c6902145ddc07fd)
@@ -276,6 +276,12 @@
     <ClInclude Include="FilterTypesMenuWrapper.h">
       <Filter>Source Files\GUI\Utils</Filter>
     </ClInclude>
+    <ClInclude Include="GuiOptions.h">
+      <Filter>Source Files\Tools</Filter>
+    </ClInclude>
+    <ClInclude Include="TaskContextMenu.h">
+      <Filter>Source Files\Tools</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\common\TShellExtMenuConfig.cpp">
@@ -473,6 +479,12 @@
     <ClCompile Include="FilterTypesMenuWrapper.cpp">
       <Filter>Source Files\GUI\Utils</Filter>
     </ClCompile>
+    <ClCompile Include="GuiOptions.cpp">
+      <Filter>Source Files\Tools</Filter>
+    </ClCompile>
+    <ClCompile Include="TaskContextMenu.cpp">
+      <Filter>Source Files\Tools</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <None Include="res\ch.rc2">
Index: src/ch/resource.h
===================================================================
diff -u -rc88853d744d42c9d0d18d14f920190d535bb714a -r814b694086d5dc450efb6a5e5c6902145ddc07fd
--- src/ch/resource.h	(.../resource.h)	(revision c88853d744d42c9d0d18d14f920190d535bb714a)
+++ src/ch/resource.h	(.../resource.h)	(revision 814b694086d5dc450efb6a5e5c6902145ddc07fd)
@@ -65,6 +65,7 @@
 #define IDR_ERROR_MASS_SKIP_MENU        237
 #define IDR_ERROR_MASS_RETRY_MENU       238
 #define IDR_FILTER_TYPE_MENU            244
+#define IDR_TASK_MENU                   247
 #define IDC_PROGRAM_STATIC              1000
 #define IDC_ADDFILE_BUTTON              1002
 #define IDC_STATUS_LIST                 1003
@@ -822,7 +823,7 @@
 #define IDS_STATUS_LOADERROR_STRING     21555
 #define IDS_EXPORTING_TASK_FAILED       21556
 #define IDS_LOGFILEEMPTY_STRING         21558
-#define IDS_INVALID_FILTER_STRING              21559
+#define IDS_INVALID_FILTER_STRING       21559
 #define IDS_STATUS_EXCLUDE_EMPTY_DIRECTORIES_STRING 21560
 #define ID_POPUP_SHOW_STATUS            32773
 #define ID_POPUP_TIME_CRITICAL          32774
@@ -869,14 +870,25 @@
 #define ID_POPUP_FILTER_FILE_REGEX_EXAMPLE 32846
 #define ID_POPUP_FILTER_PATH_REGEX_EXAMPLE 32847
 #define ID_POPUP_FILTER_SEPARATOR_CHAR  32848
+#define ID_TASK_MENU_PAUSE              32856
+#define ID_TASK_MENU_RESUME             32857
+#define ID_TASK_MENU_RESTART            32858
+#define ID_TASK_MENU_CANCEL             32859
+#define ID_TASK_MENU_REMOVE             32860
+#define ID_TASK_MENU_RESET_FEEDBACK     32861
+#define ID_TASK_MENU_RESUME_ALL         32867
+#define ID_TASK_MENU_PAUSE_ALL          32868
+#define ID_TASK_MENU_RESTART_ALL        32869
+#define ID_TASK_MENU_CANCEL_ALL         32870
+#define ID_TASK_MENU_REMOVE_INACTIVE    32871
 
 // Next default values for new objects
 // 
 #ifdef APSTUDIO_INVOKED
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_3D_CONTROLS                     1
-#define _APS_NEXT_RESOURCE_VALUE        246
-#define _APS_NEXT_COMMAND_VALUE         32849
+#define _APS_NEXT_RESOURCE_VALUE        248
+#define _APS_NEXT_COMMAND_VALUE         32872
 #define _APS_NEXT_CONTROL_VALUE         1451
 #define _APS_NEXT_SYMED_VALUE           101
 #endif