screensaver/screensaverplugins/snsrbigclockscreensaverplugin/src/snsrbigclockscreensaver.cpp
author hgs
Fri, 23 Jul 2010 13:47:57 +0300
changeset 69 87476091b3f5
parent 62 341166945d65
child 86 e4f038c420f7
permissions -rw-r--r--
201029
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
62
hgs
parents:
diff changeset
     1
/*
hgs
parents:
diff changeset
     2
* Copyright (c) 2009 - 2010 Nokia Corporation and/or its subsidiary(-ies).
hgs
parents:
diff changeset
     3
* All rights reserved.
hgs
parents:
diff changeset
     4
* This component and the accompanying materials are made available
hgs
parents:
diff changeset
     5
* under the terms of "Eclipse Public License v1.0"
hgs
parents:
diff changeset
     6
* which accompanies this distribution, and is available
hgs
parents:
diff changeset
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
hgs
parents:
diff changeset
     8
*
hgs
parents:
diff changeset
     9
* Initial Contributors:
hgs
parents:
diff changeset
    10
* Nokia Corporation - initial contribution.
hgs
parents:
diff changeset
    11
*
hgs
parents:
diff changeset
    12
* Contributors:
hgs
parents:
diff changeset
    13
*
hgs
parents:
diff changeset
    14
* Description: Big clock Screensaver.
hgs
parents:
diff changeset
    15
*
hgs
parents:
diff changeset
    16
*/
hgs
parents:
diff changeset
    17
hgs
parents:
diff changeset
    18
#include "snsrbigclockscreensaver.h"
hgs
parents:
diff changeset
    19
hgs
parents:
diff changeset
    20
#ifdef Q_OS_SYMBIAN
hgs
parents:
diff changeset
    21
#include <e32std.h>
hgs
parents:
diff changeset
    22
#endif // Q_OS_SYMBIAN
hgs
parents:
diff changeset
    23
hgs
parents:
diff changeset
    24
#include <QDebug>
hgs
parents:
diff changeset
    25
#include <QTime>
hgs
parents:
diff changeset
    26
#include <QTimer>
69
hgs
parents: 62
diff changeset
    27
#include <XQSettingsManager> 
hgs
parents: 62
diff changeset
    28
#include <HbInstance>
hgs
parents: 62
diff changeset
    29
#include <HbMainWindow>
62
hgs
parents:
diff changeset
    30
69
hgs
parents: 62
diff changeset
    31
#include <screensaverdomaincrkeys.h>
62
hgs
parents:
diff changeset
    32
#include "snsranalogclockcontainer.h"
hgs
parents:
diff changeset
    33
#include "snsrdigitalclockcontainer.h"
hgs
parents:
diff changeset
    34
#include "snsroledanalogclockcontainer.h"
hgs
parents:
diff changeset
    35
#include "snsroleddigitalclockcontainer.h"
69
hgs
parents: 62
diff changeset
    36
#include "snsrblankcontainer.h"
62
hgs
parents:
diff changeset
    37
#include "snsrindicatormodel.h"
hgs
parents:
diff changeset
    38
hgs
parents:
diff changeset
    39
/*!
hgs
parents:
diff changeset
    40
    \class SnsrBigClockScreensaver
hgs
parents:
diff changeset
    41
    \ingroup group_snsrbigclockscreensaverplugin
hgs
parents:
diff changeset
    42
    \brief Screensaver with big digital clock.
hgs
parents:
diff changeset
    43
 */
hgs
parents:
diff changeset
    44
hgs
parents:
diff changeset
    45
/*!
hgs
parents:
diff changeset
    46
    Constructs a new SnsrBigClockScreensaver.
hgs
parents:
diff changeset
    47
 */
hgs
parents:
diff changeset
    48
SnsrBigClockScreensaver::SnsrBigClockScreensaver() :
hgs
parents:
diff changeset
    49
    mMainWindow(0),
hgs
parents:
diff changeset
    50
    mCurrentContainer(0),
69
hgs
parents: 62
diff changeset
    51
    mIndicatorModel(0),
hgs
parents: 62
diff changeset
    52
    m_setManager(0)
62
hgs
parents:
diff changeset
    53
{
hgs
parents:
diff changeset
    54
    mMainWindow = HbInstance::instance()->allMainWindows().at(0);
hgs
parents:
diff changeset
    55
    // for nice looking clock hand transformations
hgs
parents:
diff changeset
    56
    mMainWindow->setRenderHint(QPainter::SmoothPixmapTransform);
hgs
parents:
diff changeset
    57
    
hgs
parents:
diff changeset
    58
    // This model holds indicator status information and must exist as
hgs
parents:
diff changeset
    59
    // long as screensaver does.
hgs
parents:
diff changeset
    60
    mIndicatorModel = new SnsrIndicatorModel(this);
hgs
parents:
diff changeset
    61
}
hgs
parents:
diff changeset
    62
hgs
parents:
diff changeset
    63
/*!
hgs
parents:
diff changeset
    64
    Destructs the class.
hgs
parents:
diff changeset
    65
 */
hgs
parents:
diff changeset
    66
SnsrBigClockScreensaver::~SnsrBigClockScreensaver()
hgs
parents:
diff changeset
    67
{
69
hgs
parents: 62
diff changeset
    68
    mMainWindow->unsetOrientation( /*animate*/false );
62
hgs
parents:
diff changeset
    69
    // mCurrentContainer, mIndicatorModel - deleted by the parent
hgs
parents:
diff changeset
    70
}
hgs
parents:
diff changeset
    71
hgs
parents:
diff changeset
    72
/*!
hgs
parents:
diff changeset
    73
    @copydoc Screensaver::onInitialize()
hgs
parents:
diff changeset
    74
*/
hgs
parents:
diff changeset
    75
bool SnsrBigClockScreensaver::onInitialize()
hgs
parents:
diff changeset
    76
{
hgs
parents:
diff changeset
    77
    qDebug() << "SnsrBigClockScreensaver::onInitialize()";
hgs
parents:
diff changeset
    78
    return true;
hgs
parents:
diff changeset
    79
}
hgs
parents:
diff changeset
    80
hgs
parents:
diff changeset
    81
/*!
hgs
parents:
diff changeset
    82
    @copydoc Screensaver::onForeground()
hgs
parents:
diff changeset
    83
 */
hgs
parents:
diff changeset
    84
bool SnsrBigClockScreensaver::onForeground()
hgs
parents:
diff changeset
    85
{
hgs
parents:
diff changeset
    86
    SCREENSAVER_TEST_FUNC_ENTRY("SnsrBigClockScreensaver::onForeground")
hgs
parents:
diff changeset
    87
    qDebug() << "SnsrBigClockScreensaver::onForeground()";
hgs
parents:
diff changeset
    88
hgs
parents:
diff changeset
    89
    removeCurrentContainer();
hgs
parents:
diff changeset
    90
69
hgs
parents: 62
diff changeset
    91
    emit screenPowerModeRequested( Screensaver::ScreenModeFullPower );
hgs
parents: 62
diff changeset
    92
    
62
hgs
parents:
diff changeset
    93
    SnsrBigClockContainer* newContainer( 0 );
hgs
parents:
diff changeset
    94
    if (clockFormat() == ClockFormatAnalog) {
hgs
parents:
diff changeset
    95
        newContainer = new SnsrAnalogClockContainer();
hgs
parents:
diff changeset
    96
    }
hgs
parents:
diff changeset
    97
    else {
hgs
parents:
diff changeset
    98
        newContainer = new SnsrDigitalClockContainer();
hgs
parents:
diff changeset
    99
    }
hgs
parents:
diff changeset
   100
hgs
parents:
diff changeset
   101
    setCurrentContainer( newContainer );
69
hgs
parents: 62
diff changeset
   102
    
62
hgs
parents:
diff changeset
   103
    SCREENSAVER_TEST_FUNC_EXIT("SnsrBigClockScreensaver::onForeground")
hgs
parents:
diff changeset
   104
    return true;
hgs
parents:
diff changeset
   105
}
hgs
parents:
diff changeset
   106
hgs
parents:
diff changeset
   107
/*!
hgs
parents:
diff changeset
   108
    @copydoc Screensaver::onPartialForeground()
hgs
parents:
diff changeset
   109
 */
hgs
parents:
diff changeset
   110
bool SnsrBigClockScreensaver::onPartialForeground()
hgs
parents:
diff changeset
   111
{
hgs
parents:
diff changeset
   112
    SCREENSAVER_TEST_FUNC_ENTRY("SnsrBigClockScreensaver::onPartialForeground")
hgs
parents:
diff changeset
   113
    qDebug() << "SnsrBigClockScreensaver::onPartialForeground()";
hgs
parents:
diff changeset
   114
hgs
parents:
diff changeset
   115
    removeCurrentContainer();
hgs
parents:
diff changeset
   116
    
hgs
parents:
diff changeset
   117
    SnsrBigClockContainer* newContainer( 0 );
69
hgs
parents: 62
diff changeset
   118
        
hgs
parents: 62
diff changeset
   119
    // Check ScreensaverStatus from repository
hgs
parents: 62
diff changeset
   120
    XQSettingsManager::Error error;
hgs
parents: 62
diff changeset
   121
    int screensaverOn = 1; 
hgs
parents: 62
diff changeset
   122
    XQCentralRepositorySettingsKey settingsKey(
hgs
parents: 62
diff changeset
   123
            KCRUidScreensaverSettings.iUid, KScreensaverStatus ); // TUid as same repository used in control panel via Symbian APIs 
hgs
parents: 62
diff changeset
   124
    m_setManager = new XQSettingsManager(this);
hgs
parents: 62
diff changeset
   125
    if (m_setManager) {
hgs
parents: 62
diff changeset
   126
        screensaverOn = m_setManager->readItemValue(settingsKey, XQSettingsManager::TypeInt).toInt();
hgs
parents: 62
diff changeset
   127
        error = m_setManager->error();
hgs
parents: 62
diff changeset
   128
        if (error != XQSettingsManager::NoError) {
hgs
parents: 62
diff changeset
   129
            qDebug("Error reading value from XQSettingsManager.. error = %d", error);
hgs
parents: 62
diff changeset
   130
        }
hgs
parents: 62
diff changeset
   131
        delete m_setManager;
hgs
parents: 62
diff changeset
   132
    }
hgs
parents: 62
diff changeset
   133
    
hgs
parents: 62
diff changeset
   134
    if (screensaverOn) {
hgs
parents: 62
diff changeset
   135
        if (clockFormat() == ClockFormatAnalog) {
hgs
parents: 62
diff changeset
   136
            newContainer = new SnsrOledAnalogClockContainer();
hgs
parents: 62
diff changeset
   137
        }
hgs
parents: 62
diff changeset
   138
        else {
hgs
parents: 62
diff changeset
   139
            newContainer = new SnsrOledDigitalClockContainer();
hgs
parents: 62
diff changeset
   140
        }
62
hgs
parents:
diff changeset
   141
    }
hgs
parents:
diff changeset
   142
    else {
69
hgs
parents: 62
diff changeset
   143
        newContainer = new SnsrBlankContainer();
62
hgs
parents:
diff changeset
   144
    }
69
hgs
parents: 62
diff changeset
   145
    
62
hgs
parents:
diff changeset
   146
    setCurrentContainer( newContainer );
hgs
parents:
diff changeset
   147
hgs
parents:
diff changeset
   148
    SCREENSAVER_TEST_FUNC_EXIT("SnsrBigClockScreensaver::onPartialForeground")
hgs
parents:
diff changeset
   149
    return true;
hgs
parents:
diff changeset
   150
}
hgs
parents:
diff changeset
   151
hgs
parents:
diff changeset
   152
/*!
hgs
parents:
diff changeset
   153
    @copydoc Screensaver::onBackground()
hgs
parents:
diff changeset
   154
 */
hgs
parents:
diff changeset
   155
bool SnsrBigClockScreensaver::onBackground()
hgs
parents:
diff changeset
   156
{
hgs
parents:
diff changeset
   157
    SCREENSAVER_TEST_FUNC_ENTRY("SnsrBigClockScreensaver::onBackground")
hgs
parents:
diff changeset
   158
    qDebug() << "SnsrBigClockScreensaver::onBackground()";
hgs
parents:
diff changeset
   159
hgs
parents:
diff changeset
   160
    removeCurrentContainer();
hgs
parents:
diff changeset
   161
hgs
parents:
diff changeset
   162
    SCREENSAVER_TEST_FUNC_EXIT("SnsrBigClockScreensaver::onBackground")
hgs
parents:
diff changeset
   163
    return true;
hgs
parents:
diff changeset
   164
}
hgs
parents:
diff changeset
   165
hgs
parents:
diff changeset
   166
/*!
hgs
parents:
diff changeset
   167
    @copydoc Screensaver::onPowerSave()
hgs
parents:
diff changeset
   168
 */
hgs
parents:
diff changeset
   169
bool SnsrBigClockScreensaver::onPowerSave()
hgs
parents:
diff changeset
   170
{
hgs
parents:
diff changeset
   171
    SCREENSAVER_TEST_FUNC_ENTRY("SnsrBigClockScreensaver::onPowerSave")
hgs
parents:
diff changeset
   172
    qDebug() << "SnsrBigClockScreensaver::onPowerSave()";
hgs
parents:
diff changeset
   173
hgs
parents:
diff changeset
   174
    SCREENSAVER_TEST_FUNC_EXIT("SnsrBigClockScreensaver::onPowerSave")
hgs
parents:
diff changeset
   175
    return false;
hgs
parents:
diff changeset
   176
}
hgs
parents:
diff changeset
   177
hgs
parents:
diff changeset
   178
/*!
hgs
parents:
diff changeset
   179
    @copydoc Screensaver::onClose()
hgs
parents:
diff changeset
   180
 */
hgs
parents:
diff changeset
   181
bool SnsrBigClockScreensaver::onClose()
hgs
parents:
diff changeset
   182
{
hgs
parents:
diff changeset
   183
    SCREENSAVER_TEST_FUNC_ENTRY("SnsrBigClockScreensaver::onClose")
hgs
parents:
diff changeset
   184
    qDebug() << "SnsrBigClockScreensaver::onClose()";
hgs
parents:
diff changeset
   185
hgs
parents:
diff changeset
   186
    bool ret(false);
hgs
parents:
diff changeset
   187
    if (onBackground()) {
hgs
parents:
diff changeset
   188
        delete mCurrentContainer;
hgs
parents:
diff changeset
   189
        mCurrentContainer = 0;
hgs
parents:
diff changeset
   190
        ret = true;
hgs
parents:
diff changeset
   191
    }
hgs
parents:
diff changeset
   192
hgs
parents:
diff changeset
   193
    SCREENSAVER_TEST_FUNC_EXIT("SnsrBigClockScreensaver::onClose")
hgs
parents:
diff changeset
   194
    return ret;
hgs
parents:
diff changeset
   195
}
hgs
parents:
diff changeset
   196
hgs
parents:
diff changeset
   197
/*!
hgs
parents:
diff changeset
   198
    @copydoc Screensaver::onHandleActiveIndicators
hgs
parents:
diff changeset
   199
 */
hgs
parents:
diff changeset
   200
void SnsrBigClockScreensaver::onHandleActiveIndicators(
hgs
parents:
diff changeset
   201
        const QList<HbIndicatorInterface*> &activeIndicators)
hgs
parents:
diff changeset
   202
{
hgs
parents:
diff changeset
   203
    mIndicatorModel->handleActiveIndicators(activeIndicators);
hgs
parents:
diff changeset
   204
}
hgs
parents:
diff changeset
   205
hgs
parents:
diff changeset
   206
/*!
hgs
parents:
diff changeset
   207
    @copydoc Screensaver::onHandleActivatedIndicator
hgs
parents:
diff changeset
   208
 */
hgs
parents:
diff changeset
   209
void SnsrBigClockScreensaver::onHandleActivatedIndicator(
hgs
parents:
diff changeset
   210
        HbIndicatorInterface *activatedIndicator)
hgs
parents:
diff changeset
   211
{
hgs
parents:
diff changeset
   212
    mIndicatorModel->handleActivatedIndicator(activatedIndicator);
hgs
parents:
diff changeset
   213
}
hgs
parents:
diff changeset
   214
hgs
parents:
diff changeset
   215
/*!
hgs
parents:
diff changeset
   216
    @copydoc Screensaver::onHandleDeactivatedIndicator
hgs
parents:
diff changeset
   217
 */
hgs
parents:
diff changeset
   218
void SnsrBigClockScreensaver::onHandleDeactivatedIndicator(
hgs
parents:
diff changeset
   219
        HbIndicatorInterface *deactivatedIndicator)
hgs
parents:
diff changeset
   220
{
hgs
parents:
diff changeset
   221
    mIndicatorModel->handleDeactivatedIndicator(deactivatedIndicator);
hgs
parents:
diff changeset
   222
}
hgs
parents:
diff changeset
   223
69
hgs
parents: 62
diff changeset
   224
/*!
hgs
parents: 62
diff changeset
   225
    @copydoc Screensaver::getActiveScreenRows
hgs
parents: 62
diff changeset
   226
 */
hgs
parents: 62
diff changeset
   227
void SnsrBigClockScreensaver::getActiveScreenRows(int *firstActiveRow, int *lastActiveRow)
hgs
parents: 62
diff changeset
   228
{
hgs
parents: 62
diff changeset
   229
    if ( mCurrentContainer ) {
hgs
parents: 62
diff changeset
   230
        mCurrentContainer->getActiveScreenRows( firstActiveRow, lastActiveRow );
hgs
parents: 62
diff changeset
   231
    }
hgs
parents: 62
diff changeset
   232
    else {
hgs
parents: 62
diff changeset
   233
        qWarning() << "No current container when active rows queried.";
hgs
parents: 62
diff changeset
   234
    }
hgs
parents: 62
diff changeset
   235
}
hgs
parents: 62
diff changeset
   236
hgs
parents: 62
diff changeset
   237
/*!
hgs
parents: 62
diff changeset
   238
    @copydoc Screensaver::updateLayout
hgs
parents: 62
diff changeset
   239
 */
hgs
parents: 62
diff changeset
   240
void SnsrBigClockScreensaver::updateLayout()
hgs
parents: 62
diff changeset
   241
{
hgs
parents: 62
diff changeset
   242
    if ( mCurrentContainer ) {
hgs
parents: 62
diff changeset
   243
        if ( mCurrentContainer->isOrientationLocked() ) {
hgs
parents: 62
diff changeset
   244
            mMainWindow->setOrientation( mMainWindow->orientation(), /*animate*/false );
hgs
parents: 62
diff changeset
   245
        }
hgs
parents: 62
diff changeset
   246
        else {
hgs
parents: 62
diff changeset
   247
            mMainWindow->unsetOrientation( /*animate*/false );
hgs
parents: 62
diff changeset
   248
        }
hgs
parents: 62
diff changeset
   249
        mCurrentContainer->changeLayout( mMainWindow->orientation() );
hgs
parents: 62
diff changeset
   250
    }
hgs
parents: 62
diff changeset
   251
    else {
hgs
parents: 62
diff changeset
   252
        qWarning() << "No current container when updateLayout called.";
hgs
parents: 62
diff changeset
   253
    }
hgs
parents: 62
diff changeset
   254
}
hgs
parents: 62
diff changeset
   255
hgs
parents: 62
diff changeset
   256
/*!
hgs
parents: 62
diff changeset
   257
    Update the area visible in the power save screen mode. Power save mode gets
hgs
parents: 62
diff changeset
   258
    also activated on call if not already active.
hgs
parents: 62
diff changeset
   259
 */
hgs
parents: 62
diff changeset
   260
void SnsrBigClockScreensaver::updateActiveAreaForLowPower()
hgs
parents: 62
diff changeset
   261
{
hgs
parents: 62
diff changeset
   262
    emit screenPowerModeRequested( Screensaver::ScreenModeLowPower );
hgs
parents: 62
diff changeset
   263
}
62
hgs
parents:
diff changeset
   264
hgs
parents:
diff changeset
   265
/*!
hgs
parents:
diff changeset
   266
    Determines the curent clock format settings.
hgs
parents:
diff changeset
   267
    \retval ClockFormat.
hgs
parents:
diff changeset
   268
 */
hgs
parents:
diff changeset
   269
SnsrBigClockScreensaver::ClockFormat SnsrBigClockScreensaver::clockFormat()
hgs
parents:
diff changeset
   270
{
hgs
parents:
diff changeset
   271
#ifdef Q_OS_SYMBIAN
hgs
parents:
diff changeset
   272
    if (TLocale().ClockFormat() == EClockAnalog) {
hgs
parents:
diff changeset
   273
        return ClockFormatAnalog;
hgs
parents:
diff changeset
   274
    } else {
hgs
parents:
diff changeset
   275
        return ClockFormatDigital;
hgs
parents:
diff changeset
   276
    }
hgs
parents:
diff changeset
   277
#else
hgs
parents:
diff changeset
   278
    // windows build - change the format every 30 seconds for testing purposes
hgs
parents:
diff changeset
   279
    if (QTime::currentTime().second() < 30) {
hgs
parents:
diff changeset
   280
        return ClockFormatAnalog;
hgs
parents:
diff changeset
   281
    } else {
hgs
parents:
diff changeset
   282
        return ClockFormatDigital;
hgs
parents:
diff changeset
   283
    }
hgs
parents:
diff changeset
   284
#endif // Q_OS_SYMBIAN
hgs
parents:
diff changeset
   285
}
hgs
parents:
diff changeset
   286
hgs
parents:
diff changeset
   287
void SnsrBigClockScreensaver::removeCurrentContainer()
hgs
parents:
diff changeset
   288
{
hgs
parents:
diff changeset
   289
    if ( mCurrentContainer ) {
hgs
parents:
diff changeset
   290
        disconnect(
hgs
parents:
diff changeset
   291
            &mTimer, SIGNAL(timeout()),
hgs
parents:
diff changeset
   292
            mCurrentContainer, SLOT(update())
hgs
parents:
diff changeset
   293
            );
hgs
parents:
diff changeset
   294
        disconnect( 
hgs
parents:
diff changeset
   295
            mCurrentContainer, SIGNAL(unlockRequested()), 
hgs
parents:
diff changeset
   296
            this, SIGNAL(unlockRequested()) );
69
hgs
parents: 62
diff changeset
   297
        if (mTimer.timerId()!= -1) {
hgs
parents: 62
diff changeset
   298
            mTimer.stop();
hgs
parents: 62
diff changeset
   299
        }
62
hgs
parents:
diff changeset
   300
        emit viewChanged(0);
hgs
parents:
diff changeset
   301
        
hgs
parents:
diff changeset
   302
        delete mCurrentContainer;
hgs
parents:
diff changeset
   303
        mCurrentContainer = 0;
hgs
parents:
diff changeset
   304
    }
69
hgs
parents: 62
diff changeset
   305
    
hgs
parents: 62
diff changeset
   306
    mMainWindow->unsetOrientation( /*animate*/false );
62
hgs
parents:
diff changeset
   307
}
hgs
parents:
diff changeset
   308
hgs
parents:
diff changeset
   309
void SnsrBigClockScreensaver::setCurrentContainer( SnsrBigClockContainer* newContainer )
hgs
parents:
diff changeset
   310
{
hgs
parents:
diff changeset
   311
    mCurrentContainer = newContainer;
69
hgs
parents: 62
diff changeset
   312
    mCurrentContainer->setParent(this);
62
hgs
parents:
diff changeset
   313
    connect( &mTimer, SIGNAL(timeout()), mCurrentContainer, SLOT(update()) );
hgs
parents:
diff changeset
   314
    connect( mCurrentContainer, SIGNAL(unlockRequested()), SIGNAL(unlockRequested()) );
69
hgs
parents: 62
diff changeset
   315
    connect( mCurrentContainer, SIGNAL(activeAreaMoved()), SLOT(updateActiveAreaForLowPower()) );
62
hgs
parents:
diff changeset
   316
69
hgs
parents: 62
diff changeset
   317
    mCurrentContainer->setIndicatorModel(*mIndicatorModel);
hgs
parents: 62
diff changeset
   318
hgs
parents: 62
diff changeset
   319
    int updateInterval = mCurrentContainer->updateIntervalInMilliseconds(); 
hgs
parents: 62
diff changeset
   320
    // blankcontainer is empty one, don't start timer with -1 return value
hgs
parents: 62
diff changeset
   321
    if ( updateInterval != -1) {
hgs
parents: 62
diff changeset
   322
        mTimer.start(updateInterval);
hgs
parents: 62
diff changeset
   323
    }
62
hgs
parents:
diff changeset
   324
    
69
hgs
parents: 62
diff changeset
   325
    
62
hgs
parents:
diff changeset
   326
    emit viewChanged(mCurrentContainer);
hgs
parents:
diff changeset
   327
}
hgs
parents:
diff changeset
   328