VirtualBox

Ignore:
Timestamp:
Jul 13, 2007 11:17:50 AM (18 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
22869
Message:

#2124: VirtualBox LogViewer search mechanism.
VirtualBox LogViewer default search mechanism implemented:

  1. The Search Mechanism panel could be invoked for the LogViewer with the opened logs inside by the Ctrl-F keys combination. If there is other opinions about how to invoke this panel (other combination, button or menu), please let me know.
  1. This mechanism allows the incremental search in forward direction and search for the required phrase in both directions. Currently supported key-combinations are F3/Shift-F3 and nls-linked Ctrl-N/Ctrl-P (Next/Previous - could be different for other languages).
  1. Case-Sensitive feature supported.
  1. Log-browser scrolling and selection upon the required target is found.
Location:
trunk/src/VBox/Frontends/VirtualBox/ui
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/ui/VBoxVMLogViewer.ui

    r3016 r3610  
    155155    <include location="global" impldecl="in implementation">qdatetime.h</include>
    156156    <include location="global" impldecl="in implementation">qobjectlist.h</include>
     157    <include location="global" impldecl="in implementation">qcheckbox.h</include>
     158    <include location="global" impldecl="in implementation">qlabel.h</include>
     159    <include location="global" impldecl="in implementation">qlineedit.h</include>
     160    <include location="global" impldecl="in implementation">qtoolbutton.h</include>
     161    <include location="global" impldecl="in implementation">qmessagebox.h</include>
     162    <include location="global" impldecl="in implementation">qfocusdata.h</include>
    157163</includes>
    158164<forwards>
     
    160166    <forward>class QTabWidget</forward>
    161167    <forward>class QTextBrowser</forward>
     168    <forward>class VBoxLogSearchPanel</forward>
    162169</forwards>
    163170<variables>
     
    171178    <variable access="private">QStringList mLogFilesList;</variable>
    172179    <variable access="private">QPushButton *mDefaultButton;</variable>
     180    <variable access="private">VBoxLogSearchPanel *mSearchPanel;</variable>
    173181</variables>
    174182<slots>
     
    191199    <function access="pritave">loadLogFile( const QString &amp; )</function>
    192200    <function access="pritave" returnType="QTextBrowser*">createLogPage( const QString &amp; )</function>
     201    <function returnType="QTextBrowser*">currentLogPage()</function>
    193202</functions>
    194203<pixmapinproject/>
  • trunk/src/VBox/Frontends/VirtualBox/ui/VBoxVMLogViewer.ui.h

    r3018 r3610  
    3131
    3232
     33class VBoxLogSearchPanel : public QWidget
     34{
     35    Q_OBJECT
     36
     37public:
     38
     39    VBoxLogSearchPanel (QWidget *aParent,
     40                        VBoxVMLogViewer *aViewer,
     41                        const char *aName)
     42        : QWidget (aParent, aName)
     43        , mViewer (aViewer)
     44        , mButtonClose (0)
     45        , mSearchName (0), mSearchString (0)
     46        , mButtonPrev (0), mButtonNext (0)
     47        , mCaseSensitive (0)
     48        , mWarningSpacer (0), mWarningIcon (0), mWarningString (0)
     49    {
     50        mButtonClose = new QToolButton (this);
     51        mButtonClose->setAutoRaise (true);
     52        mButtonClose->setFocusPolicy (QWidget::TabFocus);
     53        mButtonClose->setAccel (QKeySequence (Qt::Key_Escape));
     54        connect (mButtonClose, SIGNAL (clicked()), this, SLOT (hide()));
     55        mButtonClose->setIconSet (VBoxGlobal::iconSet ("delete_16px.png",
     56                                                   "delete_dis_16px.png"));
     57
     58        mSearchName = new QLabel (this);
     59        mSearchString = new QLineEdit (this);
     60        mSearchString->setSizePolicy (QSizePolicy::Preferred,
     61                                      QSizePolicy::Fixed);
     62        connect (mSearchString, SIGNAL (textChanged (const QString &)),
     63                 this, SLOT (findCurrent (const QString &)));
     64
     65        mButtonPrev = new QToolButton (this);
     66        mButtonPrev->setEnabled (false);
     67        mButtonPrev->setAutoRaise (true);
     68        mButtonPrev->setFocusPolicy (QWidget::TabFocus);
     69        mButtonPrev->setUsesTextLabel (true);
     70        mButtonPrev->setTextPosition (QToolButton::BesideIcon);
     71        connect (mButtonPrev, SIGNAL (clicked()), this, SLOT (findBack()));
     72        mButtonPrev->setIconSet (VBoxGlobal::iconSet ("list_moveup_16px.png",
     73                                             "list_moveup_disabled_16px.png"));
     74
     75        mButtonNext = new QToolButton (this);
     76        mButtonNext->setEnabled (false);
     77        mButtonNext->setAutoRaise (true);
     78        mButtonNext->setFocusPolicy (QWidget::TabFocus);
     79        mButtonNext->setUsesTextLabel (true);
     80        mButtonNext->setTextPosition (QToolButton::BesideIcon);
     81        connect (mButtonNext, SIGNAL (clicked()), this, SLOT (findNext()));
     82        mButtonNext->setIconSet (VBoxGlobal::iconSet ("list_movedown_16px.png",
     83                                           "list_movedown_disabled_16px.png"));
     84
     85        mCaseSensitive = new QCheckBox (this);
     86
     87        mWarningSpacer = new QSpacerItem (0, 0, QSizePolicy::Fixed,
     88                                                QSizePolicy::Minimum);
     89        mWarningIcon = new QLabel (this);
     90        mWarningIcon->hide();
     91        QImage img = QMessageBox::standardIcon (QMessageBox::Warning).
     92                                                convertToImage();
     93        if (!img.isNull())
     94        {
     95            img = img.smoothScale (16, 16);
     96            QPixmap pixmap;
     97            pixmap.convertFromImage (img);
     98            mWarningIcon->setPixmap (pixmap);
     99        }
     100        mWarningString = new QLabel (this);
     101        mWarningString->hide();
     102
     103        QSpacerItem *spacer = new QSpacerItem (0, 0, QSizePolicy::Expanding,
     104                                                     QSizePolicy::Minimum);
     105
     106        QHBoxLayout *mainLayout = new QHBoxLayout (this, 5, 5);
     107        mainLayout->addWidget (mButtonClose);
     108        mainLayout->addWidget (mSearchName);
     109        mainLayout->addWidget (mSearchString);
     110        mainLayout->addWidget (mButtonPrev);
     111        mainLayout->addWidget (mButtonNext);
     112        mainLayout->addWidget (mCaseSensitive);
     113        mainLayout->addItem   (mWarningSpacer);
     114        mainLayout->addWidget (mWarningIcon);
     115        mainLayout->addWidget (mWarningString);
     116        mainLayout->addItem   (spacer);
     117
     118        setFocusProxy (mCaseSensitive);
     119
     120        languageChange();
     121    }
     122
     123    void languageChange()
     124    {
     125        QToolTip::add (mButtonClose, tr ("Close the search panel"));
     126        mSearchName->setText (tr ("Find "));
     127        QToolTip::add (mSearchString, tr ("Enter search string here"));
     128        mButtonPrev->setTextLabel (tr ("&Previous"));
     129        mButtonPrev->setAccel (QKeySequence (tr ("Alt+P")));
     130        QToolTip::add (mButtonPrev,
     131            tr ("Search for the previous occurrence of the string"));
     132        mButtonNext->setTextLabel (tr ("&Next"));
     133        mButtonNext->setAccel (QKeySequence (tr ("Alt+N")));
     134        QToolTip::add (mButtonNext,
     135            tr ("Search for the next occurrence of the string"));
     136        mCaseSensitive->setText (tr ("Cas&e Sensitive"));
     137        QToolTip::add (mCaseSensitive,
     138            tr ("Check this box to perform Case Sensitive search"));
     139        mWarningString->setText (tr ("Unable to find string"));
     140    }
     141
     142private slots:
     143
     144    void findNext()
     145    {
     146        search (true);
     147    }
     148
     149    void findBack()
     150    {
     151        search (false);
     152    }
     153
     154    void findCurrent (const QString &aSearchString)
     155    {
     156        mButtonNext->setEnabled (aSearchString.length());
     157        mButtonPrev->setEnabled (aSearchString.length());
     158        toggleWarning (!aSearchString.length());
     159        if (aSearchString.length())
     160            search (true, true);
     161        else
     162            mViewer->currentLogPage()->removeSelection();
     163    }
     164
     165private:
     166
     167    void search (bool aForward, bool aStartCurrent = false)
     168    {
     169        QTextBrowser *browser = mViewer->currentLogPage();
     170        int startPrg = 0, endPrg = 0;
     171        int startInd = 0, endInd = 0;
     172        if (browser->hasSelectedText())
     173            browser->getSelection (&startPrg, &startInd, &endPrg, &endInd);
     174
     175        bool found = false;
     176        int increment = aForward ? 1 : -1;
     177        int border = aForward ? browser->paragraphs() : -1;
     178        int startFrom = aStartCurrent ? startInd : startInd + increment;
     179        int paragraph = startFrom < 0 ? startPrg + increment : startPrg;
     180        for (; paragraph != border; paragraph += increment)
     181        {
     182            QString text = browser->text (paragraph);
     183            int res = aForward ?
     184                text.find (mSearchString->text(), startFrom,
     185                           mCaseSensitive->isChecked()) :
     186                text.findRev (mSearchString->text(), startFrom,
     187                              mCaseSensitive->isChecked());
     188            if (res != -1)
     189            {
     190                found = true;
     191                browser->setSelection (paragraph, res, paragraph,
     192                                       res + mSearchString->text().length());
     193                break;
     194            }
     195            startFrom = aForward ? 0 : -1;
     196        }
     197
     198        toggleWarning (found);
     199        if (!found)
     200            browser->setSelection (startPrg, startInd, endPrg, endInd);
     201    }
     202
     203    bool eventFilter (QObject *aObject, QEvent *aEvent)
     204    {
     205        switch (aEvent->type())
     206        {
     207            case QEvent::KeyPress:
     208            {
     209                QKeyEvent *e = static_cast<QKeyEvent*> (aEvent);
     210
     211                /* processing the return keypress for the mSearchString
     212                 * widget as the search next string action */
     213                if (aObject == mSearchString &&
     214                    (e->state() == 0 || e->state() & Keypad) &&
     215                    (e->key() == Key_Enter || e->key() == Key_Return))
     216                {
     217                    findNext();
     218                    return true;
     219                }
     220                /* processing other search next/previous shortcuts */
     221                else if (e->key() == Key_F3)
     222                {
     223                    if (e->state() == 0)
     224                        findNext();
     225                    else if (e->state() == ShiftButton)
     226                        findBack();
     227                    return true;
     228                }
     229                /* processing ctrl-f key combination as the shortcut to
     230                 * move to the search field */
     231                else if (e->state() == ControlButton && e->key() == Key_F)
     232                {
     233                    mSearchString->setFocus();
     234                    return true;
     235                }
     236
     237                break;
     238            }
     239            default:
     240                break;
     241        }
     242        return false;
     243    }
     244
     245    void showEvent (QShowEvent *aEvent)
     246    {
     247        QWidget::showEvent (aEvent);
     248        qApp->installEventFilter (this);
     249        mSearchString->setFocus();
     250    }
     251
     252    void hideEvent (QHideEvent *aEvent)
     253    {
     254        if (focusData()->focusWidget()->parent() == this)
     255           focusNextPrevChild (true);
     256        qApp->removeEventFilter (this);
     257        QWidget::hideEvent (aEvent);
     258    }
     259
     260    void toggleWarning (bool aHide)
     261    {
     262        mWarningSpacer->changeSize (aHide ? 0 : 16, 0, QSizePolicy::Fixed,
     263                                                       QSizePolicy::Minimum);
     264        mWarningIcon->setHidden (aHide);
     265        mWarningString->setHidden (aHide);
     266    }
     267
     268    VBoxVMLogViewer *mViewer;
     269    QToolButton     *mButtonClose;
     270    QLabel          *mSearchName;
     271    QLineEdit       *mSearchString;
     272    QToolButton     *mButtonPrev;
     273    QToolButton     *mButtonNext;
     274    QCheckBox       *mCaseSensitive;
     275    QSpacerItem     *mWarningSpacer;
     276    QLabel          *mWarningIcon;
     277    QLabel          *mWarningString;
     278};
     279
     280
    33281VBoxVMLogViewer::LogViewersMap VBoxVMLogViewer::mSelfArray = LogViewersMap();
    34282
     
    79327    logsFrameLayout->addWidget (mLogList);
    80328
     329    /* search panel creation */
     330    mSearchPanel = new VBoxLogSearchPanel (mLogsFrame, this,
     331                                           "VBoxLogSearchPanel");
     332    logsFrameLayout->addWidget (mSearchPanel);
     333    mSearchPanel->hide();
     334
     335    /* fix the tab order to ensure the dialog keys are always the last */
     336    setTabOrder (mSearchPanel->focusProxy(), mSaveButton);
     337    setTabOrder (mSaveButton, mRefreshButton);
     338    setTabOrder (mRefreshButton, mCloseButton);
     339    setTabOrder (mCloseButton, mLogList);
     340
    81341    /* applying language settings */
    82342    languageChangeImp();
     
    114374    if (!mMachine.isNull())
    115375        setCaption (tr ("%1 - VirtualBox Log Viewer").arg (mMachine.GetName()));
     376    /* translate a search panel */
     377    if (mSearchPanel)
     378        mSearchPanel->languageChange();
    116379}
    117380
     
    203466            case Key_Escape:
    204467            {
    205                 close();
     468                mCloseButton->animateClick();
    206469                break;
    207470            }
    208471        }
     472    }
     473    else if (aEvent->state() == Qt::ControlButton &&
     474             aEvent->key() == Qt::Key_F)
     475    {
     476        if (mLogList->isEnabled())
     477            mSearchPanel->show();
    209478    }
    210479    else
     
    336605
    337606
     607QTextBrowser* VBoxVMLogViewer::currentLogPage()
     608{
     609    return static_cast<QTextBrowser*> (mLogList->currentPage());
     610}
     611
     612
    338613void VBoxVMLogViewer::save()
    339614{
     
    364639}
    365640
     641#include "VBoxVMLogViewer.ui.moc"
     642
Note: See TracChangeset for help on using the changeset viewer.

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