- Timestamp:
- Jan 18, 2007 6:56:16 PM (18 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox/ui
- Files:
-
- 2 edited
-
VBoxNewHDWzd.ui (modified) (20 diffs)
-
VBoxNewHDWzd.ui.h (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/ui/VBoxNewHDWzd.ui
r132 r169 28 28 <x>0</x> 29 29 <y>0</y> 30 <width>5 20</width>31 <height>4 00</height>30 <width>542</width> 31 <height>499</height> 32 32 </rect> 33 33 </property> … … 78 78 </property> 79 79 </widget> 80 <widget class="QLa bel">80 <widget class="QLayoutWidget"> 81 81 <property name="name"> 82 <cstring>txWelcome</cstring> 83 </property> 84 <property name="text"> 85 <string><p>This wizard will help you to create a new virtual hard disk image for your virtual machine.</p> 82 <cstring>layout33</cstring> 83 </property> 84 <vbox> 85 <property name="name"> 86 <cstring>unnamed</cstring> 87 </property> 88 <widget class="QLabel"> 89 <property name="name"> 90 <cstring>txWelcome</cstring> 91 </property> 92 <property name="sizePolicy"> 93 <sizepolicy> 94 <hsizetype>1</hsizetype> 95 <vsizetype>0</vsizetype> 96 <horstretch>0</horstretch> 97 <verstretch>0</verstretch> 98 </sizepolicy> 99 </property> 100 <property name="text"> 101 <string><p>This wizard will help you to create a new virtual hard disk image for your virtual machine.</p> 86 102 <p>Use the <b>Next</b> button to go to the next page of the wizard 87 103 and the <b>Back</b> button to return to the previous page.</p></string> 88 </property> 89 <property name="alignment"> 90 <set>WordBreak|AlignTop</set> 91 </property> 104 </property> 105 <property name="alignment"> 106 <set>WordBreak|AlignTop</set> 107 </property> 108 </widget> 109 <spacer> 110 <property name="name"> 111 <cstring>spacer30</cstring> 112 </property> 113 <property name="orientation"> 114 <enum>Vertical</enum> 115 </property> 116 <property name="sizeType"> 117 <enum>Expanding</enum> 118 </property> 119 <property name="sizeHint"> 120 <size> 121 <width>0</width> 122 <height>0</height> 123 </size> 124 </property> 125 </spacer> 126 </vbox> 92 127 </widget> 93 128 </hbox> … … 107 142 <number>20</number> 108 143 </property> 144 <property name="resizeMode"> 145 <enum>Minimum</enum> 146 </property> 109 147 <widget class="QLabel"> 110 148 <property name="name"> … … 141 179 <cstring>textLabel1_2</cstring> 142 180 </property> 181 <property name="sizePolicy"> 182 <sizepolicy> 183 <hsizetype>1</hsizetype> 184 <vsizetype>0</vsizetype> 185 <horstretch>0</horstretch> 186 <verstretch>0</verstretch> 187 </sizepolicy> 188 </property> 143 189 <property name="text"> 144 190 <string><p>Select the type of virtual hard disk image you want to create.</p> … … 150 196 </property> 151 197 <property name="alignment"> 152 <set>WordBreak|Align VCenter</set>198 <set>WordBreak|AlignTop</set> 153 199 </property> 154 200 </widget> … … 206 252 <property name="sizeHint"> 207 253 <size> 208 <width> 20</width>209 <height> 90</height>254 <width>0</width> 255 <height>0</height> 210 256 </size> 211 257 </property> … … 263 309 <cstring>txNameComment</cstring> 264 310 </property> 311 <property name="sizePolicy"> 312 <sizepolicy> 313 <hsizetype>1</hsizetype> 314 <vsizetype>0</vsizetype> 315 <horstretch>0</horstretch> 316 <verstretch>0</verstretch> 317 </sizepolicy> 318 </property> 265 319 <property name="text"> 266 320 <string><p>Press the <b>Select</b> button to select the location and name of the file … … 268 322 </property> 269 323 <property name="alignment"> 270 <set>WordBreak|Align VCenter</set>324 <set>WordBreak|AlignTop</set> 271 325 </property> 272 326 </widget> … … 319 373 <cstring>txSizeComment</cstring> 320 374 </property> 375 <property name="sizePolicy"> 376 <sizepolicy> 377 <hsizetype>1</hsizetype> 378 <vsizetype>0</vsizetype> 379 <horstretch>0</horstretch> 380 <verstretch>0</verstretch> 381 </sizepolicy> 382 </property> 321 383 <property name="text"> 322 384 <string><p>Select the size of the virtual hard disk image in megabytes. This size will be reported to the Guest OS … … 324 386 </property> 325 387 <property name="alignment"> 326 <set>WordBreak|Align VCenter</set>388 <set>WordBreak|AlignTop</set> 327 389 </property> 328 390 </widget> … … 482 544 <property name="sizeHint"> 483 545 <size> 484 <width> 20</width>485 <height> 20</height>546 <width>0</width> 547 <height>0</height> 486 548 </size> 487 549 </property> … … 505 567 <number>20</number> 506 568 </property> 569 <property name="resizeMode"> 570 <enum>Minimum</enum> 571 </property> 507 572 <widget class="QLabel"> 508 573 <property name="name"> … … 532 597 <cstring>unnamed</cstring> 533 598 </property> 599 <property name="spacing"> 600 <number>15</number> 601 </property> 534 602 <widget class="QLabel"> 535 603 <property name="name"> 536 604 <cstring>txSummaryHdr</cstring> 605 </property> 606 <property name="sizePolicy"> 607 <sizepolicy> 608 <hsizetype>1</hsizetype> 609 <vsizetype>0</vsizetype> 610 <horstretch>0</horstretch> 611 <verstretch>0</verstretch> 612 </sizepolicy> 537 613 </property> 538 614 <property name="text"> … … 540 616 </property> 541 617 <property name="alignment"> 542 <set>WordBreak|Align VCenter</set>618 <set>WordBreak|AlignTop</set> 543 619 </property> 544 620 </widget> … … 552 628 <vsizetype>5</vsizetype> 553 629 <horstretch>0</horstretch> 554 <verstretch> 1</verstretch>630 <verstretch>0</verstretch> 555 631 </sizepolicy> 556 632 </property> … … 568 644 <property name="name"> 569 645 <cstring>txSummaryFtr</cstring> 646 </property> 647 <property name="sizePolicy"> 648 <sizepolicy> 649 <hsizetype>1</hsizetype> 650 <vsizetype>0</vsizetype> 651 <horstretch>0</horstretch> 652 <verstretch>0</verstretch> 653 </sizepolicy> 570 654 </property> 571 655 <property name="text"> … … 574 658 </string> 575 659 </property> 660 <property name="alignment"> 661 <set>WordBreak|AlignTop</set> 662 </property> 576 663 </widget> 577 664 <spacer> … … 587 674 <property name="sizeHint"> 588 675 <size> 589 <width> 20</width>590 <height> 20</height>676 <width>0</width> 677 <height>0</height> 591 678 </size> 592 679 </property> … … 631 718 <include location="global" impldecl="in implementation">qvalidator.h</include> 632 719 <include location="global" impldecl="in implementation">qlocale.h</include> 633 <include location="local" impldecl="in implementation">math.h</include>634 720 </includes> 635 721 <variables> 636 722 <variable access="private">QIWidgetValidator *wvalNameAndSize;</variable> 637 723 <variable access="private">CHardDisk chd;</variable> 638 <variable access="private">int sliderS tep;</variable>639 <variable access="private">Q_UINT64 MaxVDISize;</variable>724 <variable access="private">int sliderScale;</variable> 725 <variable access="private">Q_UINT64 maxVDISize;</variable> 640 726 <variable access="private">Q_UINT64 currentSize;</variable> 641 727 </variables> … … 650 736 <function access="private">init()</function> 651 737 <function>setRecommendedFileName( const QString & aName )</function> 652 <function>setRecommendedSize( ulongaSize )</function>738 <function>setRecommendedSize( Q_UINT64 aSize )</function> 653 739 <function returnType="QString">imageFileName()</function> 654 740 <function returnType="Q_UINT64">imageSize()</function> 655 741 <function returnType="bool">isDynamicImage()</function> 656 742 <function returnType="CHardDisk">hardDisk() { return chd; }</function> 743 <function>showPage( QWidget * page )</function> 744 <function>updateSizeToolTip (Q_UINT64)</function> 657 745 <function>accept()</function> 658 746 <function access="private" returnType="bool">createHardDisk()</function> 659 <function>showPage( QWidget * page )</function>660 747 </functions> 661 748 <pixmapinproject/> -
trunk/src/VBox/Frontends/VirtualBox/ui/VBoxNewHDWzd.ui.h
r132 r169 33 33 *****************************************************************************/ 34 34 35 static const int MinVDISize = 4; 35 /** Minimum VDI size in MB */ 36 static const Q_UINT64 MinVDISize = 4; 37 38 /** Initial VDI size in MB */ 39 static const Q_UINT64 InitialVDISize = 2 * _1K; 36 40 37 41 /** … … 48 52 if (fi.fileName() == file) 49 53 { 50 / / no path info at all, use defaultFolder54 /* no path info at all, use defaultFolder */ 51 55 fi = QFileInfo (defaultFolder, file); 52 56 } 53 57 else if (fi.isRelative()) 54 58 { 55 / / resolve relatively to homeFolder59 /* resolve relatively to homeFolder */ 56 60 fi = QFileInfo (homeFolder, file); 57 61 } … … 60 64 } 61 65 62 66 /// @todo (r=dmik) not currently used 67 #if 0 63 68 class QISizeValidator : public QValidator 64 69 { 65 70 public: 66 QISizeValidator (QObject * aParent, ULONG64 aMinSize, ULONG64 aMaxSize, 71 72 QISizeValidator (QObject * aParent, 73 Q_UINT64 aMinSize, Q_UINT64 aMaxSize, 67 74 const char * aName = 0) : 68 QValidator (aParent, aName), mMinSize (aMinSize), mMaxSize(aMaxSize) {}75 QValidator (aParent, aName), mMinSize (aMinSize), mMaxSize (aMaxSize) {} 69 76 70 77 ~QISizeValidator() {} … … 100 107 QLocale::system().toDouble (size, &result); 101 108 102 ULONG64 sizeMB = vboxGlobal().parseSize (input) / _1M;103 if (size MB > mMaxSize || sizeMB < mMinSize)109 Q_UINT64 sizeB = vboxGlobal().parseSize (input); 110 if (sizeB > mMaxSize || sizeB < mMinSize) 104 111 warning = true; 105 112 … … 112 119 113 120 protected: 114 ULONG64 mMinSize; 115 ULONG64 mMaxSize; 121 122 Q_UINT64 mMinSize; 123 Q_UINT64 mMaxSize; 116 124 }; 117 125 #endif 126 127 static inline int log2i (Q_UINT64 val) 128 { 129 Q_UINT64 n = val; 130 int pow = -1; 131 while (n) 132 { 133 ++ pow; 134 n >>= 1; 135 } 136 return pow; 137 } 138 139 static inline int sizeMBToSlider (Q_UINT64 val, int sliderScale) 140 { 141 int pow = log2i (val); 142 Q_UINT64 tickMB = Q_UINT64 (1) << pow; 143 Q_UINT64 tickMBNext = Q_UINT64 (1) << (pow + 1); 144 int step = (val - tickMB) * sliderScale / (tickMBNext - tickMB); 145 return pow * sliderScale + step; 146 } 147 148 static inline Q_UINT64 sliderToSizeMB (int val, int sliderScale) 149 { 150 int pow = val / sliderScale; 151 int step = val % sliderScale; 152 Q_UINT64 tickMB = Q_UINT64 (1) << pow; 153 Q_UINT64 tickMBNext = Q_UINT64 (1) << (pow + 1); 154 return tickMB + (tickMBNext - tickMB) * step / sliderScale; 155 } 118 156 119 157 void VBoxNewHDWzd::init() 120 158 { 121 / / disable help buttons122 helpButton()->setShown ( false);123 124 / /fix tab order to get the proper direction125 // (originally the focus goes Next/Finish -> Back -> Cancel -> page)126 QWidget::setTabOrder ( backButton(), nextButton());127 QWidget::setTabOrder ( nextButton(), finishButton());128 QWidget::setTabOrder ( finishButton(), cancelButton());129 130 / /setup connections and set validation for pages131 // ----------------------------------------------------------------------132 133 / / Image type page134 135 / / Name and Size page159 /* disable help buttons */ 160 helpButton()->setShown (false); 161 162 /* fix tab order to get the proper direction 163 * (originally the focus goes Next/Finish -> Back -> Cancel -> page) */ 164 QWidget::setTabOrder (backButton(), nextButton()); 165 QWidget::setTabOrder (nextButton(), finishButton()); 166 QWidget::setTabOrder (finishButton(), cancelButton()); 167 168 /* setup connections and set validation for pages 169 * ---------------------------------------------------------------------- */ 170 171 /* Image type page */ 172 173 /* Name and Size page */ 136 174 137 175 CSystemProperties sysProps = vboxGlobal().virtualBox().GetSystemProperties(); 138 176 139 MaxVDISize = sysProps.GetMaxVDISize(); 177 maxVDISize = sysProps.GetMaxVDISize(); 178 179 /* Detect how many steps to recognize between adjacent powers of 2 180 * to ensure that the last slider step is exactly maxVDISize */ 181 sliderScale = 0; 182 { 183 int pow = log2i (maxVDISize); 184 Q_UINT64 tickMB = Q_UINT64 (1) << pow; 185 if (tickMB < maxVDISize) 186 { 187 Q_UINT64 tickMBNext = Q_UINT64 (1) << (pow + 1); 188 Q_UINT64 gap = tickMBNext - maxVDISize; 189 /// @todo (r=dmik) overflow may happen if maxVDISize is TOO big 190 sliderScale = (int) ((tickMBNext - tickMB) / gap); 191 } 192 } 193 sliderScale = QMAX (sliderScale, 8); 140 194 141 195 leName->setValidator (new QRegExpValidator (QRegExp( ".+" ), this)); 142 196 143 leSize->setValidator (new Q ISizeValidator (this, MinVDISize, MaxVDISize));197 leSize->setValidator (new QRegExpValidator (vboxGlobal().sizeRegexp(), this)); 144 198 leSize->setAlignment (Qt::AlignRight); 145 199 146 wvalNameAndSize = new QIWidgetValidator (pageNameAndSize, this ); 147 connect( 148 wvalNameAndSize, SIGNAL( validityChanged (const QIWidgetValidator *) ), 149 this, SLOT( enableNext (const QIWidgetValidator *) ) 150 ); 151 152 // Summary page 153 154 // filter out Enter keys in order to direct them to the default dlg button 200 wvalNameAndSize = new QIWidgetValidator (pageNameAndSize, this); 201 connect (wvalNameAndSize, SIGNAL (validityChanged (const QIWidgetValidator *)), 202 this, SLOT (enableNext (const QIWidgetValidator *))); 203 connect (wvalNameAndSize, SIGNAL (isValidRequested (QIWidgetValidator *)), 204 this, SLOT (revalidate (QIWidgetValidator *))); 205 /* we ask revalidate only when currentSize is changed after manually 206 * editing the line edit field; the slider cannot produce invalid values */ 207 connect (leSize, SIGNAL (textChanged (const QString &)), 208 wvalNameAndSize, SLOT (revalidate())); 209 210 /* Summary page */ 211 212 /* filter out Enter keys in order to direct them to the default dlg button */ 155 213 QIKeyFilter *ef = new QIKeyFilter (this, Key_Enter); 156 ef->watchOn (teSummary) ;157 158 / /set initial values159 // ----------------------------------------------------------------------160 161 / / Image type page162 163 / / Name and Size page214 ef->watchOn (teSummary); 215 216 /* set initial values 217 * ---------------------------------------------------------------------- */ 218 219 /* Image type page */ 220 221 /* Name and Size page */ 164 222 165 223 static ulong HDNumber = 0; 166 224 leName->setText (QString ("NewHardDisk%1.vdi").arg (++ HDNumber)); 167 225 168 sliderStep = 50;169 226 slSize->setFocusPolicy (QWidget::StrongFocus); 170 slSize->setPageStep (sliderS tep);171 slSize->setLineStep (sliderS tep);227 slSize->setPageStep (sliderScale); 228 slSize->setLineStep (sliderScale / 8); 172 229 slSize->setTickInterval (0); 173 slSize->setMinValue ((int)(log10 ((double)MinVDISize) / log10 (2.0) * sliderStep)); 174 slSize->setMaxValue ((int)(log10 ((double)(MaxVDISize + 1)) / log10 (2.0) * sliderStep)); 230 slSize->setMinValue (sizeMBToSlider (MinVDISize, sliderScale)); 231 slSize->setMaxValue (sizeMBToSlider (maxVDISize, sliderScale)); 232 175 233 txSizeMin->setText (vboxGlobal().formatSize (MinVDISize * _1M)); 176 txSizeMax->setText (vboxGlobal().formatSize (MaxVDISize * _1M)); 177 // initial HD size value = pow(2.0, 11) = 2048 MB 178 currentSize = 2 * _1K; 234 txSizeMax->setText (vboxGlobal().formatSize (maxVDISize * _1M)); 235 236 /* limit the max. size of QLineEdit (STUPID Qt has NO correct means for that) */ 237 leSize->setMaximumSize ( 238 leSize->fontMetrics().width ("88888.88 MB") + leSize->frameWidth() * 2, 239 leSize->height()); 240 241 setRecommendedSize (InitialVDISize); 242 243 /* Summary page */ 244 245 teSummary->setPaper (pageSummary->backgroundBrush()); 246 247 /* update the next button state for pages with validation 248 * (validityChanged() connected to enableNext() will do the job) */ 249 wvalNameAndSize->revalidate(); 250 251 /* the finish button on the Summary page is always enabled */ 252 setFinishEnabled (pageSummary, true); 253 } 254 255 256 void VBoxNewHDWzd::setRecommendedFileName (const QString &aName) 257 { 258 leName->setText (aName); 259 } 260 261 262 void VBoxNewHDWzd::setRecommendedSize (Q_UINT64 aSize) 263 { 264 AssertReturnVoid (aSize >= MinVDISize && aSize <= maxVDISize); 265 currentSize = aSize; 266 slSize->setValue (sizeMBToSlider (currentSize, sliderScale)); 179 267 leSize->setText (vboxGlobal().formatSize (currentSize * _1M)); 180 slSize->setValue ((int)(log10 ((double)currentSize) / log10 (2.0) * sliderStep)); 181 // limit the max. size of QLineEdit (STUPID Qt has NO correct means for that) 182 leSize->setMaximumSize( 183 leSize->fontMetrics().width ("88888.88 MB") + leSize->frameWidth() * 2, 184 leSize->height() 185 ); 186 187 // Summary page 188 189 teSummary->setPaper (pageSummary->backgroundBrush()); 190 191 // update the next button state for pages with validation 192 // (validityChanged() connected to enableNext() will do the job) 193 wvalNameAndSize->revalidate(); 194 195 // the finish button on the Summary page is always enabled 196 setFinishEnabled (pageSummary, true); 197 } 198 199 200 void VBoxNewHDWzd::setRecommendedFileName (const QString &aName) 201 { 202 leName->setText (aName); 203 } 204 205 206 void VBoxNewHDWzd::setRecommendedSize (ulong aSize) 207 { 208 AssertReturn (aSize >= (ulong) MinVDISize && 209 aSize <= (ulong) MaxVDISize, (void) 0); 210 currentSize = aSize; 211 slSize->setValue ((int)(log10 ((double)currentSize) / log10 (2.0) * sliderStep)); 212 leSize->setText (vboxGlobal().formatSize(aSize * _1M)); 268 updateSizeToolTip (currentSize * _1M); 213 269 } 214 270 … … 223 279 224 280 225 Q_UINT64 VBoxNewHDWzd::imageSize()281 ULONG64 VBoxNewHDWzd::imageSize() 226 282 { 227 283 return currentSize; … … 235 291 236 292 237 void VBoxNewHDWzd::enableNext ( const QIWidgetValidator *wval)293 void VBoxNewHDWzd::enableNext (const QIWidgetValidator *wval) 238 294 { 239 295 setNextEnabled (wval->widget(), wval->isValid()); … … 241 297 242 298 243 void VBoxNewHDWzd::revalidate( QIWidgetValidator * /*wval*/ ) 244 { 245 // do individual validations for pages 246 247 // template: 248 // QWidget *pg = wval->widget(); 249 // bool valid = wval->isOtherValid(); 250 // 251 // if ( pg == pageXXX ) { 252 // valid = XXX; 253 // } 254 // 255 // wval->setOtherValid( valid ); 256 } 257 299 void VBoxNewHDWzd::revalidate (QIWidgetValidator *wval) 300 { 301 /* do individual validations for pages */ 302 303 QWidget *pg = wval->widget(); 304 bool valid = wval->isOtherValid(); 305 306 if (pg == pageNameAndSize) 307 { 308 valid = currentSize >= MinVDISize && currentSize <= maxVDISize; 309 } 310 311 wval->setOtherValid (valid); 312 } 313 314 315 void VBoxNewHDWzd::updateSizeToolTip (Q_UINT64 sizeB) 316 { 317 QString tip = tr ("<nobr>%1 Bytes</nobr>").arg (sizeB); 318 QToolTip::add (slSize, tip); 319 QToolTip::add (leSize, tip); 320 } 258 321 259 322 void VBoxNewHDWzd::showPage( QWidget *page ) … … 274 337 type.remove ('&'); 275 338 339 Q_UINT64 sizeB = imageSize() * _1M; 340 276 341 // compose summary 277 342 QString summary = QString (tr( … … 279 344 "<tr><td>Type:</td><td>%1</td></tr>" 280 345 "<tr><td>Location:</td><td>%2</td></tr>" 281 "<tr><td>Size:</td><td>%3 MB</td></tr>"346 "<tr><td>Size:</td><td>%3 (%4 Bytes)</td></tr>" 282 347 "</table>" 283 348 )) 284 349 .arg (type) 285 350 .arg (composeFullFileName (imageFileName())) 286 .arg (imageSize()); 351 .arg (VBoxGlobal::formatSize (sizeB)) 352 .arg (sizeB); 287 353 teSummary->setText (summary); 288 / / set Finish to default354 /* set Finish to default */ 289 355 finishButton()->setDefault (true); 290 356 } 291 357 else 292 358 { 293 / / always set Next to default359 /* always set Next to default */ 294 360 nextButton()->setDefault (true); 295 361 } … … 297 363 QWizard::showPage (page); 298 364 299 / /fix focus on the last page. when we go to the last page300 //having the Next in focus the focus goes to the Cancel301 // button because when the Next hides Finish is not yet shown.365 /* fix focus on the last page. when we go to the last page 366 * having the Next in focus the focus goes to the Cancel 367 * button because when the Next hides Finish is not yet shown. */ 302 368 if (page == pageSummary && focusWidget() == cancelButton()) 303 369 finishButton()->setFocus(); 304 370 305 // setup focus for individual pages 306 if (page == pageType) { 371 /* setup focus for individual pages */ 372 if (page == pageType) 373 { 307 374 bgType->setFocus(); 308 } else if (page == pageNameAndSize) { 375 } 376 else if (page == pageNameAndSize) 377 { 309 378 leName->setFocus(); 310 } else if (page == pageSummary) { 379 } 380 else if (page == pageSummary) 381 { 311 382 teSummary->setFocus(); 312 383 } 313 384 } 385 314 386 315 387 void VBoxNewHDWzd::accept() … … 395 467 if (focusWidget() == slSize) 396 468 { 397 currentSize = (ULONG64)(pow (2.0, ((double)val / sliderStep)));469 currentSize = sliderToSizeMB (val, sliderScale); 398 470 leSize->setText (vboxGlobal().formatSize (currentSize * _1M)); 471 updateSizeToolTip (currentSize * _1M); 399 472 } 400 473 } … … 405 478 if (focusWidget() == leSize) 406 479 { 407 currentSize = vboxGlobal().parseSize (text) / _1M; 408 slSize->setValue ((int)(log10 ((double)currentSize) / log10 (2.0) * sliderStep)); 480 currentSize = vboxGlobal().parseSize (text); 481 updateSizeToolTip (currentSize); 482 currentSize /= _1M; 483 slSize->setValue (sizeMBToSlider (currentSize, sliderScale)); 409 484 } 410 485 } … … 413 488 void VBoxNewHDWzd::tbNameSelect_clicked() 414 489 { 415 / / set the first parent directory that exists as the current490 /* set the first parent directory that exists as the current */ 416 491 QFileInfo fld (composeFullFileName (leName->text())); 417 492 do
Note:
See TracChangeset
for help on using the changeset viewer.

