VirtualBox

Ignore:
Timestamp:
Oct 15, 2015 5:27:34 PM (9 years ago)
Author:
vboxsync
Message:

FE/Qt: 8069: Filtering feature implementation in VM Log-Viewer and Cleanup/Rework of old code.

Location:
trunk/src/VBox/Frontends/VirtualBox/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/UIVMLogViewer.cpp

    r57832 r58267  
    55
    66/*
    7  * Copyright (C) 2008-2012 Oracle Corporation
     7 * Copyright (C) 2010-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2222/* Qt includes: */
    2323# include <QCheckBox>
     24# include <QComboBox>
    2425# include <QDateTime>
    2526# include <QDir>
     
    4647#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
    4748
    48 
    49 /* VM Log Viewer search panel: */
     49/** QWidget extension
     50  * providing GUI for search-panel in VM Log-Viewer. */
    5051class UIVMLogViewerSearchPanel : public QIWithRetranslateUI<QWidget>
    5152{
     
    5455public:
    5556
    56     /* Constructor: */
     57    /** Constructs search-panel by passing @a pParent to the QWidget base-class constructor.
     58      * @a pViewer is the instance of VM Log-Viewer. */
    5759    UIVMLogViewerSearchPanel(QWidget *pParent, UIVMLogViewer *pViewer)
    5860        : QIWithRetranslateUI<QWidget>(pParent)
     
    6466        , m_pWarningSpacer(0), m_pWarningIcon(0), m_pWarningLabel(0)
    6567    {
    66         /* Close button: */
     68        /* Prepare: */
     69        prepare();
     70    }
     71
     72private slots:
     73
     74    /** Handles find next/back action triggering.
     75      * @a iButton specifies id of next/back button. */
     76    void find(int iButton)
     77    {
     78        if (iButton)
     79            findNext();
     80        else
     81            findBack();
     82    }
     83
     84    /** Handles textchanged event from search-editor.
     85      * @a strSearchString specifies the search-string. */
     86    void findCurrent(const QString &strSearchString)
     87    {
     88        m_pNextPrevButtons->setEnabled(0, strSearchString.length());
     89        m_pNextPrevButtons->setEnabled(1, strSearchString.length());
     90        toggleWarning(!strSearchString.length());
     91        if (strSearchString.length())
     92            search(true, true);
     93        else
     94        {
     95            QTextEdit *pBrowser = m_pViewer->currentLogPage();
     96            if (pBrowser && pBrowser->textCursor().hasSelection())
     97            {
     98                QTextCursor cursor = pBrowser->textCursor();
     99                cursor.setPosition(cursor.anchor());
     100                pBrowser->setTextCursor(cursor);
     101            }
     102        }
     103    }
     104
     105private:
     106
     107    /** Prepares search-panel. */
     108    void prepare()
     109    {
     110        /* Prepare widgets: */
     111        prepareWidgets();
     112
     113        /* Prepare main-layout: */
     114        prepareMainLayout();
     115
     116        /* Prepare connections: */
     117        prepareConnections();
     118
     119        /* Retranslate finally: */
     120        retranslateUi();
     121    }
     122
     123    /** Prepares widgets. */
     124    void prepareWidgets()
     125    {
     126        /* Create close-button: */
    67127        m_pCloseButton = new UIMiniCancelButton(this);
    68 
    69         /* Search field: */
     128        AssertPtrReturnVoid(m_pCloseButton);
     129
     130        /* Create search-editor: */
     131        m_pSearchEditor = new UISearchField(this);
     132        AssertPtrReturnVoid(m_pSearchEditor);
     133        /* Prepare search-editor: */
     134        m_pSearchEditor->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
     135
     136        /* Create search-label: */
    70137        m_pSearchLabel = new QLabel(this);
    71         m_pSearchEditor = new UISearchField(this);
    72         m_pSearchEditor->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
     138        AssertPtrReturnVoid(m_pSearchLabel);
     139        /* Prepare search-label: */
    73140        m_pSearchLabel->setBuddy(m_pSearchEditor);
    74141
    75         /* Next/Previous buttons: */
     142        /* Create Next/Prev button-box: */
    76143        m_pNextPrevButtons = new UIRoundRectSegmentedButton(this, 2);
     144        AssertPtrReturnVoid(m_pNextPrevButtons);
     145        /* Prepare Next/Prev button-box: */
    77146        m_pNextPrevButtons->setEnabled(0, false);
    78147        m_pNextPrevButtons->setEnabled(1, false);
     
    83152#endif /* !Q_WS_MAC */
    84153
    85         /* Case sensitive check-box: */
     154        /* Create case-sensitive checkbox: */
    86155        m_pCaseSensitiveCheckBox = new QCheckBox(this);
    87 
    88         /* Warning label: */
     156        AssertPtrReturnVoid(m_pCaseSensitiveCheckBox);
     157        /* Setup focus proxy: */
     158        setFocusProxy(m_pCaseSensitiveCheckBox);
     159
     160        /* Create warning-spacer: */
    89161        m_pWarningSpacer = new QSpacerItem(0, 0, QSizePolicy::Fixed, QSizePolicy::Minimum);
     162        AssertPtrReturnVoid(m_pWarningSpacer);
     163
     164        /* Create warning-icon: */
    90165        m_pWarningIcon = new QLabel(this);
     166        AssertPtrReturnVoid(m_pWarningIcon);
     167        /* Prepare warning-icon: */
    91168        m_pWarningIcon->hide();
    92169        QIcon icon = UIIconPool::defaultIcon(UIIconPool::UIDefaultIconType_MessageBoxWarning, this);
    93170        if (!icon.isNull())
    94171            m_pWarningIcon->setPixmap(icon.pixmap(16, 16));
     172
     173        /* Create warning-label: */
    95174        m_pWarningLabel = new QLabel(this);
     175        AssertPtrReturnVoid(m_pWarningLabel);
     176        /* Prepare warning-label: */
    96177        m_pWarningLabel->hide();
    97         QSpacerItem *pSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
    98 
     178
     179        /* Create spacer-item: */
     180        m_pSpacerItem = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
     181        AssertPtrReturnVoid(m_pSpacerItem);
     182
     183        /* Prepare fonts: */
    99184#ifdef VBOX_DARWIN_USE_NATIVE_CONTROLS
    100185        QFont font = m_pSearchLabel->font();
     
    104189        m_pWarningLabel->setFont(font);
    105190#endif /* VBOX_DARWIN_USE_NATIVE_CONTROLS */
    106 
    107         /* Placing widgets: */
     191    }
     192
     193    /** Prepares main-layout. */
     194    void prepareMainLayout()
     195    {
     196        /* Create main-layout: */
    108197        QHBoxLayout *pMainLayout = new QHBoxLayout(this);
    109         pMainLayout->setSpacing(5);
    110         pMainLayout->setContentsMargins(0, 0, 0, 0);
    111         pMainLayout->addWidget(m_pCloseButton);
    112         pMainLayout->addWidget(m_pSearchLabel);
    113         pMainLayout->addWidget(m_pSearchEditor);
    114         pMainLayout->addWidget(m_pNextPrevButtons);
    115         pMainLayout->addWidget(m_pCaseSensitiveCheckBox);
    116         pMainLayout->addItem(m_pWarningSpacer);
    117         pMainLayout->addWidget(m_pWarningIcon);
    118         pMainLayout->addWidget(m_pWarningLabel);
    119         pMainLayout->addItem(pSpacer);
    120 
    121         /* Setup focus proxy: */
    122         setFocusProxy(m_pCaseSensitiveCheckBox);
    123 
    124         /* Setup connections: */
     198        AssertPtrReturnVoid(pMainLayout);
     199        {
     200            /* Prepare main-layout: */
     201            pMainLayout->setSpacing(5);
     202            pMainLayout->setContentsMargins(0, 0, 0, 0);
     203            pMainLayout->addWidget(m_pCloseButton);
     204            pMainLayout->addWidget(m_pSearchLabel);
     205            pMainLayout->addWidget(m_pSearchEditor);
     206            pMainLayout->addWidget(m_pNextPrevButtons);
     207            pMainLayout->addWidget(m_pCaseSensitiveCheckBox);
     208            pMainLayout->addItem(m_pWarningSpacer);
     209            pMainLayout->addWidget(m_pWarningIcon);
     210            pMainLayout->addWidget(m_pWarningLabel);
     211            pMainLayout->addItem(m_pSpacerItem);
     212        }
     213    }
     214
     215    /** Prepares connections. */
     216    void prepareConnections()
     217    {
    125218        connect(m_pCloseButton, SIGNAL(clicked()), this, SLOT(hide()));
    126219        connect(m_pSearchEditor, SIGNAL(textChanged(const QString &)),
    127220                this, SLOT(findCurrent(const QString &)));
    128221        connect(m_pNextPrevButtons, SIGNAL(clicked(int)), this, SLOT(find(int)));
    129 
    130         /* Retranslate finally: */
    131         retranslateUi();
    132     }
    133 
    134 private slots:
    135 
    136     /* Slot to find specified tag,
    137      * called by next/previous buttons: */
    138     void find(int iButton)
    139     {
    140         if (iButton)
    141             findNext();
    142         else
    143             findBack();
    144     }
    145 
    146     /* Slot to find specified tag,
    147      * called when text changed in search editor: */
    148     void findCurrent(const QString &strSearchString)
    149     {
    150         m_pNextPrevButtons->setEnabled(0, strSearchString.length());
    151         m_pNextPrevButtons->setEnabled(1, strSearchString.length());
    152         toggleWarning(!strSearchString.length());
    153         if (strSearchString.length())
    154             search(true, true);
    155         else
    156         {
    157             QTextEdit *pBrowser = m_pViewer->currentLogPage();
    158             if (pBrowser && pBrowser->textCursor().hasSelection())
    159             {
    160                 QTextCursor cursor = pBrowser->textCursor();
    161                 cursor.setPosition(cursor.anchor());
    162                 pBrowser->setTextCursor(cursor);
    163             }
    164         }
    165     }
    166 
    167 private:
    168 
    169     /* Translation stuff: */
     222    }
     223
     224    /** Handles translation event. */
    170225    void retranslateUi()
    171226    {
     
    186241    }
    187242
    188     /* Key press filter: */
     243    /** Handles Qt key-press @a pEevent. */
    189244    void keyPressEvent(QKeyEvent *pEvent)
    190245    {
     
    210265    }
    211266
    212     /* Event filter, used for keyboard processing: */
     267    /** Handles Qt @a pEvent, used for keyboard processing. */
    213268    bool eventFilter(QObject *pObject, QEvent *pEvent)
    214269    {
     
    270325    }
    271326
    272     /* Show event reimplementation: */
     327    /** Handles Qt show @a pEvent. */
    273328    void showEvent(QShowEvent *pEvent)
    274329    {
     
    278333    }
    279334
    280     /* Hide event reimplementation: */
     335    /** Handles Qt hide @a pEvent. */
    281336    void hideEvent(QHideEvent *pEvent)
    282337    {
    283338        QWidget *pFocus = QApplication::focusWidget();
    284339        if (pFocus && pFocus->parent() == this)
    285            focusNextPrevChild(true);
     340            focusNextPrevChild(true);
    286341        QWidget::hideEvent(pEvent);
    287342    }
    288343
    289     /* Search routine: */
     344    /** Search routine.
     345      * @a fForward specifies the direction of search.
     346      * @a fStartCurrent specifies if the search should start from beginning of log. */
    290347    void search(bool fForward, bool fStartCurrent = false)
    291348    {
     
    333390    }
    334391
    335     /* Search routine wrappers: */
     392    /** Forward search routine wrapper. */
    336393    void findNext() { search(true); }
     394
     395    /** Backward search routine wrapper. */
    337396    void findBack() { search(false); }
    338397
    339     /* Function to show/hide search border warning: */
     398    /** Shows/hides the search border warning using @a fHide as hint. */
    340399    void toggleWarning(bool fHide)
    341400    {
     
    349408    }
    350409
    351     /* Widgets: */
     410    /** Holds the reference to the VM Log-Viewer this search-panel belongs to. */
    352411    UIVMLogViewer *m_pViewer;
     412    /** Holds the instance of close-button we create. */
    353413    UIMiniCancelButton *m_pCloseButton;
     414    /** Holds the instance of search-label we create. */
    354415    QLabel *m_pSearchLabel;
     416    /** Holds the instance of search-editor we create. */
    355417    UISearchField *m_pSearchEditor;
     418    /** Holds the instance of next/back button-box we create. */
    356419    UIRoundRectSegmentedButton *m_pNextPrevButtons;
     420    /** Holds the instance of case-sensitive checkbox we create. */
    357421    QCheckBox *m_pCaseSensitiveCheckBox;
     422    /** Holds the instance of warning spacer-item we create. */
    358423    QSpacerItem *m_pWarningSpacer;
     424    /** Holds the instance of warning icon we create. */
    359425    QLabel *m_pWarningIcon;
     426    /** Holds the instance of warning label we create. */
    360427    QLabel *m_pWarningLabel;
     428    /** Holds the instance of spacer item we create. */
     429    QSpacerItem *m_pSpacerItem;
    361430};
    362431
    363 /* VM Log Viewer array: */
     432/** QWidget extension
     433  * providing GUI for filter panel in VM Log Viewer. */
     434class UIVMLogViewerFilterPanel : public QIWithRetranslateUI<QWidget>
     435{
     436    Q_OBJECT;
     437
     438public:
     439
     440    /** Constructs the filter-panel by passing @a pParent to the QWidget base-class constructor.
     441      * @a pViewer specifies the reference to the VM Log-Viewer this filter-panel belongs to. */
     442    UIVMLogViewerFilterPanel(QWidget *pParent, UIVMLogViewer *pViewer)
     443        : QIWithRetranslateUI<QWidget>(pParent)
     444        , m_pViewer(pViewer)
     445        , m_pCloseButton(0)
     446        , m_pFilterLabel(0), m_pFilterComboBox(0)
     447    {
     448        /* Prepare: */
     449        prepare();
     450    }
     451
     452public slots:
     453
     454    /** Applies filter settings and filters the current log-page.
     455      * @a iCurrentIndex specifies index of current log-page, but it is actually not used in the method. */
     456    void applyFilter(const int iCurrentIndex = 0)
     457    {
     458        Q_UNUSED(iCurrentIndex);
     459        QTextEdit *pCurrentPage = m_pViewer->currentLogPage();
     460        AssertReturnVoid(pCurrentPage);
     461        const QString *pCurrentLog = m_pViewer->currentLog();
     462        if (pCurrentLog)
     463        {
     464            QString strInputText(pCurrentLog->data());
     465            /* Prepare filter-data: */
     466            QString strFilteredText;
     467            const QRegExp rxFilterExp(m_strFilterText, Qt::CaseInsensitive);
     468
     469            /* If filter regular-expression is not empty and valid, filter the log: */
     470            if (!rxFilterExp.isEmpty() && rxFilterExp.isValid())
     471            {
     472                while (!strInputText.isEmpty())
     473                {
     474                    /* Read each line and check if it matches regular-expression: */
     475                    const int index = strInputText.indexOf('\n');
     476                    if (index > 0)
     477                    {
     478                        QString strLine = strInputText.left(index + 1);
     479                        if (strLine.contains(rxFilterExp))
     480                            strFilteredText.append(strLine);
     481                    }
     482                    strInputText.remove(0, index + 1);
     483                }
     484                pCurrentPage->setPlainText(strFilteredText);
     485            }
     486            /* Restore entire log when filter regular expression is empty or not valid: */
     487            else
     488                pCurrentPage->setPlainText(strInputText);
     489
     490            /* Move the cursor position to end: */
     491            QTextCursor cursor = pCurrentPage->textCursor();
     492            cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
     493            pCurrentPage->setTextCursor(cursor);
     494        }
     495    }
     496
     497private slots:
     498
     499    /** Handles the textchanged event from filter editor. */
     500    void filter(const QString &strSearchString)
     501    {
     502        m_strFilterText = strSearchString;
     503        applyFilter();
     504    }
     505
     506private:
     507
     508    /** Prepares filter-panel. */
     509    void prepare()
     510    {
     511        /* Prepare widgets: */
     512        prepareWidgets();
     513
     514        /* Prepare main-layout: */
     515        prepareMainLayout();
     516
     517        /* Prepare connections: */
     518        prepareConnections();
     519
     520        /* Retranslate finally: */
     521        retranslateUi();
     522    }
     523
     524    /** Prepares widgets. */
     525    void prepareWidgets()
     526    {
     527        /* Create close-button: */
     528        m_pCloseButton = new UIMiniCancelButton(this);
     529        AssertPtrReturnVoid(m_pCloseButton);
     530
     531        /* Create filter-combobox: */
     532        m_pFilterComboBox = new QComboBox(this);
     533        AssertPtrReturnVoid(m_pFilterComboBox);
     534        /* Prepare filter-combobox: */
     535        m_pFilterComboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
     536        m_pFilterComboBox->setEditable(true);
     537        QStringList strFilterPresets;
     538        strFilterPresets << "" << "GUI" << "NAT" << "AHCI" << "VD" << "Audio" << "VUSB" << "SUP" << "PGM" << "HDA"
     539                         << "HM" << "VMM" << "GIM" << "CPUM";
     540        strFilterPresets.sort();
     541        m_pFilterComboBox->addItems(strFilterPresets);
     542
     543        /* Create filter-label: */
     544        m_pFilterLabel = new QLabel(this);
     545        AssertPtrReturnVoid(m_pFilterLabel);
     546        /* Prepare filter-label: */
     547        m_pFilterLabel->setBuddy(m_pFilterComboBox);
     548#ifdef VBOX_DARWIN_USE_NATIVE_CONTROLS
     549        QFont font = m_pFilterLabel->font();
     550        font.setPointSize(::darwinSmallFontSize());
     551        m_pFilterLabel->setFont(font);
     552#endif /* VBOX_DARWIN_USE_NATIVE_CONTROLS */
     553    }
     554
     555    /** Prepares main-layout. */
     556    void prepareMainLayout()
     557    {
     558        /* Create main-layout: */
     559        QHBoxLayout *pMainLayout = new QHBoxLayout(this);
     560        AssertPtrReturnVoid(pMainLayout);
     561        {
     562            /* Prepare main-layout: */
     563            pMainLayout->setSpacing(5);
     564            pMainLayout->setContentsMargins(0, 0, 0, 0);
     565            pMainLayout->addWidget(m_pCloseButton);
     566            pMainLayout->addWidget(m_pFilterLabel);
     567            pMainLayout->addWidget(m_pFilterComboBox);
     568        }
     569    }
     570
     571    /** Prepares connections. */
     572    void prepareConnections()
     573    {
     574        connect(m_pCloseButton, SIGNAL(clicked()), this, SLOT(hide()));
     575        connect(m_pFilterComboBox, SIGNAL(editTextChanged(const QString &)),
     576                this, SLOT(filter(const QString &)));
     577    }
     578
     579    /** Handles the translation event. */
     580    void retranslateUi()
     581    {
     582        m_pCloseButton->setToolTip(UIVMLogViewer::tr("Close the search panel"));
     583        m_pFilterLabel->setText(UIVMLogViewer::tr("Filter"));
     584        m_pFilterComboBox->setToolTip(UIVMLogViewer::tr("Enter filtering string here"));
     585    }
     586
     587    /** Handles Qt @a pEvent, used for keyboard processing. */
     588    bool eventFilter(QObject *pObject, QEvent *pEvent)
     589    {
     590        /* Depending on event-type: */
     591        switch (pEvent->type())
     592        {
     593            /* Process key press only: */
     594            case QEvent::KeyPress:
     595            {
     596                /* Cast to corresponding key press event: */
     597                QKeyEvent *pKeyEvent = static_cast<QKeyEvent*>(pEvent);
     598
     599                /* Handle Ctrl+T key combination as a shortcut to focus search field: */
     600                if (pKeyEvent->QInputEvent::modifiers() == Qt::ControlModifier &&
     601                         pKeyEvent->key() == Qt::Key_T)
     602                {
     603                    if (m_pViewer->currentLogPage())
     604                    {
     605                        if (isHidden())
     606                            show();
     607                        m_pFilterComboBox->setFocus();
     608                        return true;
     609                    }
     610                }
     611                break;
     612            }
     613            default:
     614                break;
     615        }
     616        /* Call to base-class: */
     617        return QWidget::eventFilter(pObject, pEvent);
     618    }
     619
     620    /** Handles the Qt show @a pEvent. */
     621    void showEvent(QShowEvent *pEvent)
     622    {
     623        QWidget::showEvent(pEvent);
     624        m_pFilterComboBox->setFocus();
     625    }
     626
     627    /** Handles the Qt hide @a pEvent. */
     628    void hideEvent(QHideEvent *pEvent)
     629    {
     630        QWidget *pFocus = QApplication::focusWidget();
     631        if (pFocus && pFocus->parent() == this)
     632            focusNextPrevChild(true);
     633        QWidget::hideEvent(pEvent);
     634    }
     635
     636    /** Holds the reference to VM Log-Viewer this filter-panel belongs to. */
     637    UIVMLogViewer *m_pViewer;
     638    /** Holds the instance of close-button we create. */
     639    UIMiniCancelButton *m_pCloseButton;
     640    /** Holds the instance of filter-label we create. */
     641    QLabel *m_pFilterLabel;
     642    /** Holds instance of filter combo-box we create. */
     643    QComboBox *m_pFilterComboBox;
     644    /** Holds the filter text. */
     645    QString m_strFilterText;
     646};
     647
     648/** Holds the VM Log-Viewer array. */
    364649VMLogViewerMap UIVMLogViewer::m_viewers = VMLogViewerMap();
    365650
     
    388673    , m_machine(machine)
    389674{
    390     /* Apply UI decorations: */
    391     Ui::UIVMLogViewer::setupUi(this);
    392 
    393     /* Apply window icons: */
    394     setWindowIcon(UIIconPool::iconSetFull(":/vm_show_logs_32px.png", ":/vm_show_logs_16px.png"));
    395 
    396     /* Create VM Log Vewer container: */
    397     m_pViewerContainer = new QITabWidget(centralWidget());
    398     m_pMainLayout->insertWidget(0, m_pViewerContainer);
    399 
    400     /* Create VM Log Vewer search panel: */
    401     m_pSearchPanel = new UIVMLogViewerSearchPanel(centralWidget(), this);
    402     centralWidget()->installEventFilter(m_pSearchPanel);
    403     m_pSearchPanel->hide();
    404     m_pMainLayout->insertWidget(1, m_pSearchPanel);
    405 
    406     /* Add missing buttons & retrieve standard buttons: */
    407     mBtnHelp = m_pButtonBox->button(QDialogButtonBox::Help);
    408     mBtnFind = m_pButtonBox->addButton(QString::null, QDialogButtonBox::ActionRole);
    409     mBtnRefresh = m_pButtonBox->addButton(QString::null, QDialogButtonBox::ActionRole);
    410     mBtnClose = m_pButtonBox->button(QDialogButtonBox::Close);
    411     mBtnSave = m_pButtonBox->button(QDialogButtonBox::Save);
    412 
    413     /* Setup connections: */
    414     connect(m_pButtonBox, SIGNAL(helpRequested()), &msgCenter(), SLOT(sltShowHelpHelpDialog()));
    415     connect(mBtnFind, SIGNAL(clicked()), this, SLOT(search()));
    416     connect(mBtnRefresh, SIGNAL(clicked()), this, SLOT(refresh()));
    417     connect(mBtnClose, SIGNAL(clicked()), this, SLOT(close()));
    418     connect(mBtnSave, SIGNAL(clicked()), this, SLOT(save()));
    419 
    420     /* Reading log files: */
    421     refresh();
    422 
    423     /* Load settings: */
    424     loadSettings();
    425 
    426     /* Loading language constants */
    427     retranslateUi();
     675    /* Prepare VM Log-Viewer: */
     676    prepare();
    428677}
    429678
    430679UIVMLogViewer::~UIVMLogViewer()
    431680{
    432     /* Save settings: */
    433     saveSettings();
    434 
    435     if (!m_machine.isNull())
    436         m_viewers.remove(m_machine.GetName());
    437 }
    438 
    439 QTextEdit* UIVMLogViewer::currentLogPage()
    440 {
    441     if (m_pViewerContainer->isEnabled())
    442     {
    443         QWidget *pContainer = m_pViewerContainer->currentWidget();
    444         QTextEdit *pBrowser = pContainer->findChild<QTextEdit*>();
    445         Assert(pBrowser);
    446         return pBrowser ? pBrowser : 0;
    447     }
    448     else
    449         return 0;
     681    /* Cleanup VM Log-Viewer: */
     682    cleanup();
    450683}
    451684
     
    457690void UIVMLogViewer::refresh()
    458691{
     692    /* Disconnect this connection to avoid initial signals during page creation/deletion: */
     693    disconnect(m_pViewerContainer, SIGNAL(currentChanged(int)), m_pFilterPanel, SLOT(applyFilter(int)));
     694
    459695    /* Clearing old data if any: */
     696    for (int index = 0; index < m_book.count(); index++)
     697    {
     698        QTextEdit* pLogPage = m_book.at(index).second;
     699        if (pLogPage)
     700            delete m_logMap[pLogPage];
     701    }
    460702    m_book.clear();
     703    m_logMap.clear();
    461704    m_pViewerContainer->setEnabled(true);
    462705    while (m_pViewerContainer->count())
     
    500743                /* Add the actual file name and the QTextEdit containing the content to a list: */
    501744                m_book << qMakePair(strFileName, pLogViewer);
     745                /* Add the log-text to the map: */
     746                m_logMap[pLogViewer] = new QString(strText);
    502747                isAnyLogPresent = true;
    503748            }
     
    523768    m_pViewerContainer->setCurrentIndex(0);
    524769
     770    /* Apply the filter settings: */
     771    m_pFilterPanel->applyFilter();
     772
     773    /* Setup this connection after refresh to avoid initial signals during page creation: */
     774    connect(m_pViewerContainer, SIGNAL(currentChanged(int)), m_pFilterPanel, SLOT(applyFilter(int)));
     775
    525776    /* Enable/Disable save button & tab widget according log presence: */
    526     mBtnFind->setEnabled(isAnyLogPresent);
    527     mBtnSave->setEnabled(isAnyLogPresent);
     777    m_pButtonFind->setEnabled(isAnyLogPresent);
     778    m_pButtonSave->setEnabled(isAnyLogPresent);
     779    m_pButtonFilter->setEnabled(isAnyLogPresent);
    528780    m_pViewerContainer->setEnabled(isAnyLogPresent);
    529781}
     
    550802}
    551803
     804void UIVMLogViewer::filter()
     805{
     806    m_pFilterPanel->isHidden() ? m_pFilterPanel->show() : m_pFilterPanel->hide();
     807}
     808
     809void UIVMLogViewer::prepare()
     810{
     811    /* Apply UI decorations: */
     812    Ui::UIVMLogViewer::setupUi(this);
     813
     814    /* Apply window icons: */
     815    setWindowIcon(UIIconPool::iconSetFull(":/vm_show_logs_32px.png", ":/vm_show_logs_16px.png"));
     816
     817    /* Prepare widgets: */
     818    prepareWidgets();
     819
     820    /* Prepare connections: */
     821    prepareConnections();
     822
     823    /* Reading log files: */
     824    refresh();
     825
     826    /* Load settings: */
     827    loadSettings();
     828
     829    /* Loading language constants */
     830    retranslateUi();
     831}
     832
     833void UIVMLogViewer::prepareWidgets()
     834{
     835    /* Create VM Log-Viewer container: */
     836    m_pViewerContainer = new QITabWidget(centralWidget());
     837    AssertPtrReturnVoid(m_pViewerContainer);
     838    /* Layout VM Log-Viewer container: */
     839    m_pMainLayout->insertWidget(0, m_pViewerContainer);
     840
     841    /* Create VM Log-Viewer search-panel: */
     842    m_pSearchPanel = new UIVMLogViewerSearchPanel(centralWidget(), this);
     843    AssertPtrReturnVoid(m_pSearchPanel);
     844    /* Prepare VM Log-Viewer search-panel: */
     845    centralWidget()->installEventFilter(m_pSearchPanel);
     846    m_pSearchPanel->hide();
     847    /* Layout VM Log-Viewer search-panel: */
     848    m_pMainLayout->insertWidget(1, m_pSearchPanel);
     849
     850    /* Create VM Log-Viewer filter-panel: */
     851    m_pFilterPanel = new UIVMLogViewerFilterPanel(centralWidget(), this);
     852    AssertPtrReturnVoid(m_pFilterPanel);
     853    /* Prepare VM Log-Viewer filter-panel: */
     854    centralWidget()->installEventFilter(m_pFilterPanel);
     855    m_pFilterPanel->hide();
     856    /* Layout VM Log-Viewer filter-panel: */
     857    m_pMainLayout->insertWidget(2, m_pFilterPanel);
     858
     859    /* Create/Prepare standard buttons from button-box: */
     860    m_pButtonHelp = m_pButtonBox->button(QDialogButtonBox::Help);
     861    AssertPtrReturnVoid(m_pButtonHelp);
     862    m_pButtonFind = m_pButtonBox->addButton(QString::null, QDialogButtonBox::ActionRole);
     863    AssertPtrReturnVoid(m_pButtonFind);
     864    m_pButtonFilter = m_pButtonBox->addButton(QString::null, QDialogButtonBox::ActionRole);
     865    AssertPtrReturnVoid(m_pButtonFilter);
     866    m_pButtonClose = m_pButtonBox->button(QDialogButtonBox::Close);
     867    AssertPtrReturnVoid(m_pButtonClose);
     868    m_pButtonSave = m_pButtonBox->button(QDialogButtonBox::Save);
     869    AssertPtrReturnVoid(m_pButtonSave);
     870    m_pButtonRefresh = m_pButtonBox->addButton(QString::null, QDialogButtonBox::ActionRole);
     871    AssertPtrReturnVoid(m_pButtonRefresh);
     872}
     873
     874void UIVMLogViewer::prepareConnections()
     875{
     876    /* Prepare connections: */
     877    connect(m_pButtonBox, SIGNAL(helpRequested()), &msgCenter(), SLOT(sltShowHelpHelpDialog()));
     878    connect(m_pButtonFind, SIGNAL(clicked()), this, SLOT(search()));
     879    connect(m_pButtonRefresh, SIGNAL(clicked()), this, SLOT(refresh()));
     880    connect(m_pButtonClose, SIGNAL(clicked()), this, SLOT(close()));
     881    connect(m_pButtonSave, SIGNAL(clicked()), this, SLOT(save()));
     882    connect(m_pButtonFilter, SIGNAL(clicked()), this, SLOT(filter()));
     883}
     884
     885void UIVMLogViewer::cleanup()
     886{
     887    /* Save settings: */
     888    saveSettings();
     889
     890    /* Delete the log if not already: */
     891    for (int index = 0; index < m_book.count(); index++)
     892    {
     893        QTextEdit* pLogPage = m_book.at(index).second;
     894        if (pLogPage)
     895            delete m_logMap[pLogPage];
     896    }
     897
     898    if (!m_machine.isNull())
     899        m_viewers.remove(m_machine.GetName());
     900}
     901
    552902void UIVMLogViewer::retranslateUi()
    553903{
     
    560910
    561911    /* Translate other tags: */
    562     mBtnFind->setText(tr("&Find"));
    563     mBtnRefresh->setText(tr("&Refresh"));
    564     mBtnSave->setText(tr("&Save"));
    565     mBtnClose->setText(tr("Close"));
     912    m_pButtonFind->setText(tr("&Find"));
     913    m_pButtonRefresh->setText(tr("&Refresh"));
     914    m_pButtonSave->setText(tr("&Save"));
     915    m_pButtonClose->setText(tr("Close"));
     916    m_pButtonFilter->setText(tr("Fil&ter"));
    566917}
    567918
     
    574925     * the widget style & layout are not fully done, at least the minimum
    575926     * size hint is not properly calculated. Since this is sometimes necessary,
    576      * we provide our own "polish" implementation. */
     927     * we provide our own "polish" implementation: */
    577928
    578929    if (m_fIsPolished)
     
    581932    m_fIsPolished = true;   
    582933
    583     /* Make sure the log view widget has the focus */
     934    /* Make sure the log view widget has the focus: */
    584935    QWidget *pCurrentLogPage = currentLogPage();
    585936    if (pCurrentLogPage)
     
    595946        case Qt::Key_Escape:
    596947        {
    597             mBtnClose->animateClick();
     948            m_pButtonClose->animateClick();
    598949            return;
    599950        }
     
    624975}
    625976
     977QTextEdit* UIVMLogViewer::currentLogPage()
     978{
     979    if (m_pViewerContainer->isEnabled())
     980    {
     981        QWidget *pContainer = m_pViewerContainer->currentWidget();
     982        QTextEdit *pBrowser = pContainer->findChild<QTextEdit*>();
     983        Assert(pBrowser);
     984        return pBrowser ? pBrowser : 0;
     985    }
     986    else
     987        return 0;
     988}
     989
    626990QTextEdit* UIVMLogViewer::createLogPage(const QString &strName)
    627991{
     
    6411005    m_pViewerContainer->addTab(pPageContainer, strName);
    6421006    return pLogViewer;
     1007}
     1008
     1009const QString* UIVMLogViewer::currentLog()
     1010{
     1011    return m_logMap[currentLogPage()];
    6431012}
    6441013
  • trunk/src/VBox/Frontends/VirtualBox/src/UIVMLogViewer.h

    r57496 r58267  
    55
    66/*
    7  * Copyright (C) 2008-2012 Oracle Corporation
     7 * Copyright (C) 2010-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1616 */
    1717
    18 #ifndef __UIVMLogViewer_h__
    19 #define __UIVMLogViewer_h__
     18#ifndef ___UIVMLogViewer_h___
     19#define ___UIVMLogViewer_h___
    2020
    2121/* Qt includes: */
     
    2525
    2626/* GUI includes: */
     27#include "QIWithRetranslateUI.h"
    2728#include "UIVMLogViewer.gen.h"
    28 #include "QIWithRetranslateUI.h"
    2929
    3030/* COM includes: */
     
    3333
    3434/* Forward declarations: */
     35class QComboBox;
     36class QITabWidget;
    3537class QPushButton;
    3638class QTextEdit;
    37 class QITabWidget;
    3839class UIVMLogViewer;
     40class UIVMLogViewerFilterPanel;
    3941class UIVMLogViewerSearchPanel;
    4042
    41 /* Typedefs: */
     43/* Type definitions: */
    4244typedef QMap<QString, UIVMLogViewer*> VMLogViewerMap;
    4345typedef QPair<QString, QTextEdit*> LogPage;
    4446typedef QList<LogPage> LogBook;
     47typedef QMap<QTextEdit*, QString*> VMLogMap;
    4548
    46 /* VM Log Viewer window: */
     49/** QMainWindow extension
     50  * providing GUI with VirtualBox LogViewer. */
    4751class UIVMLogViewer : public QIWithRetranslateUI2<QMainWindow>,
    4852                      public Ui::UIVMLogViewer
     
    5256public:
    5357
    54     /* Static method to create/show VM Log Viewer: */
     58    /** Static method to create/show VM Log Viewer by passing @a pParent to QWidget base-class constructor.
     59      * @a machine specifies the machine for which VM Log-Viewer is requested. */
    5560    static void showLogViewerFor(QWidget *pParent, const CMachine &machine);
    5661
    5762protected:
    5863
    59     /* Constructor/destructor: */
     64    /** Constructs the VM Log-Viewer by passing @a pParent to QWidget base-class constructor.
     65      * @a flags specifies Qt window flags.
     66      * @a machine specifies the machine for which VM Log-Viewer is requested. */
    6067    UIVMLogViewer(QWidget *pParent, Qt::WindowFlags flags, const CMachine &machine);
     68    /** Destructs the VM Log-Viewer. */
    6169    ~UIVMLogViewer();
    6270
    6371private slots:
    6472
    65     /* Button slots: */
     73    /** Handles search action triggering. */
    6674    void search();
     75    /** Handles search action triggering. */
    6776    void refresh();
     77    /** Handles close action triggering. */
    6878    bool close();
     79    /** Handles save action triggering. */
    6980    void save();
     81    /** Handles filter action triggering. */
     82    void filter();
    7083
    7184private:
    7285
    73     /* Translation stuff: */
     86    /** Prepares VM Log-Viewer. */
     87    void prepare();
     88
     89    /** Prepares widgets. */
     90    void prepareWidgets();
     91
     92    /** Prepares connections. */
     93    void prepareConnections();
     94
     95    /** Cleanups VM Log-Viewer. */
     96    void cleanup();
     97
     98    /** Handles translation event. */
    7499    void retranslateUi();
    75100
    76     /* Event handlers: */
    77     void showEvent(QShowEvent *aEvent);
     101    /** Handles Qt show @a pEvent. */
     102    void showEvent(QShowEvent *pEvent);
     103
     104    /** Handles Qt key-press @a pEvent. */
    78105    void keyPressEvent(QKeyEvent *pEvent);
    79106
    80     /* Various helpers: */
     107    /** Returns the current log-page. */
    81108    QTextEdit* currentLogPage();
     109    /** Returns the newly created log-page using @a strPage filename. */
    82110    QTextEdit* createLogPage(const QString &strPage);
     111    /** Returns the content of current log-page. */
     112    const QString* currentLog();
    83113
    84114    /** Load settings helper. */
     
    88118    void saveSettings();
    89119
    90     /* Array containing all VM Log Viewers: */
     120    /** Holds the list of all VM Log Viewers. */
    91121    static VMLogViewerMap m_viewers;
    92122
    93     /* VM Log Viewer variables: */
     123    /** Holds whether the dialog is polished. */
    94124    bool m_fIsPolished;
     125
     126    /** Holds the machine instance. */
    95127    CMachine m_machine;
     128
     129    /** Holds container for log-pages. */
    96130    QITabWidget *m_pViewerContainer;
     131
     132    /** Holds the instance of search panel. */
    97133    UIVMLogViewerSearchPanel *m_pSearchPanel;
     134
     135    /** Holds the list of log-pages. */
    98136    LogBook m_book;
     137
     138    /** Holds the instance of filter panel. */
     139    UIVMLogViewerFilterPanel *m_pFilterPanel;
     140
     141    /** Holds the list of log-content. */
     142    VMLogMap m_logMap;
    99143
    100144    /** Current dialog geometry. */
    101145    QRect m_geometry;
    102146
    103     /* Buttons: */
    104     QPushButton *mBtnHelp;
    105     QPushButton *mBtnFind;
    106     QPushButton *mBtnRefresh;
    107     QPushButton *mBtnClose;
    108     QPushButton *mBtnSave;
     147    /** Holds the help button instance. */
     148    QPushButton *m_pButtonHelp;
     149    /** Holds the find button instance. */
     150    QPushButton *m_pButtonFind;
     151    /** Holds the refresh button instance. */
     152    QPushButton *m_pButtonRefresh;
     153    /** Holds the close button instance. */
     154    QPushButton *m_pButtonClose;
     155    /** Holds the save button instance. */
     156    QPushButton *m_pButtonSave;
     157    /** Holds the filter button instance. */
     158    QPushButton *m_pButtonFilter;
    109159
    110     /* Friends: */
    111160    friend class UIVMLogViewerSearchPanel;
     161    friend class UIVMLogViewerFilterPanel;
    112162};
    113163
    114 #endif // __UIVMLogViewer_h__
     164#endif /* !___UIVMLogViewer_h___ */
    115165
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette