Index: /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk	(revision 70538)
+++ /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk	(revision 70539)
@@ -335,4 +335,5 @@
 	src/hostnetwork/UIHostNetworkDetailsWidget.h \
 	src/hostnetwork/UIHostNetworkManager.h \
+	src/logviewer/UIVMLogPage.h \
 	src/logviewer/UIVMLogViewerBookmarksPanel.h \
 	src/logviewer/UIVMLogViewerDialog.h \
@@ -547,6 +548,6 @@
 	src/globals/UIMainEventListener.cpp \
 	src/globals/UIThreadPool.cpp \
+	src/logviewer/UIVMLogPage.cpp \
 	src/logviewer/UIVMLogViewerFilterPanel.cpp \
-	src/logviewer/UIVMLogViewerWidget.cpp \
 	src/medium/UIMediumEnumerator.cpp \
 	src/runtime/UIActionPoolRuntime.cpp \
@@ -653,4 +654,5 @@
 	src/hostnetwork/UIHostNetworkManager.cpp \
 	src/hostnetwork/UIHostNetworkUtils.cpp \
+	src/logviewer/UIVMLogPage.cpp \
 	src/logviewer/UIVMLogViewerBookmarksPanel.cpp \
 	src/logviewer/UIVMLogViewerDialog.cpp \
Index: /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogPage.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogPage.cpp	(revision 70539)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogPage.cpp	(revision 70539)
@@ -0,0 +1,350 @@
+/* $Id$ */
+/** @file
+ * VBox Qt GUI - UIVMLogViewer class implementation.
+ */
+
+/*
+ * Copyright (C) 2010-2017 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifdef VBOX_WITH_PRECOMPILED_HEADERS
+# include <precomp.h>
+#else  /* !VBOX_WITH_PRECOMPILED_HEADERS */
+
+/* Qt includes: */
+# include <QDateTime>
+# include <QDir>
+# include <QVBoxLayout>
+# if defined(RT_OS_SOLARIS)
+#  include <QFontDatabase>
+# endif
+# include <QPainter>
+# include <QPlainTextEdit>
+# include <QScrollBar>
+# include <QTextBlock>
+
+/* GUI includes: */
+# include "QIFileDialog.h"
+# include "QITabWidget.h"
+# include "UIExtraDataManager.h"
+# include "UIIconPool.h"
+# include "UIMessageCenter.h"
+# include "UIVMLogPage.h"
+# include "UIVMLogViewerBookmarksPanel.h"
+# include "UIVMLogViewerFilterPanel.h"
+# include "UIVMLogViewerSearchPanel.h"
+# include "UIToolBar.h"
+
+/* COM includes: */
+# include "CSystemProperties.h"
+
+# include "VBoxGlobal.h"
+
+#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
+
+
+/** We use a modified scrollbar style for our QPlainTextEdits to get the
+    markings on the scrollbars correctly. The default scrollbarstyle does not
+    reveal the height of the pushbuttons on the scrollbar (on either side of it, with arrow on them)
+    to compute the marking locations correctly. Thus we turn these push buttons off: */
+const QString verticalScrollBarStyle("QScrollBar:vertical {"
+                                     "border: 1px ridge grey; "
+                                     "margin: 0px 0px 0 0px;}"
+                                     "QScrollBar::handle:vertical {"
+                                     "min-height: 10px;"
+                                     "background: grey;}"
+                                     "QScrollBar::add-line:vertical {"
+                                     "width: 0px;}"
+                                     "QScrollBar::sub-line:vertical {"
+                                     "width: 0px;}");
+
+const QString horizontalScrollBarStyle("QScrollBar:horizontal {"
+                                       "border: 1px ridge grey; "
+                                       "margin: 0px 0px 0 0px;}"
+                                       "QScrollBar::handle:horizontal {"
+                                       "min-height: 10px;"
+                                       "background: grey;}"
+                                       "QScrollBar::add-line:horizontal {"
+                                       "height: 0px;}"
+                                       "QScrollBar::sub-line:horizontal {"
+                                       "height: 0px;}");
+
+class UIIndicatorScrollBar : public QScrollBar
+{
+    Q_OBJECT;
+
+public:
+
+    UIIndicatorScrollBar(QWidget *parent = 0)
+        :QScrollBar(parent)
+    {
+        setStyleSheet(verticalScrollBarStyle);
+    }
+
+    void setMarkingsVector(const QVector<float> &vector)
+    {
+        m_markingsVector = vector;
+    }
+
+    void clearMarkingsVector()
+    {
+        m_markingsVector.clear();
+    }
+
+protected:
+
+    virtual void paintEvent(QPaintEvent *pEvent) /* override */
+    {
+        QScrollBar::paintEvent(pEvent);
+        /* Put a red line to marking position: */
+        for (int i = 0; i < m_markingsVector.size(); ++i)
+        {
+            QPointF p1 = QPointF(0, m_markingsVector[i] * height());
+            QPointF p2 = QPointF(width(), m_markingsVector[i] * height());
+
+            QPainter painter(this);
+            painter.setRenderHint(QPainter::Antialiasing, true);
+            painter.setPen(QPen(QColor(255, 0, 0, 75), 1.1f));
+            painter.drawLine(p1, p2);
+        }
+    }
+
+private:
+
+    /* Stores the relative (to scrollbar's height) positions of markings,
+       where we draw a horizontal line. Values are in [0.0, 1.0]*/
+    QVector<float> m_markingsVector;
+};
+
+/* Sub-class QPlainTextEdit for some addtional context menu items: */
+class UIVMLogViewerTextEdit : public QPlainTextEdit
+{
+    Q_OBJECT;
+
+signals:
+
+    void sigContextMenuBookmarkAction(LogBookmark bookmark);
+
+public:
+    UIVMLogViewerTextEdit(QWidget* parent = 0)
+        :QPlainTextEdit(parent)
+    {
+        //setStyleSheet("background-color: rgba(240, 240, 240, 75%) ");
+    }
+
+protected:
+
+    void contextMenuEvent(QContextMenuEvent *pEvent)
+    {
+        QMenu *menu = createStandardContextMenu();
+        QAction *pAction = menu->addAction(tr("Bookmark"));
+        QTextBlock block = cursorForPosition(pEvent->pos()).block();
+        m_iContextMenuBookmark.first = block.firstLineNumber();
+        m_iContextMenuBookmark.second = block.text();
+
+        if (pAction)
+            connect(pAction, &QAction::triggered, this, &UIVMLogViewerTextEdit::sltBookmark);
+
+        menu->exec(pEvent->globalPos());
+
+        if (pAction)
+            disconnect(pAction, &QAction::triggered, this, &UIVMLogViewerTextEdit::sltBookmark);
+
+        delete menu;
+    }
+
+    virtual void mousePressEvent(QMouseEvent *pEvent)
+    {
+        QPlainTextEdit::mousePressEvent(pEvent);
+    }
+
+private slots:
+    /// remove
+    void sltBookmark()
+    {
+        emit sigContextMenuBookmarkAction(m_iContextMenuBookmark);
+    }
+
+private:
+
+    /* Line number and text at the context menu position */
+    LogBookmark m_iContextMenuBookmark;
+};
+
+
+UIVMLogPage::UIVMLogPage(QWidget *pParent /* = 0 */, int tabIndex /*= -1 */)
+    : QIWithRetranslateUI<QWidget>(pParent)
+    , m_pMainLayout(0)
+    , m_pPlainTextEdit(0)
+    , m_tabIndex(tabIndex)
+{
+    prepare();
+}
+
+UIVMLogPage::~UIVMLogPage()
+{
+    cleanup();
+}
+
+int UIVMLogPage::defaultLogPageWidth() const
+{
+    if (!m_pPlainTextEdit)
+        return 0;
+
+    /* Compute a width for 132 characters plus scrollbar and frame width: */
+    int iDefaultWidth = m_pPlainTextEdit->fontMetrics().width(QChar('x')) * 132 +
+                        m_pPlainTextEdit->verticalScrollBar()->width() +
+                        m_pPlainTextEdit->frameWidth() * 2;
+
+    return iDefaultWidth;
+}
+
+
+void UIVMLogPage::prepare()
+{
+    prepareWidgets();
+//     prepareActions();
+
+//     prepareToolBar();
+//     prepareMenu();
+
+//     /* Reading log files: */
+//     sltRefresh();
+
+//     /* Loading language constants: */
+    retranslateUi();
+}
+
+void UIVMLogPage::prepareWidgets()
+{
+    m_pMainLayout = new QHBoxLayout();
+    setLayout(m_pMainLayout);
+    m_pMainLayout->setSpacing(0);
+    m_pMainLayout->setContentsMargins(0, 0, 0, 0);
+
+    m_pPlainTextEdit = new UIVMLogViewerTextEdit(this);
+    m_pMainLayout->addWidget(m_pPlainTextEdit);
+
+    m_pPlainTextEdit->setVerticalScrollBar(new UIIndicatorScrollBar());
+    m_pPlainTextEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
+    QScrollBar *pHorizontalScrollBar = m_pPlainTextEdit->horizontalScrollBar();
+    if (pHorizontalScrollBar)
+        pHorizontalScrollBar->setStyleSheet(horizontalScrollBarStyle);
+
+#if defined(RT_OS_SOLARIS)
+    /* Use system fixed-width font on Solaris hosts as the Courier family fonts don't render well. */
+    QFont font = QFontDatabase::systemFont(QFontDatabase::FixedFont);
+#else
+    QFont font;
+    font.setFamily("Courier New,courier");
+#endif
+    m_pPlainTextEdit->setFont(font);
+    m_pPlainTextEdit->setWordWrapMode(QTextOption::NoWrap);
+    m_pPlainTextEdit->setReadOnly(true);
+
+}
+
+QPlainTextEdit *UIVMLogPage::textEdit()
+{
+    return m_pPlainTextEdit;
+}
+
+QTextDocument* UIVMLogPage::document()
+{
+    if (!m_pPlainTextEdit)
+        return 0;
+    return m_pPlainTextEdit->document();
+}
+
+void UIVMLogPage::setTabIndex(int index)
+{
+    m_tabIndex = index;
+}
+
+int UIVMLogPage::tabIndex()  const
+{
+    return m_tabIndex;
+}
+
+void UIVMLogPage::retranslateUi()
+{
+}
+
+void UIVMLogPage::cleanup()
+{
+}
+
+void UIVMLogPage::setLogString(const QString &strLog)
+{
+    m_strLog = strLog;
+}
+
+const QString& UIVMLogPage::logString() const
+{
+    return m_strLog;
+}
+
+void UIVMLogPage::setFileName(const QString &strFileName)
+{
+    m_strFileName = strFileName;
+}
+
+const QString& UIVMLogPage::fileName() const
+{
+    return m_strFileName;
+}
+
+void UIVMLogPage::setTextEdit(const QString &strText)
+{
+    m_pPlainTextEdit->setPlainText(strText);
+    /* Move the cursor position to end: */
+    QTextCursor cursor = m_pPlainTextEdit->textCursor();
+    cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
+    m_pPlainTextEdit->setTextCursor(cursor);
+    repaint();
+}
+
+void UIVMLogPage::markForError()
+{
+    QPalette pal = m_pPlainTextEdit->palette();
+    pal.setColor(QPalette::Base, pal.color(QPalette::Window));
+    m_pPlainTextEdit->setPalette(pal);
+}
+
+void UIVMLogPage::setScrollBarMarkingsVector(const QVector<float> &vector)
+{
+    if (!m_pPlainTextEdit)
+        return;
+    UIIndicatorScrollBar* scrollBar = qobject_cast<UIIndicatorScrollBar*>(m_pPlainTextEdit->verticalScrollBar());
+    if (scrollBar)
+        scrollBar->setMarkingsVector(vector);
+    repaint();
+}
+
+void UIVMLogPage::clearScrollBarMarkingsVector()
+{
+    if (!m_pPlainTextEdit)
+        return;
+    UIIndicatorScrollBar* scrollBar = qobject_cast<UIIndicatorScrollBar*>(m_pPlainTextEdit->verticalScrollBar());
+    if (scrollBar)
+        scrollBar->clearMarkingsVector();
+    repaint();
+}
+
+void UIVMLogPage::documentUndo()
+{
+    if (!m_pPlainTextEdit)
+        return;
+    if (m_pPlainTextEdit->document())
+        m_pPlainTextEdit->document()->undo();
+}
+
+#include "UIVMLogPage.moc"
Index: /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogPage.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogPage.h	(revision 70539)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogPage.h	(revision 70539)
@@ -0,0 +1,111 @@
+/* $Id$ */
+/** @file
+ * VBox Qt GUI - UIVMLogViewer class declaration.
+ */
+
+/*
+ * Copyright (C) 2010-2017 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef ___UIVMLogPage_h___
+#define ___UIVMLogPage_h___
+
+/* Qt includes: */
+#include <QWidget>
+/* #include <QMap> */
+#include <QPair>
+
+/* GUI includes: */
+#include "QIManagerDialog.h"
+#include "QIWithRetranslateUI.h"
+
+/* COM includes: */
+#include "COMEnums.h"
+#include "CMachine.h"
+
+/* Forward declarations: */
+class QITabWidget;
+class QPlainTextEdit;
+class QHBoxLayout;
+class UIToolBar;
+class UIVMLogViewerBookmarksPanel;
+class UIVMLogViewerFilterPanel;
+class UIVMLogViewerPanel;
+class UIVMLogViewerSearchPanel;
+
+/* Type definitions: */
+/** first is line number, second is block text */
+typedef QPair<int, QString> LogBookmark;
+
+class UIVMLogPage  : public QIWithRetranslateUI<QWidget>
+{
+    Q_OBJECT;
+
+public:
+
+    UIVMLogPage(QWidget *pParent = 0, int tabIndex = -1);
+    /** Destructs the VM Log-Viewer. */
+    ~UIVMLogPage();
+    /** Returns the width of the current log page. return 0 if there is no current log page: */
+    int defaultLogPageWidth() const;
+
+    QPlainTextEdit *textEdit();
+    QTextDocument  *document();
+
+    void setTabIndex(int index);
+    int tabIndex()  const;
+
+    /* Only to be called when log file is re-read. */
+    void setLogString(const QString &strLog);
+    const QString& logString() const;
+
+    void setFileName(const QString &strFileName);
+    const QString& fileName() const;
+
+    /** Ses plaintextEdit's text. Note that the text we
+        show currently might be different than
+        m_strLog. For example during filtering. */
+    void setTextEdit(const QString &strText);
+
+    /* Marks the plain text edit When we dont have a log content. */
+    void markForError();
+
+    void setScrollBarMarkingsVector(const QVector<float> &vector);
+    void clearScrollBarMarkingsVector();
+
+    /* Undos the changes done to textDocument */
+    void documentUndo();
+
+protected:
+
+private slots:
+
+
+private:
+    void prepare();
+    void prepareWidgets();
+    void cleanup();
+    void retranslateUi();
+
+    QHBoxLayout    *m_pMainLayout;
+    QPlainTextEdit *m_pPlainTextEdit;
+    /** Stores the log file (unmodified) content. */
+    QString         m_strLog;
+    /** Stores full path and name of the log file. */
+    QString         m_strFileName;
+    /** This is the index of the tab containing this widget in UIVMLogViewerWidget. */
+    int             m_tabIndex;
+
+    QVector<LogBookmark> m_bookmarkMap;
+
+};
+
+#endif /* !___UIVMLogPage_h___ */
Index: /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerFilterPanel.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerFilterPanel.cpp	(revision 70538)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerFilterPanel.cpp	(revision 70539)
@@ -199,19 +199,22 @@
 void UIVMLogViewerFilterPanel::filter()
 {
-    QPlainTextEdit *pCurrentPage = viewer()->currentLogPage();
-    AssertReturnVoid(pCurrentPage);
-    const QString* strInputText = viewer()->currentLog();
+    if (!viewer())
+        return;
+    QPlainTextEdit *pCurrentTextEdit = textEdit();
+    if (!pCurrentTextEdit)
+        return;
+    const QString* originalLogString = logString();
     m_iUnfilteredLineCount = 0;
     m_iFilteredLineCount = 0;
-    if (!strInputText || strInputText->isNull())
-        return;
-    QTextDocument *document = pCurrentPage->document();
+    if (!originalLogString || originalLogString->isNull())
+        return;
+    QTextDocument *document = textDocument();
     if (!document)
         return;
-    QStringList stringLines = strInputText->split("\n");
+    QStringList stringLines = originalLogString->split("\n");
     m_iUnfilteredLineCount = stringLines.size();
     if (m_filterTermList.empty())
     {
-        document->setPlainText(*strInputText);
+        document->setPlainText(*originalLogString);
         emit sigFilterApplied();
         m_iFilteredLineCount = document->lineCount();
@@ -238,7 +241,7 @@
 
     /* Move the cursor position to end: */
-    QTextCursor cursor = pCurrentPage->textCursor();
+    QTextCursor cursor = pCurrentTextEdit->textCursor();
     cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
-    pCurrentPage->setTextCursor(cursor);
+    pCurrentTextEdit->setTextCursor(cursor);
 
     emit sigFilterApplied();
@@ -452,11 +455,8 @@
                 pKeyEvent->key() == Qt::Key_T)
             {
-                if (viewer()->currentLogPage())
-                {
-                    if (isHidden())
-                        show();
-                    m_pFilterComboBox->setFocus();
-                    return true;
-                }
+                if (isHidden())
+                    show();
+                m_pFilterComboBox->setFocus();
+                return true;
             }
             else if (pKeyEvent->key() == Qt::Key_Return && m_pFilterComboBox && m_pFilterComboBox->hasFocus())
Index: /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerPanel.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerPanel.cpp	(revision 70538)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerPanel.cpp	(revision 70539)
@@ -23,18 +23,13 @@
 # include <QComboBox>
 # include <QHBoxLayout>
-# if defined(RT_OS_SOLARIS)
-#  include <QFontDatabase>
-# endif
 # include <QLabel>
-# include <QLineEdit>
 # include <QPlainTextEdit>
-# include <QPushButton>
 # include <QTextCursor>
 # include <QToolButton>
-# include <QScrollArea>
 
 /* GUI includes: */
 # include "UIIconPool.h"
 # include "UISpecialControls.h"
+# include "UIVMLogPage.h"
 # include "UIVMLogViewerPanel.h"
 # include "UIVMLogViewerWidget.h"
@@ -125,2 +120,30 @@
     QWidget::hideEvent(pEvent);
 }
+
+QTextDocument  *UIVMLogViewerPanel::textDocument()
+{
+    QPlainTextEdit *pEdit = textEdit();
+    if (!pEdit)
+        return 0;
+    return textEdit()->document();
+}
+
+QPlainTextEdit *UIVMLogViewerPanel::textEdit()
+{
+    if (!viewer())
+        return 0;
+    UIVMLogPage *logPage = viewer()->currentLogPage();
+    if (!logPage)
+        return 0;
+    return logPage->textEdit();
+}
+
+const QString* UIVMLogViewerPanel::logString() const
+{
+    if (!viewer())
+        return 0;
+    const UIVMLogPage* const page = qobject_cast<const UIVMLogPage* const>(viewer()->currentLogPage());
+    if (!page)
+        return 0;
+    return &(page->logString());
+}
Index: /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerPanel.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerPanel.h	(revision 70538)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerPanel.h	(revision 70539)
@@ -26,10 +26,7 @@
 
 /* Forward declarations: */
-class QComboBox;
 class QHBoxLayout;
-class QLabel;
-class QLineEdit;
-class QPushButton;
-class UIVMFilterLineEdit;
+class QPlainTextEdit;
+class QTextDocument;
 class UIMiniCancelButton;
 class UIVMLogViewerWidget;
@@ -69,4 +66,8 @@
     void hideEvent(QHideEvent *pEvent);
 
+    QTextDocument  *textDocument();
+    QPlainTextEdit *textEdit();
+    /* Return the unmodified log. */
+    const QString* logString() const;
 private slots:
 
Index: /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerSearchPanel.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerSearchPanel.cpp	(revision 70538)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerSearchPanel.cpp	(revision 70539)
@@ -35,4 +35,5 @@
 # include "UIIconPool.h"
 # include "UISpecialControls.h"
+# include "UIVMLogPage.h"
 # include "UIVMLogViewerSearchPanel.h"
 # include "UIVMLogViewerWidget.h"
@@ -121,24 +122,23 @@
         search(BackwardSearch, true);
         emit sigHighlightingUpdated();
+        return;
     }
     /* If search-string is empty, reset cursor position: */
-    else
-    {
-        if (viewer())
-        {
-            /* Get current log-page: */
-            QPlainTextEdit *pBrowser = viewer()->currentLogPage();
-            /* If current log-page is valid and cursor has selection: */
-            if (pBrowser && pBrowser->textCursor().hasSelection())
-            {
-                /* Get cursor and reset position: */
-                QTextCursor cursor = pBrowser->textCursor();
-                cursor.setPosition(cursor.anchor());
-                pBrowser->setTextCursor(cursor);
-            }
-            m_iSearchPosition = -1;
-            clearHighlighting(-1);
-        }
-    }
+    if (!viewer())
+        return;
+
+    QPlainTextEdit *pBrowser = textEdit();
+    if (!pBrowser)
+        return;
+    /* If  cursor has selection: */
+    if (pBrowser->textCursor().hasSelection())
+    {
+        /* Get cursor and reset position: */
+        QTextCursor cursor = pBrowser->textCursor();
+        cursor.setPosition(cursor.anchor());
+        pBrowser->setTextCursor(cursor);
+    }
+    m_iSearchPosition = -1;
+    clearHighlighting(-1);
 }
 
@@ -147,8 +147,6 @@
     if (!viewer())
         return;
-    QPlainTextEdit *pTextEdit = viewer()->currentLogPage();
-    if (!pTextEdit)
-        return;
-    QTextDocument *pDocument = pTextEdit->document();
+
+    QTextDocument *pDocument = textDocument();
     if (!pDocument)
         return;
@@ -410,13 +408,10 @@
                      pKeyEvent->key() == Qt::Key_F)
             {
-                if (viewer() && viewer()->currentLogPage())
-                {
-                    /* Make sure current log-page is visible: */
-                    if (isHidden())
-                        show();
-                    /* Set focus on search-editor: */
-                    m_pSearchEditor->setFocus();
-                    return true;
-                }
+                /* Make sure current log-page is visible: */
+                if (isHidden())
+                    show();
+                /* Set focus on search-editor: */
+                m_pSearchEditor->setFocus();
+                return true;
             }
             /* Handle alpha-numeric keys to implement the "find as you type" feature: */
@@ -425,14 +420,11 @@
             {
                 /* Make sure current log-page is visible: */
-                if (viewer() && viewer()->currentLogPage())
-                {
-                    if (isHidden())
-                        show();
-                    /* Set focus on search-editor: */
-                    m_pSearchEditor->setFocus();
-                    /* Insert the text to search-editor, which triggers the search-operation for new text: */
-                    m_pSearchEditor->insert(pKeyEvent->text());
-                    return true;
-                }
+                if (isHidden())
+                    show();
+                /* Set focus on search-editor: */
+                m_pSearchEditor->setFocus();
+                /* Insert the text to search-editor, which triggers the search-operation for new text: */
+                m_pSearchEditor->insert(pKeyEvent->text());
+                return true;
             }
             break;
@@ -457,9 +449,8 @@
 void UIVMLogViewerSearchPanel::search(SearchDirection direction, bool highlight)
 {
-    if (!viewer())
-        return;
-    QPlainTextEdit *pTextEdit = viewer()->currentLogPage();
-    if (!pTextEdit) return;
-    QTextDocument *pDocument = pTextEdit->document();
+    QPlainTextEdit *pTextEdit = textEdit();
+    if (!pTextEdit)
+        return;
+    QTextDocument *pDocument = textDocument();
     if (!pDocument)
         return;
@@ -541,11 +532,8 @@
     m_matchLocationVector.clear();
 
-    QPlainTextEdit *pBrowser = viewer()->currentLogPage();
-    if (pBrowser)
-    {
-        QTextDocument* pDocument = pBrowser->document();
-        if (pDocument)
-            pDocument->undo();
-    }
+    QTextDocument* pDocument = textDocument();
+    if (pDocument)
+        pDocument->undo();
+
     configureInfoLabels();
     emit sigHighlightingUpdated();
Index: /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerSearchPanel.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerSearchPanel.h	(revision 70538)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerSearchPanel.h	(revision 70539)
@@ -107,4 +107,5 @@
     QTextDocument::FindFlags constructFindFlags(SearchDirection eDirection);
 
+
     /** Holds the instance of search-label we create. */
     QLabel *m_pSearchLabel;
Index: /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerWidget.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerWidget.cpp	(revision 70538)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerWidget.cpp	(revision 70539)
@@ -38,4 +38,5 @@
 # include "UIIconPool.h"
 # include "UIMessageCenter.h"
+# include "UIVMLogPage.h"
 # include "UIVMLogViewerWidget.h"
 # include "UIVMLogViewerBookmarksPanel.h"
@@ -52,142 +53,9 @@
 
 
-/** We use a modified scrollbar style for our QPlainTextEdits to get the
-    markings on the scrollbars correctly. The default scrollbarstyle does not
-    reveal the height of the pushbuttons on the scrollbar (on either side of it, with arrow on them)
-    to compute the marking locations correctly. Thus we turn these push buttons off: */
-const QString verticalScrollBarStyle("QScrollBar:vertical {"
-                                     "border: 1px ridge grey; "
-                                     "margin: 0px 0px 0 0px;}"
-                                     "QScrollBar::handle:vertical {"
-                                     "min-height: 10px;"
-                                     "background: grey;}"
-                                     "QScrollBar::add-line:vertical {"
-                                     "width: 0px;}"
-                                     "QScrollBar::sub-line:vertical {"
-                                     "width: 0px;}");
-
-const QString horizontalScrollBarStyle("QScrollBar:horizontal {"
-                                       "border: 1px ridge grey; "
-                                       "margin: 0px 0px 0 0px;}"
-                                       "QScrollBar::handle:horizontal {"
-                                       "min-height: 10px;"
-                                       "background: grey;}"
-                                       "QScrollBar::add-line:horizontal {"
-                                       "height: 0px;}"
-                                       "QScrollBar::sub-line:horizontal {"
-                                       "height: 0px;}");
-
-class UIIndicatorScrollBar : public QScrollBar
-{
-    Q_OBJECT;
-
-public:
-
-    UIIndicatorScrollBar(QWidget *parent = 0)
-        :QScrollBar(parent)
-    {
-        setStyleSheet(verticalScrollBarStyle);
-    }
-
-    void setMarkingsVector(const QVector<float> &vector)
-    {
-        m_markingsVector = vector;
-    }
-
-protected:
-
-    virtual void paintEvent(QPaintEvent *pEvent) /* override */
-    {
-        QScrollBar::paintEvent(pEvent);
-        /* Put a red line to marking position: */
-        for (int i = 0; i < m_markingsVector.size(); ++i)
-        {
-            QPointF p1 = QPointF(0, m_markingsVector[i] * height());
-            QPointF p2 = QPointF(width(), m_markingsVector[i] * height());
-
-            QPainter painter(this);
-            painter.setRenderHint(QPainter::Antialiasing, true);
-            painter.setPen(QPen(QColor(255, 0, 0, 75), 1.1f));
-            painter.drawLine(p1, p2);
-        }
-    }
-
-private:
-
-    /* Stores the relative (to scrollbar's height) positions of markings,
-       where we draw a horizontal line. Values are in [0.0, 1.0]*/
-    QVector<float> m_markingsVector;
-};
-
-/* Sub-class QPlainTextEdit for some addtional context menu items: */
-class UIVMLogViewerTextEdit : public QPlainTextEdit
-{
-    Q_OBJECT;
-
-signals:
-
-    void sigContextMenuBookmarkAction(LogBookmark bookmark);
-
-public:
-    UIVMLogViewerTextEdit(QWidget* parent = 0, const QString& logFileName = QString())
-        :QPlainTextEdit(parent),
-         m_logFileName(logFileName)
-    {
-        //setStyleSheet("background-color: rgba(240, 240, 240, 75%) ");
-    }
-
-    const QString& logFileName() const
-    {
-        return m_logFileName;
-    }
-
-protected:
-
-    void contextMenuEvent(QContextMenuEvent *pEvent)
-    {
-        QMenu *menu = createStandardContextMenu();
-        QAction *pAction = menu->addAction(tr("Bookmark"));
-        QTextBlock block = cursorForPosition(pEvent->pos()).block();
-        m_iContextMenuBookmark.first = block.firstLineNumber();
-        m_iContextMenuBookmark.second = block.text();
-
-        if (pAction)
-            connect(pAction, &QAction::triggered, this, &UIVMLogViewerTextEdit::sltBookmark);
-
-        menu->exec(pEvent->globalPos());
-
-        if (pAction)
-            disconnect(pAction, &QAction::triggered, this, &UIVMLogViewerTextEdit::sltBookmark);
-
-        delete menu;
-    }
-
-    virtual void mousePressEvent(QMouseEvent *pEvent)
-    {
-        QPlainTextEdit::mousePressEvent(pEvent);
-    }
-
-private slots:
-    /// remove
-    void sltBookmark()
-    {
-        emit sigContextMenuBookmarkAction(m_iContextMenuBookmark);
-    }
-
-private:
-
-    /* Line number and text at the context menu position */
-    LogBookmark m_iContextMenuBookmark;
-    /* Name of the log file this text edit created to show. */
-    QString m_logFileName;
-};
-
-
 UIVMLogViewerWidget::UIVMLogViewerWidget(EmbedTo enmEmbedding, QWidget *pParent /* = 0 */, const CMachine &machine /* = CMachine() */)
     : QIWithRetranslateUI<QWidget>(pParent)
     , m_fIsPolished(false)
     , m_comMachine(machine)
-    , m_pViewerContainer(0)
-    , m_iCurrentTabIndex(-1)
+    , m_pTabWidget(0)
     , m_pSearchPanel(0)
     , m_pFilterPanel(0)
@@ -216,8 +84,8 @@
 int UIVMLogViewerWidget::defaultLogPageWidth() const
 {
-    if (!m_pViewerContainer)
+    if (!m_pTabWidget)
         return 0;
 
-    QWidget *pContainer = m_pViewerContainer->currentWidget();
+    QWidget *pContainer = m_pTabWidget->currentWidget();
     if (!pContainer)
         return 0;
@@ -239,35 +107,35 @@
 }
 
-void UIVMLogViewerWidget::sltDeleteBookmark(int index)
-{
-    QVector<LogBookmark>* bookmarkVector = currentBookmarkVector();
-    if(!bookmarkVector || bookmarkVector->size() <= index)
-        return;
-    bookmarkVector->remove(index, 1);
-    if (m_pBookmarksPanel)
-        m_pBookmarksPanel->updateBookmarkList(bookmarkVector);
+void UIVMLogViewerWidget::sltDeleteBookmark(int /*index*/)
+{
+    // QVector<LogBookmark>* bookmarkVector = currentBookmarkVector();
+    // if (!bookmarkVector || bookmarkVector->size() <= index)
+    //     return;
+    // bookmarkVector->remove(index, 1);
+    // if (m_pBookmarksPanel)
+    //     m_pBookmarksPanel->updateBookmarkList(bookmarkVector);
 }
 
 void UIVMLogViewerWidget::sltDeleteAllBookmarks()
 {
-    QVector<LogBookmark>* bookmarkVector = currentBookmarkVector();
-    if(!bookmarkVector)
-        return;
-    bookmarkVector->clear();
-    if (m_pBookmarksPanel)
-        m_pBookmarksPanel->updateBookmarkList(bookmarkVector);
-}
-
-void UIVMLogViewerWidget::sltBookmarkSelected(int index)
-{
-    QVector<LogBookmark>* bookmarkVector = currentBookmarkVector();
-    if(!bookmarkVector || index >= bookmarkVector->size())
-        return;
-    if(!currentLogPage() || !currentLogPage()->document())
-        return;
-
-    int lineNumber = bookmarkVector->at(index).first;
-    QTextCursor cursor(currentLogPage()->document()->findBlockByLineNumber(lineNumber));
-    currentLogPage()->setTextCursor(cursor);
+    // QVector<LogBookmark>* bookmarkVector = currentBookmarkVector();
+    // if (!bookmarkVector)
+    //     return;
+    // bookmarkVector->clear();
+    // if (m_pBookmarksPanel)
+    //     m_pBookmarksPanel->updateBookmarkList(bookmarkVector);
+}
+
+void UIVMLogViewerWidget::sltBookmarkSelected(int /*index*/)
+{
+    // QVector<LogBookmark>* bookmarkVector = currentBookmarkVector();
+    // if (!bookmarkVector || index >= bookmarkVector->size())
+    //     return;
+    // if (!currentLogPage() || !currentLogPage()->document())
+    //     return;
+
+    // int lineNumber = bookmarkVector->at(index).first;
+    // QTextCursor cursor(currentLogPage()->document()->findBlockByLineNumber(lineNumber));
+    // currentLogPage()->setTextCursor(cursor);
 
 }
@@ -297,51 +165,25 @@
 {
     /* Disconnect this connection to avoid initial signals during page creation/deletion: */
-    disconnect(m_pViewerContainer, &QITabWidget::currentChanged, m_pFilterPanel, &UIVMLogViewerFilterPanel::applyFilter);
-    disconnect(m_pViewerContainer, &QITabWidget::currentChanged, this, &UIVMLogViewerWidget::sltTabIndexChange);
-
-    m_logMap.clear();
-    m_pViewerContainer->setEnabled(true);
+    disconnect(m_pTabWidget, &QITabWidget::currentChanged, m_pFilterPanel, &UIVMLogViewerFilterPanel::applyFilter);
+    disconnect(m_pTabWidget, &QITabWidget::currentChanged, this, &UIVMLogViewerWidget::sltTabIndexChange);
+
+    // m_logMap.clear();
+    m_logPageList.clear();
+    m_pTabWidget->setEnabled(true);
     /* Hide the container widget during updates to avoid flickering: */
-    m_pViewerContainer->hide();
-    while (m_pViewerContainer->count())
-    {
-        QWidget *pFirstPage = m_pViewerContainer->widget(0);
-        m_pViewerContainer->removeTab(0);
+    m_pTabWidget->hide();
+    /* Clear the tab widget. This might be an overkill but most secure way to deal with the case where
+       number of the log files changes. */
+    while (m_pTabWidget->count())
+    {
+        QWidget *pFirstPage = m_pTabWidget->widget(0);
+        m_pTabWidget->removeTab(0);
         delete pFirstPage;
     }
 
-    m_iCurrentTabIndex = -1;
-    bool noLogsToShow = false;
-    QString strDummyTabText;
-    /* check if the machine is valid: */
-    if (m_comMachine.isNull())
-    {
-        noLogsToShow = true;
-        strDummyTabText = QString(tr("<p><b>No machine</b> is currently selected. Please select a "
-                                     "Virtual Machine to see its logs"));
-    }
-    /* If machine is valid and check if there are any log files and create viewer tabs: */
-    else if (!createLogViewerPages())
-    {
-        noLogsToShow = true;
-        strDummyTabText = QString(tr("<p>No log files found. Press the "
-                                     "<b>Refresh</b> button to rescan the log folder "
-                                     "<nobr><b>%1</b></nobr>.</p>")
-                                     .arg(m_comMachine.GetLogFolder()));
-    }
-    /* If the machine is not valid or has no log files show a single viewer tab: */
-    if (noLogsToShow)
-    {
-        QPlainTextEdit *pDummyLog = createLogPage("VBox.log");
-        pDummyLog->setWordWrapMode(QTextOption::WordWrap);
-        pDummyLog->appendHtml(strDummyTabText);
-        /* We don't want it to remain white: */
-        QPalette pal = pDummyLog->palette();
-        pal.setColor(QPalette::Base, pal.color(QPalette::Window));
-        pDummyLog->setPalette(pal);
-    }
+    bool noLogsToShow = createLogViewerPages();
 
     /* Show the first tab widget's page after the refresh: */
-    m_pViewerContainer->setCurrentIndex(0);
+    m_pTabWidget->setCurrentIndex(0);
 
     /* Apply the filter settings: */
@@ -350,8 +192,6 @@
 
     /* Setup this connection after refresh to avoid initial signals during page creation: */
-    connect(m_pViewerContainer, &QITabWidget::currentChanged, m_pFilterPanel, &UIVMLogViewerFilterPanel::applyFilter);
-    connect(m_pViewerContainer, &QITabWidget::currentChanged, this, &UIVMLogViewerWidget::sltTabIndexChange);
-
-    m_iCurrentTabIndex = 0;
+    connect(m_pTabWidget, &QITabWidget::currentChanged, m_pFilterPanel, &UIVMLogViewerFilterPanel::applyFilter);
+    connect(m_pTabWidget, &QITabWidget::currentChanged, this, &UIVMLogViewerWidget::sltTabIndexChange);
 
     /* Enable/Disable toolbar actions (except Refresh) & tab widget according log presence: */
@@ -360,6 +200,6 @@
     m_pActionSave->setEnabled(!noLogsToShow);
     m_pActionBookmark->setEnabled(!noLogsToShow);
-    m_pViewerContainer->setEnabled(!noLogsToShow);
-    m_pViewerContainer->show();
+    m_pTabWidget->setEnabled(!noLogsToShow);
+    m_pTabWidget->show();
     if (m_pSearchPanel && m_pSearchPanel->isVisible())
         m_pSearchPanel->refresh();
@@ -370,9 +210,14 @@
     if (m_comMachine.isNull())
         return;
-    UIVMLogViewerTextEdit *logPage = qobject_cast<UIVMLogViewerTextEdit*>(currentLogPage());
+
+    UIVMLogPage *logPage = currentLogPage();
     if (!logPage)
         return;
+
+    const QString& fileName = logPage->fileName();
+    if (fileName.isEmpty())
+        return;
     /* Prepare "save as" dialog: */
-    const QFileInfo fileInfo(logPage->logFileName());
+    const QFileInfo fileInfo(fileName);
     /* Prepare default filename: */
     const QDateTime dtInfo = fileInfo.lastModified();
@@ -395,5 +240,5 @@
             QFile::remove(strNewFileName);
         /* Copy log into the file: */
-        QFile::copy(m_comMachine.QueryLogFilename(m_pViewerContainer->currentIndex()), strNewFileName);
+        QFile::copy(m_comMachine.QueryLogFilename(m_pTabWidget->currentIndex()), strNewFileName);
     }
 }
@@ -406,24 +251,20 @@
     if (!currentLogPage())
         return;
-    UIIndicatorScrollBar* scrollBar = qobject_cast<UIIndicatorScrollBar*>(currentLogPage()->verticalScrollBar());
-    if (scrollBar)
-        scrollBar->setMarkingsVector(m_pSearchPanel->getMatchLocationVector());
-
-    currentLogPage()->repaint();
+    currentLogPage()->setScrollBarMarkingsVector(m_pSearchPanel->getMatchLocationVector());
 }
 
 void UIVMLogViewerWidget::sltTabIndexChange(int tabIndex)
 {
-    if (m_iCurrentTabIndex == tabIndex)
-        return;
+    // if (m_iCurrentTabIndex == tabIndex)
+    //     return;
 
     resetHighlighthing();
-    if (m_pSearchPanel)
-        m_pSearchPanel->reset();
-    m_iCurrentTabIndex = tabIndex;
+    // if (m_pSearchPanel)
+    //     m_pSearchPanel->reset();
+    // m_iCurrentTabIndex = tabIndex;
     /* We keep a separate QVector<LogBookmark> for each log page: */
-    QVector<LogBookmark>* bookmarkVector = currentBookmarkVector();
-    if(bookmarkVector && m_pBookmarksPanel)
-        m_pBookmarksPanel->updateBookmarkList(bookmarkVector);
+    // QVector<LogBookmark>* bookmarkVector = currentBookmarkVector();
+    // if (bookmarkVector && m_pBookmarksPanel)
+    //     m_pBookmarksPanel->updateBookmarkList(bookmarkVector);
 }
 
@@ -437,25 +278,25 @@
 void UIVMLogViewerWidget::sltCreateBookmarkAtCurrent()
 {
-    if (!currentLogPage())
-        return;
-    QWidget* viewport = currentLogPage()->viewport();
-    if (!viewport)
-        return;
-    QPoint point(0.5 * viewport->width(), 0.5 * viewport->height());
-    QTextBlock block = currentLogPage()->cursorForPosition(point).block();
-    LogBookmark bookmark;
-    bookmark.first = block.firstLineNumber();
-    bookmark.second = block.text();
-    sltCreateBookmarkAtLine(bookmark);
+    // if (!currentTextEdit())
+    //     return;
+    // QWidget* viewport = currentTextEdit()->viewport();
+    // if (!viewport)
+    //     return;
+    // QPoint point(0.5 * viewport->width(), 0.5 * viewport->height());
+    // QTextBlock block = currentTextEdit()->cursorForPosition(point).block();
+    // LogBookmark bookmark;
+    // bookmark.first = block.firstLineNumber();
+    // bookmark.second = block.text();
+    // sltCreateBookmarkAtLine(bookmark);
 }
 
 void UIVMLogViewerWidget::sltCreateBookmarkAtLine(LogBookmark bookmark)
 {
-    QVector<LogBookmark> *pBookmarkVector = currentBookmarkVector();
-    if (!pBookmarkVector)
-        return;
-    pBookmarkVector->push_back(bookmark);
-    if (m_pBookmarksPanel)
-        m_pBookmarksPanel->updateBookmarkList(pBookmarkVector);
+    // QVector<LogBookmark> *pBookmarkVector = currentBookmarkVector();
+    // if (!pBookmarkVector)
+    //     return;
+    // pBookmarkVector->push_back(bookmark);
+    // if (m_pBookmarksPanel)
+    //     m_pBookmarksPanel->updateBookmarkList(pBookmarkVector);
 }
 
@@ -503,9 +344,9 @@
 
     /* Create VM Log-Viewer container: */
-    m_pViewerContainer = new QITabWidget(this);
-    AssertPtrReturnVoid(m_pViewerContainer);
+    m_pTabWidget = new QITabWidget(this);
+    AssertPtrReturnVoid(m_pTabWidget);
     {
         /* Add VM Log-Viewer container to main-layout: */
-        m_pMainLayout->insertWidget(1, m_pViewerContainer);
+        m_pMainLayout->insertWidget(1, m_pTabWidget);
     }
 
@@ -766,7 +607,7 @@
 
     /* Make sure the log view widget has the focus: */
-    QWidget *pCurrentLogPage = currentLogPage();
-    if (pCurrentLogPage)
-        pCurrentLogPage->setFocus();
+    // QWidget *pCurrentLogPage = currentTextEdit();
+    // if (pCurrentLogPage)
+    //     pCurrentLogPage->setFocus();
 }
 
@@ -784,7 +625,7 @@
         case Qt::Key_Back:
         {
-            if (m_pViewerContainer->currentIndex() > 0)
+            if (m_pTabWidget->currentIndex() > 0)
             {
-                m_pViewerContainer->setCurrentIndex(m_pViewerContainer->currentIndex() - 1);
+                m_pTabWidget->setCurrentIndex(m_pTabWidget->currentIndex() - 1);
                 return;
             }
@@ -794,7 +635,7 @@
         case Qt::Key_Forward:
         {
-            if (m_pViewerContainer->currentIndex() < m_pViewerContainer->count())
+            if (m_pTabWidget->currentIndex() < m_pTabWidget->count())
             {
-                m_pViewerContainer->setCurrentIndex(m_pViewerContainer->currentIndex() + 1);
+                m_pTabWidget->setCurrentIndex(m_pTabWidget->currentIndex() + 1);
                 return;
             }
@@ -807,49 +648,42 @@
 }
 
-const QString* UIVMLogViewerWidget::currentLog()
-{
-    if (!currentLogPage())
+const UIVMLogPage *UIVMLogViewerWidget::currentLogPage() const
+{
+    int currentTabIndex = m_pTabWidget->currentIndex();
+    if (currentTabIndex >= m_logPageList.size())
         return 0;
-    return &(m_logMap[currentLogPage()]);
-}
-
-QPlainTextEdit* UIVMLogViewerWidget::currentLogPage() const
-{
-    /* If viewer-container is enabled: */
-    if (m_pViewerContainer->isEnabled())
-    {
-        /* Get and return current log-page: */
-        QWidget *pContainer = m_pViewerContainer->currentWidget();
-        QPlainTextEdit *pBrowser = pContainer->findChild<QPlainTextEdit*>();
-        Assert(pBrowser);
-        return pBrowser ? pBrowser : 0;
-    }
-    /* Return NULL by default: */
-    return 0;
-}
-
-const QVector<LogBookmark>* UIVMLogViewerWidget::currentBookmarkVector() const
-{
-    UIVMLogViewerTextEdit *logPage = qobject_cast<UIVMLogViewerTextEdit*>(currentLogPage());
-    if (!logPage)
+    return qobject_cast<const UIVMLogPage*>(m_logPageList.at(currentTabIndex));
+}
+UIVMLogPage *UIVMLogViewerWidget::currentLogPage()
+{
+    int currentTabIndex = m_pTabWidget->currentIndex();
+    if (currentTabIndex >= m_logPageList.size())
         return 0;
-    QString logFileName = logPage->logFileName();
-    if (logFileName.isEmpty())
-        return 0;
-
-    return &(m_bookmarkMap[logFileName]);
-}
-
-QVector<LogBookmark>* UIVMLogViewerWidget::currentBookmarkVector()
-{
-    UIVMLogViewerTextEdit *logPage = qobject_cast<UIVMLogViewerTextEdit*>(currentLogPage());
-    if (!logPage)
-        return 0;
-    QString logFileName = logPage->logFileName();
-    if (logFileName.isEmpty())
-        return 0;
-
-    return &(m_bookmarkMap[logFileName]);
-}
+    return qobject_cast<UIVMLogPage*>(m_logPageList.at(currentTabIndex));
+}
+
+// const QVector<LogBookmark>* UIVMLogViewerWidget::currentBookmarkVector() const
+// {
+//     UIVMLogViewerTextEdit *logPage = qobject_cast<UIVMLogViewerTextEdit*>(currentLogPage());
+//     if (!logPage)
+//         return 0;
+//     QString logFileName = logPage->logFileName();
+//     if (logFileName.isEmpty())
+//         return 0;
+
+//     return &(m_bookmarkMap[logFileName]);
+// }
+
+// QVector<LogBookmark>* UIVMLogViewerWidget::currentBookmarkVector()
+// {
+//     UIVMLogViewerTextEdit *logPage = qobject_cast<UIVMLogViewerTextEdit*>(currentLogPage());
+//     if (!logPage)
+//         return 0;
+//     QString logFileName = logPage->logFileName();
+//     if (logFileName.isEmpty())
+//         return 0;
+
+//     return &(m_bookmarkMap[logFileName]);
+// }
 
 void UIVMLogViewerWidget::hidePanel(UIVMLogViewerPanel* panel)
@@ -879,7 +713,7 @@
 QPlainTextEdit* UIVMLogViewerWidget::logPage(int pIndex) const
 {
-    if (!m_pViewerContainer->isEnabled())
+    if (!m_pTabWidget->isEnabled())
         return 0;
-    QWidget* pContainer = m_pViewerContainer->widget(pIndex);
+    QWidget* pContainer = m_pTabWidget->widget(pIndex);
     if (!pContainer)
         return 0;
@@ -890,85 +724,85 @@
 bool UIVMLogViewerWidget::createLogViewerPages()
 {
+    bool noLogsToShow = false;
+
+    QString strDummyTabText;
+    /* check if the machine is valid: */
     if (m_comMachine.isNull())
-        return false;
-
-    bool logsExists = false;
+    {
+        noLogsToShow = true;
+        strDummyTabText = QString(tr("<p><b>No machine</b> is currently selected. Please select a "
+                                     "Virtual Machine to see its logs"));
+    }
+
     const CSystemProperties &sys = vboxGlobal().virtualBox().GetSystemProperties();
     unsigned cMaxLogs = sys.GetLogHistoryCount() + 1 /*VBox.log*/ + 1 /*VBoxHardening.log*/; /** @todo Add api for getting total possible log count! */
-    for (unsigned i = 0; i < cMaxLogs; ++i)
-    {
-        /* Query the log file name for index i: */
-        QString strFileName = m_comMachine.QueryLogFilename(i);
-        if (!strFileName.isEmpty())
+
+    /* If machine is valid then check if there are any log files and create viewer tabs: */
+    if (cMaxLogs == 0)
+    {
+        noLogsToShow = true;
+        strDummyTabText = QString(tr("<p>No log files found. Press the "
+                                     "<b>Refresh</b> button to rescan the log folder "
+                                     "<nobr><b>%1</b></nobr>.</p>")
+                                     .arg(m_comMachine.GetLogFolder()));
+    }
+    else{
+        for (unsigned i = 0; i < cMaxLogs; ++i)
         {
-            /* Try to read the log file with the index i: */
-            ULONG uOffset = 0;
-            QString strText;
-            while (true)
+            /* Query the log file name for index i: */
+            QString strFileName = m_comMachine.QueryLogFilename(i);
+            if (!strFileName.isEmpty())
             {
-                QVector<BYTE> data = m_comMachine.ReadLog(i, uOffset, _1M);
-                if (data.size() == 0)
-                    break;
-                strText.append(QString::fromUtf8((char*)data.data(), data.size()));
-                uOffset += data.size();
-            }
-            /* Anything read at all? */
-            if (uOffset > 0)
-            {
-                /* Create a log viewer page and append the read text to it: */
-                QPlainTextEdit *pLogViewer = createLogPage(strFileName);
-                pLogViewer->setPlainText(strText);
-                /* Move the cursor position to end: */
-                QTextCursor cursor = pLogViewer->textCursor();
-                cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
-                pLogViewer->setTextCursor(cursor);
-                /* Add the log-text to the map: */
-                m_logMap[pLogViewer] = strText;
-                logsExists = true;
+                /* Try to read the log file with the index i: */
+                ULONG uOffset = 0;
+                QString strText;
+                while (true)
+                {
+                    QVector<BYTE> data = m_comMachine.ReadLog(i, uOffset, _1M);
+                    if (data.size() == 0)
+                        break;
+                    strText.append(QString::fromUtf8((char*)data.data(), data.size()));
+                    uOffset += data.size();
+                }
+                /* Anything read at all? */
+                if (uOffset > 0)
+                {
+                    createLogPage(strFileName, strText);
+                }
             }
         }
     }
-    return logsExists;
-}
-
-QPlainTextEdit* UIVMLogViewerWidget::createLogPage(const QString &strFileName)
-{
+    /* if noLogsToShow then ceate a single log page with an error message: */
+    if (noLogsToShow)
+    {
+        createLogPage("No Logs", strDummyTabText, noLogsToShow);
+    }
+    return noLogsToShow;
+}
+
+void UIVMLogViewerWidget::createLogPage(const QString &strFileName, const QString &strLogContent, bool noLogsToShow /* = false */)
+{
+    AssertPtrReturnVoid(m_pTabWidget);
+
     /* Create page-container: */
-    QWidget *pPageContainer = new QWidget;
-    AssertPtrReturn(pPageContainer, 0);
-    {
-        /* Create page-layout: */
-        QVBoxLayout *pPageLayout = new QVBoxLayout(pPageContainer);
-        AssertPtrReturn(pPageLayout, 0);
-        /* Create Log-Viewer: */
-        UIVMLogViewerTextEdit *pLogViewer = new UIVMLogViewerTextEdit(pPageContainer, strFileName);
-        connect(pLogViewer, &UIVMLogViewerTextEdit::sigContextMenuBookmarkAction,
-                this, &UIVMLogViewerWidget::sltCreateBookmarkAtLine);
-
-        AssertPtrReturn(pLogViewer, 0);
-        {
-            /* Configure Log-Viewer: */
-            pLogViewer->setVerticalScrollBar(new UIIndicatorScrollBar());
-            pLogViewer->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
-            QScrollBar *pHorizontalScrollBar = pLogViewer->horizontalScrollBar();
-            if (pHorizontalScrollBar)
-                pHorizontalScrollBar->setStyleSheet(horizontalScrollBarStyle);
-#if defined(RT_OS_SOLARIS)
-            /* Use system fixed-width font on Solaris hosts as the Courier family fonts don't render well. */
-            QFont font = QFontDatabase::systemFont(QFontDatabase::FixedFont);
-#else
-            QFont font;
-            font.setFamily("Courier New,courier");
-#endif
-            pLogViewer->setFont(font);
-            pLogViewer->setWordWrapMode(QTextOption::NoWrap);
-            pLogViewer->setReadOnly(true);
-            /* Add Log-Viewer to page-layout: */
-            pPageLayout->addWidget(pLogViewer);
-        }
-        /* Add page-container to viewer-container: */
-        m_pViewerContainer->addTab(pPageContainer, QFileInfo(strFileName).fileName());
-        return pLogViewer;
-    }
+    UIVMLogPage* pLogPage = new UIVMLogPage(this);
+    AssertPtrReturnVoid(pLogPage);
+    /* Set the file name only if we really have log file to read. */
+    if (!noLogsToShow)
+        pLogPage->setFileName(strFileName);
+
+    /* Add page-container to viewer-container: */
+    int tabIndex = m_pTabWidget->insertTab(m_pTabWidget->count(), pLogPage, QFileInfo(strFileName).fileName());
+
+    pLogPage->setTabIndex(tabIndex);
+    m_logPageList.resize(m_pTabWidget->count());
+    m_logPageList[tabIndex] = pLogPage;
+
+    /* Set the log string of the UIVMLogPage: */
+    pLogPage->setLogString(strLogContent);
+    /* Also set text edit since we want to display this text: */
+    pLogPage->setTextEdit(strLogContent);
+    if (noLogsToShow)
+        pLogPage->markForError();
 }
 
@@ -976,18 +810,21 @@
 {
     /* Undo the document changes to remove highlighting: */
-    QPlainTextEdit *pTextEdit = logPage(m_iCurrentTabIndex);
-    if (pTextEdit)
-    {
-        QTextDocument *pDocument = pTextEdit->document();
-        if (pDocument)
-            pDocument->undo();
-    }
-    UIIndicatorScrollBar* scrollBar = qobject_cast<UIIndicatorScrollBar*>(pTextEdit->verticalScrollBar());
-    if (scrollBar)
-    {
-        scrollBar->setMarkingsVector(QVector<float>());
-        pTextEdit->repaint();
-    }
-}
-
-#include "UIVMLogViewerWidget.moc"
+    UIVMLogPage* logPage = currentLogPage();
+    if (!logPage)
+        return;
+    logPage->documentUndo();
+    logPage->clearScrollBarMarkingsVector();
+    // QPlainTextEdit *pTextEdit = logPage(m_iCurrentTabIndex);
+    // if (pTextEdit)
+    // {
+    //     QTextDocument *pDocument = pTextEdit->document();
+    //     if (pDocument)
+    //         pDocument->undo();
+    // }
+    // UIIndicatorScrollBar* scrollBar = qobject_cast<UIIndicatorScrollBar*>(pTextEdit->verticalScrollBar());
+    // if (scrollBar)
+    // {
+    //     scrollBar->setMarkingsVector(QVector<float>());
+    //     pTextEdit->repaint();
+    // }
+}
Index: /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerWidget.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerWidget.h	(revision 70538)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/logviewer/UIVMLogViewerWidget.h	(revision 70539)
@@ -37,4 +37,5 @@
 class QVBoxLayout;
 class UIToolBar;
+class UIVMLogPage;
 class UIVMLogViewerBookmarksPanel;
 class UIVMLogViewerFilterPanel;
@@ -44,13 +45,14 @@
 /* Type definitions: */
 /** value is the content of the log file */
-typedef QMap<QPlainTextEdit*, QString> VMLogMap;
+//typedef QMap<QPlainTextEdit*, QString> VMLogMap;
 /** first is line number, second is block text */
-typedef QPair<int, QString> LogBookmark;
+//typedef QPair<int, QString> LogBookmark;
 /** key is log file name, value is a vector of bookmarks. */
-typedef QMap<QString, QVector<LogBookmark> > BookmarkMap;
-
-
-/** QIMainWindow extension
-  * providing GUI with VirtualBox LogViewer. */
+//typedef QMap<QString, QVector<LogBookmark> > BookmarkMap;
+
+
+/** QWidget extension providing GUI for VirtualBox LogViewer. It
+ *  encapsulates log pages, toolbar, a tab widget and manages
+ *  interaction between these classes. */
 class UIVMLogViewerWidget  : public QIWithRetranslateUI<QWidget>
 {
@@ -137,12 +139,13 @@
     /** @} */
 
-    /** Returns the current log-page. */
-    QPlainTextEdit* currentLogPage() const;
+
     /** Returns the log-page from the tab with index @a pIndex. */
     QPlainTextEdit* logPage(int pIndex) const;
     /** Returns the newly created log-page using @a strPage filename. */
-    QPlainTextEdit* createLogPage(const QString &strPage);
-    /** Returns the content of current log-file as it is read. */
-    const QString* currentLog();
+    void createLogPage(const QString &strFileName, const QString &strLogContent, bool noLogsToShow = false);
+
+
+    UIVMLogPage *currentLogPage();
+    const UIVMLogPage *currentLogPage() const;
 
     /** Attempts to read the logs through the API, returns true if there exists any logs, false otherwise. */
@@ -152,8 +155,4 @@
     void resetHighlighthing();
 
-    /** Returns the vector of bookmarks for the current log page */
-    QVector<LogBookmark>* currentBookmarkVector();
-    const QVector<LogBookmark>* currentBookmarkVector() const;
-
     void hidePanel(UIVMLogViewerPanel* panel);
     void showPanel(UIVMLogViewerPanel* panel);
@@ -166,8 +165,11 @@
 
     /** Holds container for log-pages. */
-    QITabWidget *m_pViewerContainer;
+    QITabWidget        *m_pTabWidget;
+    /** Stores the UIVMLogPage instances. This is modified as we add and remove new tabs
+     *  to the m_pTabWidget. Index is the index of the tab widget. */
+    QVector<QWidget*>  m_logPageList;
 
     /** Holds the index to the current tab: */
-    int          m_iCurrentTabIndex;
+    //int          m_iCurrentTabIndex;
 
     /** Holds the instance of search-panel. */
@@ -179,6 +181,6 @@
 
     /** Holds the list of log file content. */
-    VMLogMap             m_logMap;
-    mutable BookmarkMap  m_bookmarkMap;
+    // VMLogMap             m_logMap;
+    // mutable BookmarkMap  m_bookmarkMap;
     QVBoxLayout         *m_pMainLayout;
 
