ソースを参照

Merge remote-tracking branch 'sankhesh/screeshot-resolution'

* sankhesh/screeshot-resolution:
  Added option to allow/disallow transparency in screenshot
  Added screenshot output resolution support
  Tweak ctkFileDialog to better handle return key
  Cleanup ctkThumbnailListWidget and ctkDICOMThumbnailListWidget
Steve Pieper 12 年 前
コミット
c7741eaca6

+ 3 - 3
Libs/DICOM/Widgets/Testing/Cpp/ctkDICOMThumbnailListWidgetTest1.cpp

@@ -44,7 +44,8 @@ int ctkDICOMThumbnailListWidgetTest1( int argc, char * argv [] )
 
   try
     {
-    ctkDICOMDatabase myCTK( argv[1] );
+    QFileInfo databasePath(QString(argv[1]));
+    ctkDICOMDatabase myCTK( databasePath.absoluteFilePath() );
 
     if (!myCTK.initializeDatabase(argv[2]))
       {
@@ -56,8 +57,7 @@ int ctkDICOMThumbnailListWidgetTest1( int argc, char * argv [] )
     model.setDatabase(myCTK.database());
 
     ctkDICOMThumbnailListWidget widget;
-    //widget.setDatabaseDirectory(QDir::currentPath());
-    widget.setDatabaseDirectory("E:\\work\\CTK\\CTK-VTK-64\\CTK-build\\Libs\\DICOM\\Widgets\\Testing\\Cpp");
+    widget.setDatabaseDirectory(databasePath.absolutePath());
     widget.addThumbnails(model.index(0,0));
     widget.show();
 

+ 2 - 6
Libs/DICOM/Widgets/ctkDICOMThumbnailListWidget.cpp

@@ -94,7 +94,6 @@ ctkDICOMThumbnailListWidgetPrivate
 void ctkDICOMThumbnailListWidgetPrivate
 ::addPatientThumbnails(const QModelIndex &index)
 {
-  Q_Q(ctkDICOMThumbnailListWidget);
   QModelIndex patientIndex = index;
 
   ctkDICOMModel* model = const_cast<ctkDICOMModel*>(
@@ -122,7 +121,6 @@ void ctkDICOMThumbnailListWidgetPrivate
 void ctkDICOMThumbnailListWidgetPrivate
 ::addStudyThumbnails(const QModelIndex &index)
 {
-  Q_Q(ctkDICOMThumbnailListWidget);
   QModelIndex studyIndex = index;
 
   ctkDICOMModel* model = const_cast<ctkDICOMModel*>(qobject_cast<const ctkDICOMModel*>(index.model()));
@@ -148,7 +146,6 @@ void ctkDICOMThumbnailListWidgetPrivate
 void ctkDICOMThumbnailListWidgetPrivate
 ::addSeriesThumbnails(const QModelIndex &index)
 {
-  Q_Q(ctkDICOMThumbnailListWidget);
   QModelIndex studyIndex = index.parent();
   QModelIndex seriesIndex = index;
 
@@ -175,9 +172,8 @@ void ctkDICOMThumbnailListWidgetPrivate
 ::addThumbnailWidget(const QModelIndex& imageIndex,
                      const QModelIndex& sourceIndex, const QString &text)
 {
-  Q_Q(ctkDICOMThumbnailListWidget);
-
-  ctkDICOMModel* model = const_cast<ctkDICOMModel*>(qobject_cast<const ctkDICOMModel*>(imageIndex.model()));
+  ctkDICOMModel* model = const_cast<ctkDICOMModel*>(
+    qobject_cast<const ctkDICOMModel*>(imageIndex.model()));
 
   if(!model)
     {

BIN
Libs/Widgets/Resources/Icons/lock.png


BIN
Libs/Widgets/Resources/Icons/unlock.png


+ 154 - 78
Libs/Widgets/Resources/UI/ctkScreenshotDialog.ui

@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>704</width>
-    <height>235</height>
+    <width>579</width>
+    <height>334</height>
    </rect>
   </property>
   <property name="sizePolicy">
@@ -19,8 +19,72 @@
   <property name="windowTitle">
    <string>Screen Capture Options</string>
   </property>
-  <layout class="QVBoxLayout" name="verticalLayout">
-   <item>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="2" column="0">
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QLabel" name="CountDownLabel">
+       <property name="text">
+        <string>0 s</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QLabel" name="ImageFullNameLabel">
+       <property name="text">
+        <string>Untitled_0.png</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_2">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="QDialogButtonBox" name="ButtonBox">
+       <property name="standardButtons">
+        <set>QDialogButtonBox::Close|QDialogButtonBox::Ok</set>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item row="1" column="0">
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>0</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item row="0" column="0">
     <widget class="QGroupBox" name="OptionGroupBox">
      <property name="enabled">
       <bool>false</bool>
@@ -34,7 +98,7 @@
      <property name="title">
       <string>Options</string>
      </property>
-     <layout class="QFormLayout" name="formLayout">
+     <layout class="QGridLayout" name="gridLayout_2">
       <item row="0" column="0">
        <widget class="QLabel" name="DirectoryLabel">
         <property name="text">
@@ -43,7 +107,7 @@
        </widget>
       </item>
       <item row="0" column="1">
-       <widget class="ctkDirectoryButton" name="DirectoryButton">
+       <widget class="ctkPathLineEdit" name="DirectoryPathLineEdit" native="true">
         <property name="toolTip">
          <string>Select a directory in which screen captures will be saved.</string>
         </property>
@@ -77,10 +141,13 @@
        <widget class="QSpinBox" name="ImageVersionNumberSpinBox"/>
       </item>
       <item row="3" column="0">
-       <widget class="QLabel" name="ScaleFactorLabel">
+       <widget class="QRadioButton" name="ScaleFactorRadioButton">
         <property name="text">
          <string>Scale factor:</string>
         </property>
+        <property name="checked">
+         <bool>true</bool>
+        </property>
        </widget>
       </item>
       <item row="3" column="1">
@@ -105,28 +172,99 @@
         </property>
        </widget>
       </item>
-      <item row="4" column="0">
+      <item row="4" column="0" colspan="2">
+       <layout class="QHBoxLayout" name="horizontalLayout_2">
+        <item>
+         <widget class="QRadioButton" name="OutputResolutionRadioButton">
+          <property name="text">
+           <string>Output resolution:</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QSpinBox" name="WidthSpinBox">
+          <property name="toolTip">
+           <string>Width of the screenshot</string>
+          </property>
+          <property name="suffix">
+           <string> px</string>
+          </property>
+          <property name="minimum">
+           <number>1</number>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QLabel" name="xLabel">
+          <property name="text">
+           <string>x</string>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignCenter</set>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QSpinBox" name="HeightSpinBox">
+          <property name="toolTip">
+           <string>Height of the screenshot</string>
+          </property>
+          <property name="suffix">
+           <string> px</string>
+          </property>
+          <property name="minimum">
+           <number>1</number>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QToolButton" name="LockAspectToolButton">
+          <property name="enabled">
+           <bool>false</bool>
+          </property>
+          <property name="toolTip">
+           <string>Lock/unlock aspect ratio</string>
+          </property>
+          <property name="icon">
+           <iconset resource="../ctkWidgets.qrc">
+            <normaloff>:/Icons/unlock.png</normaloff>
+            <normalon>:/Icons/lock.png</normalon>:/Icons/unlock.png</iconset>
+          </property>
+          <property name="checkable">
+           <bool>true</bool>
+          </property>
+          <property name="checked">
+           <bool>false</bool>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+      <item row="5" column="0">
        <widget class="QLabel" name="OverwriteLabel">
         <property name="text">
          <string>Overwrite:</string>
         </property>
        </widget>
       </item>
-      <item row="4" column="1">
+      <item row="5" column="1">
        <widget class="QCheckBox" name="OverwriteCheckBox">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
         <property name="text">
          <string/>
         </property>
        </widget>
       </item>
-      <item row="5" column="0">
+      <item row="6" column="0">
        <widget class="QLabel" name="DelayLabel">
         <property name="text">
          <string>Screenshot delay:</string>
         </property>
        </widget>
       </item>
-      <item row="5" column="1">
+      <item row="6" column="1">
        <widget class="QSpinBox" name="DelaySpinBox">
         <property name="suffix">
          <string> s</string>
@@ -139,80 +277,18 @@
      </layout>
     </widget>
    </item>
-   <item>
-    <spacer name="verticalSpacer">
-     <property name="orientation">
-      <enum>Qt::Vertical</enum>
-     </property>
-     <property name="sizeHint" stdset="0">
-      <size>
-       <width>20</width>
-       <height>0</height>
-      </size>
-     </property>
-    </spacer>
-   </item>
-   <item>
-    <layout class="QHBoxLayout" name="horizontalLayout">
-     <item>
-      <widget class="QLabel" name="CountDownLabel">
-       <property name="text">
-        <string>0 s</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <spacer name="horizontalSpacer">
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>40</width>
-         <height>20</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-     <item>
-      <widget class="QLabel" name="ImageFullNameLabel">
-       <property name="text">
-        <string>Untitled_0.png</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <spacer name="horizontalSpacer_2">
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>40</width>
-         <height>20</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-     <item>
-      <widget class="QDialogButtonBox" name="ButtonBox">
-       <property name="standardButtons">
-        <set>QDialogButtonBox::Close|QDialogButtonBox::Ok</set>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
   </layout>
  </widget>
  <customwidgets>
   <customwidget>
-   <class>ctkDirectoryButton</class>
+   <class>ctkPathLineEdit</class>
    <extends>QWidget</extends>
-   <header>ctkDirectoryButton.h</header>
+   <header>ctkPathLineEdit.h</header>
   </customwidget>
  </customwidgets>
- <resources/>
+ <resources>
+  <include location="../ctkWidgets.qrc"/>
+ </resources>
  <connections>
   <connection>
    <sender>ButtonBox</sender>

+ 2 - 1
Libs/Widgets/Resources/ctkWidgets.qrc

@@ -1,6 +1,8 @@
 <RCC>
     <qresource prefix="/">
         <file>Icons/edit.png</file>
+        <file>Icons/lock.png</file>
+        <file>Icons/unlock.png</file>
         <file>Icons/minus.png</file>
         <file>Icons/plus.png</file>
         <file>Icons/expand-down.png</file>
@@ -234,7 +236,6 @@
         <file>Icons/Languages/ua.png</file>
         <file>Icons/Languages/ug.png</file>
         <file>Icons/Languages/um.png</file>
-        <file>Icons/Languages/us.png</file>
         <file>Icons/Languages/uy.png</file>
         <file>Icons/Languages/uz.png</file>
         <file>Icons/Languages/va.png</file>

+ 17 - 0
Libs/Widgets/ctkFileDialog.cpp

@@ -24,6 +24,7 @@
 #include <QEvent>
 #include <QGridLayout>
 #include <QLabel>
+#include <QLineEdit>
 #include <QListView>
 #include <QPushButton>
 
@@ -187,3 +188,19 @@ void ctkFileDialog::onSelectionChanged()
 {
   emit this->fileSelectionChanged(this->selectedFiles());
 }
+
+//------------------------------------------------------------------------------
+void ctkFileDialog::accept()
+{
+  QLineEdit* fileNameEdit = qobject_cast<QLineEdit*>(this->sender());
+  if (fileNameEdit)
+    {
+    QFileInfo info(fileNameEdit->text());
+    if (info.isDir())
+      {
+      setDirectory(info.absoluteFilePath());
+      return;
+      }
+    }
+  this->Superclass::accept();
+}

+ 8 - 1
Libs/Widgets/ctkFileDialog.h

@@ -34,7 +34,10 @@ class ctkFileDialogPrivate;
 /// Customizable QFileDialog.
 /// An extra widget can be added at the bottom of the dialog
 /// under the file format combobox. The Accept button is also controllable
-/// using setAcceptButtonEnable()
+/// using setAcceptButtonEnable().
+/// The behavior of the "return" key is the following:
+///  - it selects the directory written in the line edit or it
+///  - it accepts the dialog if the directory is already selected.
 class CTK_WIDGETS_EXPORT ctkFileDialog : public QFileDialog
 {
   Q_OBJECT
@@ -61,6 +64,7 @@ public:
 
   /// Internally used
   bool eventFilter(QObject *obj, QEvent *event);
+
 public Q_SLOTS:
   /// Can be used to prevent the accept button to be enabled. It's typically
   /// a slot that can be connected to assure that the user doesn't accept the
@@ -79,6 +83,9 @@ protected Q_SLOTS:
 protected:
   QScopedPointer<ctkFileDialogPrivate> d_ptr;
 
+  /// Reimplemented to override the return key behavior
+  virtual void accept();
+
 private:
   Q_DECLARE_PRIVATE(ctkFileDialog);
   Q_DISABLE_COPY(ctkFileDialog);

+ 144 - 7
Libs/Widgets/ctkScreenshotDialog.cpp

@@ -36,6 +36,8 @@ ctkScreenshotDialogPrivate::ctkScreenshotDialogPrivate(ctkScreenshotDialog& obje
 {
   this->CaptureButton = 0;
   this->CountDownValue = 0;
+  this->AspectRatio = 1.0;
+  this->AllowTransparency = true;
 }
 
 //-----------------------------------------------------------------------------
@@ -68,11 +70,20 @@ void ctkScreenshotDialogPrivate::setupUi(QDialog * widget)
   connect(this->ImageVersionNumberSpinBox, SIGNAL(valueChanged(int)), SLOT(updateFullNameLabel()));
   connect(this->DelaySpinBox, SIGNAL(valueChanged(int)), SLOT(resetCountDownValue()));
   connect(&this->CountDownTimer, SIGNAL(timeout()), SLOT(updateCountDown()));
+  connect(this->ScaleFactorRadioButton, SIGNAL(toggled(bool)), SLOT(selectScaleFactor(bool)));
+  connect(this->OutputResolutionRadioButton, SIGNAL(toggled(bool)), SLOT(selectOutputResolution(bool)));
+  connect(this->LockAspectToolButton, SIGNAL(toggled(bool)), SLOT(lockAspectRatio(bool)));
+  connect(this->WidthSpinBox, SIGNAL(editingFinished()), SLOT(onWidthEdited()));
+  connect(this->HeightSpinBox, SIGNAL(editingFinished()), SLOT(onHeightEdited()));
 
   this->CaptureButton = okButton;
 
   // Called to enable/disable buttons
   q->setWidgetToGrab(0);
+  // Set a sufficient range (1, 2^16) on the spin boxes
+  this->WidthSpinBox->setRange(1, 65536);
+  this->HeightSpinBox->setRange(1, 65536);
+  this->DirectoryPathLineEdit->setFilters(ctkPathLineEdit::Dirs);
 }
 
 //-----------------------------------------------------------------------------
@@ -123,6 +134,113 @@ void ctkScreenshotDialogPrivate::updateCountDown()
 }
 
 //-----------------------------------------------------------------------------
+void ctkScreenshotDialogPrivate::useScalarFactor(bool scale)
+{
+  this->ScaleFactorSpinBox->setEnabled(scale);
+  this->WidthSpinBox->setEnabled(!scale);
+  this->HeightSpinBox->setEnabled(!scale);
+  this->xLabel->setEnabled(!scale);
+  this->LockAspectToolButton->setEnabled(!scale);
+}
+
+//-----------------------------------------------------------------------------
+void ctkScreenshotDialogPrivate::selectScaleFactor(bool scale)
+{
+  this->useScalarFactor(scale);
+}
+
+//-----------------------------------------------------------------------------
+void ctkScreenshotDialogPrivate::selectOutputResolution(bool scale)
+{
+  this->useScalarFactor(!scale);
+}
+
+//-----------------------------------------------------------------------------
+void ctkScreenshotDialogPrivate::lockAspectRatio(bool lock)
+{
+  Q_Q(ctkScreenshotDialog);
+  if(lock)
+    {
+    QSize curSize = q->widgetSize();
+    if(curSize.height() > 0)
+      {
+      this->AspectRatio = curSize.width()/static_cast<double>(curSize.height());
+      }
+    else
+      {
+      QString message = QString("Height of widget: ") + curSize.height() +\
+        QString(" is invalid. Check widget dimensions. Using default aspect\
+          ratio (1.0).");
+      QMessageBox::warning(q, "Invalid widget dimensions", message,
+        QMessageBox::Ok);
+      this->AspectRatio = 1.0;
+      }
+    }
+}
+
+//-----------------------------------------------------------------------------
+void ctkScreenshotDialogPrivate::onWidthEdited()
+{
+  Q_Q(ctkScreenshotDialog);
+  if(this->LockAspectToolButton->isChecked())
+    {
+    if(this->AspectRatio > 0)
+      {
+      this->HeightSpinBox->setValue(static_cast<int>(this->WidthSpinBox->value()/this->AspectRatio));
+      }
+    else
+      {
+      QString message = QString("Aspect ratio: ") + this->AspectRatio +\
+        QString(" is invalid. Check widget dimensions.");
+      QMessageBox::warning(q, "Invalid aspect ratio", message, QMessageBox::Ok);
+      }
+    }
+}
+
+//-----------------------------------------------------------------------------
+void ctkScreenshotDialogPrivate::onHeightEdited()
+{
+  if(this->LockAspectToolButton->isChecked())
+    {
+    this->WidthSpinBox->setValue(static_cast<int>(this->HeightSpinBox->value()*this->AspectRatio));
+    }
+}
+
+//-----------------------------------------------------------------------------
+void ctkScreenshotDialog::enforceResolution(int width, int height)
+{
+  Q_D(ctkScreenshotDialog);
+  d->OutputResolutionRadioButton->setChecked(true);
+  d->useScalarFactor(true);
+  d->ScaleFactorRadioButton->setEnabled(false);
+  d->OutputResolutionRadioButton->setEnabled(false);
+  d->ScaleFactorSpinBox->setEnabled(false);
+  d->WidthSpinBox->setValue(width);
+  d->HeightSpinBox->setValue(height);
+}
+
+//-----------------------------------------------------------------------------
+void ctkScreenshotDialog::enforceResolution(QSize size)
+{
+  this->enforceResolution(size.width(), size.height());
+}
+
+//-----------------------------------------------------------------------------
+QSize ctkScreenshotDialog::widgetSize()
+{
+  Q_D(ctkScreenshotDialog);
+  QPixmap viewportPixmap = QPixmap::grabWidget(d->WidgetToGrab.data());
+  return viewportPixmap.size();
+}
+
+//-----------------------------------------------------------------------------
+void ctkScreenshotDialog::enableTransparency(bool enable)
+{
+  Q_D(ctkScreenshotDialog);
+  d->AllowTransparency = enable;
+}
+
+//-----------------------------------------------------------------------------
 void ctkScreenshotDialogPrivate::saveScreenshot(int delayInSeconds)
 {
   Q_Q(ctkScreenshotDialog);
@@ -140,7 +258,7 @@ void ctkScreenshotDialogPrivate::saveScreenshot(int delayInSeconds)
   this->setWaitingForScreenshot(true);
   this->CountDownValue = delayInSeconds;
   this->CountDownTimer.start(1000);
-  // Add 1ms to give time to set the countdown at 0. 
+  // Add 1ms to give time to set the countdown at 0.
   QTimer::singleShot(delayInSeconds * 1000 + 1, q, SLOT(instantScreenshot()));
 }
 
@@ -170,6 +288,9 @@ void ctkScreenshotDialog::setWidgetToGrab(QWidget* newWidgetToGrab)
   d->CaptureButton->setEnabled(newWidgetToGrab != 0);
 
   d->WidgetToGrab = newWidgetToGrab;
+  QSize curSize = this->widgetSize();
+  d->HeightSpinBox->setValue(curSize.height());
+  d->WidthSpinBox->setValue(curSize.width());
 }
 
 //-----------------------------------------------------------------------------
@@ -197,14 +318,14 @@ QString ctkScreenshotDialog::baseFileName() const
 void ctkScreenshotDialog::setDirectory(const QString& newDirectory)
 {
   Q_D(ctkScreenshotDialog);
-  d->DirectoryButton->setDirectory(newDirectory);
+  d->DirectoryPathLineEdit->setCurrentPath(newDirectory);
 }
 
 //-----------------------------------------------------------------------------
 QString ctkScreenshotDialog::directory()const
 {
   Q_D(const ctkScreenshotDialog);
-  return d->DirectoryButton->directory();
+  return d->DirectoryPathLineEdit->currentPath();
 }
 
 //-----------------------------------------------------------------------------
@@ -247,12 +368,22 @@ void ctkScreenshotDialog::instantScreenshot()
   d->setWaitingForScreenshot(false);
   d->resetCountDownValue();
 
-  // Rescale
-  QPixmap rescaledViewportPixmap = viewportPixmap.scaled(
+  // Rescale based on scale factor or output resolution specified
+  QPixmap rescaledViewportPixmap = viewportPixmap;
+  if(d->ScaleFactorRadioButton->isChecked())
+    {
+    rescaledViewportPixmap = viewportPixmap.scaled(
       viewportPixmap.size().width() * d->ScaleFactorSpinBox->value(),
       viewportPixmap.size().height() * d->ScaleFactorSpinBox->value());
+    }
+  else if(d->OutputResolutionRadioButton->isChecked())
+    {
+    rescaledViewportPixmap = viewportPixmap.scaled(
+      d->WidthSpinBox->value(),
+      d->HeightSpinBox->value());
+    }
 
-  QString filename = QString("%1/%2_%3.png").arg(d->DirectoryButton->directory())
+  QString filename = QString("%1/%2_%3.png").arg(d->DirectoryPathLineEdit->currentPath())
                      .arg(d->ImageNameLineEdit->text())
                      .arg(d->ImageVersionNumberSpinBox->value());
 
@@ -278,7 +409,13 @@ void ctkScreenshotDialog::instantScreenshot()
       }
     }
 
-  rescaledViewportPixmap.save(filename);
+  QImage img = rescaledViewportPixmap.toImage();
+  if( !d->AllowTransparency &&
+      img.hasAlphaChannel())
+    {
+    img = img.convertToFormat(QImage::Format_RGB32);
+    }
+  img.save(filename);
 
   d->ImageVersionNumberSpinBox->setValue(d->ImageVersionNumberSpinBox->value() + 1);
 }

+ 11 - 0
Libs/Widgets/ctkScreenshotDialog.h

@@ -80,6 +80,17 @@ public:
   void setDelay(int seconds);
   int delay()const;
 
+  /// Disable scaling or output resolution control and take a fixed
+  /// resolution screenshot. Default output resolution is (300,300)
+  void enforceResolution(int width = 300, int height = 300);
+  void enforceResolution(QSize size = QSize(300,300));
+
+  /// Get the original widget size
+  QSize widgetSize();
+
+  /// Allow/Disallow transparency in the output screenshot
+  void enableTransparency(bool enable = true);
+
 public Q_SLOTS:
   /// Instantanely grabs the content of \a widgetToGrag. Generates a
   /// png file into \a directory. It automatically increments the image name

+ 14 - 0
Libs/Widgets/ctkScreenshotDialog_p.h

@@ -47,6 +47,8 @@ public:
   void setWaitingForScreenshot(bool waiting);
   bool isWaitingForScreenshot()const;
 
+  void useScalarFactor(bool use = true);
+
 public Q_SLOTS:
 
   void saveScreenshot(int delayInSeconds);
@@ -59,11 +61,23 @@ public Q_SLOTS:
 
   void updateCountDown();
 
+  void selectScaleFactor(bool scale);
+
+  void selectOutputResolution(bool scale);
+
+  void lockAspectRatio(bool lock);
+
+  void onWidthEdited();
+
+  void onHeightEdited();
+
 public:
   QWeakPointer<QWidget> WidgetToGrab;
   QPushButton*          CaptureButton;
   int                   CountDownValue;
   QTimer                CountDownTimer;
+  double                AspectRatio;
+  bool                  AllowTransparency;
 };
 
 #endif

+ 5 - 6
Libs/Widgets/ctkThumbnailListWidget.cpp

@@ -54,6 +54,8 @@ static ctkLogger logger("org.commontk.Widgets.ctkThumbnailListWidget");
 ctkThumbnailListWidgetPrivate
 ::ctkThumbnailListWidgetPrivate(ctkThumbnailListWidget* parent)
   : q_ptr(parent)
+  , CurrentThumbnail(-1)
+  , ThumbnailSize(-1, -1)
   , RequestRelayout(false)
 {
 }
@@ -70,9 +72,6 @@ void ctkThumbnailListWidgetPrivate::init()
   flowLayout->setHorizontalSpacing(4);
   this->ScrollAreaContentWidget->setLayout(flowLayout);
   this->ScrollArea->installEventFilter(q);
-
-  this->ThumbnailSize = QSize(-1, -1);
-  this->CurrentThumbnail = -1;
 }
 
 //----------------------------------------------------------------------------
@@ -185,16 +184,16 @@ void ctkThumbnailListWidget::addThumbnails(const QList<QPixmap>& thumbnails)
 {
   for(int i=0; i<thumbnails.count(); i++)
     {
-    this->addThumbnail("", thumbnails[i]);
+    this->addThumbnail(thumbnails[i]);
     }
 }
 
 //----------------------------------------------------------------------------
-void ctkThumbnailListWidget::addThumbnail(const QString& label, const QPixmap& pixmap)
+void ctkThumbnailListWidget::addThumbnail(const QPixmap& pixmap, const QString& label)
 {
   Q_D(ctkThumbnailListWidget);
   ctkThumbnailLabel* widget = new ctkThumbnailLabel(d->ScrollAreaContentWidget);
-  widget->setText("");
+  widget->setText(label);
   if(d->ThumbnailSize.isValid())
     {
     widget->setFixedSize(d->ThumbnailSize);

+ 1 - 1
Libs/Widgets/ctkThumbnailListWidget.h

@@ -43,7 +43,7 @@ public:
   virtual ~ctkThumbnailListWidget();
 
   /// Add a thumbnail to the widget
-  void addThumbnail(const QString& label, const QPixmap& thumbnail);
+  void addThumbnail(const QPixmap& thumbnail, const QString& label = QString());
 
   /// Add multiple thumbnails to the widget
   void addThumbnails(const QList<QPixmap>& thumbnails);

+ 3 - 3
Libs/Widgets/ctkThumbnailListWidget_p.h

@@ -43,13 +43,13 @@ public:
   void addThumbnail(ctkThumbnailLabel* thumbnail);
   void updateScrollAreaContentWidgetSize(QSize size);
 
+protected:
+  ctkThumbnailListWidget* const q_ptr;
+
   int CurrentThumbnail;
   QSize ThumbnailSize;
   bool RequestRelayout;
 
-protected:
-  ctkThumbnailListWidget* const q_ptr;
-
 private:
   Q_DISABLE_COPY( ctkThumbnailListWidgetPrivate );
 };