Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
127 KB
Referenced Files
None
Subscribers
None
diff --git a/dialogs/historydialog.cpp b/dialogs/historydialog.cpp
index 548eb00..9b9a0e8 100644
--- a/dialogs/historydialog.cpp
+++ b/dialogs/historydialog.cpp
@@ -1,275 +1,282 @@
#include "historydialog.h"
#include "ui_historydialog.h"
#include "../tools/os.h"
#include "../tools/uploader.h"
#include "../tools/screenshotmanager.h"
#include <QClipboard>
#include <QDesktopServices>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QFileSystemWatcher>
#include <QMenu>
#include <QMessageBox>
#include <QSortFilterProxyModel>
#include <QUrl>
#include <QSettings>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlTableModel>
#include <QDebug>
HistoryDialog::HistoryDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::HistoryDialog)
{
ui->setupUi(this);
ui->filterEdit->setText(tr("Filter.."));
ui->filterEdit->installEventFilter(this);
if (ScreenshotManager::instance()->history().isOpen())
{
mModel = new QSqlTableModel(this, ScreenshotManager::instance()->history());
mModel->setTable("history");
mModel->setHeaderData(0, Qt::Horizontal, tr("Screenshot"));
mModel->setHeaderData(1, Qt::Horizontal, tr("URL"));
mModel->select();
mFilterModel = new QSortFilterProxyModel(mModel);
mFilterModel->setSourceModel(mModel);
mFilterModel->setDynamicSortFilter(true);
mFilterModel->setSortCaseSensitivity(Qt::CaseInsensitive);
mFilterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
mFilterModel->setFilterKeyColumn(-1);
ui->tableView->setModel(mFilterModel);
ui->tableView->hideColumn(2); // No delete hash.
ui->tableView->hideColumn(3); // No timestamp.
ui->tableView->horizontalHeader()->setClickable(false);
ui->tableView->horizontalHeader()->setMovable(false);
ui->tableView->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch);
ui->tableView->horizontalHeader()->setResizeMode(1, QHeaderView::ResizeToContents);
ui->tableView->verticalHeader()->hide();
ui->tableView->setTextElideMode(Qt::ElideLeft);
ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
ui->tableView->setAlternatingRowColors(true);
ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
ui->tableView->setSortingEnabled(true);
if (ui->tableView->model()->rowCount() > 0)
{
ui->clearButton->setEnabled(true);
ui->filterEdit->setEnabled(true);
}
connect(ui->tableView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(selectionChanged(QItemSelection,QItemSelection)));
connect(ui->tableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(open(QModelIndex)));
connect(ui->tableView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenu(QPoint)));
}
else {
ui->tableView->setEnabled(false);
ui->clearButton->setEnabled(false);
}
ui->uploadProgressBar->setValue (Uploader::instance()->progressSent());
if (Uploader::instance()->progressTotal() == 0) {
ui->uploadProgressBar->setMaximum(1);
}
else {
ui->uploadProgressBar->setMaximum(Uploader::instance()->progressTotal());
}
connect(Uploader::instance(), SIGNAL(progress(qint64,qint64)), this, SLOT(uploadProgress(qint64, qint64)));
connect(ui->uploadButton, SIGNAL(clicked()), this, SLOT(upload()));
connect(ui->clearButton , SIGNAL(clicked()), this, SLOT(clear()));
}
HistoryDialog::~HistoryDialog()
{
delete ui;
}
void HistoryDialog::clear()
{
if (QMessageBox::question(this,
tr("Clearing the screenshot history"),
tr("Are you sure you want to clear your entire screenshot history?\nThis cannot be undone."),
tr("Clear History"),
tr("Don't Clear")) == 1) {
return;
}
ScreenshotManager::instance()->clearHistory();
close();
}
void HistoryDialog::contextMenu(QPoint point)
{
mContextIndex = ui->tableView->indexAt(point);;
QMenu contextMenu(ui->tableView);
QAction copyAction((mContextIndex.column() == 0) ? tr("Copy Path") : tr("Copy URL"), &contextMenu);
connect(&copyAction, SIGNAL(triggered()), this, SLOT(copy()));
contextMenu.addAction(&copyAction);
QAction deleteAction(tr("Delete from imgur.com"), &contextMenu);
QAction locationAction(tr("Open Location"), &contextMenu);
QAction removeAction(tr("Remove history entry"), &contextMenu);
+ if (mContextIndex.data().toString().isEmpty()) {
+ copyAction.setEnabled(false);
+ deleteAction.setEnabled(false);
+ }
+
if (mContextIndex.column() == 0) {
connect(&locationAction, SIGNAL(triggered()), this, SLOT(location()));
+
contextMenu.addAction(&locationAction);
}
else {
connect(&deleteAction, SIGNAL(triggered()), this, SLOT(deleteImage()));
contextMenu.addAction(&deleteAction);
}
connect(&removeAction, SIGNAL(triggered()), this, SLOT(removeHistoryEntry()));
-
- if (mContextIndex.data().toString().isEmpty()) {
- copyAction.setEnabled(false);
- deleteAction.setEnabled(false);
- }
-
contextMenu.addAction(&removeAction);
-
contextMenu.exec(QCursor::pos());
}
void HistoryDialog::copy()
{
qApp->clipboard()->setText(mContextIndex.data().toString());
}
void HistoryDialog::deleteImage()
{
QDesktopServices::openUrl(mContextIndex.sibling(mContextIndex.row(), 2).data().toString());
}
void HistoryDialog::location()
{
QDesktopServices::openUrl("file:///" + QFileInfo(mContextIndex.data().toString()).absolutePath());
}
void HistoryDialog::removeHistoryEntry()
{
- ScreenshotManager::instance()->removeHistory(mContextIndex.data().toString(), mContextIndex.sibling(mContextIndex.row(), 3).data().toLongLong());
+ if (mContextIndex.column() == 0) {
+ // File got right clicked:
+ ScreenshotManager::instance()->removeHistory(mContextIndex.data().toString(), mContextIndex.sibling(mContextIndex.row(), 3).data().toLongLong());
+ }
+ else {
+ // Screenshot URL got right clicked:
+ ScreenshotManager::instance()->removeHistory(mContextIndex.sibling(mContextIndex.row(), 0).data().toString(), mContextIndex.sibling(mContextIndex.row(), 3).data().toLongLong());
+ }
+
mModel->select();
}
void HistoryDialog::open(QModelIndex index)
{
if (index.column() == 0) {
QDesktopServices::openUrl(QUrl("file:///" + index.data().toString()));
}
else {
QDesktopServices::openUrl(index.data().toUrl());
}
}
void HistoryDialog::selectionChanged(QItemSelection selected, QItemSelection deselected)
{
Q_UNUSED(deselected);
if (selected.indexes().count() == 0){
return;
}
QModelIndex index = selected.indexes().at(0);
QString screenshot;
if (index.column() == 0) {
screenshot = index.data().toString();
}
else {
screenshot = ui->tableView->model()->index(index.row(), 0).data().toString();
}
mSelectedScreenshot = screenshot;
ui->uploadButton->setEnabled(QFile::exists(screenshot));
}
void HistoryDialog::upload()
{
Uploader::instance()->upload(mSelectedScreenshot);
ui->uploadButton->setEnabled(false);
}
void HistoryDialog::uploadProgress(qint64 sent, qint64 total)
{
ui->uploadProgressBar->setEnabled(true);
ui->uploadProgressBar->setMaximum(total);
ui->uploadProgressBar->setValue(sent);
if (sent == total) {
mModel->select();
}
}
bool HistoryDialog::eventFilter(QObject *object, QEvent *event)
{
if (object == ui->filterEdit) {
if (event->type() == QEvent::FocusIn)
{
if (ui->filterEdit->text() == tr("Filter..")) {
ui->filterEdit->setStyleSheet("");
ui->filterEdit->setText("");
mFilterModel->setFilterWildcard("");
mFilterModel->sort(3, Qt::DescendingOrder);
}
}
else if (event->type() == QEvent::FocusOut)
{
if (ui->filterEdit->text() == "") {
ui->filterEdit->setStyleSheet("color: palette(mid);");
ui->filterEdit->setText(tr("Filter.."));
mFilterModel->sort(3, Qt::DescendingOrder);
}
}
else if (event->type() == QEvent::KeyRelease)
{
if (ui->filterEdit->text() != tr("Filter..") && !ui->filterEdit->text().isEmpty()) {
mFilterModel->setFilterWildcard(ui->filterEdit->text());
mFilterModel->sort(3, Qt::DescendingOrder);
}
else {
mFilterModel->setFilterWildcard("");
mFilterModel->sort(3, Qt::DescendingOrder);
}
}
}
return QDialog::eventFilter(object, event);
}
bool HistoryDialog::event(QEvent *event)
{
if (event->type() == QEvent::Show)
{
restoreGeometry(ScreenshotManager::instance()->settings()->value("geometry/historyDialog").toByteArray());
}
- else if (event->type() == QEvent::Close)
+ else if (event->type() == QEvent::Close)
{
ScreenshotManager::instance()->settings()->setValue("geometry/historyDialog", saveGeometry());
}
return QDialog::event(event);
}
diff --git a/dialogs/optionsdialog.cpp b/dialogs/optionsdialog.cpp
index ef1f5d9..4711bd3 100644
--- a/dialogs/optionsdialog.cpp
+++ b/dialogs/optionsdialog.cpp
@@ -1,731 +1,731 @@
/*
* Copyright (C) 2012 Christian Kaiser
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <QCompleter>
#include <QDate>
#include <QDesktopServices>
#include <QDesktopWidget>
#include <QDirModel>
#include <QFileDialog>
#include <QKeyEvent>
#include <QMessageBox>
#include <QProcess>
#include <QSettings>
#include <QTimer>
#include <QUrl>
#include <QDebug>
#ifdef Q_WS_WIN
#include <windows.h>
#endif
#include "optionsdialog.h"
#include "namingdialog.h"
#include "historydialog.h"
#include "../tools/os.h"
#include "../tools/screenshot.h"
#include "../tools/screenshotmanager.h"
#include "../updater/updater.h"
OptionsDialog::OptionsDialog(QWidget *parent) :
QDialog(parent)
{
ui.setupUi(this);
setModal(true);
#if defined(Q_WS_X11)
// KDE-specific style tweaks.
if (qApp->style()->objectName() == "oxygen") {
ui.browsePushButton->setMaximumWidth(30);
ui.namingOptionsButton->setMaximumWidth(30);
ui.fileGroupBox->setFlat(false);
ui.startupGroupBox->setFlat(false);
ui.capturesGroupBox->setFlat(false);
ui.controlGroupBox->setFlat(false);
ui.interfaceGroupBox->setFlat(false);
ui.screenshotsGroupBox->setFlat(false);
ui.previewGroupBox->setFlat(false);
ui.updaterGroupBox->setFlat(false);
ui.historyGroupBox->setFlat(false);
- ui.clipboardCheckBox->setFlat(false);
+ ui.clipboardGroupBox->setFlat(false);
ui.optionsTab->layout()->setContentsMargins(0, 0, 6, 0);
ui.aboutTab->layout()->setMargin(8);
}
#endif
QTimer::singleShot(0, this, SLOT(init()));
QTimer::singleShot(1, this, SLOT(loadSettings()));
}
void OptionsDialog::accepted()
{
if (hotkeyCollision()) {
QMessageBox::critical(this, tr("Hotkey conflict"), tr("You have assigned the same hotkeys to more than one action."));
return;
}
if (ui.prefixLineEdit->text().contains(QRegExp("[?:\\\\/*\"<>|]"))) {
QMessageBox::critical(this, tr("Filename character error"), tr("The filename can't contain any of the following characters: ? : \\ / * \" < > |"));
return;
}
if (!ui.fileGroupBox->isChecked() && !ui.clipboardCheckBox->isChecked()) {
QMessageBox::critical(this, tr("Final Destination"), tr("You can't take screenshots unless you enable either file saving or the clipboard."));
return;
}
saveSettings();
accept();
}
void OptionsDialog::checkUpdatesNow()
{
Updater::instance()->checkWithFeedback();
}
void OptionsDialog::languageChange(QString language)
{
os::translate(language);
}
void OptionsDialog::loadSettings()
{
settings()->sync();
os::translate(settings()->value("options/language").toString()); // Why? Don't ask me, I'm just the programmer.
setUpdatesEnabled(false);
if (!settings()->contains("file/format")) {
// If there are no settings, get rid of the cancel button so that the user is forced to save them
ui.buttonBox->clear();
ui.buttonBox->addButton(QDialogButtonBox::Ok);
}
ui.startupCheckBox->toggle();
ui.trayCheckBox->toggle();
ui.previewAutocloseCheckBox->toggle();
QString targetDefault;
if (ScreenshotManager::instance()->portableMode()) {
targetDefault = tr("Screenshots");
}
else {
targetDefault = os::getDocumentsPath() + QDir::separator() + tr("Screenshots");
}
settings()->beginGroup("file");
ui.formatComboBox->setCurrentIndex(settings()->value("format", 1).toInt());
ui.prefixLineEdit->setText(settings()->value("prefix", tr("screenshot.")).toString());
ui.namingComboBox->setCurrentIndex(settings()->value("naming", 0).toInt());
ui.targetLineEdit->setText(settings()->value("target", targetDefault).toString());
ui.fileGroupBox->setChecked(settings()->value("enabled", true).toBool());
settings()->endGroup();
settings()->beginGroup("options");
ui.startupCheckBox->setChecked(settings()->value("startup", false).toBool());
ui.startupHideCheckBox->setChecked(settings()->value("startupHide", true).toBool());
ui.hideCheckBox->setChecked(settings()->value("hide", true).toBool());
ui.delaySpinBox->setValue(settings()->value("delay", 0).toInt());
flipToggled(settings()->value("flip", false).toBool());
ui.trayCheckBox->setChecked(settings()->value("tray", true).toBool());
ui.messageCheckBox->setChecked(settings()->value("message", true).toBool());
ui.qualitySlider->setValue(settings()->value("quality", 100).toInt());
ui.playSoundCheckBox->setChecked(settings()->value("playSound", false).toBool());
ui.updaterCheckBox->setChecked(!settings()->value("disableUpdater", false).toBool());
ui.magnifyCheckBox->setChecked(settings()->value("magnify", false).toBool());
ui.cursorCheckBox->setChecked(settings()->value("cursor", false).toBool());
ui.saveAsCheckBox->setChecked(settings()->value("saveAs", false).toBool());
ui.previewGroupBox->setChecked(settings()->value("preview", false).toBool());
ui.previewSizeSpinBox->setValue(settings()->value("previewSize", 300).toInt());
ui.previewPositionComboBox->setCurrentIndex(settings()->value("previewPosition", 3).toInt());
ui.previewAutocloseCheckBox->setChecked(settings()->value("previewAutoclose", false).toBool());
ui.previewAutocloseTimeSpinBox->setValue(settings()->value("previewAutocloseTime", 15).toInt());
ui.previewAutocloseActionComboBox->setCurrentIndex(settings()->value("previewAutocloseAction", 0).toInt());
ui.previewDefaultActionComboBox->setCurrentIndex(settings()->value("previewDefaultAction", 0).toInt());
ui.areaAutocloseCheckBox->setChecked(settings()->value("areaAutoclose", false).toBool());
// History mode is neat for normal operation but I'll keep it disabled by default on portable mode.
ui.historyCheckBox->setChecked(settings()->value("history", (ScreenshotManager::instance()->portableMode()) ? false : true).toBool());
// Advanced
ui.clipboardCheckBox->setChecked(settings()->value("clipboard", true).toBool());
ui.imgurClipboardCheckBox->setChecked(settings()->value("imgurClipboard", false).toBool());
ui.optiPngCheckBox->setChecked(settings()->value("optipng", true).toBool());
ui.closeToTrayCheckBox->setChecked(settings()->value("closeToTray", true).toBool());
ui.currentMonitorCheckBox->setChecked(settings()->value("currentMonitor", false).toBool());
ui.replaceCheckBox->setChecked(settings()->value("replace", false).toBool());
ui.uploadCheckBox->setChecked(settings()->value("uploadAuto", false).toBool());
#ifdef Q_WS_WIN
if (!QFile::exists(qApp->applicationDirPath() + QDir::separator() + "optipng.exe")) {
ui.optiPngCheckBox->setEnabled(false);
ui.optiPngLabel->setText("optipng.exe not found");
}
#elif defined(Q_WS_X11)
if (!QProcess::startDetached("optipng")) {
ui.optiPngCheckBox->setChecked(false);
ui.optiPngCheckBox->setEnabled(false);
ui.optiPngLabel->setText(tr("Install 'OptiPNG'"));
}
//TODO: Sound cue support on Linux
ui.playSoundCheckBox->setVisible(false);
ui.playSoundCheckBox->setChecked(false);
//TODO: Cursor support on X11
ui.cursorCheckBox->setVisible(false);
ui.cursorCheckBox->setChecked(false);
#endif
//TODO: Must replace with not-stupid system
QString lang = settings()->value("language").toString();
int index = ui.languageComboBox->findText(lang);
if (index == -1)
index = ui.languageComboBox->findText("English");
ui.languageComboBox->setCurrentIndex(index);
settings()->endGroup();
settings()->beginGroup("actions");
// This toggle is for the first run
ui.screenCheckBox->toggle();
ui.areaCheckBox->toggle();
ui.windowCheckBox->toggle();
ui.windowPickerCheckBox->toggle();
ui.openCheckBox->toggle();
ui.directoryCheckBox->toggle();
settings()->beginGroup("screen");
ui.screenCheckBox->setChecked(settings()->value("enabled", true).toBool());
ui.screenHotkeyWidget->setHotkey(settings()->value("hotkey", "Print").toString());
settings()->endGroup();
settings()->beginGroup("area");
ui.areaCheckBox->setChecked(settings()->value("enabled").toBool());
ui.areaHotkeyWidget->setHotkey(settings()->value("hotkey", "Ctrl+Print").toString());
settings()->endGroup();
settings()->beginGroup("window");
ui.windowCheckBox->setChecked(settings()->value("enabled").toBool());
ui.windowHotkeyWidget->setHotkey(settings()->value("hotkey", "Alt+Print").toString());
settings()->endGroup();
settings()->beginGroup("windowPicker");
ui.windowPickerCheckBox->setChecked(settings()->value("enabled").toBool());
ui.windowPickerHotkeyWidget->setHotkey(settings()->value("hotkey", "Ctrl+Alt+Print").toString());
settings()->endGroup();
settings()->beginGroup("open");
ui.openCheckBox->setChecked(settings()->value("enabled").toBool());
ui.openHotkeyWidget->setHotkey(settings()->value("hotkey", "Ctrl+PgUp").toString());
settings()->endGroup();
settings()->beginGroup("directory");
ui.directoryCheckBox->setChecked(settings()->value("enabled").toBool());
ui.directoryHotkeyWidget->setHotkey(settings()->value("hotkey", "Ctrl+PgDown").toString());
settings()->endGroup();
settings()->endGroup();
QTimer::singleShot(0, this, SLOT(updatePreview()));
setEnabled(true);
setUpdatesEnabled(true);
}
void OptionsDialog::openUrl(QString url)
{
if (url == "#aboutqt") {
qApp->aboutQt();
}
else {
QDesktopServices::openUrl(QUrl(url));
}
}
void OptionsDialog::rejected()
{
languageChange(settings()->value("options/language").toString()); // Revert language to default.
}
void OptionsDialog::saveSettings()
{
settings()->beginGroup("file");
settings()->setValue("format", ui.formatComboBox->currentIndex());
settings()->setValue("prefix", ui.prefixLineEdit->text());
settings()->setValue("naming", ui.namingComboBox->currentIndex());
settings()->setValue("target", ui.targetLineEdit->text());
settings()->setValue("enabled", ui.fileGroupBox->isChecked());
settings()->endGroup();
settings()->beginGroup("options");
settings()->setValue("startup", ui.startupCheckBox->isChecked());
settings()->setValue("startupHide", ui.startupHideCheckBox->isChecked());
settings()->setValue("hide", ui.hideCheckBox->isChecked());
settings()->setValue("delay", ui.delaySpinBox->value());
settings()->setValue("tray", ui.trayCheckBox->isChecked());
settings()->setValue("message", ui.messageCheckBox->isChecked());
settings()->setValue("quality", ui.qualitySlider->value());
settings()->setValue("playSound", ui.playSoundCheckBox->isChecked());
// We save the explicit string because addition/removal of language files can cause it to change
settings()->setValue("language", ui.languageComboBox->currentText());
// This settings is inverted because the first iteration of the Updater did not have a settings but instead relied on the messagebox choice of the user.
settings()->setValue("disableUpdater", !ui.updaterCheckBox->isChecked());
settings()->setValue("magnify", ui.magnifyCheckBox->isChecked());
settings()->setValue("cursor", ui.cursorCheckBox->isChecked());
settings()->setValue("saveAs", ui.saveAsCheckBox->isChecked());
settings()->setValue("preview", ui.previewGroupBox->isChecked());
settings()->setValue("previewSize", ui.previewSizeSpinBox->value());
settings()->setValue("previewPosition", ui.previewPositionComboBox->currentIndex());
settings()->setValue("previewAutoclose", ui.previewAutocloseCheckBox->isChecked());
settings()->setValue("previewAutocloseTime", ui.previewAutocloseTimeSpinBox->value());
settings()->setValue("previewAutocloseAction", ui.previewAutocloseActionComboBox->currentIndex());
settings()->setValue("previewDefaultAction", ui.previewDefaultActionComboBox->currentIndex());
settings()->setValue("areaAutoclose", ui.areaAutocloseCheckBox->isChecked());
settings()->setValue("history", ui.historyCheckBox->isChecked());
// Advanced
settings()->setValue("closeToTray", ui.closeToTrayCheckBox->isChecked());
settings()->setValue("clipboard", ui.clipboardCheckBox->isChecked());
settings()->setValue("imgurClipboard", ui.imgurClipboardCheckBox->isChecked());
settings()->setValue("optipng", ui.optiPngCheckBox->isChecked());
settings()->setValue("currentMonitor", ui.currentMonitorCheckBox->isChecked());
settings()->setValue("replace", ui.replaceCheckBox->isChecked());
//Upload
settings()->setValue("uploadAuto", ui.uploadCheckBox->isChecked());
settings()->endGroup();
settings()->beginGroup("actions");
settings()->beginGroup("screen");
settings()->setValue("enabled", ui.screenCheckBox->isChecked());
settings()->setValue("hotkey", ui.screenHotkeyWidget->hotkey());
settings()->endGroup();
settings()->beginGroup("area");
settings()->setValue("enabled", ui.areaCheckBox->isChecked());
settings()->setValue("hotkey", ui.areaHotkeyWidget->hotkey());
settings()->endGroup();
settings()->beginGroup("window");
settings()->setValue("enabled", ui.windowCheckBox->isChecked());
settings()->setValue("hotkey", ui.windowHotkeyWidget->hotkey());
settings()->endGroup();
settings()->beginGroup("windowPicker");
settings()->setValue("enabled", ui.windowPickerCheckBox->isChecked());
settings()->setValue("hotkey", ui.windowPickerHotkeyWidget->hotkey());
settings()->endGroup();
settings()->beginGroup("open");
settings()->setValue("enabled", ui.openCheckBox->isChecked());
settings()->setValue("hotkey", ui.openHotkeyWidget->hotkey());
settings()->endGroup();
settings()->beginGroup("directory");
settings()->setValue("enabled", ui.directoryCheckBox->isChecked());
settings()->setValue("hotkey", ui.directoryHotkeyWidget->hotkey());
settings()->endGroup();
settings()->endGroup();
}
void OptionsDialog::updatePreview()
{
Screenshot::NamingOptions options;
options.naming = (Screenshot::Naming) ui.namingComboBox->currentIndex();
options.flip = settings()->value("options/flip", false).toBool();
options.leadingZeros = settings()->value("options/naming/leadingZeros", 0).toInt();
options.dateFormat = settings()->value("options/naming/dateFormat", "yyyy-MM-dd").toString();
if (ui.fileGroupBox->isChecked()) // Only change the naming button when file options are enabled.
ui.namingOptionsButton->setDisabled((options.naming == Screenshot::Empty));
QString preview = Screenshot::getName(options,
ui.prefixLineEdit->text(),
QDir(ui.targetLineEdit->text()));
preview = QString("%1.%2").arg(preview).arg(ui.formatComboBox->currentText().toLower());
if (preview.length() >= 40) {
preview.truncate(37);
preview.append("...");
}
ui.previewLabel->setText(preview);
}
void OptionsDialog::viewHistory()
{
HistoryDialog historyDialog(this);
historyDialog.exec();
}
//
bool OptionsDialog::event(QEvent* event)
{
if (event->type() == QEvent::LanguageChange) {
// ComboBoxes revert to the first index when translated:
int naming = ui.namingComboBox->currentIndex();
int format = ui.formatComboBox->currentIndex();
int previewPosition = ui.previewPositionComboBox->currentIndex();
int previewAutoclose = ui.previewAutocloseActionComboBox->currentIndex();
int previewDefault = ui.previewDefaultActionComboBox->currentIndex();
ui.retranslateUi(this);
// Restoring comboboxes
ui.namingComboBox->setCurrentIndex(naming);
ui.formatComboBox->setCurrentIndex(format);
ui.previewPositionComboBox->setCurrentIndex(previewPosition);
ui.previewAutocloseActionComboBox->setCurrentIndex(previewAutoclose);
ui.previewDefaultActionComboBox->setCurrentIndex(previewDefault);
updatePreview();
resize(minimumSizeHint());
}
else if (event->type() == QEvent::Close || event->type() == QEvent::Hide) {
settings()->setValue("geometry/optionsDialog", saveGeometry());
if (!settings()->contains("file/format")) {
// I'm afraid I can't let you do that, Dave.
event->ignore();
return false;
}
}
else if (event->type() == QEvent::Show)
{
restoreGeometry(settings()->value("geometry/optionsDialog").toByteArray());
}
return QDialog::event(event);
}
#ifdef Q_WS_WIN
// Qt does not send the print screen key as a regular QKeyPress event, so we must use the Windows API
bool OptionsDialog::winEvent(MSG *message, long *result)
{
if ((message->message == WM_KEYUP || message->message == WM_SYSKEYUP)
&& message->wParam == VK_SNAPSHOT) {
qApp->postEvent(qApp->focusWidget(), new QKeyEvent(QEvent::KeyPress, Qt::Key_Print, qApp->keyboardModifiers()));
}
return QDialog::winEvent(message, result);
}
#endif
//
void OptionsDialog::browse()
{
QString fileName = QFileDialog::getExistingDirectory(this,
tr("Select where you want to save the screenshots"),
ui.targetLineEdit->text());
if (fileName.isEmpty())
return;
ui.targetLineEdit->setText(fileName);
}
void OptionsDialog::dialogButtonClicked(QAbstractButton *button)
{
if (ui.buttonBox->buttonRole(button) == QDialogButtonBox::ResetRole) {
QMessageBox msgBox;
msgBox.setWindowTitle(tr("Lightscreen - Restore Default Options"));
msgBox.setText(tr("Restoring the default options will cause you to lose all of your current configuration."));
msgBox.setIcon(QMessageBox::Warning);
QPushButton *restoreButton = msgBox.addButton(tr("Restore"), QMessageBox::ActionRole);
QPushButton *dontRestoreButton = msgBox.addButton(tr("Don't Restore"), QMessageBox::ActionRole);
msgBox.setDefaultButton(dontRestoreButton);
msgBox.exec();
Q_UNUSED(restoreButton)
if (msgBox.clickedButton() == dontRestoreButton)
return;
QString language = settings()->value("options/language").toString(); // Only mantain language.
settings()->clear();
settings()->setValue("options/language", language);
loadSettings();
}
}
void OptionsDialog::flipToggled(bool checked)
{
setUpdatesEnabled(false);
ui.filenameLayout->removeWidget(ui.prefixLineEdit);
ui.filenameLayout->removeWidget(ui.namingComboBox);
if (checked) {
ui.filenameLayout->addWidget(ui.namingComboBox);
ui.filenameLayout->addWidget(ui.prefixLineEdit);
}
else {
ui.filenameLayout->addWidget(ui.prefixLineEdit);
ui.filenameLayout->addWidget(ui.namingComboBox);
}
if (ui.prefixLineEdit->text() == tr("screenshot.")
&& checked)
ui.prefixLineEdit->setText(tr(".screenshot"));
if (ui.prefixLineEdit->text() == tr(".screenshot")
&& !checked)
ui.prefixLineEdit->setText(tr("screenshot."));
setUpdatesEnabled(true); // Avoids flicker
}
void OptionsDialog::init()
{
// Make the scroll area share the Tab Widget background color
QPalette optionsPalette = ui.optionsScrollArea->palette();
optionsPalette.setColor(QPalette::Window, ui.tabWidget->palette().color(QPalette::Base));
ui.optionsScrollArea->setPalette(optionsPalette);
ui.buttonBox->addButton(new QPushButton(" " + tr("Restore Defaults") + " ", this), QDialogButtonBox::ResetRole);
// Set up the autocomplete for the directory.
QCompleter *completer = new QCompleter(this);
completer->setModel(new QDirModel(QStringList(), QDir::Dirs, QDir::Name, completer));
ui.targetLineEdit->setCompleter(completer);
// HotkeyWidget icons.
ui.screenHotkeyWidget->setIcon (QIcon(":/icons/screen"));
ui.windowHotkeyWidget->setIcon (QIcon(":/icons/window"));
- ui.windowPickerHotkeyWidget->setIcon(QIcon(":/icons/picker"));
+ ui.windowPickerHotkeyWidget->setIcon(QIcon(":/icons/pickWindow"));
ui.areaHotkeyWidget->setIcon (QIcon(":/icons/area"));
ui.openHotkeyWidget->setIcon (QIcon(":/icons/lightscreen.small"));
ui.directoryHotkeyWidget->setIcon (QIcon(":/icons/folder"));
// Version
ui.versionLabel->setText(tr("Version %1").arg(qApp->applicationVersion()));
setEnabled(false); // We disable the widgets to prevent any user interaction until the settings have loaded.
//
// Connections
//
connect(ui.buttonBox , SIGNAL(clicked(QAbstractButton*)), this , SLOT(dialogButtonClicked(QAbstractButton*)));
connect(ui.buttonBox , SIGNAL(accepted()) , this , SLOT(accepted()));
connect(ui.buttonBox , SIGNAL(rejected()) , this , SLOT(rejected()));
connect(ui.namingOptionsButton , SIGNAL(clicked()) , this , SLOT(namingOptions()));
connect(ui.prefixLineEdit , SIGNAL(textEdited(QString)) , this , SLOT(updatePreview()));
connect(ui.formatComboBox , SIGNAL(currentIndexChanged(int)) , this , SLOT(updatePreview()));
connect(ui.namingComboBox , SIGNAL(currentIndexChanged(int)) , this , SLOT(updatePreview()));
connect(ui.browsePushButton , SIGNAL(clicked()) , this , SLOT(browse()));
connect(ui.checkUpdatesPushButton , SIGNAL(clicked()) , this , SLOT(checkUpdatesNow()));
connect(ui.historyPushButton , SIGNAL(clicked()) , this , SLOT(viewHistory()));
connect(ui.screenCheckBox , SIGNAL(toggled(bool)), ui.screenHotkeyWidget , SLOT(setEnabled(bool)));
connect(ui.areaCheckBox , SIGNAL(toggled(bool)), ui.areaHotkeyWidget , SLOT(setEnabled(bool)));
connect(ui.windowCheckBox , SIGNAL(toggled(bool)), ui.windowHotkeyWidget , SLOT(setEnabled(bool)));
connect(ui.windowPickerCheckBox, SIGNAL(toggled(bool)), ui.windowPickerHotkeyWidget, SLOT(setEnabled(bool)));
connect(ui.openCheckBox , SIGNAL(toggled(bool)), ui.openHotkeyWidget , SLOT(setEnabled(bool)));
connect(ui.directoryCheckBox , SIGNAL(toggled(bool)), ui.directoryHotkeyWidget, SLOT(setEnabled(bool)));
// "Save as" disables the file target input field.
connect(ui.saveAsCheckBox , SIGNAL(toggled(bool)), ui.targetLineEdit , SLOT(setDisabled(bool)));
connect(ui.saveAsCheckBox , SIGNAL(toggled(bool)), ui.browsePushButton , SLOT(setDisabled(bool)));
connect(ui.saveAsCheckBox , SIGNAL(toggled(bool)), ui.directoryLabel , SLOT(setDisabled(bool)));
connect(ui.startupCheckBox , SIGNAL(toggled(bool)), ui.startupHideCheckBox , SLOT(setEnabled(bool)));
connect(ui.qualitySlider , SIGNAL(valueChanged(int)), ui.qualityValueLabel, SLOT(setNum(int)));
connect(ui.trayCheckBox , SIGNAL(toggled(bool)), ui.messageCheckBox , SLOT(setEnabled(bool)));
connect(ui.trayCheckBox , SIGNAL(toggled(bool)), ui.closeToTrayCheckBox , SLOT(setEnabled(bool)));
// Auto-upload disables the default action button in the previews.
connect(ui.uploadCheckBox , SIGNAL(toggled(bool)), ui.previewDefaultActionLabel , SLOT(setDisabled(bool)));
connect(ui.uploadCheckBox , SIGNAL(toggled(bool)), ui.previewDefaultActionComboBox, SLOT(setDisabled(bool)));
connect(ui.directoryCheckBox , SIGNAL(toggled(bool)), ui.directoryHotkeyWidget, SLOT(setEnabled(bool)));
connect(ui.moreInformationLabel, SIGNAL(linkActivated(QString)) , this, SLOT(openUrl(QString)));
connect(ui.languageComboBox , SIGNAL(currentIndexChanged(QString)), this, SLOT(languageChange(QString)));
connect(ui.mainLabel , SIGNAL(linkActivated(QString)), this, SLOT(openUrl(QString)));
connect(ui.licenseAboutLabel, SIGNAL(linkActivated(QString)), this, SLOT(openUrl(QString)));
connect(ui.linksLabel, SIGNAL(linkActivated(QString)), this, SLOT(openUrl(QString)));
//
// Languages
//
QDir languages(":/translations");
ui.languageComboBox->addItem("English");
foreach (QString language, languages.entryList()) {
ui.languageComboBox->addItem(language);
}
}
void OptionsDialog::namingOptions()
{
NamingDialog namingDialog((Screenshot::Naming) ui.namingComboBox->currentIndex());
namingDialog.exec();
flipToggled(settings()->value("options/flip").toBool());
updatePreview();
}
//
bool OptionsDialog::hotkeyCollision()
{
// Check for hotkey collision (there's probably a better way to do this...=)
if (ui.screenCheckBox->isChecked()) {
if (ui.screenHotkeyWidget->hotkey() == ui.areaHotkeyWidget->hotkey()
&& ui.areaCheckBox->isChecked())
return true;
if (ui.screenHotkeyWidget->hotkey() == ui.windowHotkeyWidget->hotkey()
&& ui.windowCheckBox->isChecked())
return true;
if (ui.screenHotkeyWidget->hotkey() == ui.windowPickerHotkeyWidget->hotkey()
&& ui.windowPickerCheckBox->isChecked())
return true;
if (ui.screenHotkeyWidget->hotkey() == ui.openHotkeyWidget->hotkey()
&& ui.openCheckBox->isChecked())
return true;
if (ui.screenHotkeyWidget->hotkey() == ui.directoryHotkeyWidget->hotkey()
&& ui.directoryCheckBox->isChecked())
return true;
}
if (ui.areaCheckBox->isChecked()) {
if (ui.areaHotkeyWidget->hotkey() == ui.screenHotkeyWidget->hotkey()
&& ui.screenCheckBox->isChecked())
return true;
if (ui.areaHotkeyWidget->hotkey() == ui.windowHotkeyWidget->hotkey()
&& ui.windowCheckBox->isChecked())
return true;
if (ui.areaHotkeyWidget->hotkey() == ui.windowPickerHotkeyWidget->hotkey()
&& ui.windowPickerCheckBox->isChecked())
return true;
if (ui.areaHotkeyWidget->hotkey() == ui.openHotkeyWidget->hotkey()
&& ui.openCheckBox->isChecked())
return true;
if (ui.areaHotkeyWidget->hotkey() == ui.directoryHotkeyWidget->hotkey()
&& ui.directoryCheckBox->isChecked())
return true;
}
if (ui.windowCheckBox->isChecked()) {
if (ui.windowHotkeyWidget->hotkey() == ui.screenHotkeyWidget->hotkey()
&& ui.screenCheckBox->isChecked())
return true;
if (ui.windowHotkeyWidget->hotkey() == ui.areaHotkeyWidget->hotkey()
&& ui.areaCheckBox->isChecked())
return true;
if (ui.windowHotkeyWidget->hotkey() == ui.windowPickerHotkeyWidget->hotkey()
&& ui.windowPickerCheckBox->isChecked())
return true;
if (ui.windowHotkeyWidget->hotkey() == ui.openHotkeyWidget->hotkey()
&& ui.openCheckBox->isChecked())
return true;
if (ui.windowHotkeyWidget->hotkey() == ui.directoryHotkeyWidget->hotkey()
&& ui.directoryCheckBox->isChecked())
return true;
}
if (ui.openCheckBox->isChecked()) {
if (ui.openHotkeyWidget->hotkey() == ui.screenHotkeyWidget->hotkey()
&& ui.screenCheckBox->isChecked())
return true;
if (ui.openHotkeyWidget->hotkey() == ui.areaHotkeyWidget->hotkey()
&& ui.areaCheckBox->isChecked())
return true;
if (ui.openHotkeyWidget->hotkey() == ui.windowPickerHotkeyWidget->hotkey()
&& ui.windowPickerCheckBox->isChecked())
return true;
if (ui.openHotkeyWidget->hotkey() == ui.windowHotkeyWidget->hotkey()
&& ui.windowCheckBox->isChecked())
return true;
if (ui.openHotkeyWidget->hotkey() == ui.directoryHotkeyWidget->hotkey()
&& ui.directoryCheckBox->isChecked())
return true;
}
if (ui.directoryCheckBox->isChecked()) {
if (ui.directoryHotkeyWidget->hotkey() == ui.screenHotkeyWidget->hotkey()
&& ui.screenCheckBox->isChecked())
return true;
if (ui.directoryHotkeyWidget->hotkey() == ui.areaHotkeyWidget->hotkey()
&& ui.areaCheckBox->isChecked())
return true;
if (ui.directoryHotkeyWidget->hotkey() == ui.windowPickerHotkeyWidget->hotkey()
&& ui.windowPickerCheckBox->isChecked())
return true;
if (ui.directoryHotkeyWidget->hotkey() == ui.windowHotkeyWidget->hotkey()
&& ui.windowCheckBox->isChecked())
return true;
if (ui.directoryHotkeyWidget->hotkey() == ui.openHotkeyWidget->hotkey()
&& ui.openCheckBox->isChecked())
return true;
}
return false;
}
QSettings *OptionsDialog::settings() const
{
return ScreenshotManager::instance()->settings();
}
diff --git a/dialogs/previewdialog.cpp b/dialogs/previewdialog.cpp
index ed8fb24..423a396 100644
--- a/dialogs/previewdialog.cpp
+++ b/dialogs/previewdialog.cpp
@@ -1,404 +1,404 @@
/*
* Copyright (C) 2012 Christian Kaiser
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "previewdialog.h"
#include "screenshotdialog.h"
#include "../tools/screenshot.h"
#include "../tools/screenshotmanager.h"
#include "../tools/os.h"
#include <QApplication>
#include <QDesktopWidget>
#include <QGraphicsDropShadowEffect>
#include <QHBoxLayout>
#include <QIcon>
#include <QLabel>
#include <QList>
#include <QMenu>
#include <QObject>
#include <QPalette>
#include <QPushButton>
#include <QSettings>
#include <QStackedLayout>
#include <QToolButton>
#include <QDebug>
PreviewDialog::PreviewDialog(QWidget *parent) :
QDialog(parent), mAutoclose(0)
{
setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint);
setWindowTitle(tr("Screenshot Preview"));
QSettings *settings = ScreenshotManager::instance()->settings();
mSize = settings->value("options/previewSize", 300).toInt();
mPosition = settings->value("options/previewPosition", 3).toInt();
if (settings->value("options/previewAutoclose", false).toBool()) {
mAutoclose = settings->value("options/previewAutocloseTime").toInt();
mAutocloseReset = mAutoclose;
mAutocloseAction = settings->value("options/previewAutocloseAction").toInt();
}
QHBoxLayout *l = new QHBoxLayout;
mStack = new QStackedLayout;
connect(mStack, SIGNAL(currentChanged(int)), this, SLOT(indexChanged(int)));
mPrevButton = new QPushButton(QIcon(":/icons/arrow-left"), "", this);
connect(mPrevButton, SIGNAL(clicked()), this, SLOT(previous()));
mNextButton = new QPushButton(QIcon(":/icons/arrow-right"), "", this);
connect(mNextButton, SIGNAL(clicked()), this, SLOT(next()));
mPrevButton->setCursor(Qt::PointingHandCursor);
mPrevButton->setFlat(true);
mPrevButton->setGraphicsEffect(os::shadow(Qt::white));
mPrevButton->setIconSize(QSize(24, 24));
mPrevButton->setVisible(false);
mNextButton->setCursor(Qt::PointingHandCursor);
mNextButton->setFlat(true);
mNextButton->setGraphicsEffect(os::shadow(Qt::white));
mNextButton->setIconSize(QSize(24, 24));
mNextButton->setVisible(false);
l->addWidget(mPrevButton);
l->addLayout(mStack);
l->addWidget(mNextButton);
l->setMargin(0);
l->setContentsMargins(6, 6, 6, 6);
mStack->setMargin(0);
setMaximumHeight(mSize);
setLayout(l);
if (mAutoclose) {
startTimer(1000);
}
}
void PreviewDialog::add(Screenshot *screenshot)
{
if (!isVisible()) {
show();
}
if (mAutoclose) {
mAutoclose = mAutocloseReset;
}
QLabel *label = new QLabel(this);
label->setGraphicsEffect(os::shadow());
bool small = false;
QSize size = screenshot->pixmap().size();
if (size.width() > mSize || size.height() > mSize) {
size.scale(mSize, mSize, Qt::KeepAspectRatio);
}
else {
small = true;
}
QPixmap thumbnail = screenshot->pixmap().scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
label->setPixmap(thumbnail);
thumbnail = QPixmap();
label->setAlignment(Qt::AlignCenter);
if (size.height() < 120) {
label->setMinimumHeight(120);
}
if (size.width() < 140) {
label->setMinimumWidth(140);
}
label->resize(size);
QPushButton *discardPushButton = new QPushButton(QIcon(":/icons/no") , "", label);
- QPushButton *enlargePushButton = new QPushButton(QIcon(":/icons/zoom.in"), "", label);
+ QPushButton *enlargePushButton = new QPushButton(QIcon(":/icons/preview"), "", label);
QToolButton *confirmPushButton = new QToolButton(label);
confirmPushButton->setIconSize(QSize(24, 24));
confirmPushButton->setCursor(Qt::PointingHandCursor);
confirmPushButton->setGraphicsEffect(os::shadow(Qt::white));
if (ScreenshotManager::instance()->settings()->value("options/previewDefaultAction", 0).toInt() == 0
|| ScreenshotManager::instance()->settings()->value("options/uploadAuto").toBool()) {
// Default button, confirm & upload.
confirmPushButton->setIcon(QIcon(":/icons/yes"));
if (!ScreenshotManager::instance()->settings()->value("options/uploadAuto").toBool()) {
QMenu *confirmMenu = new QMenu(confirmPushButton);
confirmMenu->setObjectName("confirmMenu");
QAction *uploadAction = new QAction(QIcon(":/icons/imgur"), tr("Upload"), confirmPushButton);
connect(uploadAction, SIGNAL(triggered()), screenshot, SLOT(markUpload()));
connect(uploadAction, SIGNAL(triggered()), screenshot, SLOT(confirm()));
connect(uploadAction, SIGNAL(triggered()), this, SLOT(closePreview()));
connect(this, SIGNAL(uploadAll()), uploadAction, SLOT(trigger()));
confirmMenu->addAction(uploadAction);
confirmPushButton->setMenu(confirmMenu);
confirmPushButton->setPopupMode(QToolButton::MenuButtonPopup);
}
connect(this, SIGNAL(acceptAll()), confirmPushButton, SLOT(click()));
connect(confirmPushButton, SIGNAL(clicked()), screenshot, SLOT(confirm()));
connect(confirmPushButton, SIGNAL(clicked()), this, SLOT(closePreview()));
}
else {
// Reversed button, upload & confirm.
confirmPushButton->setIcon(QIcon(":/icons/imgur"));
QMenu *confirmMenu = new QMenu(confirmPushButton);
confirmMenu->setObjectName("confirmMenu");
QAction *confirmAction = new QAction(QIcon(":/icons/yes"), tr("Save"), confirmPushButton);
connect(this, SIGNAL(acceptAll()), confirmAction, SLOT(trigger()));
connect(confirmAction, SIGNAL(triggered()), screenshot, SLOT(confirm()));
connect(confirmAction, SIGNAL(triggered()), this, SLOT(closePreview()));
connect(confirmPushButton, SIGNAL(clicked()), screenshot, SLOT(markUpload()));
connect(confirmPushButton, SIGNAL(clicked()), screenshot, SLOT(confirm()));
connect(confirmPushButton, SIGNAL(clicked()), this, SLOT(closePreview()));
connect(this, SIGNAL(uploadAll()), confirmPushButton, SLOT(click()));
confirmMenu->addAction(confirmAction);
confirmPushButton->setMenu(confirmMenu);
confirmPushButton->setPopupMode(QToolButton::MenuButtonPopup);
}
confirmPushButton->setAutoRaise(true);
confirmPushButton->setVisible(false);
discardPushButton->setIconSize(QSize(24, 24));
discardPushButton->setCursor(Qt::PointingHandCursor);
discardPushButton->setGraphicsEffect(os::shadow(Qt::white));
discardPushButton->setFlat(true);
discardPushButton->setVisible(false);
enlargePushButton->setIconSize(QSize(22, 22));
enlargePushButton->setCursor(Qt::PointingHandCursor);
enlargePushButton->setGraphicsEffect(os::shadow(Qt::white));
enlargePushButton->setFlat(true);
enlargePushButton->setVisible(false);
enlargePushButton->setDisabled(small);
connect(this, SIGNAL(rejectAll()), discardPushButton, SLOT(click()));
connect(discardPushButton, SIGNAL(clicked()), screenshot, SLOT(discard()));
connect(discardPushButton, SIGNAL(clicked()), this, SLOT(closePreview()));
connect(enlargePushButton, SIGNAL(clicked()), this, SLOT(enlargePreview()));
QHBoxLayout *wlayout = new QHBoxLayout;
wlayout->addWidget(confirmPushButton);
wlayout->addStretch();
wlayout->addWidget(enlargePushButton);
wlayout->addStretch();
wlayout->addWidget(discardPushButton);
wlayout->setMargin(0);
QVBoxLayout *wl = new QVBoxLayout;
wl->addStretch();
wl->addLayout(wlayout);
wl->setMargin(0);
label->setLayout(wl);
mStack->addWidget(label);
mStack->setCurrentIndex(mStack->count()-1);
mNextButton->setEnabled(false);
if (mStack->count() >= 2 && !mNextButton->isVisible()) {
mNextButton->setVisible(true);
mPrevButton->setVisible(true);
}
relocate();
}
int PreviewDialog::count() const
{
return mStack->count();
}
//
void PreviewDialog::closePreview()
{
QWidget *widget = mStack->currentWidget();
mStack->removeWidget(widget);
widget->deleteLater();
if (mStack->count() == 0) {
close();
}
else {
relocate();
}
}
void PreviewDialog::enlargePreview()
{
Screenshot *screenshot = qobject_cast<Screenshot*>(ScreenshotManager::instance()->children().at(mStack->currentIndex()));
if (screenshot) {
new ScreenshotDialog(screenshot, this);
}
}
void PreviewDialog::indexChanged(int i)
{
if (i == mStack->count()-1) {
mNextButton->setEnabled(false);
mPrevButton->setEnabled(true);
}
if (i == 0 && mStack->count() > 1) {
mNextButton->setEnabled(true);
mPrevButton->setEnabled(false);
}
if (i != 0 && i != mStack->count()-1) {
mNextButton->setEnabled(true);
mPrevButton->setEnabled(true);
}
if (mStack->count() < 2) {
mNextButton->setEnabled(false);
mPrevButton->setEnabled(false);
}
if (mStack->widget(i)) {
mStack->widget(i)->setFocus();
}
if (mStack->count() > 1) {
setWindowTitle(tr("Screenshot Preview (%1 of %2)").arg(mStack->currentIndex()+1).arg(mStack->count()));
}
else {
setWindowTitle(tr("Screenshot Preview"));
}
}
void PreviewDialog::next()
{
mStack->setCurrentIndex(mStack->currentIndex()+1);
relocate();
}
void PreviewDialog::previous()
{
mStack->setCurrentIndex(mStack->currentIndex()-1);
relocate();
}
void PreviewDialog::relocate()
{
updateGeometry();
resize(minimumSizeHint());
QApplication::sendEvent(this, new QEvent(QEvent::Enter)); // Ensures the buttons are visible.
QPoint where;
switch (mPosition)
{
case 0:
where = QApplication::desktop()->availableGeometry(this).topLeft();
break;
case 1:
where = QApplication::desktop()->availableGeometry(this).topRight();
where.setX(where.x() - frameGeometry().width());
break;
case 2:
where = QApplication::desktop()->availableGeometry(this).bottomLeft();
where.setY(where.y() - frameGeometry().height());
break;
case 3:
default:
where = QApplication::desktop()->availableGeometry(this).bottomRight();
where.setX(where.x() - frameGeometry().width());
where.setY(where.y() - frameGeometry().height());
break;
}
move(where);
}
//
bool PreviewDialog::event(QEvent *event)
{
if ((event->type() == QEvent::Enter || event->type() == QEvent::Leave)
&& mStack->currentWidget())
{
foreach (QObject *child, mStack->currentWidget()->children()) {
QWidget *widget = qobject_cast<QWidget*>(child);
if (widget) {
// Lets avoid disappearing buttons and bail if the menu is open.
QMenu *confirmMenu = widget->findChild<QMenu*>("confirmMenu");
if (confirmMenu && confirmMenu->isVisible())
return false;
widget->setVisible((event->type() == QEvent::Enter));
}
}
}
else if (event->type() == QEvent::Close) {
deleteLater();
}
else if (event->type() == QEvent::MouseButtonDblClick) {
enlargePreview();
}
return QDialog::event(event);
}
void PreviewDialog::timerEvent(QTimerEvent *event)
{
if (mAutoclose == 0) {
if (mAutocloseAction == 0) {
emit acceptAll();
}
else if (mAutocloseAction == 1) {
emit uploadAll();
}
else {
emit rejectAll();
}
}
else if (mAutoclose < 0) {
killTimer(event->timerId());
}
else {
setWindowTitle(tr("Preview: Closing in %1").arg(mAutoclose));
mAutoclose--;
}
}
diff --git a/dialogs/screenshotdialog.cpp b/dialogs/screenshotdialog.cpp
index 76ac2fc..c263608 100644
--- a/dialogs/screenshotdialog.cpp
+++ b/dialogs/screenshotdialog.cpp
@@ -1,141 +1,147 @@
/*
* Copyright (C) 2012 Christian Kaiser
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "screenshotdialog.h"
#include "../tools/screenshot.h"
#include <QApplication>
#include <QDesktopWidget>
#include <QHBoxLayout>
#include <QLabel>
#include <QMouseEvent>
#include <QScrollArea>
#include <QScrollBar>
#include <QDebug>
ScreenshotDialog::ScreenshotDialog(Screenshot *screenshot, QWidget *parent) :
QDialog(parent)
{
setWindowTitle(tr("Lightscreen Screenshot Viewer"));
setWindowFlags(windowFlags() | Qt::WindowMinMaxButtonsHint);
mScrollArea = new QScrollArea(this);
mScrollArea->verticalScrollBar()->installEventFilter(this);
mScrollArea->setToolTip(tr("You can zoom in and out using the mouse wheel while holding the CTRL key. To return to the default zoom press \"Ctrl-0\"."));
QPalette newPalette = mScrollArea->palette();
newPalette.setBrush(QPalette::Background, QBrush(QPixmap(":/backgrounds/checkerboard")));
mScrollArea->setPalette(newPalette);
mLabel = new QLabel(this);
+ QPixmap pixmap = screenshot->pixmap();
+
+ if (pixmap.isNull()) {
+ pixmap.load(screenshot->unloadedFileName());
+ }
+
QHBoxLayout *layout = new QHBoxLayout(this);
- mLabel->setPixmap(screenshot->pixmap());
+ mLabel->setPixmap(pixmap);
mLabel->setScaledContents(true);
mScrollArea->setAlignment(Qt::AlignCenter);
mScrollArea->setWidget(mLabel);
layout->addWidget(mScrollArea);
layout->setMargin(0);
setLayout(layout);
setCursor(Qt::OpenHandCursor);
mOriginalSize = mLabel->size();
QSize size = (mLabel->pixmap()->size() + QSize(10, 10)); //TODO: Good padding for all platforms
if (size.width() >= qApp->desktop()->availableGeometry().width()) {
size.setWidth(qApp->desktop()->availableGeometry().size().width() - 300);
}
if (size.height() >= qApp->desktop()->availableGeometry().height()) {
size.setHeight(qApp->desktop()->availableGeometry().size().height() - 300);
}
resize(size);
move(qApp->desktop()->screen(qApp->desktop()->primaryScreen())->rect().center()-QPoint(size.width()/2, size.height()/2));
show();
}
void ScreenshotDialog::zoom(int offset)
{
if (offset == 0) {
mLabel->resize(mOriginalSize);
}
else {
QSize newSize = mLabel->size();
newSize.scale(mLabel->size() + QSize(offset, offset), Qt::KeepAspectRatio);
if (offset < 0 && (newSize.width() < 200 || newSize.height() < 200)) {
return;
}
mLabel->resize(newSize);
}
}
//
bool ScreenshotDialog::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::Wheel
&& qApp->keyboardModifiers() & Qt::ControlModifier) {
QWheelEvent *wheelEvent = static_cast<QWheelEvent *>(event);
zoom(wheelEvent->delta());
return true;
}
return QObject::eventFilter(obj, event);
}
void ScreenshotDialog::closeEvent(QCloseEvent *event)
{
Q_UNUSED(event)
deleteLater();
}
void ScreenshotDialog::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_0 && event->modifiers() & Qt::ControlModifier) {
zoom(0);
}
}
void ScreenshotDialog::mouseMoveEvent(QMouseEvent *event)
{
QPoint diff = event->pos() - mMousePos;
mMousePos = event->pos();
mScrollArea->verticalScrollBar()->setValue(mScrollArea->verticalScrollBar()->value() - diff.y());
mScrollArea->horizontalScrollBar()->setValue(mScrollArea->horizontalScrollBar()->value() - diff.x());
}
void ScreenshotDialog::mousePressEvent(QMouseEvent *event)
{
mMousePos = event->pos();
setCursor(Qt::ClosedHandCursor);
}
void ScreenshotDialog::mouseReleaseEvent(QMouseEvent *event)
{
Q_UNUSED(event)
setCursor(Qt::OpenHandCursor);
}
diff --git a/images/16/logo.failure.png b/images/16/logo.failure.png
deleted file mode 100644
index c9c7b63..0000000
Binary files a/images/16/logo.failure.png and /dev/null differ
diff --git a/images/16/logo.png b/images/16/logo.png
deleted file mode 100644
index 22aad3b..0000000
Binary files a/images/16/logo.png and /dev/null differ
diff --git a/images/16/logo.success.png b/images/16/logo.success.png
deleted file mode 100644
index e2927f9..0000000
Binary files a/images/16/logo.success.png and /dev/null differ
diff --git a/images/22/area.png b/images/22/area.png
deleted file mode 100644
index 138071c..0000000
Binary files a/images/22/area.png and /dev/null differ
diff --git a/images/22/picker.png b/images/22/picker.png
deleted file mode 100644
index adc17b9..0000000
Binary files a/images/22/picker.png and /dev/null differ
diff --git a/images/22/windowpicker.png b/images/22/windowpicker.png
deleted file mode 100644
index 13edbcf..0000000
Binary files a/images/22/windowpicker.png and /dev/null differ
diff --git a/images/24/accept.png b/images/24/accept.png
deleted file mode 100644
index d8c7635..0000000
Binary files a/images/24/accept.png and /dev/null differ
diff --git a/images/24/cancel.png b/images/24/cancel.png
deleted file mode 100644
index cb64b69..0000000
Binary files a/images/24/cancel.png and /dev/null differ
diff --git a/images/256/accept.png b/images/256/accept.png
deleted file mode 100644
index f027e38..0000000
Binary files a/images/256/accept.png and /dev/null differ
diff --git a/images/256/area.png b/images/256/area.png
deleted file mode 100644
index 34fc6b3..0000000
Binary files a/images/256/area.png and /dev/null differ
diff --git a/images/256/arrow.left.png b/images/256/arrow.left.png
deleted file mode 100644
index 8c7e5b8..0000000
Binary files a/images/256/arrow.left.png and /dev/null differ
diff --git a/images/256/arrow.right.png b/images/256/arrow.right.png
deleted file mode 100644
index f99066a..0000000
Binary files a/images/256/arrow.right.png and /dev/null differ
diff --git a/images/256/cancel.png b/images/256/cancel.png
deleted file mode 100644
index 870fa01..0000000
Binary files a/images/256/cancel.png and /dev/null differ
diff --git a/images/256/configure.png b/images/256/configure.png
deleted file mode 100644
index ccdbb7a..0000000
Binary files a/images/256/configure.png and /dev/null differ
diff --git a/images/256/folder.png b/images/256/folder.png
deleted file mode 100644
index ded4cfb..0000000
Binary files a/images/256/folder.png and /dev/null differ
diff --git a/images/256/history.png b/images/256/history.png
deleted file mode 100644
index 38a70e6..0000000
Binary files a/images/256/history.png and /dev/null differ
diff --git a/images/256/imgur.png b/images/256/imgur.png
deleted file mode 100644
index f8c7756..0000000
Binary files a/images/256/imgur.png and /dev/null differ
diff --git a/images/256/logo.png b/images/256/logo.png
deleted file mode 100644
index 8d75ffa..0000000
Binary files a/images/256/logo.png and /dev/null differ
diff --git a/images/256/minus.png b/images/256/minus.png
deleted file mode 100644
index 4f35bdc..0000000
Binary files a/images/256/minus.png and /dev/null differ
diff --git a/images/256/picker.png b/images/256/picker.png
deleted file mode 100644
index f4ada9e..0000000
Binary files a/images/256/picker.png and /dev/null differ
diff --git a/images/256/plus.png b/images/256/plus.png
deleted file mode 100644
index 7c254a9..0000000
Binary files a/images/256/plus.png and /dev/null differ
diff --git a/images/256/screen.png b/images/256/screen.png
deleted file mode 100644
index 4010a08..0000000
Binary files a/images/256/screen.png and /dev/null differ
diff --git a/images/256/tray.failure.png b/images/256/tray.failure.png
deleted file mode 100644
index de4cb2e..0000000
Binary files a/images/256/tray.failure.png and /dev/null differ
diff --git a/images/256/tray.success.png b/images/256/tray.success.png
deleted file mode 100644
index 0e5732a..0000000
Binary files a/images/256/tray.success.png and /dev/null differ
diff --git a/images/256/window.png b/images/256/window.png
deleted file mode 100644
index 907d07c..0000000
Binary files a/images/256/window.png and /dev/null differ
diff --git a/images/256/windowpicker.png b/images/256/windowpicker.png
deleted file mode 100644
index 795422e..0000000
Binary files a/images/256/windowpicker.png and /dev/null differ
diff --git a/images/48/accept.png b/images/48/accept.png
deleted file mode 100644
index 23d6481..0000000
Binary files a/images/48/accept.png and /dev/null differ
diff --git a/images/48/area.png b/images/48/area.png
deleted file mode 100644
index fa7c903..0000000
Binary files a/images/48/area.png and /dev/null differ
diff --git a/images/48/cancel.png b/images/48/cancel.png
deleted file mode 100644
index eeef724..0000000
Binary files a/images/48/cancel.png and /dev/null differ
diff --git a/images/48/picker.png b/images/48/picker.png
deleted file mode 100644
index 29e1734..0000000
Binary files a/images/48/picker.png and /dev/null differ
diff --git a/images/48/screen.png b/images/48/screen.png
deleted file mode 100644
index affa1ff..0000000
Binary files a/images/48/screen.png and /dev/null differ
diff --git a/images/48/windowpicker.png b/images/48/windowpicker.png
deleted file mode 100644
index b44f03d..0000000
Binary files a/images/48/windowpicker.png and /dev/null differ
diff --git a/images/area.big.png b/images/area.big.png
new file mode 100644
index 0000000..5a28332
Binary files /dev/null and b/images/area.big.png differ
diff --git a/images/area.png b/images/area.png
new file mode 100644
index 0000000..c98b375
Binary files /dev/null and b/images/area.png differ
diff --git a/images/24/arrow.left.png b/images/arrow.left.png
similarity index 87%
rename from images/24/arrow.left.png
rename to images/arrow.left.png
index a5a5e48..af9f606 100644
Binary files a/images/24/arrow.left.png and b/images/arrow.left.png differ
diff --git a/images/24/arrow.right.png b/images/arrow.right.png
similarity index 86%
rename from images/24/arrow.right.png
rename to images/arrow.right.png
index 0e303c7..0b60089 100644
Binary files a/images/24/arrow.right.png and b/images/arrow.right.png differ
diff --git a/images/128/checkerboard.png b/images/checkerboard.png
similarity index 100%
rename from images/128/checkerboard.png
rename to images/checkerboard.png
diff --git a/images/configure.png b/images/configure.png
new file mode 100644
index 0000000..62b0c94
Binary files /dev/null and b/images/configure.png differ
diff --git a/images/16/folder.png b/images/folder.png
similarity index 93%
rename from images/16/folder.png
rename to images/folder.png
index 27fa229..853d5e6 100644
Binary files a/images/16/folder.png and b/images/folder.png differ
diff --git a/images/16/imgur.png b/images/history.png
similarity index 85%
rename from images/16/imgur.png
rename to images/history.png
index 2fda204..c4f57d5 100644
Binary files a/images/16/imgur.png and b/images/history.png differ
diff --git a/images/imgur.png b/images/imgur.png
new file mode 100644
index 0000000..24dde03
Binary files /dev/null and b/images/imgur.png differ
diff --git a/images/lightscreen.no.png b/images/lightscreen.no.png
new file mode 100644
index 0000000..da7a4c5
Binary files /dev/null and b/images/lightscreen.no.png differ
diff --git a/images/lightscreen.small.png b/images/lightscreen.small.png
new file mode 100644
index 0000000..d904615
Binary files /dev/null and b/images/lightscreen.small.png differ
diff --git a/images/lightscreen.yes.png b/images/lightscreen.yes.png
new file mode 100644
index 0000000..3ef8f48
Binary files /dev/null and b/images/lightscreen.yes.png differ
diff --git a/images/22/minus.png b/images/minus.png
similarity index 93%
rename from images/22/minus.png
rename to images/minus.png
index a73aba6..a81c88a 100644
Binary files a/images/22/minus.png and b/images/minus.png differ
diff --git a/images/no.big.png b/images/no.big.png
new file mode 100644
index 0000000..43f994e
Binary files /dev/null and b/images/no.big.png differ
diff --git a/images/no.png b/images/no.png
new file mode 100644
index 0000000..77c3ef3
Binary files /dev/null and b/images/no.png differ
diff --git a/images/16/configure.png b/images/pickWindow.big.png
similarity index 77%
copy from images/16/configure.png
copy to images/pickWindow.big.png
index 0f29637..ee3ef2a 100644
Binary files a/images/16/configure.png and b/images/pickWindow.big.png differ
diff --git a/images/22/plus.png b/images/pickWindow.png
similarity index 87%
rename from images/22/plus.png
rename to images/pickWindow.png
index 531af10..1751712 100644
Binary files a/images/22/plus.png and b/images/pickWindow.png differ
diff --git a/images/16/configure.png b/images/picker.png
similarity index 84%
copy from images/16/configure.png
copy to images/picker.png
index 0f29637..458805d 100644
Binary files a/images/16/configure.png and b/images/picker.png differ
diff --git a/images/plus.png b/images/plus.png
new file mode 100644
index 0000000..53b57e1
Binary files /dev/null and b/images/plus.png differ
diff --git a/images/16/history.png b/images/preview.png
similarity index 85%
rename from images/16/history.png
rename to images/preview.png
index 67cf01e..1960aa0 100644
Binary files a/images/16/history.png and b/images/preview.png differ
diff --git a/images/16/configure.png b/images/screen.big.png
similarity index 88%
rename from images/16/configure.png
rename to images/screen.big.png
index 0f29637..dd607da 100644
Binary files a/images/16/configure.png and b/images/screen.big.png differ
diff --git a/images/22/screen.png b/images/screen.png
similarity index 88%
rename from images/22/screen.png
rename to images/screen.png
index 671a9f7..f59bb2e 100644
Binary files a/images/22/screen.png and b/images/screen.png differ
diff --git a/images/22/window.png b/images/window.png
similarity index 92%
rename from images/22/window.png
rename to images/window.png
index 775aad8..6f3cb61 100644
Binary files a/images/22/window.png and b/images/window.png differ
diff --git a/images/yes.big.png b/images/yes.big.png
new file mode 100644
index 0000000..92d19fd
Binary files /dev/null and b/images/yes.big.png differ
diff --git a/images/yes.png b/images/yes.png
new file mode 100644
index 0000000..071d137
Binary files /dev/null and b/images/yes.png differ
diff --git a/lightscreen.qrc b/lightscreen.qrc
index 88cf933..fc68b0b 100644
--- a/lightscreen.qrc
+++ b/lightscreen.qrc
@@ -1,36 +1,38 @@
<RCC>
<qresource prefix="/icons">
<file alias="lightscreen">images/LS.ico</file>
- <file alias="lightscreen.small">images/16/logo.png</file>
- <file alias="lightscreen.yes">images/16/logo.success.png</file>
- <file alias="lightscreen.no">images/16/logo.failure.png</file>
- <file alias="yes">images/24/accept.png</file>
- <file alias="no">images/24/cancel.png</file>
- <file alias="yes.big">images/48/accept.png</file>
- <file alias="no.big">images/48/cancel.png</file>
- <file alias="folder">images/16/folder.png</file>
- <file alias="configure">images/16/configure.png</file>
- <file alias="arrow-left">images/24/arrow.left.png</file>
- <file alias="arrow-right">images/24/arrow.right.png</file>
- <file alias="picker">images/22/picker.png</file>
- <file alias="zoom.out">images/22/minus.png</file>
- <file alias="zoom.in">images/22/plus.png</file>
- <file alias="area">images/22/area.png</file>
- <file alias="screen">images/22/screen.png</file>
- <file alias="window">images/22/window.png</file>
- <file alias="imgur">images/16/imgur.png</file>
- <file alias="view-history">images/16/history.png</file>
- <file alias="area.big">images/48/area.png</file>
- <file alias="screen.big">images/48/screen.png</file>
- <file alias="picker.big">images/48/windowpicker.png</file>
+ <file alias="lightscreen.small">images/lightscreen.small.png</file>
+ <file alias="lightscreen.yes">images/lightscreen.yes.png</file>
+ <file alias="lightscreen.no">images/lightscreen.no.png</file>
+ <file alias="yes">images/yes.png</file>
+ <file alias="no">images/no.png</file>
+ <file alias="yes.big">images/yes.big.png</file>
+ <file alias="no.big">images/no.big.png</file>
+ <file alias="folder">images/folder.png</file>
+ <file alias="configure">images/configure.png</file>
+ <file alias="arrow-left">images/arrow.left.png</file>
+ <file alias="arrow-right">images/arrow.right.png</file>
+ <file alias="picker">images/picker.png</file>
+ <file alias="pickWindow">images/pickWindow.png</file>
+ <file alias="zoom.out">images/minus.png</file>
+ <file alias="zoom.in">images/plus.png</file>
+ <file alias="area">images/area.png</file>
+ <file alias="screen">images/screen.png</file>
+ <file alias="window">images/window.png</file>
+ <file alias="imgur">images/imgur.png</file>
+ <file alias="view-history">images/history.png</file>
+ <file alias="area.big">images/area.big.png</file>
+ <file alias="screen.big">images/screen.big.png</file>
+ <file alias="pickWindow.big">images/pickWindow.big.png</file>
+ <file alias="preview">images/preview.png</file>
</qresource>
<qresource prefix="/backgrounds">
- <file alias="checkerboard">images/128/checkerboard.png</file>
+ <file alias="checkerboard">images/checkerboard.png</file>
</qresource>
<qresource prefix="/translations">
<file alias="Español">translations/spanish.qm</file>
</qresource>
<qresource prefix="/translations_qt">
<file alias="Español">translations/qt/qt_es.qm</file>
</qresource>
</RCC>
diff --git a/lightscreenwindow.cpp b/lightscreenwindow.cpp
index 3173999..6e40776 100644
--- a/lightscreenwindow.cpp
+++ b/lightscreenwindow.cpp
@@ -1,971 +1,971 @@
/*
* Copyright (C) 2012 Christian Kaiser
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <QMainWindow>
#include <QDate>
#include <QDesktopServices>
#include <QDesktopWidget>
#include <QFileInfo>
#include <QHttp>
#include <QKeyEvent>
#include <QMenu>
#include <QMessageBox>
#include <QPointer>
#include <QProcess>
#include <QSettings>
#include <QSound>
#include <QSystemTrayIcon>
#include <QTimer>
#include <QToolTip>
#include <QUrl>
#include <QDebug>
#ifdef Q_WS_WIN
#include <windows.h>
#include "tools/qwin7utils/Taskbar.h"
#include "tools/qwin7utils/TaskbarButton.h"
#include "tools/qwin7utils/Utils.h"
using namespace QW7;
#endif
/*
* Lightscreen includes
*/
#include "lightscreenwindow.h"
#include "dialogs/optionsdialog.h"
#include "dialogs/previewdialog.h"
#include "dialogs/historydialog.h"
#include "tools/globalshortcut/globalshortcutmanager.h"
#include "tools/os.h"
#include "tools/screenshot.h"
#include "tools/screenshotmanager.h"
#include "tools/uploader.h"
#include "updater/updater.h"
LightscreenWindow::LightscreenWindow(QWidget *parent) :
QMainWindow(parent),
mDoCache(false),
mHideTrigger(false),
mReviveMain(false),
mWasVisible(true),
mLastMessage(0),
mLastMode(-1),
mLastScreenshot()
{
os::translate(settings()->value("options/language", "English").toString());
ui.setupUi(this);
#ifdef Q_WS_WIN
ExtendFrameIntoClientArea(this);
#endif
setMaximumSize(size());
setMinimumSize(size());
setWindowFlags(Qt::Window);
#ifdef Q_WS_WIN
if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7) {
mTaskbarButton = new TaskbarButton(this);
}
if (QSysInfo::windowsVersion() < QSysInfo::WV_WINDOWS7) {
ui.centralWidget->setStyleSheet("QPushButton { padding: 2px; border: 1px solid #acacac; background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #eaeaea, stop:1 #e5e5e5);} QPushButton:hover { border: 1px solid #7eb4ea; background-color: #e4f0fc; }");
}
#endif
// Actions
connect(ui.screenPushButton, SIGNAL(clicked()), this, SLOT(screenshotAction()));
connect(ui.areaPushButton , SIGNAL(clicked()), this, SLOT(areaHotkey()));
connect(ui.windowPushButton, SIGNAL(clicked()), this, SLOT(windowPickerHotkey()));
connect(ui.optionsPushButton, SIGNAL(clicked()), this, SLOT(showOptions()));
connect(ui.folderPushButton , SIGNAL(clicked()), this, SLOT(goToFolder()));
connect(ui.imgurPushButton, SIGNAL(clicked()), this, SLOT(createUploadMenu()));
// Uploader
connect(Uploader::instance(), SIGNAL(progress(qint64, qint64)), this, SLOT(uploadProgress(qint64, qint64)));
connect(Uploader::instance(), SIGNAL(done(QString, QString, QString)), this, SLOT(showUploaderMessage(QString, QString)));
connect(Uploader::instance(), SIGNAL(error(QString)), this, SLOT(showUploaderError(QString)));
// Manager
connect(ScreenshotManager::instance(), SIGNAL(confirm(Screenshot*)), this, SLOT(preview(Screenshot*)));
connect(ScreenshotManager::instance(), SIGNAL(windowCleanup(Screenshot::Options&)), this, SLOT(cleanup(Screenshot::Options&)));
if (!settings()->contains("file/format")) {
showOptions(); // There are no options (or the options config is invalid or incomplete)
}
else {
QTimer::singleShot(0 , this, SLOT(applySettings()));
QTimer::singleShot(5000, this, SLOT(checkForUpdates()));
}
}
LightscreenWindow::~LightscreenWindow()
{
settings()->setValue("lastScreenshot", mLastScreenshot);
settings()->sync();
GlobalShortcutManager::instance()->clear();
delete mTrayIcon;
}
void LightscreenWindow::action(int mode)
{
if (mode == 4) {
goToFolder();
}
else {
show();
}
}
void LightscreenWindow::areaHotkey()
{
screenshotAction(2);
}
void LightscreenWindow::checkForUpdates()
{
if (settings()->value("options/disableUpdater", false).toBool())
return;
if (settings()->value("lastUpdateCheck").toInt() + 7
> QDate::currentDate().dayOfYear())
return; // If 7 days have not passed since the last update check.
connect(Updater::instance(), SIGNAL(done(bool)), this, SLOT(updaterDone(bool)));
Updater::instance()->check();
}
void LightscreenWindow::cleanup(Screenshot::Options &options)
{
// Reversing settings
if (settings()->value("options/hide").toBool()) {
#ifndef Q_WS_X11 // X is not quick enough and the notification ends up everywhere but in the icon
if (settings()->value("options/tray").toBool() && mTrayIcon) {
mTrayIcon->show();
}
#endif
if (mPreviewDialog) {
if (mPreviewDialog->count() <= 1 && mWasVisible) {
show();
}
mPreviewDialog->show();
}
else if (mWasVisible) {
show();
}
mHideTrigger = false;
}
if (settings()->value("options/tray").toBool() && mTrayIcon) {
notify(options.result);
if (settings()->value("options/message").toBool() && options.file && !options.upload) {
// This message wll get shown only when messages are enabled and the file won't get another upload pop-up soon.
showScreenshotMessage(options.result, options.fileName);
}
}
if (settings()->value("options/playSound", false).toBool()) {
if (options.result == Screenshot::Success) {
QSound::play("sounds/ls.screenshot.wav");
}
else {
#ifdef Q_WS_WIN
QSound::play("afakepathtomakewindowsplaythedefaultsoundtheresprobablyabetterwaybuticantbebothered");
#else
QSound::play("sound/ls.error.wav");
#endif
}
}
if (options.result != Screenshot::Success)
return;
mLastScreenshot = options.fileName;
}
void LightscreenWindow::closeToTrayWarning()
{
if (!settings()->value("options/closeToTrayWarning", true).toBool())
return;
mLastMessage = 3;
mTrayIcon->showMessage(tr("Closed to tray"), tr("Lightscreen will keep running, you can disable this in the options menu."));
settings()->setValue("options/closeToTrayWarning", false);
}
void LightscreenWindow::createUploadMenu()
{
QMenu* imgurMenu = new QMenu(tr("Upload"));
QAction *uploadAction = new QAction(QIcon(":/icons/imgur"), tr("&Upload last"), imgurMenu);
uploadAction->setToolTip(tr("Upload the last screenshot you took to imgur.com"));
connect(uploadAction, SIGNAL(triggered()), this, SLOT(uploadLast()));
QAction *cancelAction = new QAction(QIcon(":/icons/no"), tr("&Cancel upload"), imgurMenu);
cancelAction->setToolTip(tr("Cancel the currently uploading screenshots"));
cancelAction->setEnabled(false);
connect(this, SIGNAL(uploading(bool)), cancelAction, SLOT(setEnabled(bool)));
connect(cancelAction, SIGNAL(triggered()), this, SLOT(uploadCancel()));
QAction *historyAction = new QAction(QIcon(":/icons/view-history"), tr("View &History"), imgurMenu);
connect(historyAction, SIGNAL(triggered()), this, SLOT(showHistoryDialog()));
imgurMenu->addAction(uploadAction);
imgurMenu->addAction(cancelAction);
imgurMenu->addAction(historyAction);
imgurMenu->addSeparator();
connect(imgurMenu, SIGNAL(aboutToShow()), this, SLOT(uploadMenuShown()));
ui.imgurPushButton->setMenu(imgurMenu);
ui.imgurPushButton->showMenu();
}
void LightscreenWindow::goToFolder()
{
#ifdef Q_WS_WIN
if (!mLastScreenshot.isEmpty() && QFile::exists(mLastScreenshot)) {
QProcess::startDetached("explorer /select, \"" + mLastScreenshot +"\"");
}
else {
#endif
QString folder = settings()->value("file/target").toString();
if (folder.isEmpty())
folder = qApp->applicationDirPath();
if (QDir::toNativeSeparators(folder.at(folder.size()-1)) != QDir::separator())
folder.append(QDir::separator());
QDesktopServices::openUrl("file:///"+folder);
#ifdef Q_WS_WIN
}
#endif
}
void LightscreenWindow::messageClicked()
{
if (mLastMessage == 1) {
goToFolder();
}
else if (mLastMessage == 3) {
QTimer::singleShot(0, this, SLOT(showOptions()));
}
else {
QDesktopServices::openUrl(QUrl(Uploader::instance()->lastUrl()));
}
}
void LightscreenWindow::messageReceived(const QString &message)
{
if (message.contains(' ')) {
foreach (QString argument, message.split(' ')) {
messageReceived(argument);
}
}
if (message == "--wake") {
show();
qApp->alert(this, 500);
return;
}
if (message == "--screen")
screenshotAction();
else if (message == "--area")
screenshotAction(2);
else if (message == "--activewindow")
screenshotAction(1);
else if (message == "--pickwindow")
screenshotAction(3);
else if (message == "--folder")
action(4);
else if (message == "--uploadlast")
uploadLast();
else if (message == "--viewhistory")
showHistoryDialog();
}
void LightscreenWindow::notify(const Screenshot::Result &result)
{
switch (result)
{
case Screenshot::Success:
mTrayIcon->setIcon(QIcon(":/icons/lightscreen.yes"));
#ifdef Q_WS_WIN
if (mTaskbarButton)
mTaskbarButton->SetOverlayIcon(QIcon(":/icons/yes"), tr("Success!"));
#endif
setWindowTitle(tr("Success!"));
break;
case Screenshot::Fail:
mTrayIcon->setIcon(QIcon(":/icons/lightscreen.no"));
setWindowTitle(tr("Failed!"));
#ifdef Q_WS_WIN
if (mTaskbarButton)
mTaskbarButton->SetOverlayIcon(QIcon(":/icons/no"), tr("Failed!"));
#endif
break;
case Screenshot::Cancel:
setWindowTitle(tr("Cancelled!"));
break;
}
QTimer::singleShot(2000, this, SLOT(restoreNotification()));
}
void LightscreenWindow::preview(Screenshot* screenshot)
{
if (screenshot->options().preview) {
if (!mPreviewDialog) {
mPreviewDialog = new PreviewDialog(this);
}
mPreviewDialog->add(screenshot);
}
else {
screenshot->confirm(true);
}
}
void LightscreenWindow::quit()
{
settings()->setValue("position", pos());
int answer = 0;
QString doing;
if (ScreenshotManager::instance()->activeCount() > 0) {
doing = tr("processing");
}
if (Uploader::instance()->uploading() > 0) {
if (doing.isEmpty()) {
doing = tr("uploading");
}
else {
doing = tr("processing and uploading");
}
}
if (!doing.isEmpty()) {
answer = QMessageBox::question(this,
tr("Are you sure you want to quit?"),
tr("Lightscreen is currently %1 screenshots. Are you sure you want to quit?").arg(doing),
tr("Quit"),
tr("Don't Quit"));
}
if (answer == 0)
emit finished();
}
void LightscreenWindow::restoreNotification()
{
if (mTrayIcon)
mTrayIcon->setIcon(QIcon(":/icons/lightscreen.small"));
#ifdef Q_WS_WIN
if (mTaskbarButton)
mTaskbarButton->SetOverlayIcon(QIcon(), "");
#endif
updateUploadStatus();
}
void LightscreenWindow::screenshotAction(int mode)
{
int delayms = -1;
bool optionsHide = settings()->value("options/hide").toBool(); // Option cache, used a couple of times.
if (!mHideTrigger) {
mWasVisible = isVisible();
mHideTrigger = true;
}
// Applying pre-screenshot settings
if (optionsHide) {
hide();
#ifndef Q_WS_X11 // X is not quick enough and the notification ends up everywhere but in the icon
if (mTrayIcon)
mTrayIcon->hide();
#endif
}
// Screenshot delay
delayms = settings()->value("options/delay", 0).toInt();
delayms = delayms * 1000; // Converting the delay to milliseconds.
delayms += 400;
if (optionsHide && mPreviewDialog) {
if (mPreviewDialog->count() >= 1) {
mPreviewDialog->hide();
}
}
// The delayed functions works using the static variable lastMode
// which keeps the argument so a QTimer can call this function again.
if (delayms > 0) {
if (mLastMode < 0) {
mLastMode = mode;
QTimer::singleShot(delayms, this, SLOT(screenshotAction()));
return;
}
else {
mode = mLastMode;
mLastMode = -1;
}
}
static Screenshot::Options options;
if (!mDoCache) {
// Populating the option object that will then be passed to the screenshot engine (sounds fancy huh?)
options.file = settings()->value("file/enabled").toBool();
options.format = (Screenshot::Format) settings()->value("file/format").toInt();
options.prefix = settings()->value("file/prefix").toString();
QDir dir(settings()->value("file/target").toString());
dir.makeAbsolute();
options.directory = dir;
options.quality = settings()->value("options/quality", 100).toInt();
options.currentMonitor = settings()->value("options/currentMonitor", false).toBool();
options.clipboard = settings()->value("options/clipboard", true).toBool();
options.imgurClipboard = settings()->value("options/imgurClipboard", false).toBool();
options.preview = settings()->value("options/preview", false).toBool();
options.magnify = settings()->value("options/magnify", false).toBool();
options.cursor = settings()->value("options/cursor", false).toBool();
options.saveAs = settings()->value("options/saveAs", false).toBool();
options.animations = settings()->value("options/animations", true).toBool();
options.replace = settings()->value("options/replace", false).toBool();
options.upload = settings()->value("options/uploadAuto", false).toBool();
options.optimize = settings()->value("options/optipng", false).toBool();
Screenshot::NamingOptions namingOptions;
namingOptions.naming = (Screenshot::Naming) settings()->value("file/naming").toInt();
namingOptions.leadingZeros = settings()->value("options/naming/leadingZeros", 0).toInt();
namingOptions.flip = settings()->value("options/flip", false).toBool();
namingOptions.dateFormat = settings()->value("options/naming/dateFormat", "yyyy-MM-dd").toString();
options.namingOptions = namingOptions;
mDoCache = true;
}
options.mode = mode;
ScreenshotManager::instance()->take(options);
}
void LightscreenWindow::screenshotActionTriggered(QAction* action)
{
screenshotAction(action->data().toInt());
}
void LightscreenWindow::showHotkeyError(const QStringList &hotkeys)
{
static bool dontShow = false;
if (dontShow)
return;
QString messageText;
messageText = tr("Some hotkeys could not be registered, they might already be in use");
if (hotkeys.count() > 1) {
messageText += tr("<br>The failed hotkeys are the following:") + "<ul>";
foreach(const QString &hotkey, hotkeys) {
messageText += QString("%1%2%3").arg("<li><b>").arg(hotkey).arg("</b></li>");
}
messageText += "</ul>";
}
else {
messageText += tr("<br>The failed hotkey is <b>%1</b>").arg(hotkeys[0]);
}
messageText += tr("<br><i>What do you want to do?</i>");
QMessageBox msgBox(this);
msgBox.setWindowTitle(tr("Lightscreen"));
msgBox.setText(messageText);
QPushButton *changeButton = msgBox.addButton(tr("Change") , QMessageBox::ActionRole);
QPushButton *disableButton = msgBox.addButton(tr("Disable"), QMessageBox::ActionRole);
QPushButton *exitButton = msgBox.addButton(tr("Quit") , QMessageBox::ActionRole);
msgBox.exec();
if (msgBox.clickedButton() == exitButton) {
dontShow = true;
QTimer::singleShot(10, this, SLOT(quit()));
}
else if (msgBox.clickedButton() == changeButton) {
showOptions();
}
else if (msgBox.clickedButton() == disableButton) {
foreach(const QString &hotkey, hotkeys) {
settings()->setValue(QString("actions/%1/enabled").arg(hotkey), false);
}
}
}
void LightscreenWindow::showHistoryDialog()
{
HistoryDialog historyDialog(this);
historyDialog.exec();
updateUploadStatus();
}
void LightscreenWindow::showOptions()
{
GlobalShortcutManager::clear();
QPointer<OptionsDialog> optionsDialog = new OptionsDialog(this);
optionsDialog->exec();
optionsDialog->deleteLater();
applySettings();
}
void LightscreenWindow::showScreenshotMessage(const Screenshot::Result &result, const QString &fileName)
{
if (result == Screenshot::Cancel)
return;
// Showing message.
QString title;
QString message;
if (result == Screenshot::Success) {
title = QFileInfo(fileName).fileName();
if (settings()->value("file/target").toString().isEmpty()) {
message = QDir::toNativeSeparators(QCoreApplication::applicationDirPath());
}
else {
message = tr("Saved to \"%1\"").arg(settings()->value("file/target").toString());
}
}
else {
title = tr("The screenshot was not taken");
message = tr("An error occurred.");
}
mLastMessage = 1;
mTrayIcon->showMessage(title, message);
}
void LightscreenWindow::showUploaderError(const QString &error)
{
mLastMessage = -1;
if (mTrayIcon && !error.isEmpty() && settings()->value("options/message").toBool()) {
mTrayIcon->showMessage(tr("Upload error"), error);
}
updateUploadStatus();
}
void LightscreenWindow::showUploaderMessage(QString fileName, QString url)
{
if (mTrayIcon && settings()->value("options/message").toBool()) {
QString screenshot = QFileInfo(fileName).fileName();
if (screenshot.startsWith(".lstemp."))
screenshot = tr("Screenshot");
mLastMessage = 2;
mTrayIcon->showMessage(tr("%1 uploaded").arg(screenshot), tr("Click here to go to %1").arg(url));
}
updateUploadStatus();
}
void LightscreenWindow::toggleVisibility(QSystemTrayIcon::ActivationReason reason)
{
if (reason != QSystemTrayIcon::DoubleClick)
return;
if (isVisible()) {
hide();
}
else {
show();
}
}
void LightscreenWindow::updateUploadStatus()
{
int uploadCount = Uploader::instance()->uploading();
QString statusString;
if (uploadCount > 0) {
statusString = tr("%1 uploading - Lightscreen").arg(uploadCount);
//ui.imgurPushButton->setIcon(QIcon(":/icons/imgur.upload"));
emit uploading(true);
}
else {
statusString = tr("Lightscreen");
//ui.imgurPushButton->setIcon(QIcon(":/icons/imgur"));
emit uploading(false);
#ifdef Q_WS_WIN
if (mTaskbarButton) {
mTaskbarButton->SetProgresValue(0, 0);
mTaskbarButton->SetState(STATE_NOPROGRESS);
}
#endif
}
if (mTrayIcon) {
mTrayIcon->setToolTip(statusString);
}
setWindowTitle(statusString);
}
void LightscreenWindow::updaterDone(bool result)
{
settings()->setValue("lastUpdateCheck", QDate::currentDate().dayOfYear());
if (!result)
return;
QMessageBox msgBox;
msgBox.setWindowTitle(tr("Lightscreen"));
msgBox.setText(tr("There's a new version of Lightscreen available.<br>Would you like to see more information?<br>(<em>You can turn this notification off</em>)"));
msgBox.setIcon(QMessageBox::Information);
QPushButton *yesButton = msgBox.addButton(QMessageBox::Yes);
QPushButton *turnOffButton = msgBox.addButton(tr("Turn Off"), QMessageBox::ActionRole);
QPushButton *remindButton = msgBox.addButton(tr("Remind Me Later"), QMessageBox::RejectRole);
Q_UNUSED(remindButton);
msgBox.exec();
if (msgBox.clickedButton() == yesButton) {
QDesktopServices::openUrl(QUrl("http://lightscreen.sourceforge.net/whatsnew/?from=" + qApp->applicationVersion()));
}
else if (msgBox.clickedButton() == turnOffButton) {
settings()->setValue("options/disableUpdater", true);
}
}
void LightscreenWindow::upload(const QString &fileName)
{
Uploader::instance()->upload(fileName);
}
void LightscreenWindow::uploadCancel()
{
if (Uploader::instance()->uploading() <= 0) {
return;
}
int confirm = QMessageBox::question(this, tr("Upload cancel"), tr("Do you want to cancel all screenshot uploads?"), tr("Cancel"), tr("Don't Cancel"));
if (confirm == 0) {
Uploader::instance()->cancel();
updateUploadStatus();
}
}
void LightscreenWindow::uploadLast()
{
upload(mLastScreenshot);
updateUploadStatus();
}
void LightscreenWindow::uploadProgress(qint64 sent, qint64 total)
{
#ifdef Q_WS_WIN
if (mTaskbarButton)
mTaskbarButton->SetProgresValue(sent, total);
if (isVisible() && total > 0) {
int uploadCount = Uploader::instance()->uploading();
int progress = (sent*100)/total;
if (uploadCount > 1) {
setWindowTitle(tr("%1% of %2 uploads - Lightscreen").arg(progress).arg(uploadCount));
}
else {
setWindowTitle(tr("%1% - Lightscreen").arg(progress));
}
}
#endif
}
void LightscreenWindow::uploadMenuShown()
{
QMenu *imgurMenu = qobject_cast<QMenu*>(sender());
imgurMenu->actions().at(0)->setEnabled(!mLastScreenshot.isEmpty());
}
void LightscreenWindow::windowHotkey()
{
screenshotAction(1);
}
void LightscreenWindow::windowPickerHotkey()
{
screenshotAction(3);
}
//
void LightscreenWindow::applySettings()
{
bool tray = settings()->value("options/tray").toBool();
if (tray && !mTrayIcon) {
createTrayIcon();
mTrayIcon->show();
}
else if (!tray && mTrayIcon) {
mTrayIcon->deleteLater();
}
connectHotkeys();
mDoCache = false;
if (settings()->value("lastScreenshot").isValid() && mLastScreenshot.isEmpty())
mLastScreenshot = settings()->value("lastScreenshot").toString();
os::setStartup(settings()->value("options/startup").toBool(), settings()->value("options/startupHide").toBool());
}
//
void LightscreenWindow::connectHotkeys()
{
// Set to true because if the hotkey is disabled it will show an error.
bool screen = true, area = true, window = true, windowPicker = true, open = true, directory = true;
if (settings()->value("actions/screen/enabled").toBool())
screen = GlobalShortcutManager::instance()->connect(settings()->value(
"actions/screen/hotkey").value<QKeySequence> (), this, SLOT(screenshotAction()));
if (settings()->value("actions/area/enabled").toBool())
area = GlobalShortcutManager::instance()->connect(settings()->value(
"actions/area/hotkey").value<QKeySequence> (), this, SLOT(areaHotkey()));
if (settings()->value("actions/window/enabled").toBool())
window = GlobalShortcutManager::instance()->connect(settings()->value(
"actions/window/hotkey").value<QKeySequence> (), this, SLOT(windowHotkey()));
if (settings()->value("actions/windowPicker/enabled").toBool())
windowPicker = GlobalShortcutManager::instance()->connect(settings()->value(
"actions/windowPicker/hotkey").value<QKeySequence> (), this, SLOT(windowPickerHotkey()));
if (settings()->value("actions/open/enabled").toBool())
open = GlobalShortcutManager::instance()->connect(settings()->value(
"actions/open/hotkey").value<QKeySequence> (), this, SLOT(show()));
if (settings()->value("actions/directory/enabled").toBool())
directory = GlobalShortcutManager::instance()->connect(settings()->value(
"actions/directory/hotkey").value<QKeySequence> (), this, SLOT(goToFolder()));
QStringList failed;
if (!screen) failed << "screen";
if (!area) failed << "area";
if (!window) failed << "window";
if (!windowPicker) failed << "window picker";
if (!open) failed << "open";
if (!directory) failed << "directory";
if (!failed.isEmpty())
showHotkeyError(failed);
}
void LightscreenWindow::createTrayIcon()
{
mTrayIcon = new QSystemTrayIcon(QIcon(":/icons/lightscreen.small"), this);
updateUploadStatus();
connect(mTrayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(toggleVisibility(QSystemTrayIcon::ActivationReason)));
connect(mTrayIcon, SIGNAL(messageClicked()), this, SLOT(messageClicked()));
QAction *hideAction = new QAction(QIcon(":/icons/lightscreen.small"), tr("Show&/Hide"), mTrayIcon);
connect(hideAction, SIGNAL(triggered()), this, SLOT(toggleVisibility()));
QAction *screenAction = new QAction(QIcon(":/icons/screen"), tr("&Screen"), mTrayIcon);
screenAction->setData(QVariant(0));
QAction *windowAction = new QAction(QIcon(":/icons/window"), tr("Active &Window"), this);
windowAction->setData(QVariant(1));
- QAction *windowPickerAction = new QAction(QIcon(":/icons/picker"), tr("&Pick Window"), this);
+ QAction *windowPickerAction = new QAction(QIcon(":/icons/pickWindow"), tr("&Pick Window"), this);
windowPickerAction->setData(QVariant(3));
QAction *areaAction = new QAction(QIcon(":/icons/area"), tr("&Area"), mTrayIcon);
areaAction->setData(QVariant(2));
QActionGroup *screenshotGroup = new QActionGroup(mTrayIcon);
screenshotGroup->addAction(screenAction);
screenshotGroup->addAction(areaAction);
screenshotGroup->addAction(windowAction);
screenshotGroup->addAction(windowPickerAction);
connect(screenshotGroup, SIGNAL(triggered(QAction*)), this, SLOT(screenshotActionTriggered(QAction*)));
// Duplicated for the screenshot button :(
QAction *uploadAction = new QAction(QIcon(":/icons/imgur"), tr("&Upload last"), mTrayIcon);
uploadAction->setToolTip(tr("Upload the last screenshot you took to imgur.com"));
connect(uploadAction, SIGNAL(triggered()), this, SLOT(uploadLast()));
QAction *cancelAction = new QAction(QIcon(":/icons/no"), tr("&Cancel upload"), mTrayIcon);
cancelAction->setToolTip(tr("Cancel the currently uploading screenshots"));
cancelAction->setEnabled(false);
connect(this, SIGNAL(uploading(bool)), cancelAction, SLOT(setEnabled(bool)));
connect(cancelAction, SIGNAL(triggered()), this, SLOT(uploadCancel()));
QAction *historyAction = new QAction(QIcon(":/icons/view-history"), tr("View History"), mTrayIcon);
connect(historyAction, SIGNAL(triggered()), this, SLOT(showHistoryDialog()));
//
QAction *optionsAction = new QAction(QIcon(":/icons/configure"), tr("View &Options"), mTrayIcon);
connect(optionsAction, SIGNAL(triggered()), this, SLOT(showOptions()));
QAction *goAction = new QAction(QIcon(":/icons/folder"), tr("&Go to Folder"), mTrayIcon);
connect(goAction, SIGNAL(triggered()), this, SLOT(goToFolder()));
QAction *quitAction = new QAction(tr("&Quit"), mTrayIcon);
connect(quitAction, SIGNAL(triggered()), this, SLOT(quit()));
QMenu* screenshotMenu = new QMenu(tr("Screenshot"));
screenshotMenu->addAction(screenAction);
screenshotMenu->addAction(areaAction);
screenshotMenu->addAction(windowAction);
screenshotMenu->addAction(windowPickerAction);
// Duplicated for the screenshot button :(
QMenu* imgurMenu = new QMenu(tr("Upload"));
imgurMenu->addAction(uploadAction);
imgurMenu->addAction(cancelAction);
imgurMenu->addAction(historyAction);
imgurMenu->addSeparator();
QMenu* trayIconMenu = new QMenu;
trayIconMenu->addAction(hideAction);
trayIconMenu->addSeparator();
trayIconMenu->addMenu(imgurMenu);
trayIconMenu->addSeparator();
trayIconMenu->addMenu(screenshotMenu);
trayIconMenu->addAction(optionsAction);
trayIconMenu->addAction(goAction);
trayIconMenu->addSeparator();
trayIconMenu->addAction(quitAction);
mTrayIcon->setContextMenu(trayIconMenu);
}
#ifdef Q_WS_WIN
bool LightscreenWindow::winEvent(MSG *message, long *result)
{
Taskbar::GetInstance()->winEvent(message, result);
return false;
}
#endif
QSettings *LightscreenWindow::settings() const
{
return ScreenshotManager::instance()->settings();
}
// Event handling
bool LightscreenWindow::event(QEvent *event)
{
if (event->type() == QEvent::Hide) {
settings()->setValue("position", pos());
}
else if (event->type() == QEvent::Close) {
if (settings()->value("options/tray").toBool() && settings()->value("options/closeToTray").toBool()) {
closeToTrayWarning();
hide();
}
else {
quit();
}
}
else if (event->type() == QEvent::Show) {
QPoint savedPosition = settings()->value("position").toPoint();
if (!savedPosition.isNull() && qApp->desktop()->availableGeometry().contains(QRect(savedPosition, size())))
move(savedPosition);
}
else if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
#ifdef Q_WS_MAC
if (keyEvent->modifiers() == Qt::ControlModifier && e->key() == Qt::Key_Period) {
keyEvent->ignore();
if(isVisible())
toggleVisibility();
return false;
}
else
#endif
if (!keyEvent->modifiers() && keyEvent->key() == Qt::Key_Escape) {
keyEvent->ignore();
if(isVisible())
toggleVisibility();
return false;
}
}
else if (event->type() == QEvent::LanguageChange) {
ui.retranslateUi(this);
resize(minimumSizeHint());
}
return QMainWindow::event(event);
}
diff --git a/lightscreenwindow.ui b/lightscreenwindow.ui
index 1f97bbb..273d192 100644
--- a/lightscreenwindow.ui
+++ b/lightscreenwindow.ui
@@ -1,225 +1,225 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>LightscreenWindowClass</class>
<widget class="QMainWindow" name="LightscreenWindowClass">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>262</width>
<height>115</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Lightscreen</string>
</property>
<property name="windowIcon">
<iconset resource="lightscreen.qrc">
<normaloff>:/icons/lightscreen</normaloff>:/icons/lightscreen</iconset>
</property>
<property name="animated">
<bool>false</bool>
</property>
<property name="unifiedTitleAndToolBarOnMac">
<bool>true</bool>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QGridLayout" name="gridLayout">
<property name="margin">
<number>3</number>
</property>
<property name="spacing">
<number>2</number>
</property>
<item row="0" column="1">
<widget class="QPushButton" name="areaPushButton">
<property name="minimumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>Area capture</string>
</property>
<property name="whatsThis">
<string>Capture a specific area of your desktop, resize and move it around!</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="lightscreen.qrc">
<normaloff>:/icons/area.big</normaloff>:/icons/area.big</iconset>
</property>
<property name="iconSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="shortcut">
<string>Ctrl+A</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="windowPushButton">
<property name="minimumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>Pick window</string>
</property>
<property name="whatsThis">
<string>Drop the picker onto a window to capture it.</string>
</property>
<property name="icon">
<iconset resource="lightscreen.qrc">
- <normaloff>:/icons/picker.big</normaloff>:/icons/picker.big</iconset>
+ <normaloff>:/icons/pickWindow.big</normaloff>:/icons/pickWindow.big</iconset>
</property>
<property name="iconSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="shortcut">
<string>Ctrl+P</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="optionsPushButton">
<property name="minimumSize">
<size>
<width>0</width>
<height>26</height>
</size>
</property>
<property name="toolTip">
<string>Configure Lightscreen</string>
</property>
<property name="text">
<string>&amp;Options</string>
</property>
<property name="icon">
<iconset resource="lightscreen.qrc">
<normaloff>:/icons/configure</normaloff>:/icons/configure</iconset>
</property>
<property name="shortcut">
<string>Ctrl+O</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="folderPushButton">
<property name="minimumSize">
<size>
<width>0</width>
<height>26</height>
</size>
</property>
<property name="toolTip">
<string>Open the current Screenshot folder</string>
</property>
<property name="text">
<string>&amp;Folder</string>
</property>
<property name="icon">
<iconset resource="lightscreen.qrc">
<normaloff>:/icons/folder</normaloff>:/icons/folder</iconset>
</property>
<property name="shortcut">
<string>Ctrl+F</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="imgurPushButton">
<property name="minimumSize">
<size>
<width>0</width>
<height>26</height>
</size>
</property>
<property name="toolTip">
<string>Imgur upload controls</string>
</property>
<property name="text">
<string>&amp;Upload</string>
</property>
<property name="icon">
<iconset resource="lightscreen.qrc">
<normaloff>:/icons/imgur</normaloff>:/icons/imgur</iconset>
</property>
<property name="shortcut">
<string>Ctrl+U</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="screenPushButton">
<property name="minimumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>Fullscreen capture</string>
</property>
<property name="whatsThis">
<string>Take a screenshot of your entire desktop.</string>
</property>
<property name="icon">
<iconset resource="lightscreen.qrc">
<normaloff>:/icons/screen.big</normaloff>:/icons/screen.big</iconset>
</property>
<property name="iconSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="shortcut">
<string>Ctrl+S</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
<include location="lightscreen.qrc"/>
</resources>
<connections/>
</ui>
diff --git a/tools/screenshot.cpp b/tools/screenshot.cpp
index 1842246..a0292b7 100644
--- a/tools/screenshot.cpp
+++ b/tools/screenshot.cpp
@@ -1,514 +1,507 @@
/*
* Copyright (C) 2012 Christian Kaiser
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <QApplication>
#include <QClipboard>
#include <QDateTime>
#include <QDesktopWidget>
#include <QFileDialog>
#include <QPainter>
#include <QPixmap>
#include <QProcess>
#include <QDebug>
#include "windowpicker.h"
#include "../dialogs/areadialog.h"
#include "uploader.h"
#include "screenshot.h"
#include "screenshotmanager.h"
#include "os.h"
#ifdef Q_WS_WIN
#include <windows.h>
#endif
#ifdef Q_WS_X11
#include <QX11Info>
#include <X11/X.h>
#include <X11/Xlib.h>
#endif
Screenshot::Screenshot(QObject *parent, Screenshot::Options options):
QObject(parent),
mOptions(options),
mPixmapDelay(false),
mUnloaded(false),
mUnloadFilename()
{
// Here be crickets
}
Screenshot::~Screenshot()
{
qDebug() << "Deleting Screenshot object!";
if (!mUnloadFilename.isEmpty()) {
QFile::remove(mUnloadFilename);
}
}
QString Screenshot::getName(NamingOptions options, QString prefix, QDir directory)
{
QString naming;
int naming_largest = 0;
if (options.flip) {
naming = "%1" + prefix;
}
else {
naming = prefix + "%1";
}
switch (options.naming)
{
case Screenshot::Numeric: // Numeric
// Iterating through the folder to find the largest numeric naming.
foreach(QString file, directory.entryList(QDir::Files))
{
if (file.contains(prefix)) {
file.chop(file.size() - file.lastIndexOf("."));
file.remove(prefix);
if (file.toInt()> naming_largest) {
naming_largest = file.toInt();
}
}
}
if (options.leadingZeros > 0) {
//Pretty, huh?
QString format;
QTextStream (&format) << "%0" << (options.leadingZeros+1) << "d";
naming = naming.arg(QString().sprintf(format.toAscii(), naming_largest + 1));
}
else {
naming = naming.arg(naming_largest + 1);
}
break;
case Screenshot::Date: // Date
naming = naming.arg(QLocale().toString(QDateTime::currentDateTime(), options.dateFormat));
break;
case Screenshot::Timestamp: // Timestamp
naming = naming.arg(QDateTime::currentDateTime().toTime_t());
break;
case Screenshot::Empty:
naming = naming.arg("");
break;
}
return naming;
}
QString& Screenshot::unloadedFileName()
{
return mUnloadFilename;
}
Screenshot::Options &Screenshot::options()
{
return mOptions;
}
QPixmap &Screenshot::pixmap()
{
- if (mUnloaded) {
- // A local reference.. what could go wrong? Nothing! Right guys? Guys?
- QPixmap p;
- p.load(mUnloadFilename);
- return p;
- }
-
return mPixmap;
}
//
void Screenshot::confirm(bool result)
{
qDebug() << "Screenshot::confirm(" << result << ")";
if (result) {
save();
}
else {
mOptions.result = Screenshot::Cancel;
emit finished();
}
emit cleanup();
mPixmap = QPixmap();
}
void Screenshot::confirmation()
{
qDebug() << "Screenshot: Asking for confirmation.";
emit askConfirmation();
if (mOptions.file) {
unloadPixmap();
}
}
void Screenshot::discard()
{
confirm(false);
}
void Screenshot::markUpload()
{
mOptions.upload = true;
}
void Screenshot::optimize()
{
QProcess* process = new QProcess(this);
// Delete the QProcess once it's done.
connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), this , SLOT(optimizationDone()));
connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), process, SLOT(deleteLater()));
QString optiPNG;
#ifdef Q_OS_UNIX
optiPNG = "optipng";
#else
optiPNG = qApp->applicationDirPath() + QDir::separator() + "optipng.exe";
#endif
if (!QFile::exists(optiPNG)) {
emit optimizationDone();
}
process->start(optiPNG, QStringList() << mOptions.fileName);
if (process->state() == QProcess::NotRunning) {
emit optimizationDone();
process->deleteLater();
}
}
void Screenshot::optimizationDone()
{
if (mOptions.upload) {
upload();
}
else {
emit finished();
}
}
void Screenshot::save()
{
QString name = "";
QString fileName = "";
Screenshot::Result result = Screenshot::Fail;
if (mOptions.file && !mOptions.saveAs) {
name = newFileName();
}
else if (mOptions.file && mOptions.saveAs) {
name = QFileDialog::getSaveFileName(0, tr("Save as.."), newFileName(), "*" + extension());
}
if (!mOptions.replace && QFile::exists(name+extension())) {
// Ugly? You should see my wife!
int count = 0;
int cunt = 0;
QString naming = QFileInfo(name).fileName();
foreach(QString file, QFileInfo(name+extension()).dir().entryList(QDir::Files)) {
if (file.contains(naming)) {
file.remove(naming);
file.remove(" (");
file.remove(")");
file.remove(extension());
cunt = file.toInt();
if (cunt > count) {
count = cunt;
}
}
}
name = name + " (" + QString::number(count+1) + ")";
}
if (mOptions.clipboard && !(mOptions.upload && mOptions.imgurClipboard)) {
qDebug() << "Setting the clipboard pixmap, unloaded:" << mUnloaded;
if (mUnloaded) {
mUnloaded = false;
mPixmap = QPixmap(mUnloadFilename);
}
QApplication::clipboard()->setPixmap(mPixmap, QClipboard::Clipboard);
if (!mOptions.file) {
result = (Screenshot::Result)1;
}
}
// In the following code I use (Screenshot::Result)1 instead of Screenshot::Success because of some weird issue with the X11 headers. //TODO
if (mOptions.file) {
fileName = name + extension();
if (name.isEmpty()) {
result = Screenshot::Cancel;
}
else if (mUnloaded) {
result = (QFile::rename(mUnloadFilename, fileName)) ? (Screenshot::Result)1: Screenshot::Fail;
}
else if (mPixmap.save(fileName, 0, mOptions.quality)) {
result = (Screenshot::Result)1;
}
else {
result = Screenshot::Fail;
}
os::addToRecentDocuments(fileName);
}
mOptions.fileName = fileName;
mOptions.result = result;
if (!mOptions.result)
emit finished();
if (mOptions.format == Screenshot::PNG && mOptions.optimize && mOptions.file) {
if (!mOptions.upload) {
ScreenshotManager::instance()->saveHistory(mOptions.fileName);
}
optimize();
}
else if (mOptions.upload) {
upload();
}
else if (mOptions.file) {
ScreenshotManager::instance()->saveHistory(mOptions.fileName);
emit finished();
}
else {
emit finished();
}
}
void Screenshot::setPixmap(QPixmap pixmap)
{
mPixmap = pixmap;
if (mPixmap.isNull()) {
emit confirm(false);
}
else {
confirmation();
}
}
void Screenshot::take()
{
switch (mOptions.mode)
{
case Screenshot::WholeScreen:
wholeScreen();
break;
case Screenshot::SelectedArea:
selectedArea();
break;
case Screenshot::ActiveWindow:
activeWindow();
break;
case Screenshot::SelectedWindow:
selectedWindow();
break;
}
if (mPixmapDelay)
return;
if (mPixmap.isNull()) {
confirm(false);
}
else {
confirmation();
}
}
void Screenshot::upload()
{
if (mOptions.file) {
Uploader::instance()->upload(mOptions.fileName);
}
else if (unloadPixmap()) {
Uploader::instance()->upload(mUnloadFilename);
}
else {
emit finished();
}
}
void Screenshot::uploadDone(QString url)
{
if (mOptions.imgurClipboard && !url.isEmpty())
QApplication::clipboard()->setText(url, QClipboard::Clipboard);
qDebug() << "Screenshot: UploadDone: " << url;
emit finished();
}
//
void Screenshot::activeWindow()
{
#ifdef Q_WS_WIN
HWND fWindow = GetForegroundWindow();
if (fWindow == NULL)
return;
if (fWindow == GetDesktopWindow()) {
wholeScreen();
return;
}
mPixmap = os::grabWindow(GetForegroundWindow());
#endif
#if defined(Q_WS_X11)
Window focus;
int revert;
XGetInputFocus(QX11Info::display(), &focus, &revert);
mPixmap = QPixmap::grabWindow(focus);
#endif
}
QString Screenshot::extension() const
{
switch (mOptions.format) {
case Screenshot::PNG:
return ".png";
break;
case Screenshot::BMP:
return ".bmp";
break;
case Screenshot::JPEG:
default:
return ".jpg";
break;
}
}
void Screenshot::grabDesktop()
{
QRect geometry;
if (mOptions.currentMonitor) {
geometry = qApp->desktop()->screenGeometry(QCursor::pos());
}
else {
geometry = qApp->desktop()->geometry();
}
mPixmap = QPixmap::grabWindow(qApp->desktop()->winId(), geometry.x(), geometry.y(), geometry.width(), geometry.height());
if (mOptions.cursor && !mPixmap.isNull()) {
QPainter painter(&mPixmap);
painter.drawPixmap(QCursor::pos(), os::cursor());
}
}
QString Screenshot::newFileName() const
{
if (!mOptions.directory.exists()) {
mOptions.directory.mkpath(mOptions.directory.path());
}
QString naming = Screenshot::getName(mOptions.namingOptions, mOptions.prefix, mOptions.directory);
QString path = QDir::toNativeSeparators(mOptions.directory.path());
// Cleanup
if (path.at(path.size()-1) != QDir::separator() && !path.isEmpty()) {
path.append(QDir::separator());
}
QString fileName;
fileName.append(path);
fileName.append(naming);
return fileName;
}
void Screenshot::selectedArea()
{
grabDesktop();
if (mPixmap.isNull())
return;
AreaDialog selector(this);
int result = selector.exec();
if (result == QDialog::Accepted) {
mPixmap = mPixmap.copy(selector.resultRect());
}
else {
mPixmap = QPixmap();
}
}
void Screenshot::selectedWindow()
{
WindowPicker* windowPicker = new WindowPicker;
mPixmapDelay = true;
connect(windowPicker, SIGNAL(pixmap(QPixmap)), this, SLOT(setPixmap(QPixmap)));
}
bool Screenshot::unloadPixmap()
{
if (mUnloaded)
return true;
// Unloading the pixmap to reduce memory usage during previews
- mUnloadFilename = QDir::tempPath() + QDir::separator() + QString(".lstemp.%1%2").arg(qrand() * qrand() + QDateTime::currentDateTime().toTime_t()).arg(extension());
+ mUnloadFilename = mOptions.directory.path() + QDir::separator() + QString(".lstemp.%1%2").arg(qrand() * qrand() + QDateTime::currentDateTime().toTime_t()).arg(extension());
mUnloaded = mPixmap.save(mUnloadFilename, 0, mOptions.quality);
if (mUnloaded) {
mPixmap = QPixmap();
}
return mUnloaded;
}
void Screenshot::wholeScreen()
{
grabDesktop();
}
diff --git a/tools/windowpicker.cpp b/tools/windowpicker.cpp
index 59d76b1..2367a13 100644
--- a/tools/windowpicker.cpp
+++ b/tools/windowpicker.cpp
@@ -1,304 +1,304 @@
/*
* Copyright (C) 2012 Christian Kaiser
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <QApplication>
#include <QDesktopWidget>
#include <QLabel>
#include <QMouseEvent>
#include <QPushButton>
#include <QRubberBand>
#include <QRubberBand>
#include <QVBoxLayout>
#include <QWidget>
#include <QDebug>
#include "windowpicker.h"
#include "os.h"
#if defined(Q_OS_WIN)
#include <windows.h>
#elif defined(Q_WS_X11)
#include <QX11Info>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#endif
WindowPicker::WindowPicker() : QWidget(0), mCrosshair(":/icons/picker"), mWindowLabel(0), mTaken(false)
{
#if defined(Q_OS_WIN)
setWindowFlags(Qt::SplashScreen | Qt::WindowStaysOnTopHint);
#elif defined(Q_WS_X11)
setWindowFlags(Qt::WindowStaysOnTopHint);
#endif
setWindowTitle(tr("Lightscreen Window Picker"));
setStyleSheet("QWidget { color: #000; } #frame { padding: 7px 10px; border: 4px solid #232323; background-color: rgba(250, 250, 250, 255); }");
QLabel *helpLabel = new QLabel(tr("Grab the window picker by clicking and holding down the mouse button, then drag it to the window of your choice and release it to capture."), this);
helpLabel->setMinimumWidth(400);
helpLabel->setMaximumWidth(400);
helpLabel->setWordWrap(true);
mWindowIcon = new QLabel(this);
mWindowIcon->setMinimumSize(22, 22);
mWindowIcon->setMaximumSize(22, 22);
mWindowIcon->setScaledContents(true);
mWindowLabel = new QLabel(tr(" - Start dragging to select windows"), this);
mWindowLabel->setStyleSheet("font-weight: bold");
mCrosshairLabel = new QLabel(this);
mCrosshairLabel->setAlignment(Qt::AlignHCenter);
mCrosshairLabel->setPixmap(mCrosshair);
QPushButton *closeButton = new QPushButton(tr("Close"));
connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
QHBoxLayout *windowLayout = new QHBoxLayout;
windowLayout->addWidget(mWindowIcon);
windowLayout->addWidget(mWindowLabel);
windowLayout->setMargin(0);
QHBoxLayout *buttonLayout = new QHBoxLayout;
buttonLayout->addStretch(0);
buttonLayout->addWidget(closeButton);
buttonLayout->setMargin(0);
QHBoxLayout *crosshairLayout = new QHBoxLayout;
crosshairLayout->addStretch(0);
crosshairLayout->addWidget(mCrosshairLabel);
crosshairLayout->addStretch(0);
crosshairLayout->setMargin(0);
QVBoxLayout *fl = new QVBoxLayout;
fl->addWidget(helpLabel);
fl->addLayout(windowLayout);
fl->addLayout(crosshairLayout);
fl->addLayout(buttonLayout);
fl->setMargin(0);
QFrame *frame = new QFrame(this);
frame->setObjectName("frame");
frame->setLayout(fl);
QVBoxLayout *l = new QVBoxLayout;
l->setMargin(0);
l->addWidget(frame);
setLayout(l);
resize(sizeHint());
move(QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(QCursor::pos())).center()-QPoint(width()/2, height()/2));
show();
}
WindowPicker::~WindowPicker() {
qApp->restoreOverrideCursor();
}
void WindowPicker::cancel() {
mWindowIcon->setPixmap(QPixmap());
mCrosshairLabel->setPixmap(mCrosshair);
qApp->restoreOverrideCursor();
}
void WindowPicker::closeEvent(QCloseEvent*)
{
if (!mTaken)
emit pixmap(QPixmap());
qApp->restoreOverrideCursor();
deleteLater();
}
void WindowPicker::mouseMoveEvent(QMouseEvent *event)
{
QString windowName;
#if defined(Q_OS_WIN)
POINT mousePos;
mousePos.x = event->globalX();
mousePos.y = event->globalY();
HWND cWindow = GetAncestor(WindowFromPoint(mousePos), GA_ROOT);
mCurrentWindow = (WId) cWindow;
if (mCurrentWindow == winId()) {
mWindowIcon->setPixmap(QPixmap());
mWindowLabel->setText("");
return;
}
// Text
WCHAR str[60];
HICON icon;
::GetWindowText((HWND)mCurrentWindow, str, 60);
windowName = QString::fromWCharArray(str);
///
// Retrieving the application icon
icon = (HICON)::GetClassLong((HWND)mCurrentWindow, GCL_HICON);
if (icon != NULL) {
mWindowIcon->setPixmap(QPixmap::fromWinHICON(icon));
}
else {
mWindowIcon->setPixmap(QPixmap());
}
#elif defined(Q_WS_X11)
Window cWindow = os::windowUnderCursor(false);
if (cWindow == mCurrentWindow) {
return;
}
mCurrentWindow = cWindow;
if (mCurrentWindow == winId()) {
mWindowIcon->setPixmap(QPixmap());
mWindowLabel->setText("");
return;
}
// Getting the window name property.
XTextProperty tp;
char **text;
int count;
if (XGetTextProperty(QX11Info::display(), cWindow, &tp, XA_WM_NAME) != 0 && tp.value != NULL ) {
if (tp.encoding == XA_STRING) {
windowName = QString::fromLocal8Bit((const char*) tp.value);
}
else if (XmbTextPropertyToTextList( QX11Info::display(), &tp, &text, &count) == Success &&
text != NULL && count > 0) {
windowName = QString::fromLocal8Bit(text[0]);
XFreeStringList(text);
}
XFree(tp.value);
}
// Retrieving the _NET_WM_ICON property.
Atom type_ret = None;
unsigned char *data = 0;
int format = 0;
unsigned long n = 0;
unsigned long extra = 0;
int width = 0;
int height = 0;
Atom _net_wm_icon = XInternAtom(QX11Info::display(), "_NET_WM_ICON", False);
if (XGetWindowProperty(QX11Info::display(), cWindow, _net_wm_icon, 0, 1, False,
XA_CARDINAL, &type_ret, &format, &n, &extra, (unsigned char **)&data) == Success && data)
{
width = data[0];
XFree(data);
}
if (XGetWindowProperty(QX11Info::display(), cWindow, _net_wm_icon, 1, 1, False,
XA_CARDINAL, &type_ret, &format, &n, &extra, (unsigned char **)&data) == Success && data)
{
height = data[0];
XFree(data);
}
if (XGetWindowProperty(QX11Info::display(), cWindow, _net_wm_icon, 2, width*height, False,
XA_CARDINAL, &type_ret, &format, &n, &extra, (unsigned char **)&data) == Success && data)
{
QImage img(data, width, height, QImage::Format_ARGB32);
mWindowIcon->setPixmap(QPixmap::fromImage(img));
XFree(data);
}
else {
mWindowIcon->setPixmap(QPixmap());
}
#endif
QString windowText;
if (!mWindowIcon->pixmap()) {
windowText = QString(" - %1").arg(windowName);
}
else {
windowText = windowName;
}
if (windowText == " - ") {
mWindowLabel->setText("");
return;
}
if (windowText.length() == 62) {
mWindowLabel->setText(windowText + "...");
}
else {
mWindowLabel->setText(windowText);
}
}
void WindowPicker::mousePressEvent(QMouseEvent *event)
{
qApp->setOverrideCursor(QCursor(mCrosshair));
mCrosshairLabel->setMinimumWidth(mCrosshairLabel->width());
mCrosshairLabel->setMinimumHeight(mCrosshairLabel->height());
mCrosshairLabel->setPixmap(QPixmap());
QWidget::mousePressEvent(event);
}
void WindowPicker::mouseReleaseEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
#if defined(Q_OS_WIN)
POINT mousePos;
mousePos.x = event->globalX();
mousePos.y = event->globalY();
HWND window = GetAncestor(WindowFromPoint(mousePos), GA_ROOT);
#elif defined(Q_WS_X11)
Window window = os::windowUnderCursor(false);
#endif
- if (window == (HWND)winId()) {
+ if ((WId)window == winId()) {
cancel();
return;
}
mTaken = true;
setWindowFlags(windowFlags() ^ Qt::WindowStaysOnTopHint);
close();
#ifdef Q_WS_X11
emit pixmap(QPixmap::grabWindow(mCurrentWindow));
#else
emit pixmap(os::grabWindow((WId)window));
#endif
return;
}
close();
}

File Metadata

Mime Type
text/x-diff
Expires
Wed, Jun 17, 9:15 PM (1 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
70345
Default Alt Text
(127 KB)

Event Timeline