summaryrefslogtreecommitdiffstats
path: root/ksnapshot
diff options
context:
space:
mode:
Diffstat (limited to 'ksnapshot')
-rw-r--r--ksnapshot/Makefile.am21
-rw-r--r--ksnapshot/README29
-rw-r--r--ksnapshot/configure.in.in6
-rw-r--r--ksnapshot/hi16-app-ksnapshot.pngbin0 -> 852 bytes
-rw-r--r--ksnapshot/hi22-app-ksnapshot.pngbin0 -> 1328 bytes
-rw-r--r--ksnapshot/hi32-app-ksnapshot.pngbin0 -> 2056 bytes
-rw-r--r--ksnapshot/hi48-app-ksnapshot.pngbin0 -> 3530 bytes
-rw-r--r--ksnapshot/hisc-app-ksnapshot.svgzbin0 -> 5445 bytes
-rw-r--r--ksnapshot/ksnapshot.cpp510
-rw-r--r--ksnapshot/ksnapshot.desktop92
-rw-r--r--ksnapshot/ksnapshot.h150
-rw-r--r--ksnapshot/ksnapshotiface.h65
-rw-r--r--ksnapshot/ksnapshotwidget.ui361
-rw-r--r--ksnapshot/ksnapshotwidget.ui.h138
-rw-r--r--ksnapshot/main.cpp77
-rw-r--r--ksnapshot/regiongrabber.cpp177
-rw-r--r--ksnapshot/regiongrabber.h70
-rw-r--r--ksnapshot/uninstall.desktop2
-rw-r--r--ksnapshot/windowgrabber.cpp353
-rw-r--r--ksnapshot/windowgrabber.h59
20 files changed, 2110 insertions, 0 deletions
diff --git a/ksnapshot/Makefile.am b/ksnapshot/Makefile.am
new file mode 100644
index 00000000..a9dae435
--- /dev/null
+++ b/ksnapshot/Makefile.am
@@ -0,0 +1,21 @@
+bin_PROGRAMS= ksnapshot
+
+INCLUDES = -DKSNAPVERSION="\"0.7\"" $(all_includes)
+
+ksnapshot_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+ksnapshot_LDADD = $(LIB_KDEPRINT)
+
+ksnapshot_SOURCES = ksnapshotiface.skel main.cpp ksnapshot.cpp \
+ regiongrabber.cpp windowgrabber.cpp ksnapshotwidget.ui
+
+ksnapshot_METASOURCES = AUTO
+
+xdg_apps_DATA = ksnapshot.desktop
+
+KDE_ICON = ksnapshot
+
+EXTRA_DIST = $(xdg_apps_DATA)
+
+messages: rc.cpp
+ $(XGETTEXT) rc.cpp *.cpp -o $(podir)/ksnapshot.pot
+
diff --git a/ksnapshot/README b/ksnapshot/README
new file mode 100644
index 00000000..0aa0b121
--- /dev/null
+++ b/ksnapshot/README
@@ -0,0 +1,29 @@
+ KSnapshot Release Notes
+ =======================
+
+KSnapshot is intended to be an easy to use program for making
+screenshots. I can be bound to the Print Screen" key, as the program
+takes a snapshot of the desktop on startup (before it displays it
+window), so it's a simple way of of making snapshots.
+
+Currently Implemented features:
+
+- Mini Preview image
+- Adjustable time delay.
+- Auto hides it own window when grabbing.
+- Grabs desktop or specific windows
+- Save to various formats
+- Auto increment filename
+
+
+The original KSnapshot was implemented by Richard Moore (rich@kde.org)
+for KDE1. Shortly before KDE2 I rewrote most of it to bring it a bit
+closer to KDE2' higher standards.
+
+This version is still not good, but I wanted something that doesn't
+break translations and is still comfortable to old ksnapshot users.
+
+Use Pixie if you want more functionality.
+
+Matthias ( ettrich@kde.org)
+
diff --git a/ksnapshot/configure.in.in b/ksnapshot/configure.in.in
new file mode 100644
index 00000000..56c82023
--- /dev/null
+++ b/ksnapshot/configure.in.in
@@ -0,0 +1,6 @@
+dnl Check for the X shaped windows extension - test taken from kdebase/kwin/clients/keramik
+KDE_CHECK_HEADERS(X11/extensions/shape.h,,,
+[
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+])
diff --git a/ksnapshot/hi16-app-ksnapshot.png b/ksnapshot/hi16-app-ksnapshot.png
new file mode 100644
index 00000000..79743e82
--- /dev/null
+++ b/ksnapshot/hi16-app-ksnapshot.png
Binary files differ
diff --git a/ksnapshot/hi22-app-ksnapshot.png b/ksnapshot/hi22-app-ksnapshot.png
new file mode 100644
index 00000000..446af476
--- /dev/null
+++ b/ksnapshot/hi22-app-ksnapshot.png
Binary files differ
diff --git a/ksnapshot/hi32-app-ksnapshot.png b/ksnapshot/hi32-app-ksnapshot.png
new file mode 100644
index 00000000..4619ae8d
--- /dev/null
+++ b/ksnapshot/hi32-app-ksnapshot.png
Binary files differ
diff --git a/ksnapshot/hi48-app-ksnapshot.png b/ksnapshot/hi48-app-ksnapshot.png
new file mode 100644
index 00000000..f962f5a0
--- /dev/null
+++ b/ksnapshot/hi48-app-ksnapshot.png
Binary files differ
diff --git a/ksnapshot/hisc-app-ksnapshot.svgz b/ksnapshot/hisc-app-ksnapshot.svgz
new file mode 100644
index 00000000..22f4e3fb
--- /dev/null
+++ b/ksnapshot/hisc-app-ksnapshot.svgz
Binary files differ
diff --git a/ksnapshot/ksnapshot.cpp b/ksnapshot/ksnapshot.cpp
new file mode 100644
index 00000000..a0e1d06f
--- /dev/null
+++ b/ksnapshot/ksnapshot.cpp
@@ -0,0 +1,510 @@
+/*
+ * KSnapshot
+ *
+ * (c) Richard J. Moore 1997-2002
+ * (c) Matthias Ettrich 2000
+ * (c) Aaron J. Seigo 2002
+ * (c) Nadeem Hasan 2003
+ * (c) Bernd Brandstetter 2004
+ *
+ * Released under the LGPL see file LICENSE for details.
+ */
+
+
+#include <klocale.h>
+#include <kimageio.h>
+#include <kfiledialog.h>
+#include <kimagefilepreview.h>
+#include <kmessagebox.h>
+#include <kdebug.h>
+#include <kapplication.h>
+#include <kprinter.h>
+#include <kio/netaccess.h>
+#include <ksavefile.h>
+#include <ktempfile.h>
+
+#include <qbitmap.h>
+#include <qdragobject.h>
+#include <qimage.h>
+#include <qclipboard.h>
+#include <qvbox.h>
+
+#include <kaccel.h>
+#include <knotifyclient.h>
+#include <khelpmenu.h>
+#include <kpopupmenu.h>
+#include <kpushbutton.h>
+#include <kstartupinfo.h>
+
+#include <qcursor.h>
+#include <qregexp.h>
+#include <qpainter.h>
+#include <qpaintdevicemetrics.h>
+#include <qwhatsthis.h>
+
+#include <stdlib.h>
+
+#include "ksnapshot.h"
+#include "regiongrabber.h"
+#include "windowgrabber.h"
+#include "ksnapshotwidget.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
+#include <config.h>
+
+#include <kglobal.h>
+
+#define kApp KApplication::kApplication()
+
+KSnapshot::KSnapshot(QWidget *parent, const char *name, bool grabCurrent)
+ : DCOPObject("interface"),
+ KDialogBase(parent, name, true, QString::null, Help|User1, User1,
+ true, KStdGuiItem::quit() )
+{
+ grabber = new QWidget( 0, 0, WStyle_Customize | WX11BypassWM );
+ grabber->move( -1000, -1000 );
+ grabber->installEventFilter( this );
+
+ KStartupInfo::appStarted();
+
+ QVBox *vbox = makeVBoxMainWidget();
+ mainWidget = new KSnapshotWidget( vbox, "mainWidget" );
+
+ connect(mainWidget, SIGNAL(startImageDrag()), SLOT(slotDragSnapshot()));
+
+ connect( mainWidget, SIGNAL( newClicked() ), SLOT( slotGrab() ) );
+ connect( mainWidget, SIGNAL( saveClicked() ), SLOT( slotSaveAs() ) );
+ connect( mainWidget, SIGNAL( printClicked() ), SLOT( slotPrint() ) );
+ connect( mainWidget, SIGNAL( copyClicked() ), SLOT( slotCopy() ) );
+
+ grabber->show();
+ grabber->grabMouse( waitCursor );
+
+ if ( !grabCurrent )
+ snapshot = QPixmap::grabWindow( qt_xrootwin() );
+ else {
+ mainWidget->setMode( WindowUnderCursor );
+ mainWidget->setIncludeDecorations( true );
+ performGrab();
+ }
+
+ updatePreview();
+ grabber->releaseMouse();
+ grabber->hide();
+
+ KConfig *conf=KGlobal::config();
+ conf->setGroup("GENERAL");
+ mainWidget->setDelay(conf->readNumEntry("delay",0));
+ mainWidget->setMode( conf->readNumEntry( "mode", 0 ) );
+ mainWidget->setIncludeDecorations(conf->readBoolEntry("includeDecorations",true));
+ filename = KURL::fromPathOrURL( conf->readPathEntry( "filename", QDir::currentDirPath()+"/"+i18n("snapshot")+"1.png" ));
+
+ // Make sure the name is not already being used
+ while(KIO::NetAccess::exists( filename, false, this )) {
+ autoincFilename();
+ }
+
+ connect( &grabTimer, SIGNAL( timeout() ), this, SLOT( grabTimerDone() ) );
+ connect( &updateTimer, SIGNAL( timeout() ), this, SLOT( updatePreview() ) );
+ QTimer::singleShot( 0, this, SLOT( updateCaption() ) );
+
+ KHelpMenu *helpMenu = new KHelpMenu(this, KGlobal::instance()->aboutData(), false);
+
+ QPushButton *helpButton = actionButton( Help );
+ helpButton->setPopup(helpMenu->menu());
+
+ KAccel* accel = new KAccel(this);
+ accel->insert(KStdAccel::Quit, kapp, SLOT(quit()));
+ accel->insert( "QuickSave", i18n("Quick Save Snapshot &As..."),
+ i18n("Save the snapshot to the file specified by the user without showing the file dialog."),
+ CTRL+SHIFT+Key_S, this, SLOT(slotSave()));
+ accel->insert(KStdAccel::Save, this, SLOT(slotSaveAs()));
+// accel->insert(KShortcut(CTRL+Key_A), this, SLOT(slotSaveAs()));
+ accel->insert( "SaveAs", i18n("Save Snapshot &As..."),
+ i18n("Save the snapshot to the file specified by the user."),
+ CTRL+Key_A, this, SLOT(slotSaveAs()));
+ accel->insert(KStdAccel::Print, this, SLOT(slotPrint()));
+ accel->insert(KStdAccel::New, this, SLOT(slotGrab()));
+ accel->insert(KStdAccel::Copy, this, SLOT(slotCopy()));
+
+ accel->insert( "Quit2", Key_Q, this, SLOT(slotSave()));
+ accel->insert( "Save2", Key_S, this, SLOT(slotSaveAs()));
+ accel->insert( "Print2", Key_P, this, SLOT(slotPrint()));
+ accel->insert( "New2", Key_N, this, SLOT(slotGrab()));
+ accel->insert( "New3", Key_Space, this, SLOT(slotGrab()));
+
+ setEscapeButton( User1 );
+ connect( this, SIGNAL( user1Clicked() ), SLOT( reject() ) );
+
+ mainWidget->btnNew->setFocus();
+}
+
+KSnapshot::~KSnapshot()
+{
+}
+
+void KSnapshot::resizeEvent( QResizeEvent *event)
+{
+ if( !updateTimer.isActive() )
+ updateTimer.start(200, true);
+ else
+ updateTimer.changeInterval(200);
+}
+
+bool KSnapshot::save( const QString &filename )
+{
+ return save( KURL::fromPathOrURL( filename ));
+}
+
+bool KSnapshot::save( const KURL& url )
+{
+ if ( KIO::NetAccess::exists( url, false, this ) ) {
+ const QString title = i18n( "File Exists" );
+ const QString text = i18n( "<qt>Do you really want to overwrite <b>%1</b>?</qt>" ).arg(url.prettyURL());
+ if (KMessageBox::Continue != KMessageBox::warningContinueCancel( this, text, title, i18n("Overwrite") ) )
+ {
+ return false;
+ }
+ }
+
+ QString type( KImageIO::type(url.path()) );
+ if ( type.isNull() )
+ type = "PNG";
+
+ bool ok = false;
+
+ if ( url.isLocalFile() ) {
+ KSaveFile saveFile( url.path() );
+ if ( saveFile.status() == 0 ) {
+ if ( snapshot.save( saveFile.file(), type.latin1() ) )
+ ok = saveFile.close();
+ }
+ }
+ else {
+ KTempFile tmpFile;
+ tmpFile.setAutoDelete( true );
+ if ( tmpFile.status() == 0 ) {
+ if ( snapshot.save( tmpFile.file(), type.latin1() ) ) {
+ if ( tmpFile.close() )
+ ok = KIO::NetAccess::upload( tmpFile.name(), url, this );
+ }
+ }
+ }
+
+ QApplication::restoreOverrideCursor();
+ if ( !ok ) {
+ kdWarning() << "KSnapshot was unable to save the snapshot" << endl;
+
+ QString caption = i18n("Unable to save image");
+ QString text = i18n("KSnapshot was unable to save the image to\n%1.")
+ .arg(url.prettyURL());
+ KMessageBox::error(this, text, caption);
+ }
+
+ return ok;
+}
+
+void KSnapshot::slotSave()
+{
+ if ( save(filename) ) {
+ modified = false;
+ autoincFilename();
+ }
+}
+
+void KSnapshot::slotSaveAs()
+{
+ QStringList mimetypes = KImageIO::mimeTypes( KImageIO::Writing );
+ KFileDialog dlg( filename.url(), mimetypes.join(" "), this, "filedialog", true);
+
+ dlg.setOperationMode( KFileDialog::Saving );
+ dlg.setCaption( i18n("Save As") );
+
+ KImageFilePreview *ip = new KImageFilePreview( &dlg );
+ dlg.setPreviewWidget( ip );
+
+ if ( !dlg.exec() )
+ return;
+
+ KURL url = dlg.selectedURL();
+ if ( !url.isValid() )
+ return;
+
+ if ( save(url) ) {
+ filename = url;
+ modified = false;
+ autoincFilename();
+ }
+}
+
+void KSnapshot::slotCopy()
+{
+ QClipboard *cb = QApplication::clipboard();
+ cb->setPixmap( snapshot );
+}
+
+void KSnapshot::slotDragSnapshot()
+{
+ QDragObject *drobj = new QImageDrag(snapshot.convertToImage(), this);
+ drobj->setPixmap(mainWidget->preview());
+ drobj->dragCopy();
+}
+
+void KSnapshot::slotGrab()
+{
+ hide();
+
+ if ( mainWidget->delay() && mainWidget->mode() != Region )
+ grabTimer.start( mainWidget->delay() * 1000, true );
+ else {
+ if ( mainWidget->mode() == Region ) {
+ rgnGrab = new RegionGrabber();
+ connect( rgnGrab, SIGNAL( regionGrabbed( const QPixmap & ) ),
+ SLOT( slotRegionGrabbed( const QPixmap & ) ) );
+ }
+ else {
+ grabber->show();
+ grabber->grabMouse( crossCursor );
+ }
+ }
+}
+
+void KSnapshot::slotPrint()
+{
+ KPrinter printer;
+ if (snapshot.width() > snapshot.height())
+ printer.setOrientation(KPrinter::Landscape);
+ else
+ printer.setOrientation(KPrinter::Portrait);
+
+ qApp->processEvents();
+
+ if (printer.setup(this, i18n("Print Screenshot")))
+ {
+ qApp->processEvents();
+
+ QPainter painter(&printer);
+ QPaintDeviceMetrics metrics(painter.device());
+
+ float w = snapshot.width();
+ float dw = w - metrics.width();
+ float h = snapshot.height();
+ float dh = h - metrics.height();
+ bool scale = false;
+
+ if ( (dw > 0.0) || (dh > 0.0) )
+ scale = true;
+
+ if ( scale ) {
+
+ QImage img = snapshot.convertToImage();
+ qApp->processEvents();
+
+ float newh, neww;
+ if ( dw > dh ) {
+ neww = w-dw;
+ newh = neww/w*h;
+ }
+ else {
+ newh = h-dh;
+ neww = newh/h*w;
+ }
+
+ img = img.smoothScale( int(neww), int(newh), QImage::ScaleMin );
+ qApp->processEvents();
+
+ int x = (metrics.width()-img.width())/2;
+ int y = (metrics.height()-img.height())/2;
+
+ painter.drawImage( x, y, img);
+ }
+ else {
+ int x = (metrics.width()-snapshot.width())/2;
+ int y = (metrics.height()-snapshot.height())/2;
+ painter.drawPixmap( x, y, snapshot );
+ }
+ }
+
+ qApp->processEvents();
+}
+
+void KSnapshot::slotRegionGrabbed( const QPixmap &pix )
+{
+ if ( !pix.isNull() )
+ {
+ snapshot = pix;
+ updatePreview();
+ modified = true;
+ updateCaption();
+ }
+
+ delete rgnGrab;
+ QApplication::restoreOverrideCursor();
+ show();
+}
+
+void KSnapshot::slotWindowGrabbed( const QPixmap &pix )
+{
+ if ( !pix.isNull() )
+ {
+ snapshot = pix;
+ updatePreview();
+ modified = true;
+ updateCaption();
+ }
+
+ QApplication::restoreOverrideCursor();
+ show();
+}
+
+void KSnapshot::closeEvent( QCloseEvent * e )
+{
+ KConfig *conf=KGlobal::config();
+ conf->setGroup("GENERAL");
+ conf->writeEntry("delay",mainWidget->delay());
+ conf->writeEntry("mode",mainWidget->mode());
+ conf->writeEntry("includeDecorations",mainWidget->includeDecorations());
+ KURL url = filename;
+ url.setPass( QString::null );
+ conf->writePathEntry("filename",url.url());
+ e->accept();
+}
+
+bool KSnapshot::eventFilter( QObject* o, QEvent* e)
+{
+ if ( o == grabber && e->type() == QEvent::MouseButtonPress ) {
+ QMouseEvent* me = (QMouseEvent*) e;
+ if ( QWidget::mouseGrabber() != grabber )
+ return false;
+ if ( me->button() == LeftButton )
+ performGrab();
+ }
+ return false;
+}
+
+void KSnapshot::autoincFilename()
+{
+ // Extract the filename from the path
+ QString name= filename.fileName();
+
+ // If the name contains a number then increment it
+ QRegExp numSearch("[0-9]+");
+
+ // Does it have a number?
+ int start = numSearch.search(name);
+ if (start != -1) {
+ // It has a number, increment it
+ int len = numSearch.matchedLength();
+ QString numAsStr= name.mid(start, len);
+ QString number = QString::number(numAsStr.toInt() + 1);
+ number = number.rightJustify( len, '0');
+ name.replace(start, len, number );
+ }
+ else {
+ // no number
+ start = name.findRev('.');
+ if (start != -1) {
+ // has a . somewhere, e.g. it has an extension
+ name.insert(start, '1');
+ }
+ else {
+ // no extension, just tack it on to the end
+ name += '1';
+ }
+ }
+
+ //Rebuild the path
+ KURL newURL = filename;
+ newURL.setFileName( name );
+ setURL( newURL.url() );
+}
+
+void KSnapshot::updatePreview()
+{
+ mainWidget->setPreview( snapshot );
+}
+
+void KSnapshot::grabTimerDone()
+{
+ if ( mainWidget->mode() == Region ) {
+ rgnGrab = new RegionGrabber();
+ connect( rgnGrab, SIGNAL( regionGrabbed( const QPixmap & ) ),
+ SLOT( slotRegionGrabbed( const QPixmap & ) ) );
+ }
+ else {
+ performGrab();
+ }
+ KNotifyClient::beep(i18n("The screen has been successfully grabbed."));
+}
+
+void KSnapshot::performGrab()
+{
+ grabber->releaseMouse();
+ grabber->hide();
+ grabTimer.stop();
+ if ( mainWidget->mode() == ChildWindow ) {
+ WindowGrabber wndGrab;
+ connect( &wndGrab, SIGNAL( windowGrabbed( const QPixmap & ) ),
+ SLOT( slotWindowGrabbed( const QPixmap & ) ) );
+ wndGrab.exec();
+ }
+ else if ( mainWidget->mode() == WindowUnderCursor ) {
+ snapshot = WindowGrabber::grabCurrent( mainWidget->includeDecorations() );
+ }
+ else {
+ snapshot = QPixmap::grabWindow( qt_xrootwin() );
+ }
+ updatePreview();
+ QApplication::restoreOverrideCursor();
+ modified = true;
+ updateCaption();
+ show();
+}
+
+void KSnapshot::setTime(int newTime)
+{
+ mainWidget->setDelay(newTime);
+}
+
+int KSnapshot::timeout()
+{
+ return mainWidget->delay();
+}
+
+void KSnapshot::setURL( const QString &url )
+{
+ KURL newURL = KURL::fromPathOrURL( url );
+ if ( newURL == filename )
+ return;
+
+ filename = newURL;
+ updateCaption();
+}
+
+void KSnapshot::setGrabMode( int m )
+{
+ mainWidget->setMode( m );
+}
+
+int KSnapshot::grabMode()
+{
+ return mainWidget->mode();
+}
+
+void KSnapshot::updateCaption()
+{
+ setCaption( kApp->makeStdCaption( filename.fileName(), true, modified ) );
+}
+
+void KSnapshot::slotMovePointer(int x, int y)
+{
+ QCursor::setPos( x, y );
+}
+
+void KSnapshot::exit()
+{
+ reject();
+}
+#include "ksnapshot.moc"
diff --git a/ksnapshot/ksnapshot.desktop b/ksnapshot/ksnapshot.desktop
new file mode 100644
index 00000000..311a2199
--- /dev/null
+++ b/ksnapshot/ksnapshot.desktop
@@ -0,0 +1,92 @@
+[Desktop Entry]
+GenericName=Screen Capture Program
+GenericName[af]=Skerm Vang Program
+GenericName[ar]=برنامج تصوير الشاشة
+GenericName[bg]=Снимки на екрана
+GenericName[bs]=Program za "hvatanje" slike
+GenericName[ca]=Programa de captura de pantalla
+GenericName[cs]=Snímač obrazovky
+GenericName[cy]=Rhaglen Cipio'r Sgrîn
+GenericName[da]=Program til øjebliksbilleder
+GenericName[de]=Bildschirmphotos
+GenericName[el]=Πρόγραμμα σύλληψης οθόνης
+GenericName[eo]=Ekranfota programo
+GenericName[es]=Capturador de pantalla
+GenericName[et]=Töölaua pildistamine
+GenericName[eu]=Pantailari argazkiak ateratzeko programa
+GenericName[fa]=برنامۀ گیراندازی پرده
+GenericName[fi]=Ruudunkaappausohjelma
+GenericName[fr]=Logiciel de capture d'écran
+GenericName[ga]=Clár gabhála scáileáin
+GenericName[gl]=Progama para facer capturas de pantalla
+GenericName[he]=תוכנית לצילום המסך
+GenericName[hi]=स्क्रीन केप्चर प्रोग्राम
+GenericName[hr]=Program za snimanje zaslona
+GenericName[hu]=Képlopó
+GenericName[is]=Forrit sem grípur skjámyndir
+GenericName[it]=Scatta foto allo schermo
+GenericName[ja]=スクリーンキャプチャプログラム
+GenericName[kk]=Экраннан түсіріп алу бағдарламасы
+GenericName[km]=កម្មវិធី​ចាប់យក​អេក្រង់
+GenericName[lt]=Ekrano kopijos programa
+GenericName[lv]=Ekrāna Sagrābšanas Programma
+GenericName[ms]=Program Cekupan Skrin
+GenericName[mt]=Programm biex tieħu "ritratt" tal-iskrin
+GenericName[nb]=Skjermdumpprogram
+GenericName[nds]=Schirmfotos opnehmen
+GenericName[ne]=पर्दा समात्ने कार्यक्रम
+GenericName[nl]=Schermafdrukprogramma
+GenericName[nn]=Program for skjermbilete
+GenericName[nso]=Lenaneo lago Apesa Pontsho
+GenericName[pl]=Program do zrzutów ekranu
+GenericName[pt]=Programa de Captura do Ecrã
+GenericName[pt_BR]=Programa de Captura de Tela
+GenericName[ro]=Program de captură de ecran
+GenericName[ru]=Создание снимков экрана
+GenericName[rw]=Porogaramu Gufata Mugaragaza
+GenericName[se]=Šearbmagovvenprográmma
+GenericName[sk]=Zachytenie obrazovky
+GenericName[sl]=Program za zajem zaslona
+GenericName[sr]=Програм за снимање екрана
+GenericName[sr@Latn]=Program za snimanje ekrana
+GenericName[sv]=Ta en skärmdump
+GenericName[ta]=திரை கைப்பற்றும் நிரலி
+GenericName[tg]=Эҷоди суратҳои экран
+GenericName[th]=โปรแกรมจับภาพหน้าจอ
+GenericName[tr]=Ekran Yakalama Programı
+GenericName[uk]=Захоплювач екрана
+GenericName[uz]=Skrinshot olish dasturi
+GenericName[uz@cyrillic]=Скриншот олиш дастури
+GenericName[ven]=Mbekanya mushumo ino gavha tshikirini
+GenericName[wa]=Programe po fé des waitroûlêyes
+GenericName[xh]=Iinkcazelo Ezigcina Ikhusi
+GenericName[zh_CN]=屏幕截图程序
+GenericName[zh_HK]=螢幕擷取程式
+GenericName[zh_TW]=畫面擷取程式
+GenericName[zu]=Iprogremu Yokubamba Isikrini
+Name=KSnapshot
+Name[af]=K-kiekie
+Name[cy]=KCipluniau
+Name[eo]=Ekranfotilo
+Name[fr]=KSnapShot
+Name[hi]=के-स्नेपशॉट
+Name[lv]=KSnapšots
+Name[ne]=केडीई स्न्यापसट
+Name[pl]=Zrzuty ekranu
+Name[sv]=Ksnapshot
+Name[ta]=கேதிரையை நகலெடுத்தல்
+Name[th]=จับภาพ - K
+Name[ven]=Tshinepe tsha K
+Name[wa]=KWaitroûlêye
+Name[zh_TW]=KSnapshot 快照
+Name[zu]=KEsincane isithombe
+MimeType=
+Exec=ksnapshot -caption "%c" %i %m
+Icon=ksnapshot
+Path=
+Type=Application
+Terminal=false
+DocPath=ksnapshot/index.html
+X-KDE-StartupNotify=true
+X-DCOP-ServiceType=Multi
+Categories=Qt;KDE;Graphics;
diff --git a/ksnapshot/ksnapshot.h b/ksnapshot/ksnapshot.h
new file mode 100644
index 00000000..486c0a1b
--- /dev/null
+++ b/ksnapshot/ksnapshot.h
@@ -0,0 +1,150 @@
+// -*- c++ -*-
+
+#ifndef KSNAPSHOT_H
+#define KSNAPSHOT_H
+#include "ksnapshotiface.h"
+
+#include <qbitmap.h>
+#include <qcursor.h>
+#include <qlabel.h>
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qstyle.h>
+#include <qtimer.h>
+
+#include <dcopclient.h>
+#include <kglobalsettings.h>
+#include <kdialogbase.h>
+#include <kurl.h>
+
+class RegionGrabber;
+class KSnapshotWidget;
+
+class KSnapshotPreview : public QLabel
+{
+ Q_OBJECT
+
+ public:
+ KSnapshotPreview(QWidget *parent, const char *name = 0)
+ : QLabel(parent, name)
+ {
+ setAlignment(AlignHCenter | AlignVCenter);
+ setCursor(QCursor(Qt::PointingHandCursor));
+ }
+ virtual ~KSnapshotPreview() {}
+
+ void setPixmap(const QPixmap& pm)
+ {
+ // if this looks convoluted, that's because it is. drawing a PE_SizeGrip
+ // does unexpected things when painting directly onto the pixmap
+ QPixmap pixmap(pm);
+ QPixmap handle(15, 15);
+ QBitmap mask(15, 15, true);
+
+ {
+ QPainter p(&mask);
+ style().drawPrimitive(QStyle::PE_SizeGrip, &p, QRect(0, 0, 15, 15), palette().active());
+ p.end();
+ handle.setMask(mask);
+ }
+
+ {
+ QPainter p(&handle);
+ style().drawPrimitive(QStyle::PE_SizeGrip, &p, QRect(0, 0, 15, 15), palette().active());
+ p.end();
+ }
+
+ QRect rect(pixmap.width() - 16, pixmap.height() - 16, 15, 15);
+ QPainter p(&pixmap);
+ p.drawPixmap(rect, handle);
+ p.end();
+ QLabel::setPixmap(pixmap);
+ }
+
+ signals:
+ void startDrag();
+
+ protected:
+ void mousePressEvent(QMouseEvent * e)
+ {
+ mClickPt = e->pos();
+ }
+
+ void mouseMoveEvent(QMouseEvent * e)
+ {
+ if (mClickPt != QPoint(0, 0) &&
+ (e->pos() - mClickPt).manhattanLength() > KGlobalSettings::dndEventDelay())
+ {
+ mClickPt = QPoint(0, 0);
+ emit startDrag();
+ }
+ }
+
+ void mouseReleaseEvent(QMouseEvent * /*e*/)
+ {
+ mClickPt = QPoint(0, 0);
+ }
+
+ QPoint mClickPt;
+};
+
+class KSnapshot : public KDialogBase, virtual public KSnapshotIface
+{
+ Q_OBJECT
+
+public:
+ KSnapshot(QWidget *parent= 0, const char *name= 0, bool grabCurrent=false);
+ ~KSnapshot();
+
+ enum CaptureMode { FullScreen=0, WindowUnderCursor=1, Region=2, ChildWindow=3 };
+
+ bool save( const QString &filename );
+ QString url() const { return filename.url(); }
+
+protected slots:
+ void slotGrab();
+ void slotSave();
+ void slotSaveAs();
+ void slotCopy();
+ void slotPrint();
+ void slotMovePointer( int x, int y );
+
+ void setTime(int newTime);
+ void setURL(const QString &newURL);
+ void setGrabMode( int m );
+ void exit();
+
+protected:
+ void reject() { close(); }
+
+ virtual void closeEvent( QCloseEvent * e );
+ void resizeEvent(QResizeEvent*);
+ bool eventFilter( QObject*, QEvent* );
+
+private slots:
+ void grabTimerDone();
+ void slotDragSnapshot();
+ void updateCaption();
+ void updatePreview();
+ void slotRegionGrabbed( const QPixmap & );
+ void slotWindowGrabbed( const QPixmap & );
+
+private:
+ bool save( const KURL& url );
+ void performGrab();
+ void autoincFilename();
+ int grabMode();
+ int timeout();
+
+ QPixmap snapshot;
+ QTimer grabTimer;
+ QTimer updateTimer;
+ QWidget* grabber;
+ KURL filename;
+ KSnapshotWidget *mainWidget;
+ RegionGrabber *rgnGrab;
+ bool modified;
+};
+
+#endif // KSNAPSHOT_H
+
diff --git a/ksnapshot/ksnapshotiface.h b/ksnapshot/ksnapshotiface.h
new file mode 100644
index 00000000..6b1f3477
--- /dev/null
+++ b/ksnapshot/ksnapshotiface.h
@@ -0,0 +1,65 @@
+/** KSnapshot DCOP interface
+ File: ksnapshotiface.h
+ Date: January 12, 2001
+ Author: Ian Geiser <geiseri@linuxppc.com>
+ Comments:
+ This is an addition to the existing KSnapshot code
+ that will allow other applications to access internal
+ public member functions via dcop.
+**/
+
+#ifndef __KS_IFACE_H
+#define __KS_IFACE_H
+
+#include <dcopobject.h>
+
+class KSnapshotIface : virtual public DCOPObject
+{
+ K_DCOP
+ k_dcop:
+ /** the current filename (as a URL) that will
+ be used to save to */
+ virtual QString url() const = 0;
+
+ /** Grab an image **/
+ virtual void slotGrab() = 0;
+
+ /** Prints the image. */
+ virtual void slotPrint() = 0;
+
+ /** Saves the image **/
+ virtual void slotSave() = 0;
+
+ /** Save the image to the specified filename */
+ virtual bool save(const QString &filename) = 0;
+
+ /** Saves image as **/
+ virtual void slotSaveAs() = 0;
+
+ /** Copy the snapshot to the clipboard. **/
+ virtual void slotCopy() = 0;
+
+ /** Set the timeout value */
+ virtual void setTime(int newTime) = 0;
+
+ /** Get the current timeout value */
+ virtual int timeout() = 0;
+
+ /** Set the URL to the file to save **/
+ virtual void setURL(const QString &newURL) = 0;
+
+ /** Set the ability to grab the entire screen, just the window
+ containing the mouse, or a region */
+ virtual void setGrabMode(int grab) = 0;
+
+ /** Return the current grab mode */
+ virtual int grabMode() = 0;
+
+ /** Move the mouse pointer. */
+ virtual void slotMovePointer( int x, int y ) = 0;
+
+ /** Exit KSnapshot **/
+ virtual void exit() = 0;
+};
+
+#endif
diff --git a/ksnapshot/ksnapshotwidget.ui b/ksnapshot/ksnapshotwidget.ui
new file mode 100644
index 00000000..88efce1a
--- /dev/null
+++ b/ksnapshot/ksnapshotwidget.ui
@@ -0,0 +1,361 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>KSnapshotWidget</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>KSnapshotWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>356</width>
+ <height>226</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="KSnapshotPreview" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>lblImage</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>200</width>
+ <height>130</height>
+ </size>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>This is a preview of the current snapshot.
+
+The image can be dragged to another application or document to copy the full screenshot there. Try it with the Konqueror file manager.
+
+You can also copy the image to the clipboard by pressing Ctrl+C.</string>
+ </property>
+ </widget>
+ <widget class="Line" row="1" column="0" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>line1</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="3" column="1">
+ <property name="name">
+ <cstring>spinDelay</cstring>
+ </property>
+ <property name="suffix">
+ <string> sec</string>
+ </property>
+ <property name="specialValueText">
+ <string>No delay</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Snapshot delay in seconds</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qt&gt;
+This is the number of seconds to wait after clicking the &lt;i&gt;New Snapshot&lt;/i&gt; button before taking the snapshot.
+&lt;p&gt;
+This is very useful for getting windows, menus and other items on the screen set up just the way you want.
+&lt;p&gt;
+If &lt;i&gt;no delay&lt;/i&gt; is set, the program will wait for a mouse click before taking a snapshot.
+&lt;/p&gt;
+&lt;/qt&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>lblDelay</cstring>
+ </property>
+ <property name="text">
+ <string>Snapshot &amp;delay:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>spinDelay</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Cap&amp;ture mode:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>comboMode</cstring>
+ </property>
+ </widget>
+ <spacer row="3" column="2" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>Spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>156</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QCheckBox" row="4" column="0" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>cbIncludeDecorations</cstring>
+ </property>
+ <property name="text">
+ <string>Include &amp;window decorations</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>When enabled, snapshot of a window will also include the window decorations</string>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="2" column="1" rowspan="1" colspan="3">
+ <item>
+ <property name="text">
+ <string>Full Screen</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Window Under Cursor</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Region</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Section of Window</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>comboMode</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qt&gt;Using this menu, you can select from the four following snapshot modes:
+&lt;p&gt;
+&lt;b&gt;Full Screen&lt;/b&gt; - captures the entire desktop.&lt;br&gt;
+&lt;b&gt;Window Under Cursor&lt;/b&gt; - captures only the window (or menu) that is under the mouse cursor when the snapshot is taken.&lt;br&gt;
+&lt;b&gt;Region&lt;/b&gt; - captures only the region of the desktop that you specify. When taking a new snapshot in this mode you will be able to select any area of the screen by clicking and dragging the mouse.&lt;/p&gt;
+&lt;b&gt;Section of Window&lt;/b&gt; - captures only a section of the window. When taking a new snapshot in this mode you will be able to select any child window by moving the mouse over it.&lt;/p&gt;&lt;/qt&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="0" column="3">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>btnNew</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;New Snapshot</string>
+ </property>
+ <property name="iconSet">
+ <iconset>"ksnapshot", 32</iconset>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Click this button to take a new snapshot.</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer6</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>btnSave</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Save As...</string>
+ </property>
+ <property name="iconSet">
+ <iconset>"filesave"</iconset>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Click this button to save the current snapshot. To quickly save the snapshot without showing the file dialog, press Ctrl+Shift+S. The filename is automatically incremented after each save.</string>
+ </property>
+ </widget>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>btnCopy</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Copy to Clipboard</string>
+ </property>
+ <property name="iconSet">
+ <iconset>"editcopy"</iconset>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Click this button to copy the current snapshot to the clipboard.</string>
+ </property>
+ </widget>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>btnPrint</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Print...</string>
+ </property>
+ <property name="iconSet">
+ <iconset>"fileprint"</iconset>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Click this button to print the current screenshot.</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>KSnapshotPreview</class>
+ <header location="local">ksnapshot.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>5</hordata>
+ <verdata>5</verdata>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ <signal>startDrag()</signal>
+ </customwidget>
+</customwidgets>
+<images>
+ <image name="image0">
+ <data format="PNG" length="660">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000025b49444154789cb595bf4b1b6118c73f962bbc070e115af006210107f52fa8b18b071dbb445ca48bb8199c544a8b53b153092e3ad9d8ad53c962390a2da6507227441207e10296be190a774330070af74202760889899e3f22f50bc7ddfb72efe7799eef7bcf7b0305bbc06d9a4a4e9d5f9e2bd885819bd63cba0ff4a6f9eec800e7fffbd2da01fed81ff1a48d52014213b715d22b3d060d853cdce1d587d65407ec491b79b8d31fb02d0d2ea7d2012b15007422f6ab2f6f04a0ae82bbcb3f3939416882e02ca07454c2dab5086a01c9e749e2237174a1230605524ab29fb2e47fe431c652c8a3cf57c1ddca6e67f16b3ef62f1be7c0616e768ecdad4d8686860008c31067df415625beef475610095e7dbddaf3865db4d9dade223d9fc6adb8acbd5ba37c502608028488dee84830407c344e7a298daee90c3f1d263196400c0adc631773da64617e81dcd71caaaeb0be5977032f2e2d32f37206f385090de0319dbb528ae4641273da647c7c1c599591e06b3b2f24243c0d5b830678358ff03444fe9658df2dc2d390443c81eff5e1b1b56b613c3198189d20168b213481e77b88b868d95171c9ede6281f96b18bf6ddc1fe5f1fafe6513fabb7364783bdfc1efaa08e5b7129154b4c3e9b24359ba21ed4717e3a77b3423515eeb18bac4a6455a29a0a73da445624a56209236eb43eb326a497d29119477bac4179bf8c936f65a2ce14c6b0c1f2ea32ebefd7498c24b08b362b6f57709cabd9f65aa1c72e464d088280cc4686cc462672615b6d1b841ebb06dc50085a3d6f8ca56e845d96d06304f56a34f8e264533d3ddf979a5dcf0f75d0dffa6bbaaf1e0cfc0ff3922877348d5d5a0000000049454e44ae426082</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>comboMode</sender>
+ <signal>activated(int)</signal>
+ <receiver>KSnapshotWidget</receiver>
+ <slot>slotModeChanged(int)</slot>
+ </connection>
+ <connection>
+ <sender>btnNew</sender>
+ <signal>clicked()</signal>
+ <receiver>KSnapshotWidget</receiver>
+ <slot>slotNewClicked()</slot>
+ </connection>
+ <connection>
+ <sender>btnPrint</sender>
+ <signal>clicked()</signal>
+ <receiver>KSnapshotWidget</receiver>
+ <slot>slotPrintClicked()</slot>
+ </connection>
+ <connection>
+ <sender>btnSave</sender>
+ <signal>clicked()</signal>
+ <receiver>KSnapshotWidget</receiver>
+ <slot>slotSaveClicked()</slot>
+ </connection>
+ <connection>
+ <sender>btnCopy</sender>
+ <signal>clicked()</signal>
+ <receiver>KSnapshotWidget</receiver>
+ <slot>slotCopyClicked()</slot>
+ </connection>
+ <connection>
+ <sender>lblImage</sender>
+ <signal>startDrag()</signal>
+ <receiver>KSnapshotWidget</receiver>
+ <slot>slotStartDrag()</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>btnNew</tabstop>
+ <tabstop>btnSave</tabstop>
+ <tabstop>btnCopy</tabstop>
+ <tabstop>btnPrint</tabstop>
+ <tabstop>comboMode</tabstop>
+ <tabstop>spinDelay</tabstop>
+ <tabstop>cbIncludeDecorations</tabstop>
+</tabstops>
+<includes>
+ <include location="global" impldecl="in implementation">kdialog.h</include>
+ <include location="global" impldecl="in implementation">kiconloader.h</include>
+ <include location="global" impldecl="in implementation">kglobalsettings.h</include>
+ <include location="local" impldecl="in implementation">ksnapshotwidget.ui.h</include>
+</includes>
+<signals>
+ <signal>newClicked()</signal>
+ <signal>saveClicked()</signal>
+ <signal>copyClicked()</signal>
+ <signal>printClicked()</signal>
+ <signal>startImageDrag()</signal>
+</signals>
+<slots>
+ <slot access="protected" specifier="non virtual">slotModeChanged( int mode )</slot>
+ <slot access="protected" specifier="non virtual">slotNewClicked()</slot>
+ <slot access="protected" specifier="non virtual">slotSaveClicked()</slot>
+ <slot access="protected" specifier="non virtual">slotCopyClicked()</slot>
+ <slot access="protected" specifier="non virtual">slotPrintClicked()</slot>
+ <slot access="protected" specifier="non virtual">slotStartDrag()</slot>
+ <slot specifier="non virtual" returnType="int">previewWidth()</slot>
+ <slot specifier="non virtual" returnType="int">previewHeight()</slot>
+</slots>
+<functions>
+ <function specifier="non virtual">setPreview( const QPixmap &amp; pm )</function>
+ <function specifier="non virtual">setDelay( int i )</function>
+ <function specifier="non virtual">setIncludeDecorations( bool b )</function>
+ <function specifier="non virtual">setMode( int mode )</function>
+ <function specifier="non virtual" returnType="int">delay()</function>
+ <function specifier="non virtual" returnType="bool">includeDecorations()</function>
+ <function specifier="non virtual" returnType="int">mode()</function>
+ <function specifier="non virtual" returnType="QPixmap">preview()</function>
+</functions>
+<pixmapfunction>SmallIconSet</pixmapfunction>
+<layoutdefaults spacing="6" margin="11"/>
+<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/>
+<includehints>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/ksnapshot/ksnapshotwidget.ui.h b/ksnapshot/ksnapshotwidget.ui.h
new file mode 100644
index 00000000..d7e757f5
--- /dev/null
+++ b/ksnapshot/ksnapshotwidget.ui.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+** ui.h extension file, included from the uic-generated form implementation.
+**
+** If you wish to add, delete or rename functions or slots use
+** Qt Designer which will update this file, preserving your code. Create an
+** init() function in place of a constructor, and a destroy() function in
+** place of a destructor.
+*****************************************************************************/
+
+
+void KSnapshotWidget::slotModeChanged( int mode )
+{
+ switch ( mode )
+ {
+ case 0:
+ cbIncludeDecorations->setEnabled(false);
+ break;
+ case 1:
+ cbIncludeDecorations->setEnabled(true);
+ break;
+ case 2:
+ cbIncludeDecorations->setEnabled(false);
+ break;
+ case 3:
+ cbIncludeDecorations->setEnabled(false);
+ break;
+ default:
+ break;
+ }
+
+ spinDelay->setEnabled(mode != 2);
+}
+
+
+void KSnapshotWidget::setPreview( const QPixmap &pm )
+{
+ QImage img = pm.convertToImage();
+ double r1 = ( ( double ) pm.height() ) / pm.width();
+ if ( r1 * previewWidth() < previewHeight() )
+ img = img.smoothScale( previewWidth(),
+ int( previewWidth() * r1 ),
+ QImage::ScaleMin );
+ else
+ img = img.smoothScale( ( int ) ( ( ( double )previewHeight() ) / r1 ),
+ previewHeight(), QImage::ScaleMin );
+
+ QToolTip::remove( lblImage );
+ QToolTip::add( lblImage,
+ QString( "Preview of the snapshot image (%1 x %2)" )
+ .arg( pm.width() ).arg( pm.height() ) );
+
+ lblImage->setPixmap( img );
+ lblImage->adjustSize();
+}
+
+
+void KSnapshotWidget::setDelay( int i )
+{
+ spinDelay->setValue(i);
+}
+
+
+void KSnapshotWidget::setIncludeDecorations( bool b )
+{
+ cbIncludeDecorations->setChecked(b);
+}
+
+
+void KSnapshotWidget::setMode( int mode )
+{
+ comboMode->setCurrentItem(mode);
+ slotModeChanged(mode);
+}
+
+
+int KSnapshotWidget::delay()
+{
+ return spinDelay->value();
+}
+
+
+bool KSnapshotWidget::includeDecorations()
+{
+ return cbIncludeDecorations->isChecked();
+}
+
+
+int KSnapshotWidget::mode()
+{
+ return comboMode->currentItem();
+}
+
+
+void KSnapshotWidget::slotNewClicked()
+{
+ emit newClicked();
+}
+
+
+void KSnapshotWidget::slotSaveClicked()
+{
+ emit saveClicked();
+}
+
+
+void KSnapshotWidget::slotPrintClicked()
+{
+ emit printClicked();
+}
+
+
+void KSnapshotWidget::slotStartDrag()
+{
+ emit startImageDrag();
+}
+
+
+QPixmap KSnapshotWidget::preview()
+{
+ return *lblImage->pixmap();
+}
+
+
+int KSnapshotWidget::previewWidth()
+{
+ return lblImage->width();
+}
+
+
+int KSnapshotWidget::previewHeight()
+{
+ return lblImage->height();
+}
+
+void KSnapshotWidget::slotCopyClicked()
+{
+ emit copyClicked();
+}
diff --git a/ksnapshot/main.cpp b/ksnapshot/main.cpp
new file mode 100644
index 00000000..f3e397e2
--- /dev/null
+++ b/ksnapshot/main.cpp
@@ -0,0 +1,77 @@
+/*
+ (c) Richard J. Moore 1997-2002
+ (c) Matthias Ettrich 2000
+ (c) Aaron J. Seigo 2002-2004
+ (c) Nadeem Hasan 2003
+ (c) Waldo Bastian 1999-2002
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or ( at your option ) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <kapplication.h>
+#include <kimageio.h>
+#include <klocale.h>
+#include <kcmdlineargs.h>
+#include <kaboutdata.h>
+#include <kiconloader.h>
+
+#include "ksnapshot.h"
+
+static const char description[] =
+ I18N_NOOP("KDE Screenshot Utility");
+
+static KCmdLineOptions options[] =
+{
+ { "c", 0, 0 },
+ { "current", I18N_NOOP("Captures the window under the mouse on startup (instead of the desktop)"), 0 },
+ { 0, 0, 0 }
+};
+
+int main(int argc, char **argv)
+{
+ KAboutData aboutData( "ksnapshot", I18N_NOOP("KSnapshot"),
+ KSNAPVERSION, description, KAboutData::License_GPL,
+ "(c) 1997-2004, Richard J. Moore,\n(c) 2000, Matthias Ettrich,\n(c) 2002-2003 Aaron J. Seigo");
+ aboutData.addAuthor("Richard J. Moore",0, "rich@kde.org");
+ aboutData.addAuthor("Matthias Ettrich",0, "ettrich@kde.org");
+ aboutData.addAuthor("Aaron J. Seigo", 0, "aseigo@kde.org");
+ aboutData.addCredit( "Nadeem Hasan", I18N_NOOP("Region Grabbing\nReworked GUI"),
+ "nhasan@kde.org" );
+
+ KCmdLineArgs::init( argc, argv, &aboutData );
+ KCmdLineArgs::addCmdLineOptions( options ); // Add our own options.
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+
+ KApplication app;
+
+ KImageIO::registerFormats();
+
+ // Create top level window
+ KSnapshot *toplevel;
+
+ if ( args->isSet( "current" ) )
+ toplevel = new KSnapshot( 0, 0, true );
+ else
+ toplevel = new KSnapshot();
+
+ args->clear();
+ app.dcopClient()->setDefaultObject( toplevel->objId() );
+ toplevel->setCaption( app.makeStdCaption("") );
+ app.setMainWidget(toplevel);
+ toplevel->show();
+ return app.exec();
+}
+
diff --git a/ksnapshot/regiongrabber.cpp b/ksnapshot/regiongrabber.cpp
new file mode 100644
index 00000000..c1d8ed98
--- /dev/null
+++ b/ksnapshot/regiongrabber.cpp
@@ -0,0 +1,177 @@
+/*
+ Copyright (C) 2003 Nadeem Hasan <nhasan@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or ( at your option ) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "regiongrabber.h"
+
+#include <qapplication.h>
+#include <qpainter.h>
+#include <qpalette.h>
+#include <qstyle.h>
+#include <qtimer.h>
+#include <qtooltip.h>
+
+#include <kglobalsettings.h>
+
+SizeTip::SizeTip( QWidget *parent, const char *name )
+ : QLabel( parent, name, WStyle_Customize | WX11BypassWM |
+ WStyle_StaysOnTop | WStyle_NoBorder | WStyle_Tool )
+{
+ setMargin( 2 );
+ setIndent( 0 );
+ setFrameStyle( QFrame::Plain | QFrame::Box );
+
+ setPalette( QToolTip::palette() );
+}
+
+void SizeTip::setTip( const QRect &rect )
+{
+ QString tip = QString( "%1x%2" ).arg( rect.width() )
+ .arg( rect.height() );
+
+ setText( tip );
+ adjustSize();
+
+ positionTip( rect );
+}
+
+void SizeTip::positionTip( const QRect &rect )
+{
+ QRect tipRect = geometry();
+ tipRect.moveTopLeft( QPoint( 0, 0 ) );
+
+ if ( rect.intersects( tipRect ) )
+ {
+ QRect deskR = KGlobalSettings::desktopGeometry( QPoint( 0, 0 ) );
+
+ tipRect.moveCenter( QPoint( deskR.width()/2, deskR.height()/2 ) );
+ if ( !rect.contains( tipRect, true ) && rect.intersects( tipRect ) )
+ tipRect.moveBottomRight( geometry().bottomRight() );
+ }
+
+ move( tipRect.topLeft() );
+}
+
+RegionGrabber::RegionGrabber()
+ : QWidget( 0, 0, WStyle_Customize | WX11BypassWM ),
+ mouseDown( false ), sizeTip( 0L )
+{
+ sizeTip = new SizeTip( ( QWidget * )0L );
+
+ tipTimer = new QTimer( this );
+ connect( tipTimer, SIGNAL( timeout() ), SLOT( updateSizeTip() ) );
+
+ QTimer::singleShot( 200, this, SLOT( initGrabber() ) );
+}
+
+RegionGrabber::~RegionGrabber()
+{
+ delete sizeTip;
+}
+
+void RegionGrabber::initGrabber()
+{
+ pixmap = QPixmap::grabWindow( qt_xrootwin() );
+ setPaletteBackgroundPixmap( pixmap );
+
+ QDesktopWidget desktopWidget;
+ QRect desktopSize;
+ if ( desktopWidget.isVirtualDesktop() )
+ desktopSize = desktopWidget.geometry();
+ else
+ desktopSize = desktopWidget.screenGeometry( qt_xrootwin() );
+
+ setGeometry( desktopSize );
+ showFullScreen();
+
+ QApplication::setOverrideCursor( crossCursor );
+}
+
+void RegionGrabber::mousePressEvent( QMouseEvent *e )
+{
+ if ( e->button() == LeftButton )
+ {
+ mouseDown = true;
+ grabRect = QRect( e->pos(), e->pos() );
+ }
+}
+
+void RegionGrabber::mouseMoveEvent( QMouseEvent *e )
+{
+ if ( mouseDown )
+ {
+ sizeTip->hide();
+ tipTimer->start( 250, true );
+
+ drawRubber();
+ grabRect.setBottomRight( e->pos() );
+ drawRubber();
+ }
+}
+
+void RegionGrabber::mouseReleaseEvent( QMouseEvent *e )
+{
+ mouseDown = false;
+ drawRubber();
+ sizeTip->hide();
+
+ grabRect.setBottomRight( e->pos() );
+ grabRect = grabRect.normalize();
+
+ QPixmap region = QPixmap::grabWindow( winId(), grabRect.x(), grabRect.y(),
+ grabRect.width(), grabRect.height() );
+
+ QApplication::restoreOverrideCursor();
+
+ emit regionGrabbed( region );
+}
+
+void RegionGrabber::keyPressEvent( QKeyEvent *e )
+{
+ if ( e->key() == Key_Escape )
+ {
+ QApplication::restoreOverrideCursor();
+ emit regionGrabbed( QPixmap() );
+ }
+ else
+ e->ignore();
+}
+
+void RegionGrabber::updateSizeTip()
+{
+ QRect rect = grabRect.normalize();
+
+ sizeTip->setTip( rect );
+ sizeTip->show();
+}
+
+void RegionGrabber::drawRubber()
+{
+ QPainter p;
+ p.begin( this );
+ p.setRasterOp( NotROP );
+ p.setPen( QPen( color0, 1 ) );
+ p.setBrush( NoBrush );
+
+ style().drawPrimitive( QStyle::PE_FocusRect, &p, grabRect, colorGroup(),
+ QStyle::Style_Default, QStyleOption( colorGroup().base() ) );
+
+ p.end();
+}
+
+#include "regiongrabber.moc"
diff --git a/ksnapshot/regiongrabber.h b/ksnapshot/regiongrabber.h
new file mode 100644
index 00000000..ee9a8238
--- /dev/null
+++ b/ksnapshot/regiongrabber.h
@@ -0,0 +1,70 @@
+/*
+ Copyright (C) 2003 Nadeem Hasan <nhasan@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or ( at your option ) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef REGIONGRABBER_H
+#define REGIONGRABBER_H
+
+#include <qlabel.h>
+#include <qpixmap.h>
+
+class QTimer;
+
+class SizeTip : public QLabel
+{
+ public:
+ SizeTip( QWidget *parent, const char *name=0 );
+ ~SizeTip() {}
+
+ void setTip( const QRect &rect );
+ void positionTip( const QRect &rect );
+};
+
+class RegionGrabber : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ RegionGrabber();
+ ~RegionGrabber();
+
+ protected slots:
+ void initGrabber();
+ void updateSizeTip();
+
+ signals:
+ void regionGrabbed( const QPixmap & );
+
+ protected:
+ void mousePressEvent( QMouseEvent *e );
+ void mouseReleaseEvent( QMouseEvent *e );
+ void mouseMoveEvent( QMouseEvent *e );
+ void keyPressEvent( QKeyEvent *e );
+
+ void drawRubber();
+
+ bool mouseDown;
+ QRect grabRect;
+ QPixmap pixmap;
+
+ SizeTip *sizeTip;
+ QTimer *tipTimer;
+};
+
+#endif // REGIONGRABBER_H
+
diff --git a/ksnapshot/uninstall.desktop b/ksnapshot/uninstall.desktop
new file mode 100644
index 00000000..e1e3e173
--- /dev/null
+++ b/ksnapshot/uninstall.desktop
@@ -0,0 +1,2 @@
+[Desktop Entry]
+Hidden=true
diff --git a/ksnapshot/windowgrabber.cpp b/ksnapshot/windowgrabber.cpp
new file mode 100644
index 00000000..036764b1
--- /dev/null
+++ b/ksnapshot/windowgrabber.cpp
@@ -0,0 +1,353 @@
+/*
+ Copyright (C) 2004 Bernd Brandstetter <bbrand@freenet.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or ( at your option ) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "windowgrabber.h"
+#include <qbitmap.h>
+#include <qpainter.h>
+#include <qptrlist.h>
+#include <algorithm>
+
+#include <config.h>
+
+#ifdef HAVE_X11_EXTENSIONS_SHAPE_H
+#include <X11/extensions/shape.h>
+#endif
+
+
+static
+const int minSize = 8;
+
+static
+bool operator< ( const QRect& r1, const QRect& r2 )
+{
+ return r1.width() * r1.height() < r2.width() * r2.height();
+}
+
+// Recursively iterates over the window w and its children, thereby building
+// a tree of window descriptors. Windows in non-viewable state or with height
+// or width smaller than minSize will be ignored.
+static
+void getWindowsRecursive( std::vector<QRect>& windows, Window w,
+ int rx = 0, int ry = 0, int depth = 0 )
+{
+ XWindowAttributes atts;
+ XGetWindowAttributes( qt_xdisplay(), w, &atts );
+ if ( atts.map_state == IsViewable &&
+ atts.width >= minSize && atts.height >= minSize ) {
+ int x = 0, y = 0;
+ if ( depth ) {
+ x = atts.x + rx;
+ y = atts.y + ry;
+ }
+
+ QRect r( x, y, atts.width, atts.height );
+ if ( std::find( windows.begin(), windows.end(), r ) == windows.end() ) {
+ windows.push_back( r );
+ }
+
+ Window root, parent;
+ Window* children;
+ unsigned int nchildren;
+
+ if( XQueryTree( qt_xdisplay(), w, &root, &parent, &children, &nchildren ) != 0 ) {
+ for( unsigned int i = 0; i < nchildren; ++i ) {
+ getWindowsRecursive( windows, children[ i ], x, y, depth + 1 );
+ }
+ if( children != NULL )
+ XFree( children );
+ }
+ }
+ if ( depth == 0 )
+ std::sort( windows.begin(), windows.end() );
+}
+
+static
+Window findRealWindow( Window w, int depth = 0 )
+{
+ if( depth > 5 )
+ return None;
+ static Atom wm_state = XInternAtom( qt_xdisplay(), "WM_STATE", False );
+ Atom type;
+ int format;
+ unsigned long nitems, after;
+ unsigned char* prop;
+ if( XGetWindowProperty( qt_xdisplay(), w, wm_state, 0, 0, False, AnyPropertyType,
+ &type, &format, &nitems, &after, &prop ) == Success ) {
+ if( prop != NULL )
+ XFree( prop );
+ if( type != None )
+ return w;
+ }
+ Window root, parent;
+ Window* children;
+ unsigned int nchildren;
+ Window ret = None;
+ if( XQueryTree( qt_xdisplay(), w, &root, &parent, &children, &nchildren ) != 0 ) {
+ for( unsigned int i = 0;
+ i < nchildren && ret == None;
+ ++i )
+ ret = findRealWindow( children[ i ], depth + 1 );
+ if( children != NULL )
+ XFree( children );
+ }
+ return ret;
+}
+
+static
+Window windowUnderCursor( bool includeDecorations = true )
+{
+ Window root;
+ Window child;
+ uint mask;
+ int rootX, rootY, winX, winY;
+ XGrabServer( qt_xdisplay() );
+ XQueryPointer( qt_xdisplay(), qt_xrootwin(), &root, &child,
+ &rootX, &rootY, &winX, &winY, &mask );
+ if( child == None )
+ child = qt_xrootwin();
+ if( !includeDecorations ) {
+ Window real_child = findRealWindow( child );
+ if( real_child != None ) // test just in case
+ child = real_child;
+ }
+ return child;
+}
+
+static
+QPixmap grabWindow( Window child, int x, int y, uint w, uint h, uint border )
+{
+ QPixmap pm( QPixmap::grabWindow( qt_xrootwin(), x, y, w, h ) );
+
+#ifdef HAVE_X11_EXTENSIONS_SHAPE_H
+ int tmp1, tmp2;
+ //Check whether the extension is available
+ if ( XShapeQueryExtension( qt_xdisplay(), &tmp1, &tmp2 ) ) {
+ QBitmap mask( w, h );
+ //As the first step, get the mask from XShape.
+ int count, order;
+ XRectangle* rects = XShapeGetRectangles( qt_xdisplay(), child,
+ ShapeBounding, &count, &order );
+ //The ShapeBounding region is the outermost shape of the window;
+ //ShapeBounding - ShapeClipping is defined to be the border.
+ //Since the border area is part of the window, we use bounding
+ // to limit our work region
+ if (rects) {
+ //Create a QRegion from the rectangles describing the bounding mask.
+ QRegion contents;
+ for ( int pos = 0; pos < count; pos++ )
+ contents += QRegion( rects[pos].x, rects[pos].y,
+ rects[pos].width, rects[pos].height );
+ XFree( rects );
+
+ //Create the bounding box.
+ QRegion bbox( 0, 0, w, h );
+
+ if( border > 0 ) {
+ contents.translate( border, border );
+ contents += QRegion( 0, 0, border, h );
+ contents += QRegion( 0, 0, w, border );
+ contents += QRegion( 0, h - border, w, border );
+ contents += QRegion( w - border, 0, border, h );
+ }
+
+ //Get the masked away area.
+ QRegion maskedAway = bbox - contents;
+ QMemArray<QRect> maskedAwayRects = maskedAway.rects();
+
+ //Construct a bitmap mask from the rectangles
+ QPainter p(&mask);
+ p.fillRect(0, 0, w, h, Qt::color1);
+ for (uint pos = 0; pos < maskedAwayRects.count(); pos++)
+ p.fillRect(maskedAwayRects[pos], Qt::color0);
+ p.end();
+
+ pm.setMask(mask);
+ }
+ }
+#endif
+
+ return pm;
+}
+
+WindowGrabber::WindowGrabber()
+: QDialog( 0, 0, true, Qt::WStyle_Customize | Qt::WStyle_NoBorder |
+ Qt::WStyle_StaysOnTop | Qt::WX11BypassWM ),
+ current( -1 ), yPos( -1 )
+{
+ Window root;
+ int y, x;
+ uint w, h, border, depth;
+ XGrabServer( qt_xdisplay() );
+ Window child = windowUnderCursor();
+ XGetGeometry( qt_xdisplay(), child, &root, &x, &y, &w, &h, &border, &depth );
+ QPixmap pm( grabWindow( child, x, y, w, h, border ) );
+ getWindowsRecursive( windows, child );
+ XUngrabServer( qt_xdisplay() );
+
+ setPaletteBackgroundPixmap( pm );
+ setFixedSize( pm.size() );
+ setMouseTracking( true );
+ setGeometry( x, y, w, h );
+}
+
+WindowGrabber::~WindowGrabber()
+{
+}
+
+QPixmap WindowGrabber::grabCurrent( bool includeDecorations )
+{
+ Window root;
+ int y, x;
+ uint w, h, border, depth;
+ XGrabServer( qt_xdisplay() );
+ Window child = windowUnderCursor( includeDecorations );
+ XGetGeometry( qt_xdisplay(), child, &root, &x, &y, &w, &h, &border, &depth );
+ Window parent;
+ Window* children;
+ unsigned int nchildren;
+ if( XQueryTree( qt_xdisplay(), child, &root, &parent,
+ &children, &nchildren ) != 0 ) {
+ if( children != NULL )
+ XFree( children );
+ int newx, newy;
+ Window dummy;
+ if( XTranslateCoordinates( qt_xdisplay(), parent, qt_xrootwin(),
+ x, y, &newx, &newy, &dummy )) {
+ x = newx;
+ y = newy;
+ }
+ }
+ QPixmap pm( grabWindow( child, x, y, w, h, border ) );
+ XUngrabServer( qt_xdisplay() );
+ return pm;
+}
+
+void WindowGrabber::mousePressEvent( QMouseEvent *e )
+{
+ if ( e->button() == QMouseEvent::RightButton )
+ yPos = e->globalY();
+ else {
+ QPixmap pm;
+ if ( current ) {
+ QRect r( windows[ current ] );
+ int w = r.width();
+ int h = r.height();
+ pm.resize( w, h );
+ copyBlt( &pm, 0, 0, paletteBackgroundPixmap(), r.x(), r.y(), w, h );
+ }
+ emit windowGrabbed( pm );
+ accept();
+ }
+}
+
+void WindowGrabber::mouseReleaseEvent( QMouseEvent *e )
+{
+ if ( e->button() == QMouseEvent::RightButton )
+ yPos = -1;
+}
+
+static
+const int minDistance = 10;
+
+void WindowGrabber::mouseMoveEvent( QMouseEvent *e )
+{
+ if ( yPos == -1 ) {
+ int w = windowIndex( e->pos() );
+ if ( w != -1 && w != current ) {
+ current = w;
+ drawBorder();
+ }
+ }
+ else {
+ int y = e->globalY();
+ if ( y > yPos + minDistance ) {
+ decreaseScope( e->pos() );
+ yPos = y;
+ }
+ else if ( y < yPos - minDistance ) {
+ increaseScope( e->pos() );
+ yPos = y;
+ }
+ }
+}
+
+void WindowGrabber::wheelEvent( QWheelEvent *e )
+{
+ if ( e->delta() > 0 )
+ increaseScope( e->pos() );
+ else if ( e->delta() < 0 )
+ decreaseScope( e->pos() );
+ else
+ e->ignore();
+}
+
+// Increases the scope to the next-bigger window containing the mouse pointer.
+// This method is activated by either rotating the mouse wheel forwards or by
+// dragging the mouse forwards while keeping the right mouse button pressed.
+void WindowGrabber::increaseScope( const QPoint &pos )
+{
+ for ( uint i = current + 1; i < windows.size(); i++ ) {
+ if ( windows[ i ].contains( pos ) ) {
+ current = i;
+ break;
+ }
+ }
+ drawBorder();
+}
+
+// Decreases the scope to the next-smaller window containing the mosue pointer.
+// This method is activated by either rotating the mouse wheel backwards or by
+// dragging the mouse backwards while keeping the right mouse button pressed.
+void WindowGrabber::decreaseScope( const QPoint &pos )
+{
+ for ( int i = current - 1; i >= 0; i-- ) {
+ if ( windows[ i ].contains( pos ) ) {
+ current = i;
+ break;
+ }
+ }
+ drawBorder();
+}
+
+// Searches and returns the index of the first (=smallest) window
+// containing the mouse pointer.
+int WindowGrabber::windowIndex( const QPoint &pos ) const
+{
+ for ( uint i = 0; i < windows.size(); i++ ) {
+ if ( windows[ i ].contains( pos ) )
+ return i;
+ }
+ return -1;
+}
+
+// Draws a border around the (child) window currently containing the pointer
+void WindowGrabber::drawBorder()
+{
+ repaint();
+
+ if ( current >= 0 ) {
+ QPainter p;
+ p.begin( this );
+ p.setPen( QPen( Qt::red, 3 ) );
+ p.drawRect( windows[ current ] );
+ p.end();
+ }
+}
+
+#include "windowgrabber.moc"
diff --git a/ksnapshot/windowgrabber.h b/ksnapshot/windowgrabber.h
new file mode 100644
index 00000000..43598576
--- /dev/null
+++ b/ksnapshot/windowgrabber.h
@@ -0,0 +1,59 @@
+/*
+ Copyright (C) 2004 Bernd Brandstetter <bbrand@freenet.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or ( at your option ) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef WINDOWGRABBER_H
+#define WINDOWGRABBER_H
+
+#include <qdialog.h>
+#include <qpixmap.h>
+#include <vector>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
+class WindowGrabber : public QDialog
+{
+ Q_OBJECT
+
+public:
+ WindowGrabber();
+ ~WindowGrabber();
+
+ static QPixmap grabCurrent( bool includeDecorations = true );
+
+signals:
+ void windowGrabbed( const QPixmap & );
+
+protected:
+ void mousePressEvent( QMouseEvent * );
+ void mouseReleaseEvent( QMouseEvent * );
+ void mouseMoveEvent( QMouseEvent * );
+ void wheelEvent( QWheelEvent * );
+
+private:
+ void drawBorder();
+ void increaseScope( const QPoint & );
+ void decreaseScope( const QPoint & );
+ int windowIndex( const QPoint & ) const;
+ std::vector<QRect> windows;
+ int current;
+ int yPos;
+};
+
+
+#endif // WINDOWGRABBER_H