You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
screengrab-packaging/src/core/ui/mainwindow.cpp

570 lines
16 KiB

/***************************************************************************
* Copyright (C) 2009 - 2013 by Artem 'DOOMer' Galichkin *
* doomer3d@gmail.com *
* *
* 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 program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "../core.h"
#include "../shortcutmanager.h"
#include <QDir>
#include <QFileDialog>
#include <QDesktopWidget>
#include <QHash>
#include <QHashIterator>
#include <QRegExp>
#include <QTimer>
#include <QToolButton>
#include <QMenu>
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent),
_ui(new Ui::MainWindow), _conf(NULL), _trayMenu(NULL)
{
_ui->setupUi(this);
_trayed = false;
#ifdef SG_GLOBAL_SHORTCUTS
// signal mapper
_globalShortcutSignals = new QSignalMapper(this);
// global shortcuts
_fullScreen = new QxtGlobalShortcut(this);
_activeWindow = new QxtGlobalShortcut(this);
_areaSelection = new QxtGlobalShortcut(this);
_globalShortcuts << _fullScreen << _activeWindow << _areaSelection;
for (int i = 0; i < _globalShortcuts.count(); ++i )
{
connect(_globalShortcuts[i], SIGNAL(activated()), _globalShortcutSignals, SLOT(map()) );
_globalShortcutSignals->setMapping(_globalShortcuts[i], i);
}
connect(_globalShortcutSignals, SIGNAL(mapped(int)), this, SLOT(globalShortcutActivate(int)));
#endif
_trayIcon = NULL;
_hideWnd = NULL;
// create actions menu
actNew = new QAction(QIcon::fromTheme("document-new"), tr("New"), this);
actSave = new QAction(QIcon::fromTheme("document-save"), tr("Save"), this);
actCopy = new QAction(QIcon::fromTheme("edit-copy"), tr("Copy"), this);
actOptions = new QAction(QIcon::fromTheme("configure"), tr("Options"), this);
actHelp = new QAction(QIcon::fromTheme("system-help"), tr("Help"), this);
actAbout = new QAction(QIcon::fromTheme("system-about"), tr("About"), this);
actQuit = new QAction(QIcon::fromTheme("application-exit"), tr("Quit"), this);
// connect actions to slots
Core *c = Core::instance();
connect(actQuit, &QAction::triggered, c, &Core::coreQuit);
connect(actNew, &QAction::triggered, c, &Core::setScreen);
connect(actSave, &QAction::triggered, this, &MainWindow::saveScreen);
connect(actCopy, &QAction::triggered, c, &Core::copyScreen);
connect(actOptions, &QAction::triggered, this, &MainWindow::showOptions);
connect(actAbout, &QAction::triggered, this, &MainWindow::showAbout);
connect(actHelp, &QAction::triggered, this, &MainWindow::showHelp);
_ui->toolBar->addAction(actNew);
_ui->toolBar->addAction(actSave);
_ui->toolBar->addAction(actCopy);
_ui->toolBar->addAction(actOptions);
_ui->toolBar->addSeparator();
QMenu *menuInfo = new QMenu(this);
menuInfo->addAction(actHelp);
menuInfo->addAction(actAbout);
QToolButton *help = new QToolButton(this);
help->setText(tr("Help"));
help->setPopupMode(QToolButton::InstantPopup);
help->setIcon(QIcon::fromTheme("system-help"));
help->setMenu(menuInfo);
_ui->toolBar->addWidget(help);
QWidget* spacer = new QWidget();
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
_ui->toolBar->addWidget(spacer);
_ui->toolBar->addAction(actQuit);
void (QSpinBox::*delayChange)(int) = &QSpinBox::valueChanged;
connect(_ui->delayBox, delayChange, this, &MainWindow::delayBoxChange);
void (QComboBox::*typeScr)(int) = &QComboBox::currentIndexChanged;
connect(_ui->cbxTypeScr, typeScr, this, &MainWindow::typeScreenShotChange);
connect(_ui->checkIncludeCursor, &QCheckBox::toggled, this, &MainWindow::checkIncludeCursor);
QIcon icon(":/res/img/logo.png");
setWindowIcon(icon);
QRect geometry = QApplication::desktop()->availableGeometry(QApplication::desktop()->screenNumber());
move(geometry.width() / 2 - width() / 2, geometry.height() / 2 - height() / 2);
_ui->scrLabel->installEventFilter(this);
}
MainWindow::~MainWindow()
{
delete _ui;
}
void MainWindow::changeEvent(QEvent *e)
{
QMainWindow::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
_ui->retranslateUi(this);
break;
default:
break;
}
}
void MainWindow::closeEvent(QCloseEvent *e)
{
if (_conf->getCloseInTray() && _conf->getShowTrayIcon())
{
windowHideShow();
e->ignore();
}
else
actQuit->activate(QAction::Trigger);
}
// resize main window
void MainWindow::resizeEvent(QResizeEvent *event)
{
Q_UNUSED(event)
// get size dcreen pixel map
QSize scaleSize = Core::instance()->getPixmap()->size(); // get orig size pixmap
scaleSize.scale(_ui->scrLabel->size(), Qt::KeepAspectRatio);
// if not scrlabel pixmap
if (!_ui->scrLabel->pixmap() || scaleSize != _ui->scrLabel->pixmap()->size())
updatePixmap(Core::instance()->getPixmap());
}
bool MainWindow::eventFilter(QObject* obj, QEvent* event)
{
if (obj == _ui->scrLabel && event->type() == QEvent::ToolTip)
displatScreenToolTip();
else if (obj == _ui->scrLabel && event->type() == QEvent::MouseButtonDblClick)
Core::instance()->openInExtViewer();
return QObject::eventFilter(obj, event);
}
void MainWindow::updatePixmap(QPixmap *pMap)
{
_ui->scrLabel->setPixmap(pMap->scaled(_ui->scrLabel->size(),
Qt::KeepAspectRatio, Qt::SmoothTransformation));
}
void MainWindow::updateModulesActions(QList<QAction *> list)
{
_ui->toolBar->insertSeparator(actOptions);
if (list.count() > 0)
{
for (int i = 0; i < list.count(); ++i)
{
QAction *action = list.at(i);
if (action)
_ui->toolBar->insertAction(actOptions, action);
}
}
}
void MainWindow::updateModulesenus(QList<QMenu *> list)
{
if (list.count() > 0)
{
for (int i = 0; i < list.count(); ++i)
{
QMenu *menu = list.at(i);
if (menu != 0)
{
QToolButton* btn = new QToolButton(this);
btn->setText(menu->title());
btn->setPopupMode(QToolButton::InstantPopup);
btn->setToolTip(menu->title());
btn->setMenu(list.at(i));
_ui->toolBar->insertWidget(actOptions, btn);
}
}
_ui->toolBar->insertSeparator(actOptions);
}
}
void MainWindow::show()
{
if (!isVisible() && !_trayed)
showNormal();
if (_conf->getShowTrayIcon())
{
_trayIcon->blockSignals(false);
_trayIcon->setContextMenu(_trayMenu); // enable context menu
}
if (_trayIcon)
_trayIcon->setVisible(true);
QMainWindow::show();
}
bool MainWindow::isTrayed() const
{
return _trayIcon != NULL;
}
void MainWindow::showTrayMessage(const QString& header, const QString& message)
{
if (_conf->getShowTrayIcon())
{
switch(_conf->getTrayMessages())
{
case 0: break; // never shown
case 1: // main window hidden
{
if (isHidden() && _trayed)
{
_trayIcon->showMessage(header, message,
QSystemTrayIcon::MessageIcon(), _conf->getTimeTrayMess()*1000 ); //5000
}
break;
}
case 2: // always show
{
_trayIcon->showMessage(header, message,
QSystemTrayIcon::MessageIcon(), _conf->getTimeTrayMess()*1000 );
break;
}
default: break;
}
}
}
void MainWindow::setConfig(Config *config)
{
_conf = config;
updateUI();
}
void MainWindow::showHelp()
{
QString localeHelpFile;
localeHelpFile = QString(SG_DOCDIR) + "%1html%1" + Config::getSysLang()+"%1index.html";
localeHelpFile = localeHelpFile.arg(QString(QDir::separator()));
if (!QFile::exists(localeHelpFile))
{
localeHelpFile = QString(SG_DOCDIR) + "%1html%1" + Config::getSysLang().section("_", 0, 0) + "%1index.html";
localeHelpFile = localeHelpFile.arg(QString(QDir::separator()));
if (!QFile::exists(localeHelpFile))
{
localeHelpFile = QString(SG_DOCDIR) + "%1html%1en%1index.html";
localeHelpFile = localeHelpFile.arg(QString(QDir::separator()));
}
}
// open find localize or eng help help
QDesktopServices::openUrl(QUrl::fromLocalFile(localeHelpFile));
}
void MainWindow::showOptions()
{
ConfigDialog *options = new ConfigDialog();
#ifdef SG_GLOBAL_SHORTCUTS
globalShortcutBlock(true);
#endif
if (isMinimized())
{
showNormal();
if (options->exec() == QDialog::Accepted)
updateUI();
hideToShot();
}
else
{
if (options->exec() == QDialog::Accepted)
updateUI();
}
#ifdef SG_GLOBAL_SHORTCUTS
globalShortcutBlock(false);
#endif
delete options;
}
void MainWindow::showAbout()
{
AboutDialog *about = new AboutDialog(this);
if (isMinimized())
{
showNormal();
about->exec();
hideToShot();
}
else
about->exec();
delete about;
}
void MainWindow::displatScreenToolTip()
{
QSize pSize = Core::instance()->getPixmap()->size();
quint16 w = pSize.width();
quint16 h = pSize.height();
QString toolTip = tr("Screenshot ") + QString::number(w) + "x" + QString::number(h);
if (_conf->getEnableExtView())
{
toolTip += "\n\n";
toolTip += tr("Double click for open screenshot in external default image viewer");
}
_ui->scrLabel->setToolTip(toolTip);
}
void MainWindow::createTray()
{
_trayed = false;
actHideShow = new QAction(tr("Hide"), this);
connect(actHideShow, &QAction::triggered, this, &MainWindow::windowHideShow);
// create tray menu
_trayMenu = new QMenu(this);
_trayMenu->addAction(actHideShow);
_trayMenu->addSeparator();
_trayMenu->addAction(actNew); // TODO - add icons (icon, action)
_trayMenu->addAction(actSave);
_trayMenu->addAction(actCopy);
_trayMenu->addSeparator();
_trayMenu->addAction(actOptions);
_trayMenu->addSeparator();
_trayMenu->addAction(actHelp);
_trayMenu->addAction(actAbout);
_trayMenu->addSeparator();
_trayMenu->addAction(actQuit);
// icon menu
QIcon icon(":/res/img/logo.png");
_trayIcon = new QSystemTrayIcon(this);
_trayIcon->setContextMenu(_trayMenu);
_trayIcon->setIcon(icon);
_trayIcon->show();
connect(_trayIcon, &QSystemTrayIcon::activated, this, &MainWindow::trayClick);
}
void MainWindow::killTray()
{
_trayed = false;
_trayMenu->clear();
delete _trayIcon;
_trayIcon = NULL;
}
void MainWindow::delayBoxChange(int delay)
{
if (delay == 0)
_ui->delayBox->setSpecialValueText(tr("None"));
_conf->setDelay(delay);
}
void MainWindow::typeScreenShotChange(int type)
{
_conf->setScreenshotType(type);
}
void MainWindow::checkIncludeCursor(bool include)
{
_conf->setIncludeCursor(include);
}
// updating UI from configdata
void MainWindow::updateUI()
{
_ui->delayBox->setValue(_conf->getDelay());
_ui->cbxTypeScr->setCurrentIndex(_conf->getDefScreenshotType());
_ui->checkIncludeCursor->setChecked(_conf->getIncludeCursor());
updateShortcuts();
// create tray object
if (_conf->getShowTrayIcon() && !_trayIcon)
createTray();
// kill tray object, if tray was disabled in the configuration dialog
if (!_conf->getShowTrayIcon() && _trayIcon)
killTray();
}
// mouse clicks on tray icom
void MainWindow::trayClick(QSystemTrayIcon::ActivationReason reason)
{
switch(reason)
{
case QSystemTrayIcon::Trigger:
windowHideShow();
break;
default: ;
}
}
void MainWindow::windowHideShow()
{
if (isHidden())
{
actHideShow->setText(tr("Hide"));
_trayed = false;
showNormal();
activateWindow();
}
else
{
actHideShow->setText(tr("Show"));
showMinimized();
hide();
_trayed = true;
}
}
void MainWindow::hideToShot()
{
if (_conf->getShowTrayIcon())
{
_trayIcon->blockSignals(true);
_trayIcon->setContextMenu(NULL); // enable context menu
}
hide();
}
void MainWindow::showWindow(const QString& str)
{
// get char of type screen (last) form received string
QString typeNum = str[str.size() - 1];
int type = typeNum.toInt();
// change type scrren in config & on main window
_ui->cbxTypeScr->setCurrentIndex(type);
typeScreenShotChange(type);
}
void MainWindow::restoreFromShot()
{
if (!isVisible() && !_trayed)
showNormal();
// if show tray
if (_conf->getShowTrayIcon())
{
_trayIcon->blockSignals(false);
_trayIcon->setContextMenu(_trayMenu); // enable context menu
}
}
void MainWindow::saveScreen()
{
// create initial filepath
QHash<QString, QString> formatsAvalible;
formatsAvalible["png"] = tr("PNG Files");
formatsAvalible["jpg"] = tr("JPEG Files");
QString format = "png";
_conf->getSaveFormat();
Core* c = Core::instance();
QString filePath = c->getSaveFilePath(format);
// create file filters
QString fileFilters;
QString filterSelected;
filterSelected = formatsAvalible[format];
QHash<QString, QString>::const_iterator iter = formatsAvalible.constBegin();
while (iter != formatsAvalible.constEnd())
{
fileFilters.append(iter.value() + " (*." + iter.key() + ");;");
++iter;
}
fileFilters.chop(2);
QString fileName;
fileName = QFileDialog::getSaveFileName(this, tr("Save As..."), filePath, fileFilters, &filterSelected, QFileDialog::DontUseNativeDialog);
QRegExp rx("\\(\\*\\.[a-z]{3,4}\\)");
quint8 tmp = filterSelected.size() - rx.indexIn(filterSelected);
filterSelected.chop(tmp + 1);
format = formatsAvalible.key(filterSelected);
// if user canceled saving
if (fileName.isEmpty())
return;
c->writeScreen(fileName, format);
}
void MainWindow::updateShortcuts()
{
actNew->setShortcut(_conf->shortcuts()->getShortcut(Config::shortcutNew));
actSave->setShortcut(_conf->shortcuts()->getShortcut(Config::shortcutSave));
actCopy->setShortcut(_conf->shortcuts()->getShortcut(Config::shortcutCopy));
actOptions->setShortcut(_conf->shortcuts()->getShortcut(Config::shortcutOptions));
actHelp->setShortcut(_conf->shortcuts()->getShortcut(Config::shortcutHelp));
actQuit->setShortcut(_conf->shortcuts()->getShortcut(Config::shortcutClose));
#ifdef SG_GLOBAL_SHORTCUTS
for (int i = 0; i < _globalShortcuts.count(); ++i)
_globalShortcuts[i]->setShortcut(QKeySequence(_core->conf->shortcuts()->getShortcut(i)));
#endif
}
#ifdef SG_GLOBAL_SHORTCUTS
void MainWindow::globalShortcutBlock(bool state)
{
for (int i = 0; i < _globalShortcuts.count(); ++i)
_globalShortcuts[i]->setDisabled(state);
}
void MainWindow::globalShortcutActivate(int type)
{
_ui->cbxTypeScr->setCurrentIndex(type);
typeScreenShotChange(type);
if (!_trayed)
hide();
QTimer::singleShot(200, _core, SLOT(screenShot()));
}
#endif