util.cpp 7.75 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/*
    Copyright 2011-2012 Heikki Holstila <heikki.holstila@gmail.com>

    This file is part of FingerTerm.

    FingerTerm 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.

    FingerTerm 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 FingerTerm.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "qplatformdefs.h"

#include <QtCore>
#include <QtGui>
#include <QDBusInterface>
John Brooks's avatar
John Brooks committed
25 26
#include <QGuiApplication>
#include <QQuickView>
27
#include <QDebug>
28 29 30 31 32 33 34

#include "mainwindow.h"
#include "terminal.h"
#include "util.h"
#include "textrender.h"
#include "version.h"

Herrie's avatar
Herrie committed
35
#ifdef HAVE_FEEDBACK
36
#include <QFeedbackEffect>
37 38
#endif

39 40 41 42 43 44 45 46 47 48 49
Util::Util(QSettings *settings, QObject *parent) :
    QObject(parent),
    iAllowGestures(false),
    newSelection(true),
    iSettings(settings),
    iWindow(0),
    iRenderer(0)
{
    swipeModeSet = false;
    swipeAllowed = true;

John Brooks's avatar
John Brooks committed
50
    connect(QGuiApplication::clipboard(), SIGNAL(dataChanged()), this, SIGNAL(clipboardOrSelectionChanged()));
51 52 53 54 55 56 57 58
}

Util::~Util()
{
    // clear the notifications on quit
    clearNotifications();
}

John Brooks's avatar
John Brooks committed
59
void Util::setWindow(QQuickView* win)
60 61 62 63 64 65 66 67 68 69
{
    iWindow = dynamic_cast<MainWindow*>(win);
    if(!iWindow)
        qFatal("invalid main window");
    connect(iWindow, SIGNAL(focusChanged(bool)), this, SLOT(onMainWinFocusChanged(bool)));
}

void Util::setWindowTitle(QString title)
{
    iCurrentWinTitle = title;
John Brooks's avatar
John Brooks committed
70
    iWindow->setTitle(title);
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
    emit windowTitleChanged();
}

QString Util::currentWindowTitle()
{
    return iCurrentWinTitle;
}

void Util::onMainWinFocusChanged(bool in)
{
    if (in) {
        clearNotifications();

        //disable & re-enable swiping when window gains focus (workaround for an "auto mode" bug)
        updateSwipeLock(false);
        updateSwipeLock(true);
    }
}

void Util::windowMinimize()
{
    iWindow->minimize();
}

void Util::openNewWindow()
{
97
    QProcess::startDetached("/usr/bin/fingerterm");
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
}

void Util::updateSwipeLock(bool suggestedState)
{
    Q_UNUSED(suggestedState)
}

QString Util::configPath()
{
    if(!iSettings)
        return QString();

    QFileInfo f(iSettings->fileName());
    return f.path();
}

QVariant Util::settingsValue(QString key)
{
    if(!iSettings)
        return QVariant();

    return iSettings->value(key);
}

void Util::setSettingsValue(QString key, QVariant value)
{
    if(iSettings)
        iSettings->setValue(key, value);
}

QString Util::versionString()
{
    return PROGRAM_VERSION;
}

int Util::uiFontSize()
{
    return 12;
}

void Util::keyPressFeedback()
{
    if( !settingsValue("ui/keyPressFeedback").toBool() )
        return;

143
#ifdef HAVE_FEEDBACK
144
    QFeedbackEffect::playThemeEffect(QFeedbackEffect::PressWeak);
145
#endif
146 147 148 149 150 151 152
}

void Util::keyReleaseFeedback()
{
    if( !settingsValue("ui/keyPressFeedback").toBool() )
        return;

153
    // TODO: check what's more comfortable, only press, or press and release
154
#ifdef HAVE_FEEDBACK
155
    QFeedbackEffect::playThemeEffect(QFeedbackEffect::ReleaseWeak);
156
#endif
157 158 159 160 161 162 163
}

void Util::bellAlert()
{
    if(!iWindow)
        return;

164
    if( settingsValue("general/visualBell").toBool() ) {
165 166 167 168 169 170 171 172
        emit visualBell();
    }
}

void Util::clearNotifications()
{
}

173 174 175 176 177 178 179 180 181 182
void Util::mousePress(float eventX, float eventY) {
    if(!iAllowGestures)
        return;

    dragOrigin = QPointF(eventX, eventY);
    newSelection = true;
}

void Util::mouseMove(float eventX, float eventY) {
    QPointF eventPos(eventX, eventY);
183

184 185 186 187
    if(!iAllowGestures)
        return;

    if(settingsValue("ui/dragMode")=="scroll") {
188
        dragOrigin = scrollBackBuffer(eventPos, dragOrigin);
189 190 191 192 193 194 195 196
    }
    else if(settingsValue("ui/dragMode")=="select" && iRenderer) {
        selectionHelper(eventPos);
    }
}

void Util::mouseRelease(float eventX, float eventY) {
    QPointF eventPos(eventX, eventY);
197 198 199
    const int reqDragLength = 140;

    if(!iAllowGestures)
200
        return;
201

202 203 204 205 206 207 208 209 210 211 212
    if(settingsValue("ui/dragMode")=="gestures") {
        int xdist = qAbs(eventPos.x() - dragOrigin.x());
        int ydist = qAbs(eventPos.y() - dragOrigin.y());
        if(eventPos.x() < dragOrigin.x()-reqDragLength && xdist > ydist*2)
            doGesture(PanLeft);
        else if(eventPos.x() > dragOrigin.x()+reqDragLength && xdist > ydist*2)
            doGesture(PanRight);
        else if(eventPos.y() > dragOrigin.y()+reqDragLength && ydist > xdist*2)
            doGesture(PanDown);
        else if(eventPos.y() < dragOrigin.y()-reqDragLength && ydist > xdist*2)
            doGesture(PanUp);
213
    }
214 215
    else if(settingsValue("ui/dragMode")=="scroll") {
        scrollBackBuffer(eventPos, dragOrigin);
216
    }
217 218 219
    else if(settingsValue("ui/dragMode")=="select" && iRenderer) {
        selectionHelper(eventPos);
        selectionFinished();
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
    }
}

void Util::selectionHelper(QPointF scenePos)
{
    int yCorr =  iRenderer->fontDescent();

    QPoint start(qRound((dragOrigin.x()+2)/iRenderer->fontWidth()),
                 qRound((dragOrigin.y()+yCorr)/iRenderer->fontHeight()));
    QPoint end(qRound((scenePos.x()+2)/iRenderer->fontWidth()),
               qRound((scenePos.y()+yCorr)/iRenderer->fontHeight()));

    if (start != end) {
        iTerm->setSelection(start, end);
        newSelection = false;
    }
}

238
QPointF Util::scrollBackBuffer(QPointF now, QPointF last)
239 240
{
    if(!iTerm)
241
        return last;
242 243 244

    int xdist = qAbs(now.x() - last.x());
    int ydist = qAbs(now.y() - last.y());
245 246 247 248 249 250 251 252 253 254 255
    int fontSize = settingsValue("ui/fontSize").toInt();

    int lines = ydist / fontSize;

    if(lines > 0 && now.y() < last.y() && xdist < ydist*2) {
        iTerm->scrollBackBufferFwd(lines);
        last = QPointF(now.x(), last.y() - lines * fontSize);
    } else if(lines > 0 && now.y() > last.y() && xdist < ydist*2) {
        iTerm->scrollBackBufferBack(lines);
        last = QPointF(now.x(), last.y() + lines * fontSize);
    }
256

257
    return last;
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
}

void Util::doGesture(Util::PanGesture gesture)
{
    if(!iTerm)
        return;

    if( gesture==PanLeft ) {
        emit gestureNotify(settingsValue("gestures/panLeftTitle").toString());
        iTerm->putString(settingsValue("gestures/panLeftCommand").toString(), true);
    }
    else if( gesture==PanRight ) {
        emit gestureNotify(settingsValue("gestures/panRightTitle").toString());
        iTerm->putString(settingsValue("gestures/panRightCommand").toString(), true);
    }
    else if( gesture==PanDown ) {
        emit gestureNotify(settingsValue("gestures/panDownTitle").toString());
        iTerm->putString(settingsValue("gestures/panDownCommand").toString(), true);
    }
    else if( gesture==PanUp ) {
        emit gestureNotify(settingsValue("gestures/panUpTitle").toString());
        iTerm->putString(settingsValue("gestures/panUpCommand").toString(), true);
    }
}

void Util::notifyText(QString text)
{
    emit gestureNotify(text);
}

void Util::copyTextToClipboard(QString str)
{
John Brooks's avatar
John Brooks committed
290
    QClipboard *cb = QGuiApplication::clipboard();
291 292 293

    cb->clear();
    cb->setText(str);
294 295 296 297 298 299 300 301 302
}

bool Util::terminalHasSelection()
{
    return !iTerm->selection().isNull();
}

bool Util::canPaste()
{
303

John Brooks's avatar
John Brooks committed
304
    QClipboard *cb = QGuiApplication::clipboard();
305

coderus's avatar
coderus committed
306
    return !cb->text().isEmpty();
307 308 309 310 311 312 313
}

void Util::selectionFinished()
{
    emit clipboardOrSelectionChanged();
}

314 315 316 317 318
//static
bool Util::charIsHexDigit(QChar ch)
{
    if (ch.isDigit()) // 0-9
        return true;
Aard's avatar
Aard committed
319
    else if (ch.toLatin1() >= 65 && ch.toLatin1() <= 70) // A-F
320
        return true;
Aard's avatar
Aard committed
321
    else if (ch.toLatin1() >= 97 && ch.toLatin1() <= 102) // a-f
322 323 324 325
        return true;

    return false;
}