Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
69 KB
Referenced Files
None
Subscribers
None
diff --git a/dialogs/optionsdialog.cpp b/dialogs/optionsdialog.cpp
index 5b9f5c5..e6a8148 100644
--- a/dialogs/optionsdialog.cpp
+++ b/dialogs/optionsdialog.cpp
@@ -1,643 +1,660 @@
/*
* Copyright (C) 2011 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 <QSettings>
#include <QUrl>
#include <QTimer>
#include <QDebug>
#if defined(Q_WS_WIN)
#include <windows.h>
#endif
#include "optionsdialog.h"
#include "namingdialog.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 (os::aeroGlass(this)) {
layout()->setMargin(2);
resize(minimumSizeHint());
}
QTimer::singleShot(0, this, SLOT(init()));
QTimer::singleShot(1, this, SLOT(loadSettings()));
}
void OptionsDialog::init()
{
#if !defined(Q_WS_WIN)
ui.cursorCheckBox->setVisible(false);
ui.cursorCheckBox->setChecked(false);
+
+ // KDE-specific style tweaks.
+ if (qApp->style()->objectName() == "oxygen") {
+ qDebug() << "OXYGENN YEAAHH";
+ 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.aboutTab->layout()->setMargin(8);
+ }
#endif
// 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.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.
setUpdatesEnabled(false);
//
// 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(textChanged(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.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)));
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.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.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();
}
QSettings *OptionsDialog::settings() const
{
return ScreenshotManager::instance()->settings();
}
/*
* Slots
*/
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::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::checkUpdatesNow()
{
Updater::instance()->checkWithFeedback();
}
void OptionsDialog::dialogButtonClicked(QAbstractButton *button)
{
if (ui.buttonBox->buttonRole(button) == QDialogButtonBox::ResetRole) {
QMessageBox msgBox;
msgBox.setWindowTitle(tr("Lightscreen - 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.exec();
Q_UNUSED(restoreButton)
if (msgBox.clickedButton() == dontRestoreButton)
return;
settings()->clear();
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() == "screenshot."
&& checked)
ui.prefixLineEdit->setText(".screenshot");
if (ui.prefixLineEdit->text() == ".screenshot"
&& !checked)
ui.prefixLineEdit->setText("screenshot.");
setUpdatesEnabled(true); // Avoids flicker
}
void OptionsDialog::languageChange(QString language)
{
os::translate(language);
}
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.previewCheckBox->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("areaAutoclose", ui.areaAutocloseCheckBox->isChecked());
// Advanced
settings()->setValue("disableHideAlert", !ui.warnHideCheckBox->isChecked());
settings()->setValue("clipboard", ui.clipboardCheckBox->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();
}
/*
* Private
*/
void OptionsDialog::loadSettings()
{
settings()->sync();
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);
// Move the first option window to the center of the screen, since Windows usually positions it in a random location since it has no visible parent.
if (!(static_cast<QWidget*>(parent())->isVisible()))
move(qApp->desktop()->screen(qApp->desktop()->primaryScreen())->rect().center()-QPoint(height()/2, width()/2));
}
ui.startupCheckBox->toggle();
ui.trayCheckBox->toggle();
ui.previewAutocloseCheckBox->toggle();
settings()->beginGroup("file");
ui.formatComboBox->setCurrentIndex(settings()->value("format", 1).toInt());
ui.prefixLineEdit->setText(settings()->value("prefix", "screenshot.").toString());
ui.namingComboBox->setCurrentIndex(settings()->value("naming", 0).toInt());
ui.targetLineEdit->setText(settings()->value("target", os::getDocumentsPath() + QDir::separator() + "Screenshots").toString()); // Defaults to $HOME$/screenshots
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", true).toBool());
ui.cursorCheckBox->setChecked(settings()->value("cursor", true).toBool());
ui.saveAsCheckBox->setChecked(settings()->value("saveAs", false).toBool());
- ui.previewCheckBox->setChecked(settings()->value("preview", 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.areaAutocloseCheckBox->setChecked(settings()->value("areaAutoclose", false).toBool());
// Advanced
ui.clipboardCheckBox->setChecked(settings()->value("clipboard", true).toBool());
ui.optiPngCheckBox->setChecked(settings()->value("optipng", true).toBool());
ui.warnHideCheckBox->setChecked(!settings()->value("disableHideAlert", false).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());
#if defined(Q_WS_WIN)
if (!QFile::exists("optipng.exe")) {
ui.optiPngCheckBox->setEnabled(false);
ui.optiPngCheckBox->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", QKeySequence(Qt::Key_Print)).value<QKeySequence> ());
settings()->endGroup();
settings()->beginGroup("area");
ui.areaCheckBox->setChecked(settings()->value("enabled").toBool());
ui.areaHotkeyWidget->setHotkey(settings()->value("hotkey", QKeySequence(Qt::CTRL + Qt::Key_Print)).value<QKeySequence> ());
settings()->endGroup();
settings()->beginGroup("window");
ui.windowCheckBox->setChecked(settings()->value("enabled").toBool());
ui.windowHotkeyWidget->setHotkey(settings()->value("hotkey", QKeySequence(Qt::ALT + Qt::Key_Print)).value<QKeySequence> ());
settings()->endGroup();
settings()->beginGroup("windowPicker");
ui.windowPickerCheckBox->setChecked(settings()->value("enabled").toBool());
ui.windowPickerHotkeyWidget->setHotkey(settings()->value("hotkey", QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_Print)).value<QKeySequence> ());
settings()->endGroup();
settings()->beginGroup("open");
ui.openCheckBox->setChecked(settings()->value("enabled").toBool());
ui.openHotkeyWidget->setHotkey(settings()->value("hotkey", QKeySequence(Qt::CTRL + Qt::Key_PageUp)).value<QKeySequence> ());
settings()->endGroup();
settings()->beginGroup("directory");
ui.directoryCheckBox->setChecked(settings()->value("enabled").toBool());
ui.directoryHotkeyWidget->setHotkey(settings()->value("hotkey", QKeySequence(Qt::SHIFT + Qt::Key_PageUp)).value<QKeySequence> ());
settings()->endGroup();
settings()->endGroup();
QTimer::singleShot(0, this, SLOT(updatePreview()));
setEnabled(true);
setUpdatesEnabled(true);
}
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;
}
void OptionsDialog::updatePreview()
{
Screenshot::NamingOptions options;
options.naming = (Screenshot::Naming)ui.namingComboBox->currentIndex();
options.flip = settings()->value("options/flip").toBool();
options.leadingZeros = settings()->value("options/naming/leadingZeros").toInt();
options.dateFormat = settings()->value("options/naming/dateFormat").toString();
ui.namingOptionsButton->setDisabled((options.naming == Screenshot::None));
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);
}
bool OptionsDialog::event(QEvent* event)
{
if (event->type() == QEvent::LanguageChange) {
ui.retranslateUi(this);
updatePreview();
resize(minimumSizeHint());
}
else if (event->type() == QEvent::Close) {
if (!settings()->contains("file/format")) {
// I'm afraid I can't let you do that, Dave.
event->ignore();
return false;
}
}
return QDialog::event(event);
}
#if defined(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
diff --git a/lightscreen.pro b/lightscreen.pro
index d23e3a4..8cffa67 100644
--- a/lightscreen.pro
+++ b/lightscreen.pro
@@ -1,61 +1,60 @@
TEMPLATE = app
TARGET = lightscreen
HEADERS += tools/os.h \
updater/updater.h \
dialogs/areadialog.h \
dialogs/optionsdialog.h \
widgets/hotkeywidget.h \
lightscreenwindow.h \
tools/screenshot.h \
dialogs/previewdialog.h \
tools/screenshotmanager.h \
tools/windowpicker.h \
tools/qtwin.h \
dialogs/updaterdialog.h \
dialogs/screenshotdialog.h \
dialogs/namingdialog.h \
tools/qtimgur.h \
tools/uploader.h
SOURCES += tools/os.cpp \
updater/updater.cpp \
dialogs/areadialog.cpp \
dialogs/optionsdialog.cpp \
widgets/hotkeywidget.cpp \
main.cpp \
lightscreenwindow.cpp \
tools/screenshot.cpp \
dialogs/previewdialog.cpp \
tools/screenshotmanager.cpp \
tools/windowpicker.cpp \
tools/qtwin.cpp \
dialogs/updaterdialog.cpp \
dialogs/screenshotdialog.cpp \
dialogs/namingdialog.cpp \
tools/qtimgur.cpp \
tools/uploader.cpp
FORMS += dialogs/optionsdialog.ui \
lightscreenwindow.ui \
dialogs/namingdialog.ui
RESOURCES += lightscreen.qrc
TRANSLATIONS += translations/untranslated.ts \
translations/spanish.ts \
translations/russian.ts \
translations/portuguese.ts \
translations/polish.ts \
translations/japanese.ts \
translations/italian.ts \
translations/dutch.ts
RC_FILE += lightscreen.rc
CODECFORSRC = UTF-8
-LIBS += libgcc
QT += network core gui xml
-win32:LIBS += libgdi32
+win32:LIBS += libgdi32 libgcc
include($$PWD/tools/globalshortcut/globalshortcut.pri)
include($$PWD/tools/qtsingleapplication/qtsingleapplication.pri)
QMAKE_CXXFLAGS = -Wextra -Wall -Wpointer-arith
OTHER_FILES += TODO.txt
diff --git a/lightscreenwindow.cpp b/lightscreenwindow.cpp
index 4723ba9..22f090c 100644
--- a/lightscreenwindow.cpp
+++ b/lightscreenwindow.cpp
@@ -1,992 +1,984 @@
/*
* Copyright (C) 2011 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 <QDate>
#include <QDesktopServices>
#include <QFileInfo>
#include <QHttp>
#include <QMenu>
#include <QMessageBox>
#include <QPointer>
#include <QProcess>
#include <QSettings>
#include <QSound>
#include <QSystemTrayIcon>
#include <QTimer>
#include <QUrl>
#include <QKeyEvent>
#include <QToolTip>
#include <QDebug>
#if defined(Q_WS_WIN)
#include <windows.h>
#endif
/*
* Lightscreen includes
*/
#include "lightscreenwindow.h"
#include "dialogs/optionsdialog.h"
#include "dialogs/previewdialog.h"
#include "tools/globalshortcut/globalshortcutmanager.h"
#include "tools/os.h"
#include "tools/screenshot.h"
#include "tools/screenshotmanager.h"
#include "tools/qtwin.h"
#include "tools/uploader.h"
#include "updater/updater.h"
LightscreenWindow::LightscreenWindow(QWidget *parent) :
QDialog(parent),
mDoCache(false),
mHideTrigger(false),
mReviveMain(false),
mWasVisible(true),
mOptimizeCount(0),
mLastMode(-1),
mLastMessage(0),
mLastScreenshot()
{
os::translate(settings()->value("options/language").toString());
ui.setupUi(this);
if (QtWin::isCompositionEnabled()) {
layout()->setMargin(0);
resize(minimumSizeHint());
}
setMaximumSize(size());
setMinimumSize(size());
setWindowFlags(windowFlags() ^ Qt::WindowContextHelpButtonHint); // Remove the what's this button, no real use in the main window.
// Actions
connect(ui.optionsPushButton , SIGNAL(clicked()), this, SLOT(showOptions()));
connect(ui.hidePushButton , SIGNAL(clicked()), this, SLOT(toggleVisibility()));
connect(ui.screenshotPushButton, SIGNAL(clicked()), this, SLOT(showScreenshotMenu()));
connect(ui.quitPushButton , SIGNAL(clicked()), this, SLOT(quit()));
// Uploader
connect(Uploader::instance(), SIGNAL(done(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);
GlobalShortcutManager::instance()->clear();
delete mTrayIcon;
}
/*
* Slots
*/
void LightscreenWindow::action(int mode)
{
if (mode == 4) {
goToFolder();
}
else {
show();
}
}
bool LightscreenWindow::closingWithoutTray()
{
if (settings()->value("options/disableHideAlert", false).toBool())
return false;
QMessageBox msgBox;
msgBox.setWindowTitle(tr("Lightscreen"));
msgBox.setText(tr("You have chosen to hide Lightscreen when there's no system tray icon, so you will not be able to access the program <b>unless you have selected a hotkey to do so</b>.<br>What do you want to do?"));
msgBox.setIcon(QMessageBox::Warning);
msgBox.setStyleSheet("QPushButton { padding: 4px 8px; }");
QPushButton *enableButton = msgBox.addButton(tr("Hide but enable tray"),
QMessageBox::ActionRole);
QPushButton *enableAndDenotifyButton = msgBox.addButton(tr("Hide and don't warn"),
QMessageBox::ActionRole);
QPushButton *hideButton = msgBox.addButton(tr("Just hide"),
QMessageBox::ActionRole);
QPushButton *abortButton = msgBox.addButton(QMessageBox::Cancel);
Q_UNUSED(abortButton);
msgBox.exec();
if (msgBox.clickedButton() == hideButton) {
return false;
}
else if (msgBox.clickedButton() == enableAndDenotifyButton) {
settings()->setValue("options/disableHideAlert", true);
applySettings();
return false;
}
else if (msgBox.clickedButton() == enableButton) {
settings()->setValue("options/tray", true);
applySettings();
return false;
}
return true; // Cancel
}
void LightscreenWindow::cleanup(Screenshot::Options options)
{
// Reversing settings
if (settings()->value("options/hide").toBool()) {
if (settings()->value("options/tray").toBool() && mTrayIcon) {
mTrayIcon->show();
}
if (PreviewDialog::isActive()) {
if (PreviewDialog::instance()->count() <= 1 && mWasVisible) {
show();
}
PreviewDialog::instance()->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) {
showScreenshotMessage(options.result, options.fileName);
}
}
if (settings()->value("options/playSound", false).toBool()) {
if (options.result == Screenshot::Success) {
QSound::play("sounds/ls.screenshot.wav");
}
else {
QSound::play("afakepathtomakewindowsplaythedefaultsoundtheresprobablyabetterwaybuticantbebothered");
}
}
if (options.result == Screenshot::Success
&& settings()->value("options/optipng").toBool()
&& settings()->value("file/format").toInt() == Screenshot::PNG)
{
compressPng(options.fileName);
}
else if (settings()->value("options/uploadAuto").toBool()) {
upload(options.fileName);
}
if (options.result == Screenshot::Success && options.file) {
mLastScreenshot = options.fileName;
}
}
void LightscreenWindow::goToFolder()
{
#ifdef Q_WS_WIN
if (!mLastScreenshot.isEmpty()) {
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::messageReceived(const QString message)
{
if (message == "-wake") {
show();
qApp->alert(this, 500);
return;
}
if (message == "-screen")
screenshotAction();
if (message == "-area")
screenshotAction(2);
if (message == "-activewindow")
screenshotAction(1);
if (message == "-pickwindow")
screenshotAction(3);
if (message == "-folder")
action(4);
}
void LightscreenWindow::messageClicked()
{
if (mLastMessage == 1) {
goToFolder();
}
else {
QDesktopServices::openUrl(QUrl(Uploader::instance()->lastUrl()));
}
}
void LightscreenWindow::preview(Screenshot* screenshot)
{
if (screenshot->options().preview) {
PreviewDialog::instance()->add(screenshot);
}
else {
screenshot->confirm(true);
}
}
void LightscreenWindow::quit()
{
settings()->setValue("position", pos());
QString doing;
int answer = 0;
if (Uploader::instance()->uploading() > 0) {
doing = tr("uploading one or more screenshots");
}
if (mOptimizeCount > 0) {
if (!doing.isNull()) {
doing = tr("optimizing and uploading screenshots");
}
else {
doing = tr("optimizing one or more screenshots");
}
}
if (!doing.isNull()) {
answer = QMessageBox::question(this,
tr("Are you sure you want to quit?"),
tr("Lightscreen is currently %1, this will finish momentarily, are you sure you want to quit?").arg(doing),
tr("Quit"),
tr("Don't quit"));
}
if (answer == 0)
accept();
}
void LightscreenWindow::restoreNotification()
{
if (mTrayIcon)
mTrayIcon->setIcon(QIcon(":/icons/lightscreen.small"));
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();
if (mTrayIcon)
mTrayIcon->hide();
}
// Screenshot delay
delayms = settings()->value("options/delay", 0).toInt();
delayms = delayms * 1000; // Converting the delay to milliseconds.
- delayms += 200;
-
-#if defined(Q_WS_WIN)
- if (optionsHide) {
- // When on Windows Vista, the window takes a little bit longer to hide
- if (QSysInfo::WindowsVersion == QSysInfo::WV_VISTA)
- delayms += 200;
- }
-#endif
+ delayms += 400;
if (optionsHide && PreviewDialog::isActive()) {
if (PreviewDialog::instance()->count() >= 1)
PreviewDialog::instance()->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();
options.directory = QDir(settings()->value("file/target").toString());
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.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();
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::showOptions()
{
GlobalShortcutManager::clear();
QPointer<OptionsDialog> optionsDialog = new OptionsDialog(this);
optionsDialog->exec();
optionsDialog->deleteLater();
applySettings();
}
void LightscreenWindow::showScreenshotMessage(Screenshot::Result result, QString fileName)
{
if (result == Screenshot::Cancel
|| PreviewDialog::isActive())
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::showUploaderMessage(QString fileName, QString url)
{
if (!mTrayIcon)
return;
QString screenshot = QFileInfo(fileName).fileName();
mLastMessage = 2;
mTrayIcon->showMessage(tr("%1 uploaded").arg(screenshot), tr("Click here to go to %1").arg(url));
updateUploadStatus();
}
void LightscreenWindow::showUploaderError(QString error)
{
if (!mTrayIcon)
return;
mLastMessage = -1;
mTrayIcon->showMessage(tr("Upload error"), error);
updateUploadStatus();
}
void LightscreenWindow::showScreenshotMenu()
{
// This slot is called only on the first click
QMenu *buttonMenu = new QMenu;
QAction *screenAction = new QAction(QIcon(":/icons/screen"), tr("&Screen"), buttonMenu);
screenAction->setData(QVariant(0));
QAction *windowAction = new QAction(QIcon(":/icons/window"),tr("Active &Window"), buttonMenu);
windowAction->setData(QVariant(1));
QAction *windowPickerAction = new QAction(QIcon(":/icons/picker"), tr("&Pick Window"), buttonMenu);
windowPickerAction->setData(QVariant(3));
QAction *areaAction = new QAction(QIcon(":/icons/area"), tr("&Area"), buttonMenu);
areaAction->setData(QVariant(2));
QAction *uploadAction = new QAction(QIcon(":/icons/imgur"), tr("&Upload last"), buttonMenu);
uploadAction->setToolTip(tr("Upload the last screenshot you took to imgur.com"));
connect(uploadAction, SIGNAL(triggered()), this, SLOT(uploadLast()));
QAction *goAction = new QAction(QIcon(":/icons/folder"), tr("&Go to Folder"), buttonMenu);
connect(goAction, SIGNAL(triggered()), this, SLOT(goToFolder()));
QActionGroup *screenshotGroup = new QActionGroup(buttonMenu);
screenshotGroup->addAction(screenAction);
screenshotGroup->addAction(windowAction);
screenshotGroup->addAction(windowPickerAction);
screenshotGroup->addAction(areaAction);
QMenu* imgurMenu = new QMenu("Upload");
imgurMenu->installEventFilter(this);
imgurMenu->addAction(uploadAction);
imgurMenu->addSeparator();
connect(screenshotGroup, SIGNAL(triggered(QAction*)), this, SLOT(screenshotActionTriggered(QAction*)));
buttonMenu->addAction(screenAction);
buttonMenu->addAction(areaAction);
buttonMenu->addAction(windowAction);
buttonMenu->addAction(windowPickerAction);
buttonMenu->addSeparator();
buttonMenu->addMenu(imgurMenu);
buttonMenu->addSeparator();
buttonMenu->addAction(goAction);
ui.screenshotPushButton->setMenu(buttonMenu);
ui.screenshotPushButton->showMenu();
}
void LightscreenWindow::notify(Screenshot::Result result)
{
switch (result)
{
case Screenshot::Success:
mTrayIcon->setIcon(QIcon(":/icons/lightscreen.yes"));
setWindowTitle(tr("Success!"));
break;
case Screenshot::Fail:
mTrayIcon->setIcon(QIcon(":/icons/lightscreen.no"));
setWindowTitle(tr("Failed!"));
break;
case Screenshot::Cancel:
setWindowTitle(tr("Cancelled!"));
break;
}
QTimer::singleShot(1500, this, SLOT(restoreNotification()));
}
void LightscreenWindow::optimizationDone()
{
// A mouthful :D
mOptimizeCount--;
QString screenshot = (qobject_cast<QProcess*>(sender()))->property("screenshot").toString();
upload(screenshot);
}
void LightscreenWindow::showHotkeyError(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::toggleVisibility(QSystemTrayIcon::ActivationReason reason)
{
if (reason != QSystemTrayIcon::DoubleClick)
return;
if (isVisible()) {
if (settings()->value("options/tray").toBool() == false
&& closingWithoutTray())
return;
hide();
}
else {
show();
}
}
// Aliases
void LightscreenWindow::windowHotkey() { screenshotAction(1); }
void LightscreenWindow::windowPickerHotkey() { screenshotAction(3); }
void LightscreenWindow::areaHotkey() { screenshotAction(2); }
/*
* Private
*/
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 = settings()->value("lastScreenshot").toString();
os::setStartup(settings()->value("options/startup").toBool(), settings()->value("options/startupHide").toBool());
}
void LightscreenWindow::compressPng(QString fileName)
{
#if defined(Q_OS_UNIX)
QProcess::startDetached("optipng " + fileName + " -quiet");
#else
if (settings()->value("options/uploadAuto").toBool()) {
// If the user has chosen to automatically upload screenshots we have to track the progress of the optimization, so we use QProcess
QProcess* optipng = new QProcess(this);
// To be read by optimizationDone() (for uploading)
optipng->setProperty("screenshot", fileName);
// Delete the QProcess once it's done.
connect(optipng, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(optimizationDone()));
connect(optipng, SIGNAL(finished(int, QProcess::ExitStatus)), optipng, SLOT(deleteLater()));
optipng->start("optipng", QStringList() << fileName);
mOptimizeCount++;
}
else {
// Otherwise start it detached from this process.
ShellExecuteW(NULL, NULL, (LPCWSTR)QString("optipng.exe").toStdWString().data(), (LPCWSTR)fileName.toStdWString().data(), NULL, SW_HIDE);
}
#endif
}
void LightscreenWindow::connectHotkeys()
{
// Set to true because if the hotkey is disabled it will show an error.
bool screen = true, area = true, window = 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())
window = 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 (!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);
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 *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("Screenshot");
screenshotMenu->addAction(screenAction);
screenshotMenu->addAction(areaAction);
screenshotMenu->addAction(windowAction);
screenshotMenu->addAction(windowPickerAction);
// Duplicated for the screenshot button :(
QMenu* imgurMenu = new QMenu("Upload");
imgurMenu->installEventFilter(this);
imgurMenu->addAction(uploadAction);
imgurMenu->addSeparator();
mUploadHistoryActions = new QActionGroup(imgurMenu);
connect(mUploadHistoryActions, SIGNAL(triggered(QAction*)), this, SLOT(uploadAction(QAction*)));
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);
}
bool LightscreenWindow::eventFilter(QObject *object, QEvent *event)
{
// Filtering upload menu(s) for show events to populate them with links to imgur.
if (event->type() == QEvent::Show) {
QMenu* menu = qobject_cast<QMenu*>(object);
QAction* uploadAction = menu->actions().at(0);
uploadAction->setEnabled(true); // Later in the loop we check to see if the last screenshot is already uploaded and disable this.
if (Uploader::instance()->screenshots().count() > 0) {
QAction* action = 0;
foreach (action, mUploadHistoryActions->actions()) {
mUploadHistoryActions->removeAction(action);
menu->removeAction(action);
delete action;
}
// Iterating back to front for the first 10 screenshots in the uploader history.
QListIterator< QPair<QString, QString> > iterator(Uploader::instance()->screenshots());
iterator.toBack();
int limit = 0;
while (iterator.hasPrevious()) {
if (limit >= 10) {
break;
}
action = new QAction(iterator.peekPrevious().second, menu);
action->setToolTip(QFileInfo(iterator.peekPrevious().first).fileName());
if (iterator.previous().first == mLastScreenshot) {
uploadAction->setEnabled(false);
}
mUploadHistoryActions->addAction(action);
menu->addAction(action);
limit++;
}
}
}
else if (event->type() == QEvent::ToolTip) {
QHelpEvent* helpEvent = dynamic_cast<QHelpEvent*>(event);
QMenu* menu = qobject_cast<QMenu*>(object);
QAction* action = menu->actionAt(helpEvent->pos());
if (action) {
QToolTip::showText(helpEvent->globalPos(), action->toolTip(), this);
}
}
return QDialog::eventFilter(object, event);
}
QSettings *LightscreenWindow::settings() const
{
return ScreenshotManager::instance()->settings();
}
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::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/new-version"));
}
else if (msgBox.clickedButton() == turnOffButton) {
settings()->setValue("disableUpdater", true);
}
}
void LightscreenWindow::upload(QString fileName)
{
Uploader::instance()->upload(fileName);
}
void LightscreenWindow::uploadAction(QAction *upload)
{
QString url = upload->text();
if (url == tr("Uploading...")) {
//int confirm = QMessageBox::question()
}
else {
QDesktopServices::openUrl(QUrl(url));
}
}
void LightscreenWindow::uploadLast()
{
upload(mLastScreenshot);
updateUploadStatus();
}
void LightscreenWindow::updateUploadStatus()
{
int uploading = Uploader::instance()->uploading();
QString statusString;
if (uploading > 0) {
statusString = tr("Lightscreen: Uploading %1 screenshot").arg(uploading);
}
else {
statusString = tr("Lightscreen %1").arg(qApp->applicationVersion());
}
if (mTrayIcon) {
mTrayIcon->setToolTip(statusString);
}
setWindowTitle(statusString);
}
// Event handling
bool LightscreenWindow::event(QEvent *event)
{
if (event->type() == QEvent::Hide) {
settings()->setValue("position", pos());
}
else if (event->type() == QEvent::Close) {
quit();
}
else if (event->type() == QEvent::Show) {
os::aeroGlass(this);
if (!settings()->value("position").toPoint().isNull())
move(settings()->value("position").toPoint());
}
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 QDialog::event(event);
}
diff --git a/tools/uploader.cpp b/tools/uploader.cpp
index 3098ae9..a124bd9 100644
--- a/tools/uploader.cpp
+++ b/tools/uploader.cpp
@@ -1,144 +1,145 @@
/*
* Copyright (C) 2011 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 "uploader.h"
#include "qtimgur.h"
#include <QList>
#include <QPair>
#include <QDebug>
-Uploader::Uploader(QObject *parent) : QObject(parent)
+Uploader::Uploader(QObject *parent) : QObject(parent), mUploading(0)
{
mImgur = new QtImgur("6920a141451d125b3e1357ce0e432409", this);
connect(mImgur, SIGNAL(uploaded(QString, QString)), this, SLOT(uploaded(QString, QString)));
connect(mImgur, SIGNAL(error(QString, QtImgur::Error)), this, SLOT(imgurError(QString, QtImgur::Error)));
}
void Uploader::upload(const QString &fileName)
{
if (fileName.isEmpty()) {
return;
}
// Cancel on duplicate
for (int i = 0; i < mScreenshots.size(); ++i) {
if (mScreenshots.at(i).first == fileName) {
return;
}
}
mImgur->upload(fileName);
QPair<QString, QString> screenshot;
screenshot.first = fileName;
screenshot.second = tr("Uploading...");
mScreenshots.append(screenshot);
+ qDebug() << "WTF";
mUploading++;
}
void Uploader::uploaded(const QString &file, const QString &url)
{
// Modifying uploaded list, adding url.
for (int i = 0; i < mScreenshots.size(); ++i) {
if (mScreenshots.at(i).first == file) {
mScreenshots[i].second = url;
break;
}
}
mUploading--;
emit done(file, url);
}
int Uploader::uploading()
{
return mUploading;
}
void Uploader::imgurError(const QString &file, const QtImgur::Error e)
{
qDebug() << "Uploader::imgurError(" << file << ", " << e << ")";
mUploading--;
// Removing the screenshot.
for (int i = 0; i < mScreenshots.size(); ++i) {
if (mScreenshots.at(i).first == file) {
mScreenshots.removeAt(i);
break;
}
}
if (e == mLastError) {
// Fail silently? Really? FINE
return;
}
QString errorString;
switch (e) {
case QtImgur::ErrorFile:
errorString = tr("Screenshot file not found.");
break;
case QtImgur::ErrorNetwork:
errorString = tr("Could not reach imgur.com");
break;
case QtImgur::ErrorCredits:
errorString = tr("You have exceeded your upload quota.");
break;
case QtImgur::ErrorUpload:
errorString = tr("Upload failed.");
break;
}
mLastError = e;
emit error(errorString);
}
QString Uploader::lastUrl()
{
QListIterator< QPair<QString, QString> > i(mScreenshots);
i.toBack();
QString url;
while (i.hasPrevious()) {
url = i.previous().second;
if (!url.contains(tr("Uploading..."))) {
return url;
}
}
return url;
}
// Singleton
Uploader* Uploader::mInstance = 0;
Uploader *Uploader::instance()
{
if (!mInstance)
mInstance = new Uploader();
return mInstance;
}
diff --git a/tools/windowpicker.cpp b/tools/windowpicker.cpp
index 6c2c1e0..5c76eef 100644
--- a/tools/windowpicker.cpp
+++ b/tools/windowpicker.cpp
@@ -1,224 +1,227 @@
/*
* Copyright (C) 2011 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 <QWidget>
#include <QDesktopWidget>
#include <QMouseEvent>
#include <QVBoxLayout>
#include <QLabel>
#include <QDebug>
#include <QRubberBand>
#include <QPushButton>
#include <QRubberBand>
#include "windowpicker.h"
#include "os.h"
#ifdef Q_OS_WIN
#include <windows.h>
#endif
WindowPicker::WindowPicker() : QWidget(0), mCrosshair(":/icons/picker"), mWindowLabel(0), mTaken(false)
{
setWindowFlags(Qt::SplashScreen | Qt::WindowStaysOnTopHint);
setWindowTitle(tr("Lightscreen Window Picker"));
setStyleSheet("QWidget { color: #000; } #frame { padding: 7px 10px; border: 1px solid #898c95; background-color: qlineargradient(spread:pad, x1:1, y1:1, x2:0.988636, y2:0.608, stop:0 rgba(235, 235, 235, 255), stop:1 rgba(255, 255, 255, 255)); border-radius: 8px; }");
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);
mWindowIndicator = new QRubberBand(QRubberBand::Rectangle, 0);
mWindowIndicator->setWindowFlags(mWindowIndicator->windowFlags() & Qt::WindowStaysOnTopHint);
mWindowIndicator->setGeometry(0, 0, 0, 0);
mWindowIndicator->show();
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();
delete mWindowIndicator;
}
void WindowPicker::cancel() {
mWindowIcon->setPixmap(QPixmap());
mCrosshairLabel->setPixmap(mCrosshair);
mWindowIndicator->setGeometry(0, 0, 0, 0);
qApp->restoreOverrideCursor();
}
void WindowPicker::mouseReleaseEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
+#ifdef Q_OS_WINDOWS
POINT mousePos;
mousePos.x = event->globalX();
mousePos.y = event->globalY();
HWND window = GetAncestor(WindowFromPoint(mousePos), GA_ROOT);
if (window == winId()) {
cancel();
return;
}
mWindowIndicator->hide();
mTaken = true;
setWindowFlags(windowFlags() ^ Qt::WindowStaysOnTopHint);
close();
emit pixmap(os::grabWindow(window));
-
+#endif
return;
}
mWindowIndicator->setGeometry(0, 0, 0, 0);
close();
}
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::mouseMoveEvent(QMouseEvent *event)
{
+#ifdef Q_OS_WINDOWS
POINT mousePos;
mousePos.x = event->globalX();
mousePos.y = event->globalY();
HWND cWindow = GetAncestor(WindowFromPoint(mousePos), GA_ROOT);
if (cWindow == mWindowIndicator->winId()) {
return;
}
if (mCurrentWindow != cWindow) {
SetForegroundWindow(cWindow);
RECT rc;
GetWindowRect(cWindow, &rc);
mWindowIndicator->setGeometry(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top);
}
mCurrentWindow = cWindow;
if (mCurrentWindow == winId()) {
mWindowIcon->setPixmap(QPixmap());
mWindowLabel->setText("");
return;
}
// Text
WCHAR str[60];
HICON icon;
::GetWindowText(mCurrentWindow, str, 60);
///
// Retrieving the application icon
icon = (HICON)::GetClassLong(mCurrentWindow, GCL_HICON);
if (icon != NULL) {
mWindowIcon->setPixmap(QPixmap::fromWinHICON(icon));
}
else {
mWindowIcon->setPixmap(QPixmap());
}
QString windowText = QString(" - %1").arg(QString::fromWCharArray(str));
if (windowText == " - ") {
mWindowLabel->setText("");
return;
}
if (windowText.length() == 62) {
mWindowLabel->setText(windowText + "...");
}
else {
mWindowLabel->setText(windowText);
}
+#endif
}
void WindowPicker::closeEvent(QCloseEvent*)
{
if (!mTaken)
emit pixmap(QPixmap());
qApp->restoreOverrideCursor();
deleteLater();
}
diff --git a/tools/windowpicker.h b/tools/windowpicker.h
index 203223f..f9c8b70 100644
--- a/tools/windowpicker.h
+++ b/tools/windowpicker.h
@@ -1,58 +1,57 @@
/*
* Copyright (C) 2011 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
*
*/
#ifndef WINDOWPICKER_H
#define WINDOWPICKER_H
#include <QWidget>
class QLabel;
class QRect;
class QRubberBand;
class WindowPicker : public QWidget
{
Q_OBJECT
public:
WindowPicker();
~WindowPicker();
signals:
void pixmap(QPixmap pixmap);
protected:
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void closeEvent(QCloseEvent*);
private:
void cancel();
private:
QPixmap mCrosshair;
QLabel *mWindowLabel;
QLabel *mWindowIcon;
QLabel *mCrosshairLabel;
QRubberBand *mWindowIndicator;
- HWND mCurrentWindow;
+ WId mCurrentWindow;
bool mTaken;
-
};
#endif // WINDOWPICKER_H

File Metadata

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

Event Timeline