<commit_before>#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QObject>
#include <QtWidgets>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    _ui(new Ui::MainWindow),
    _mainWindowIcon(":/Resources/icons/mainWindowIcon.jpg"),
    _isPlaying(false),
    _prevButtonIcon(":/Resources/icons/Button-Prev-icon.png"),
    _playButtonPlayIcon(":/Resources/icons/Button-Play-icon.png"),
    _playButtonPauseIcon(":/Resources/icons/Button-Pause-icon.png"),
    _nextButtonIcon(":/Resources/icons/Button-Next-icon.png"),
    _filename(new QLabel(this)),
    _player(0),
    _playlist(new QMediaPlaylist(this))
{
    _ui->setupUi(this);
    setWindowIcon(_mainWindowIcon);
    setWindowTitle("Music Player");

    setFixedWidth(8*72);
    setFixedHeight(5*72);

    /****************SETTING UP MENUS*********************/
    QWidget *topFiller = new QWidget;
    topFiller->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

#ifdef Q_OS_SYMBIAN
    _infoLabel = new QLabel(tr("Choose a menu option"));
#else
    _infoLabel = new QLabel(tr("Choose a menu option, or right-click to "
                              "invoke a context menu"));
#endif
    _infoLabel->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
    _infoLabel->setAlignment(Qt::AlignCenter);

    QWidget *bottomFiller = new QWidget;
    bottomFiller->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    QVBoxLayout *layout = new QVBoxLayout;
    layout->setMargin(5);
    layout->addWidget(topFiller);
    layout->addWidget(_infoLabel);
    layout->addWidget(bottomFiller);

    createActions();
    createMenus();

    /************SETTING UP STATUS BAR********************/
#ifndef Q_OS_SYMBIAN
    QString message = tr("A context menu is available by right-clicking");
    statusBar()->showMessage(message);
#endif

    setupButtons();

    /*************SETTING UP VOLUME SLIDER******************/

    _volumeLabel = new QLabel;
    _volumeLabel->setText(tr("Volume:"));
    _volumeLabel->setParent(this);
    _volumeSlider = new QSlider(Qt::Horizontal);
    _volumeSlider->setParent(this);
    _volumeSlider->setMinimum(0);
    _volumeSlider->setMaximum(100);
    _volumeSlider->setSliderPosition(_volumeSlider->maximum());
    _volumeSlider->setSingleStep(10);
    _volumeSlider->setGeometry
            (
                _nextButton.geometry().x(),
                _playButton.geometry().y()-20,
                _playButton.width(),
                20
            );

    connect(_volumeSlider,SIGNAL(valueChanged(int)),this,SLOT(_volumeSliderValueChanged()));

    /*************SETTING UP VOLUME LABEL******************/
    _volumeLabel->setGeometry
            (
                _volumeSlider->geometry().x()-60,
                _volumeSlider->geometry().y(),
                60,
                _volumeSlider->height()
            );
    _volumeLabel->show();
    _volumeSlider->show();

    /************SETTING UP FILENAME LABEL*********/
    _filename->setGeometry
            (
                _volumeLabel->geometry().x()-120,
                _volumeLabel->geometry().y(),
                _volumeLabel->geometry().width(),
                _volumeLabel->geometry().height()
            );
    _filename->show();

    /******************SOUND CODE******************/
    _player = new QMediaPlayer;
    _player->setVolume(100);
}

MainWindow::~MainWindow()
{
    delete _ui;
}

/***********PLAY BUTTON FUNCTION SLOT***********/
void MainWindow::_playButtonIsPressed ()
{
    _player->pause();

    if(!_isPlaying)
    {
        _playButton.setIcon(_playButtonPauseIcon);
        _player->play();
    }
    else _playButton.setIcon(_playButtonPlayIcon);

    _isPlaying = !_isPlaying;
}

/***********NEXT BUTTON FUNCTION SLOT***********/
void MainWindow::_nextButtonIsPressed ()
{
    _playlist->next();
    _filename->setText
            (
                _playlist->media(_playlist->currentIndex()).canonicalUrl().fileName()
            );
}

/***********PREV BUTTON FUNCTION SLOT***********/
void MainWindow::_prevButtonIsPressed ()
{
    _playlist->previous();
}

/***********VOLUME SLIDER FUNCTION SLOT***********/
void MainWindow::_volumeSliderValueChanged()
{
        _player->setVolume(_volumeSlider->value());
}

/**************MENU OPTION SLOTS****************/
void MainWindow::contextMenuEvent(QContextMenuEvent *event)
{
    QMenu menu(this);
    menu.addAction(_playAct);
    menu.addAction(_nextSongAct);
    menu.addAction(_previousSongAct);
    menu.exec(event->globalPos());
}

void MainWindow::play()
{
    _playButtonIsPressed();
}

void MainWindow::nextSong()
{
    _nextButtonIsPressed();
}

void MainWindow::previousSong()
{
    _prevButtonIsPressed();
}

void MainWindow::open()
{
    QFileDialog openFileDialog(this);
    openFileDialog.setNameFilter(tr("Audio (*.mp3 *.mp4 *.wav *.flac *.ogg)"));
    openFileDialog.setViewMode(QFileDialog::List);
    openFileDialog.setFileMode(QFileDialog::ExistingFiles);
    openFileDialog.setDirectory("../cs372-FinalProject/");

    QStringList fileNames;
    if(openFileDialog.exec())
       fileNames = openFileDialog.selectedFiles();

    QList<QMediaContent> playListFiles;

    for(QStringList::iterator file = fileNames.begin(); file < fileNames.end(); file++)
       playListFiles.append(QMediaContent(QUrl::fromLocalFile(*file)));

    _playlist->clear();
    _playlist->addMedia(playListFiles);
    _playlist->setPlaybackMode(QMediaPlaylist::Loop);
    _player->stop();
    _player->setPlaylist(_playlist);
    _player->setPosition(0);

    if(_isPlaying) _playButtonIsPressed();
}

void MainWindow::about()
{
    _infoLabel->setText(tr("Invoked Help|About"));
    QMessageBox::about(this, tr("About Menu"),
            tr("Hit Play to Play Mooxzikz. "
               "Open to Open More Moozikz."));
//TODO: docoomentimgz
}

void MainWindow::aboutQt()
{
    _infoLabel->setText(tr("Invoked Help|About Qt"));
}

void MainWindow::createActions()
{
    _openAct = new QAction(tr("&Open..."), this);
    _openAct->setStatusTip(tr("Open an existing file"));
    connect(_openAct, SIGNAL(triggered()), this, SLOT(open()));

    _exitAct = new QAction(tr("E&xit"), this);
    _exitAct->setStatusTip(tr("Exit the application"));
    connect(_exitAct, SIGNAL(triggered()), this, SLOT(close()));

    _playAct = new QAction(tr("&Play/Pause"), this);
    _playAct->setStatusTip(tr("Play a song"));
    connect(_playAct, SIGNAL(triggered()), this, SLOT(play()));

    _nextSongAct = new QAction(tr("&Next Song"), this);
    _nextSongAct->setStatusTip(tr("Switches to the Next Song"));
    connect(_nextSongAct, SIGNAL(triggered()), this, SLOT(nextSong()));

    _previousSongAct = new QAction(tr("&Previous Song"), this);
    _previousSongAct->setStatusTip(tr("Switches to the Previous Song"));
    connect(_previousSongAct, SIGNAL(triggered()), this, SLOT(previousSong()));

    _aboutAct = new QAction(tr("&About"), this);
    _aboutAct->setStatusTip(tr("Show the application's About box"));
    connect(_aboutAct, SIGNAL(triggered()), this, SLOT(about()));

    _aboutQtAct = new QAction(tr("About &Qt"), this);
    _aboutQtAct->setStatusTip(tr("Show the Qt library's About box"));
    connect(_aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
    connect(_aboutQtAct, SIGNAL(triggered()), this, SLOT(aboutQt()));
}

void MainWindow::createMenus()
{
    _fileMenu = menuBar()->addMenu(tr("&File"));
    _fileMenu->addAction(_openAct);
    _fileMenu->addSeparator();
    _fileMenu->addAction(_exitAct);

    _playMenu = menuBar()->addMenu(tr("&Play"));
    _playMenu->addSeparator();
    _playMenu->addAction(_playAct);
    _playMenu->addAction(_nextSongAct);
    _playMenu->addAction(_previousSongAct);

    _helpMenu = menuBar()->addMenu(tr("&Help"));
    _helpMenu->addAction(_aboutAct);
    _helpMenu->addAction(_aboutQtAct);
}

void MainWindow::setupButtons()
{
    const int mediaButtonYCoordinate =
            (
                height()- ((width()/5) + statusBar()->geometry().height() - 8)
            );

    //Setup signals
    connect(&_prevButton, SIGNAL(clicked()), this, SLOT(_prevButtonIsPressed()));
    connect(&_playButton, SIGNAL(clicked()), this, SLOT(_playButtonIsPressed()));
    connect(&_nextButton, SIGNAL(clicked()), this, SLOT(_nextButtonIsPressed()));

    //Setup parents
    _prevButton.setParent(this);
    _playButton.setParent(this);
    _nextButton.setParent(this);

    //Setup positions
    _prevButton.setGeometry
            (
                0,
                mediaButtonYCoordinate,
                width()/5,
                width()/5
            );
    _playButton.setGeometry
            (
                _prevButton.width()*2,
                mediaButtonYCoordinate,
                width()/5,
                width()/5
            );
    _nextButton.setGeometry
            (
                _playButton.width()*4,
                mediaButtonYCoordinate,
                width()/5,
                width()/5
            );

    //Setup icons
    _prevButton.setIcon(_prevButtonIcon);
    _prevButton.setIconSize(QSize(_prevButton.height(),_prevButton.height()));

    _playButton.setIcon(_playButtonPlayIcon);
    _playButton.setIconSize(QSize(_playButton.height(),_playButton.height()));

    _nextButton.setIcon(_nextButtonIcon);
    _nextButton.setIconSize(QSize(_nextButton.height(),_nextButton.height()));

    //Show them off
    _prevButton.show();
    _playButton.show();
    _nextButton.show();
}
<commit_msg>Fixed issue with _filename display placement.<commit_after>#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QObject>
#include <QtWidgets>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    _ui(new Ui::MainWindow),
    _mainWindowIcon(":/Resources/icons/mainWindowIcon.jpg"),
    _isPlaying(false),
    _prevButtonIcon(":/Resources/icons/Button-Prev-icon.png"),
    _playButtonPlayIcon(":/Resources/icons/Button-Play-icon.png"),
    _playButtonPauseIcon(":/Resources/icons/Button-Pause-icon.png"),
    _nextButtonIcon(":/Resources/icons/Button-Next-icon.png"),
    _filename(new QLabel(this)),
    _player(0),
    _playlist(new QMediaPlaylist(this))
{
    _ui->setupUi(this);
    setWindowIcon(_mainWindowIcon);
    setWindowTitle("Music Player");

    setFixedWidth(8*72);
    setFixedHeight(5*72);

    /****************SETTING UP MENUS*********************/
    QWidget *topFiller = new QWidget;
    topFiller->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

#ifdef Q_OS_SYMBIAN
    _infoLabel = new QLabel(tr("Choose a menu option"));
#else
    _infoLabel = new QLabel(tr("Choose a menu option, or right-click to "
                              "invoke a context menu"));
#endif
    _infoLabel->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
    _infoLabel->setAlignment(Qt::AlignCenter);

    QWidget *bottomFiller = new QWidget;
    bottomFiller->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    QVBoxLayout *layout = new QVBoxLayout;
    layout->setMargin(5);
    layout->addWidget(topFiller);
    layout->addWidget(_infoLabel);
    layout->addWidget(bottomFiller);

    createActions();
    createMenus();

    /************SETTING UP STATUS BAR********************/
#ifndef Q_OS_SYMBIAN
    QString message = tr("A context menu is available by right-clicking");
    statusBar()->showMessage(message);
#endif

    setupButtons();

    /*************SETTING UP VOLUME SLIDER******************/

    _volumeLabel = new QLabel;
    _volumeLabel->setText(tr("Volume:"));
    _volumeLabel->setParent(this);
    _volumeSlider = new QSlider(Qt::Horizontal);
    _volumeSlider->setParent(this);
    _volumeSlider->setMinimum(0);
    _volumeSlider->setMaximum(100);
    _volumeSlider->setSliderPosition(_volumeSlider->maximum());
    _volumeSlider->setSingleStep(10);
    _volumeSlider->setGeometry
            (
                _nextButton.geometry().x(),
                _playButton.geometry().y()-20,
                _playButton.width(),
                20
            );

    connect(_volumeSlider,SIGNAL(valueChanged(int)),this,SLOT(_volumeSliderValueChanged()));

    /*************SETTING UP VOLUME LABEL******************/
    _volumeLabel->setGeometry
            (
                _volumeSlider->geometry().x()-60,
                _volumeSlider->geometry().y(),
                60,
                _volumeSlider->height()
            );
    _volumeLabel->show();
    _volumeSlider->show();

    /************SETTING UP FILENAME LABEL*********/
    _filename->setGeometry
            (
                0,
                _volumeLabel->geometry().y(),
                _volumeLabel->geometry().x(),
                _volumeLabel->geometry().height()
            );
    _filename->show();

    /******************SOUND CODE******************/
    _player = new QMediaPlayer;
    _player->setVolume(100);
}

MainWindow::~MainWindow()
{
    delete _ui;
}

/***********PLAY BUTTON FUNCTION SLOT***********/
void MainWindow::_playButtonIsPressed ()
{
    _player->pause();

    if(!_isPlaying)
    {
        _playButton.setIcon(_playButtonPauseIcon);
        _player->play();
        _filename->setText
                (
                    _playlist->media(_playlist->currentIndex()).canonicalUrl().fileName()
                );
    }
    else _playButton.setIcon(_playButtonPlayIcon);

    _isPlaying = !_isPlaying;
}

/***********NEXT BUTTON FUNCTION SLOT***********/
void MainWindow::_nextButtonIsPressed ()
{
    _playlist->next();
    _filename->setText
            (
                _playlist->media(_playlist->currentIndex()).canonicalUrl().fileName()
            );
}

/***********PREV BUTTON FUNCTION SLOT***********/
void MainWindow::_prevButtonIsPressed ()
{
    _playlist->previous();
    _filename->setText
            (
                _playlist->media(_playlist->currentIndex()).canonicalUrl().fileName()
            );
}

/***********VOLUME SLIDER FUNCTION SLOT***********/
void MainWindow::_volumeSliderValueChanged()
{
        _player->setVolume(_volumeSlider->value());
}

/**************MENU OPTION SLOTS****************/
void MainWindow::contextMenuEvent(QContextMenuEvent *event)
{
    QMenu menu(this);
    menu.addAction(_playAct);
    menu.addAction(_nextSongAct);
    menu.addAction(_previousSongAct);
    menu.exec(event->globalPos());
}

void MainWindow::play()
{
    _playButtonIsPressed();
}

void MainWindow::nextSong()
{
    _nextButtonIsPressed();
}

void MainWindow::previousSong()
{
    _prevButtonIsPressed();
}

void MainWindow::open()
{
    QFileDialog openFileDialog(this);
    openFileDialog.setNameFilter(tr("Audio (*.mp3 *.mp4 *.wav *.flac *.ogg)"));
    openFileDialog.setViewMode(QFileDialog::List);
    openFileDialog.setFileMode(QFileDialog::ExistingFiles);
    openFileDialog.setDirectory("../cs372-FinalProject/");

    QStringList fileNames;
    if(openFileDialog.exec())
       fileNames = openFileDialog.selectedFiles();

    QList<QMediaContent> playListFiles;

    for(QStringList::iterator file = fileNames.begin(); file < fileNames.end(); file++)
       playListFiles.append(QMediaContent(QUrl::fromLocalFile(*file)));

    _playlist->clear();
    _playlist->addMedia(playListFiles);
    _playlist->setPlaybackMode(QMediaPlaylist::Loop);
    _player->stop();
    _player->setPlaylist(_playlist);
    _player->setPosition(0);

    if(_isPlaying) _playButtonIsPressed();
}

void MainWindow::about()
{
    _infoLabel->setText(tr("Invoked Help|About"));
    QMessageBox::about(this, tr("About Menu"),
            tr("Hit Play to Play Mooxzikz. "
               "Open to Open More Moozikz."));
//TODO: docoomentimgz
}

void MainWindow::aboutQt()
{
    _infoLabel->setText(tr("Invoked Help|About Qt"));
}

void MainWindow::createActions()
{
    _openAct = new QAction(tr("&Open..."), this);
    _openAct->setStatusTip(tr("Open an existing file"));
    connect(_openAct, SIGNAL(triggered()), this, SLOT(open()));

    _exitAct = new QAction(tr("E&xit"), this);
    _exitAct->setStatusTip(tr("Exit the application"));
    connect(_exitAct, SIGNAL(triggered()), this, SLOT(close()));

    _playAct = new QAction(tr("&Play/Pause"), this);
    _playAct->setStatusTip(tr("Play a song"));
    connect(_playAct, SIGNAL(triggered()), this, SLOT(play()));

    _nextSongAct = new QAction(tr("&Next Song"), this);
    _nextSongAct->setStatusTip(tr("Switches to the Next Song"));
    connect(_nextSongAct, SIGNAL(triggered()), this, SLOT(nextSong()));

    _previousSongAct = new QAction(tr("&Previous Song"), this);
    _previousSongAct->setStatusTip(tr("Switches to the Previous Song"));
    connect(_previousSongAct, SIGNAL(triggered()), this, SLOT(previousSong()));

    _aboutAct = new QAction(tr("&About"), this);
    _aboutAct->setStatusTip(tr("Show the application's About box"));
    connect(_aboutAct, SIGNAL(triggered()), this, SLOT(about()));

    _aboutQtAct = new QAction(tr("About &Qt"), this);
    _aboutQtAct->setStatusTip(tr("Show the Qt library's About box"));
    connect(_aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
    connect(_aboutQtAct, SIGNAL(triggered()), this, SLOT(aboutQt()));
}

void MainWindow::createMenus()
{
    _fileMenu = menuBar()->addMenu(tr("&File"));
    _fileMenu->addAction(_openAct);
    _fileMenu->addSeparator();
    _fileMenu->addAction(_exitAct);

    _playMenu = menuBar()->addMenu(tr("&Play"));
    _playMenu->addSeparator();
    _playMenu->addAction(_playAct);
    _playMenu->addAction(_nextSongAct);
    _playMenu->addAction(_previousSongAct);

    _helpMenu = menuBar()->addMenu(tr("&Help"));
    _helpMenu->addAction(_aboutAct);
    _helpMenu->addAction(_aboutQtAct);
}

void MainWindow::setupButtons()
{
    const int mediaButtonYCoordinate =
            (
                height()- ((width()/5) + statusBar()->geometry().height() - 8)
            );

    //Setup signals
    connect(&_prevButton, SIGNAL(clicked()), this, SLOT(_prevButtonIsPressed()));
    connect(&_playButton, SIGNAL(clicked()), this, SLOT(_playButtonIsPressed()));
    connect(&_nextButton, SIGNAL(clicked()), this, SLOT(_nextButtonIsPressed()));

    //Setup parents
    _prevButton.setParent(this);
    _playButton.setParent(this);
    _nextButton.setParent(this);

    //Setup positions
    _prevButton.setGeometry
            (
                0,
                mediaButtonYCoordinate,
                width()/5,
                width()/5
            );
    _playButton.setGeometry
            (
                _prevButton.width()*2,
                mediaButtonYCoordinate,
                width()/5,
                width()/5
            );
    _nextButton.setGeometry
            (
                _playButton.width()*4,
                mediaButtonYCoordinate,
                width()/5,
                width()/5
            );

    //Setup icons
    _prevButton.setIcon(_prevButtonIcon);
    _prevButton.setIconSize(QSize(_prevButton.height(),_prevButton.height()));

    _playButton.setIcon(_playButtonPlayIcon);
    _playButton.setIconSize(QSize(_playButton.height(),_playButton.height()));

    _nextButton.setIcon(_nextButtonIcon);
    _nextButton.setIconSize(QSize(_nextButton.height(),_nextButton.height()));

    //Show them off
    _prevButton.show();
    _playButton.show();
    _nextButton.show();
}
<|endoftext|>


<commit_before>#include "mainwindow.hpp"
#include "screenshotter.hpp"
#include "screenshotutil.hpp"
#include "ui_mainwindow.h"
#include <QAction>
#include <QCloseEvent>
#include <QCoreApplication>
#include <QDoubleSpinBox>
#include <QListWidgetItem>
#include <QMenu>
#include <QStatusBar>
#include <QSystemTrayIcon>
#include <QTimer>
#include <functional>
#include <hotkeying.hpp>
#include <settings.hpp>
#include <uploaders/uploadersingleton.hpp>

MainWindow *MainWindow::instance;

void addHotkeyItem(QString text, QString name, std::function<void()> *func)
{
    QListWidgetItem *item = new QListWidgetItem(text, MainWindow::inst()->ui->hotkeys);
    item->setData(Qt::UserRole + 1, name);
    MainWindow::inst()->fncs.insert(name, func);
    hotkeying::load(name, *func);
}

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
    instance = this;
    ui->setupUi(this);
    setWindowIcon(QIcon(":/icons/icon.jpg"));
    tray = new QSystemTrayIcon(windowIcon(), this);
    tray->setToolTip("KShare");
    tray->setVisible(true);
    QMenu *menu = new QMenu(this);
    QAction *quit = new QAction("Quit", this);
    QAction *shtoggle = new QAction("Show/Hide", this);
    QAction *fullscreen = new QAction("Take fullscreen shot", this);
    QAction *area = new QAction("Take area shot", this);
    menu->addActions({ quit, shtoggle });
    menu->addSeparator();
    menu->addActions({ fullscreen, area });
    connect(quit, &QAction::triggered, this, &MainWindow::quit);
    connect(shtoggle, &QAction::triggered, this, &MainWindow::toggleVisible);
    connect(fullscreen, &QAction::triggered, this, &MainWindow::on_actionFullscreen_triggered);
    connect(area, &QAction::triggered, this, &MainWindow::on_actionArea_triggered);
    tray->setContextMenu(menu);

    ui->uploaderList->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->uploaderList->setSelectionMode(QAbstractItemView::SingleSelection);

    // Add items to uploader selection
    for (Uploader *u : UploaderSingleton::inst().uploaderList()) newUploader(u);
    connect(&UploaderSingleton::inst(), &UploaderSingleton::newUploader, this, &MainWindow::newUploader);

    // Set filename scheme
    if ((settings::settings().contains("fileFormat")))
        setScheme(settings::settings().value("fileFormat").toString());
    else
        setScheme("Screenshot %(yyyy-MM-dd HH:mm:ss)date");

    auto errors = UploaderSingleton::inst().errors();
    if (errors.length() == 1)
        statusBar()->showMessage(errors.at(0).what());
    else
        statusBar()->showMessage(QString("Errors visible in console (if present). Count: " + QString::number(errors.size())));

    // Set delay
    if ((settings::settings().contains("delay")))
        ui->delay->setValue(settings::settings().value("delay").toDouble());
    else
        ui->delay->setValue(0.25);

    // keys are hot, wait what
    hotkeying::load("fullscreen", [this] { on_actionFullscreen_triggered(); });
    hotkeying::load("area", [this] { on_actionArea_triggered(); });

    ui->hotkeys->setSelectionMode(QListWidget::SingleSelection);

    addHotkeyItem("Fullscreen image", "fullscreen", new std::function<void()>([&] { on_actionFullscreen_triggered(); }));
    addHotkeyItem("Area image", "area", new std::function<void()>([&] { on_actionArea_triggered(); }));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::setScheme(QString scheme)
{
    ui->nameScheme->setText(scheme);
}

QDoubleSpinBox *MainWindow::delay()
{
    return ui->delay;
}

MainWindow *MainWindow::inst()
{
    return instance;
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    event->ignore();
    QTimer::singleShot(0, this, &MainWindow::hide);
}

void MainWindow::quit()
{
    QCoreApplication::quit();
}

void MainWindow::toggleVisible()
{
    this->setVisible(!this->isVisible());
}

void MainWindow::newUploader(Uploader *u)
{
    QListWidgetItem *item = new QListWidgetItem(u->name());
    item->setToolTip(u->description());
    ui->uploaderList->addItem(item);
    if (u->name() == UploaderSingleton::inst().selectedUploader()) item->setSelected(true);
}

void MainWindow::on_actionQuit_triggered()
{
    quit();
}

void MainWindow::on_actionFullscreen_triggered()
{
    screenshotter::fullscreenDelayed();
}

void MainWindow::on_actionArea_triggered()
{
    screenshotter::areaDelayed();
}

void MainWindow::on_uploaderList_clicked(const QModelIndex &)
{
    QList<QListWidgetItem *> index = ui->uploaderList->selectedItems();
    if (index.size() == 1)
    {
        UploaderSingleton::inst().set(index.at(0)->text());
    }
}

void MainWindow::on_nameScheme_textEdited(const QString &arg1)
{
    settings::settings().setValue("fileFormat", arg1);
}

void MainWindow::on_delay_valueChanged(double arg1)
{
    settings::settings().setValue("delay", arg1);
}

void MainWindow::on_hotkeys_doubleClicked(const QModelIndex &)
{
    if (ui->hotkeys->selectedItems().length() == 1)
    {
        QListWidgetItem *i = ui->hotkeys->selectedItems().at(0);
        QString str = i->data(Qt::UserRole + 1).toString();
        QString seq = QInputDialog::getText(ui->centralWidget, "Hotkey Input", "Insert hotkey:", QLineEdit::Normal,
                                            hotkeying::sequence(str));
        if (hotkeying::valid(seq)) hotkeying::hotkey(str, QKeySequence(seq), *fncs.value(str));
    }
}
<commit_msg>Oops pt 3<commit_after>#include "mainwindow.hpp"
#include "screenshotter.hpp"
#include "screenshotutil.hpp"
#include "ui_mainwindow.h"
#include <QAction>
#include <QCloseEvent>
#include <QCoreApplication>
#include <QDoubleSpinBox>
#include <QInputDialog>
#include <QListWidgetItem>
#include <QMenu>
#include <QStatusBar>
#include <QSystemTrayIcon>
#include <QTimer>
#include <functional>
#include <hotkeying.hpp>
#include <settings.hpp>
#include <uploaders/uploadersingleton.hpp>

MainWindow *MainWindow::instance;

void addHotkeyItem(QString text, QString name, std::function<void()> *func)
{
    QListWidgetItem *item = new QListWidgetItem(text, MainWindow::inst()->ui->hotkeys);
    item->setData(Qt::UserRole + 1, name);
    MainWindow::inst()->fncs.insert(name, func);
    hotkeying::load(name, *func);
}

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
    instance = this;
    ui->setupUi(this);
    setWindowIcon(QIcon(":/icons/icon.jpg"));
    tray = new QSystemTrayIcon(windowIcon(), this);
    tray->setToolTip("KShare");
    tray->setVisible(true);
    QMenu *menu = new QMenu(this);
    QAction *quit = new QAction("Quit", this);
    QAction *shtoggle = new QAction("Show/Hide", this);
    QAction *fullscreen = new QAction("Take fullscreen shot", this);
    QAction *area = new QAction("Take area shot", this);
    menu->addActions({ quit, shtoggle });
    menu->addSeparator();
    menu->addActions({ fullscreen, area });
    connect(quit, &QAction::triggered, this, &MainWindow::quit);
    connect(shtoggle, &QAction::triggered, this, &MainWindow::toggleVisible);
    connect(fullscreen, &QAction::triggered, this, &MainWindow::on_actionFullscreen_triggered);
    connect(area, &QAction::triggered, this, &MainWindow::on_actionArea_triggered);
    tray->setContextMenu(menu);

    ui->uploaderList->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->uploaderList->setSelectionMode(QAbstractItemView::SingleSelection);

    // Add items to uploader selection
    for (Uploader *u : UploaderSingleton::inst().uploaderList()) newUploader(u);
    connect(&UploaderSingleton::inst(), &UploaderSingleton::newUploader, this, &MainWindow::newUploader);

    // Set filename scheme
    if ((settings::settings().contains("fileFormat")))
        setScheme(settings::settings().value("fileFormat").toString());
    else
        setScheme("Screenshot %(yyyy-MM-dd HH:mm:ss)date");

    auto errors = UploaderSingleton::inst().errors();
    if (errors.length() == 1)
        statusBar()->showMessage(errors.at(0).what());
    else
        statusBar()->showMessage(QString("Errors visible in console (if present). Count: " + QString::number(errors.size())));

    // Set delay
    if ((settings::settings().contains("delay")))
        ui->delay->setValue(settings::settings().value("delay").toDouble());
    else
        ui->delay->setValue(0.25);

    // keys are hot, wait what
    hotkeying::load("fullscreen", [this] { on_actionFullscreen_triggered(); });
    hotkeying::load("area", [this] { on_actionArea_triggered(); });

    ui->hotkeys->setSelectionMode(QListWidget::SingleSelection);

    addHotkeyItem("Fullscreen image", "fullscreen", new std::function<void()>([&] { on_actionFullscreen_triggered(); }));
    addHotkeyItem("Area image", "area", new std::function<void()>([&] { on_actionArea_triggered(); }));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::setScheme(QString scheme)
{
    ui->nameScheme->setText(scheme);
}

QDoubleSpinBox *MainWindow::delay()
{
    return ui->delay;
}

MainWindow *MainWindow::inst()
{
    return instance;
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    event->ignore();
    QTimer::singleShot(0, this, &MainWindow::hide);
}

void MainWindow::quit()
{
    QCoreApplication::quit();
}

void MainWindow::toggleVisible()
{
    this->setVisible(!this->isVisible());
}

void MainWindow::newUploader(Uploader *u)
{
    QListWidgetItem *item = new QListWidgetItem(u->name());
    item->setToolTip(u->description());
    ui->uploaderList->addItem(item);
    if (u->name() == UploaderSingleton::inst().selectedUploader()) item->setSelected(true);
}

void MainWindow::on_actionQuit_triggered()
{
    quit();
}

void MainWindow::on_actionFullscreen_triggered()
{
    screenshotter::fullscreenDelayed();
}

void MainWindow::on_actionArea_triggered()
{
    screenshotter::areaDelayed();
}

void MainWindow::on_uploaderList_clicked(const QModelIndex &)
{
    QList<QListWidgetItem *> index = ui->uploaderList->selectedItems();
    if (index.size() == 1)
    {
        UploaderSingleton::inst().set(index.at(0)->text());
    }
}

void MainWindow::on_nameScheme_textEdited(const QString &arg1)
{
    settings::settings().setValue("fileFormat", arg1);
}

void MainWindow::on_delay_valueChanged(double arg1)
{
    settings::settings().setValue("delay", arg1);
}

void MainWindow::on_hotkeys_doubleClicked(const QModelIndex &)
{
    if (ui->hotkeys->selectedItems().length() == 1)
    {
        QListWidgetItem *i = ui->hotkeys->selectedItems().at(0);
        QString str = i->data(Qt::UserRole + 1).toString();
        QString seq = QInputDialog::getText(ui->centralWidget, "Hotkey Input", "Insert hotkey:", QLineEdit::Normal,
                                            hotkeying::sequence(str));
        if (hotkeying::valid(seq)) hotkeying::hotkey(str, QKeySequence(seq), *fncs.value(str));
    }
}
<|endoftext|>


<commit_before>#include "actions.h"
#include "componentactions.h"
#include "menus.h"
#include "menuactions.h"
#include "setup.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    _ui(new Ui::MainWindow),
    _mainWindowIcon(":/Resources/icons/mainWindowIcon.png"),
    _centralWidget(new QWidget(this)),
    _mainLayout(new QVBoxLayout(_centralWidget)),
    _isPlaying(false),
    _isShuffled(false),
    _prevButton(new QPushButton(this)),
    _prevButtonIcon(":/Resources/icons/Button-Prev-icon.png"),
    _playButton(new QPushButton(this)),
    _playButtonPlayIcon(":/Resources/icons/Button-Play-icon.png"),
    _playButtonPauseIcon(":/Resources/icons/Button-Pause-icon.png"),
    _nextButton(new QPushButton(this)),
    _nextButtonIcon(":/Resources/icons/Button-Next-icon.png"),
    _helpIcon(":/Resources/icons/Menu-Help-icon.png"),
    _infoIcon(":/Resources/icons/Menu-Info-icon.png"),
    _openIcon(":/Resources/icons/Menu-Open-icon.png"),
    _exitIcon(":/Resources/icons/Menu-Exit-icon.png"),
    _qtIcon(":/Resources/icons/Qt-icon.ico"),
    _volumeLabel(new QLabel(this)),
    _volumeSlider(new QSlider(Qt::Horizontal, this)),
    _fileMetadata(new QLabel(this)),
    _players(new QVector<QMediaPlayer *>),
    _currentPlayer(new QMediaPlayer),
    _progressBar(new QProgressBar(this)),
    _shuffleButton(new QPushButton),
    _playlistViews(new QVector<QListWidget *>),
    _currentPlaylistView(new QListWidget),
    _playlistTabs(new QTabWidget(this)),
    _newPlaylistTabButton(new QPushButton("New Playlist")),
    _loopCheckbox(new QCheckBox(this))
{
    setWindowIcon(_mainWindowIcon);
    setWindowTitle("Music Player");
    setCentralWidget(_centralWidget);

    /****************SETTING UP STATUS BAR*********************/
    QWidget *topFiller = new QWidget;
    topFiller->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

#ifdef Q_OS_SYMBIAN
    _infoLabel = new QLabel(tr("Choose a menu option"));
#else
    _infoLabel = new QLabel(tr("Choose a menu option, or right-click to "
                              "invoke a context menu"));
#endif
    _infoLabel->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
    _infoLabel->setAlignment(Qt::AlignCenter);

    QWidget *bottomFiller = new QWidget;
    bottomFiller->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    QVBoxLayout *layout = new QVBoxLayout;
    layout->setMargin(5);
    layout->addWidget(topFiller);
    layout->addWidget(_infoLabel);
    layout->addWidget(bottomFiller);

    /************SETTING UP STATUS BAR********************/

    #ifndef Q_OS_SYMBIAN
    QString message = tr("A context menu is available by right-clicking");
    statusBar()->showMessage(message);
    #endif

    _currentPlayer->setVolume(50);

    setup();
}

MainWindow::~MainWindow()
{
    delete _ui;
}
<commit_msg>Changed check for symbian OS to a check for Android.<commit_after>#include "actions.h"
#include "componentactions.h"
#include "menus.h"
#include "menuactions.h"
#include "setup.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    _ui(new Ui::MainWindow),
    _mainWindowIcon(":/Resources/icons/mainWindowIcon.png"),
    _centralWidget(new QWidget(this)),
    _mainLayout(new QVBoxLayout(_centralWidget)),
    _isPlaying(false),
    _isShuffled(false),
    _prevButton(new QPushButton(this)),
    _prevButtonIcon(":/Resources/icons/Button-Prev-icon.png"),
    _playButton(new QPushButton(this)),
    _playButtonPlayIcon(":/Resources/icons/Button-Play-icon.png"),
    _playButtonPauseIcon(":/Resources/icons/Button-Pause-icon.png"),
    _nextButton(new QPushButton(this)),
    _nextButtonIcon(":/Resources/icons/Button-Next-icon.png"),
    _helpIcon(":/Resources/icons/Menu-Help-icon.png"),
    _infoIcon(":/Resources/icons/Menu-Info-icon.png"),
    _openIcon(":/Resources/icons/Menu-Open-icon.png"),
    _exitIcon(":/Resources/icons/Menu-Exit-icon.png"),
    _qtIcon(":/Resources/icons/Qt-icon.ico"),
    _volumeLabel(new QLabel(this)),
    _volumeSlider(new QSlider(Qt::Horizontal, this)),
    _fileMetadata(new QLabel(this)),
    _players(new QVector<QMediaPlayer *>),
    _currentPlayer(new QMediaPlayer),
    _progressBar(new QProgressBar(this)),
    _shuffleButton(new QPushButton),
    _playlistViews(new QVector<QListWidget *>),
    _currentPlaylistView(new QListWidget),
    _playlistTabs(new QTabWidget(this)),
    _newPlaylistTabButton(new QPushButton("New Playlist")),
    _loopCheckbox(new QCheckBox(this))
{
    setWindowIcon(_mainWindowIcon);
    setWindowTitle("Music Player");
    setCentralWidget(_centralWidget);

    /****************SETTING UP STATUS BAR*********************/
    QWidget *topFiller = new QWidget;
    topFiller->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

#ifdef Q_OS_SYMBIAN
    _infoLabel = new QLabel(tr("Choose a menu option"));
#else
    _infoLabel = new QLabel(tr("Choose a menu option, or right-click to "
                              "invoke a context menu"));
#endif
    _infoLabel->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
    _infoLabel->setAlignment(Qt::AlignCenter);

    QWidget *bottomFiller = new QWidget;
    bottomFiller->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    QVBoxLayout *layout = new QVBoxLayout;
    layout->setMargin(5);
    layout->addWidget(topFiller);
    layout->addWidget(_infoLabel);
    layout->addWidget(bottomFiller);

    /************SETTING UP STATUS BAR********************/

#ifndef __ANDROID__
    QString message = tr("A context menu is available by right-clicking");
    statusBar()->showMessage(message);
#endif

    _currentPlayer->setVolume(50);

    setup();
}

MainWindow::~MainWindow()
{
    delete _ui;
}
<|endoftext|>


<commit_before>/**
 * \file
 * <!--
 * Copyright 2015 Develer S.r.l. (http://www.develer.com/)
 * -->
 *
 * \brief main cutecom-ng window
 *
 * \author Aurelien Rainone <aurelien@develer.org>
 */

#include <algorithm>
#include <iterator>

#include <QUiLoader>
#include <QLineEdit>
#include <QPropertyAnimation>
#include <QShortcut>

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "connectdialog.h"
#include "sessionmanager.h"
#include "outputmanager.h"
#include "searchhighlighter.h"

/// line ending char appended to the commands sent to the serial port
const QString LINE_ENDING = "\n";

/// maximum count of document blocks for the bootom output
const int MAX_OUTPUT_LINES = 100;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    search_widget(0),
    search_input(0)
{
    ui->setupUi(this);

    // create session and output managers
    output_mgr = new OutputManager(this);
    session_mgr = new SessionManager(this);
    connect_dlg = new ConnectDialog(this);

    // show connection dialog
    connect(ui->connectButton, &QAbstractButton::clicked, connect_dlg, &ConnectDialog::show);

    // handle reception of new data from serial port
    connect(session_mgr, &SessionManager::dataReceived, this, &MainWindow::handleDataReceived);

    // get data formatted for display and show it in output view
    connect(output_mgr, &OutputManager::dataConverted, this, &MainWindow::addDataToView);

    // get data formatted for display and show it in output view
    connect(ui->inputBox, &HistoryComboBox::lineEntered, this, &MainWindow::handleNewInput);

    // clear output manager buffer at session start
    connect(session_mgr, &SessionManager::sessionStarted, output_mgr, &OutputManager::clear);

    // clear output text
    connect(session_mgr, &SessionManager::sessionStarted, ui->mainOutput, &QPlainTextEdit::clear);
    connect(session_mgr, &SessionManager::sessionStarted, ui->bottomOutput, &QPlainTextEdit::clear);

    // call openSession when user accepts/closes connection dialog
    connect(connect_dlg, &ConnectDialog::openDeviceClicked, session_mgr, &SessionManager::openSession);

    connect(ui->splitOutputBtn, &QToolButton::clicked, this, &MainWindow::toggleOutputSplitter);

    // additional configuration for bottom output
    ui->bottomOutput->hide();
    ui->bottomOutput->document()->setMaximumBlockCount(MAX_OUTPUT_LINES);
    ui->bottomOutput->viewport()->installEventFilter(this);

    // load search widget and hide it
    QUiLoader loader;
    QFile file(":/searchwidget.ui");
    file.open(QFile::ReadOnly);
    search_widget = loader.load(&file, ui->mainOutput);
    Q_ASSERT_X(search_widget, "MainWindow::MainWindow", "error while loading searchwidget.ui");

    search_input = search_widget->findChild<QLineEdit*>("searchInput");
    Q_ASSERT_X(search_input, "MainWindow::MainWindow", "didn't find searchInput");

    search_prev_button = search_widget->findChild<QToolButton*>("previousButton");
    search_next_button = search_widget->findChild<QToolButton*>("nextButton");
    Q_ASSERT_X(search_prev_button, "MainWindow::MainWindow", "didn't find previousButton");
    Q_ASSERT_X(search_next_button, "MainWindow::MainWindow", "didn't find nextButton");

    file.close();
    search_widget->hide();

    // create the search results highlighter and connect search-related signals/slots
    SearchHighlighter *search_highlighter = new SearchHighlighter(ui->mainOutput->document());
    connect(ui->searchButton, &QToolButton::toggled, this, &MainWindow::showSearchWidget);
    connect(search_input, &QLineEdit::textChanged, search_highlighter, &SearchHighlighter::setSearchString);
    connect(search_prev_button, &QToolButton::clicked, search_highlighter, &SearchHighlighter::previousOccurence);
    connect(search_next_button, &QToolButton::clicked, search_highlighter, &SearchHighlighter::nextOccurence);
    connect(search_highlighter, &SearchHighlighter::cursorPosChanged, this, &MainWindow::handleCursosPosChanged);
    connect(search_highlighter, &SearchHighlighter::totalOccurencesChanged, this, &MainWindow::handleTotalOccurencesChanged);

    search_input->installEventFilter(this);
    ui->mainOutput->viewport()->installEventFilter(this);
    installEventFilter(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::handleNewInput(QString entry)
{
    // if session is not open, this also keeps user input
    if (session_mgr->isSessionOpen())
    {
        entry.append(LINE_ENDING);
        session_mgr->sendToSerial(entry.toLocal8Bit());
        ui->inputBox->clearEditText();
    }
}

void MainWindow::addDataToView(const QString & textdata)
{
    // problem : QTextEdit interprets a '\r' as a new line, so if a buffer ending
    //           with '\r\n' happens to be cut in the middle, there will be 1 extra
    //           line jump in the QTextEdit. To prevent we remove ending '\r' and
    //           prepend them to the next received buffer

    // flag indicating that the previously received buffer ended with CR
    static bool prev_ends_with_CR = false;

    QString newdata;
    if (prev_ends_with_CR)
    {
        // CR was removed at the previous buffer, so now we prepend it
        newdata.append('\r');
        prev_ends_with_CR = false;
    }

    if (textdata.length() > 0)
    {
        QString::const_iterator end_cit = textdata.cend();
        if (textdata.endsWith('\r'))
        {
            // if buffer ends with CR, we don't copy it
            end_cit--;
            prev_ends_with_CR = true;
        }
        std::copy(textdata.begin(), end_cit, std::back_inserter(newdata));
    }

    // record end cursor position before adding text
    QTextCursor prev_end_cursor(ui->mainOutput->document());
    prev_end_cursor.movePosition(QTextCursor::End);

    if (ui->bottomOutput->isVisible())
    {
        // append text to the top output and stay at current position
        QTextCursor cursor(ui->mainOutput->document());
        cursor.movePosition(QTextCursor::End);
        cursor.insertText(newdata);
    }
    else
    {
        // append text to the top output and scroll down
        ui->mainOutput->moveCursor(QTextCursor::End);
        ui->mainOutput->insertPlainText(newdata);
    }

    // append text to bottom output and scroll
    ui->bottomOutput->moveCursor(QTextCursor::End);
    ui->bottomOutput->insertPlainText(newdata);
}

void MainWindow::handleDataReceived(const QByteArray &data)
{
    (*output_mgr) << data;
}

void MainWindow::toggleOutputSplitter()
{
    ui->bottomOutput->setVisible(!ui->bottomOutput->isVisible());
}

bool MainWindow::eventFilter(QObject *target, QEvent *event)
{
    if (target == ui->mainOutput->viewport())
    {
        if (event->type() == QEvent::Resize)
        {
            // re position search widget when main output inner size changes
            // this takes into account existence of vertical scrollbar
            QResizeEvent *resizeEvent = static_cast<QResizeEvent*>(event);
            search_widget->move(resizeEvent->size().width() - search_widget->width(), 0);
        }
        else if (event->type() == QEvent::Wheel)
        {
            // allow mouse wheel usage only in 'browsing mode'
            if (!ui->bottomOutput->isVisible())
                return true;
        }
    }
    else
    {
        if (event->type() == QEvent::KeyPress)
        {
            QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
            if (ui->searchButton->isChecked())
            {
                // hide search widget on Escape key press
                if (keyEvent->key() == Qt::Key_Escape)
                    emit ui->searchButton->toggle();
            }
            else
            {
                // show search widget on Ctrl-F
                if (keyEvent->key() == Qt::Key_F && keyEvent->modifiers() == Qt::ControlModifier)
                    emit ui->searchButton->toggle();
            }
            if (target == search_input)
            {
                if (keyEvent->key() == Qt::Key_Return)
                {
                    if (keyEvent->modifiers() == Qt::ShiftModifier)
                        emit search_prev_button->click();
                    else
                        emit search_next_button->click();
                }
            }

        }
    }

    // base class behaviour
    return QMainWindow::eventFilter(target, event);
}

void MainWindow::showSearchWidget(bool show)
{
    // record which widget had focus before showing search widget, in
    // to return focus to it when search widget is hidden
    static QWidget *prevFocus = 0;

    QPropertyAnimation *animation = new QPropertyAnimation(search_widget, "geometry");
    animation->setDuration(150);

    // arbitrary offset chosen to be way bigger than any scrollbar width, on any platform
    const QRect rect(search_widget->geometry());
    QRect showed_pos(ui->mainOutput->viewport()->width() - rect.width(), 0, rect.width(), rect.height());
    QRect hidden_pos(ui->mainOutput->viewport()->width() - rect.width(), -rect.height(), rect.width(), rect.height());

    animation->setStartValue(show ? hidden_pos : showed_pos);
    animation->setEndValue(show ? showed_pos : hidden_pos);

    if (show)
    {
        prevFocus = QApplication::focusWidget();
        search_widget->setVisible(show);
        search_input->setFocus();
    }
    else
    {
        connect(animation, &QPropertyAnimation::destroyed, search_widget, &QWidget::hide);
        prevFocus->setFocus();
    }
    animation->start(QAbstractAnimation::DeleteWhenStopped);
}

void MainWindow::handleCursosPosChanged(int pos)
{
    // only in browsing mode
    if (ui->bottomOutput->isVisible())
    {
        // move cursor
        QTextCursor text_cursor = ui->mainOutput->textCursor();
        text_cursor.setPosition(pos);

        // ensure search result cursor is visible
        ui->mainOutput->ensureCursorVisible();
        ui->mainOutput->setTextCursor(text_cursor);
    }
}

void MainWindow::handleTotalOccurencesChanged(int total_occurences)
{
    if (total_occurences == 0)
        search_input->setStyleSheet("QLineEdit{background-color: red;}");
    else
        search_input->setStyleSheet("");
}
<commit_msg>clear buttons clear output text<commit_after>/**
 * \file
 * <!--
 * Copyright 2015 Develer S.r.l. (http://www.develer.com/)
 * -->
 *
 * \brief main cutecom-ng window
 *
 * \author Aurelien Rainone <aurelien@develer.org>
 */

#include <algorithm>
#include <iterator>

#include <QUiLoader>
#include <QLineEdit>
#include <QPropertyAnimation>
#include <QShortcut>

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "connectdialog.h"
#include "sessionmanager.h"
#include "outputmanager.h"
#include "searchhighlighter.h"

/// line ending char appended to the commands sent to the serial port
const QString LINE_ENDING = "\n";

/// maximum count of document blocks for the bootom output
const int MAX_OUTPUT_LINES = 100;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    search_widget(0),
    search_input(0)
{
    ui->setupUi(this);

    // create session and output managers
    output_mgr = new OutputManager(this);
    session_mgr = new SessionManager(this);
    connect_dlg = new ConnectDialog(this);

    // show connection dialog
    connect(ui->connectButton, &QAbstractButton::clicked, connect_dlg, &ConnectDialog::show);

    // handle reception of new data from serial port
    connect(session_mgr, &SessionManager::dataReceived, this, &MainWindow::handleDataReceived);

    // get data formatted for display and show it in output view
    connect(output_mgr, &OutputManager::dataConverted, this, &MainWindow::addDataToView);

    // get data formatted for display and show it in output view
    connect(ui->inputBox, &HistoryComboBox::lineEntered, this, &MainWindow::handleNewInput);

    // clear output manager buffer at session start
    connect(session_mgr, &SessionManager::sessionStarted, output_mgr, &OutputManager::clear);

    // clear both output text at session start
    connect(session_mgr, &SessionManager::sessionStarted, ui->mainOutput, &QPlainTextEdit::clear);
    connect(session_mgr, &SessionManager::sessionStarted, ui->bottomOutput, &QPlainTextEdit::clear);

    // clear both output text when 'clear' is clicked
    connect(ui->clearButton, &QToolButton::clicked, ui->mainOutput, &QPlainTextEdit::clear);
    connect(ui->clearButton, &QToolButton::clicked, ui->bottomOutput, &QPlainTextEdit::clear);

    // call openSession when user accepts/closes connection dialog
    connect(connect_dlg, &ConnectDialog::openDeviceClicked, session_mgr, &SessionManager::openSession);

    connect(ui->splitOutputBtn, &QToolButton::clicked, this, &MainWindow::toggleOutputSplitter);

    // additional configuration for bottom output
    ui->bottomOutput->hide();
    ui->bottomOutput->document()->setMaximumBlockCount(MAX_OUTPUT_LINES);
    ui->bottomOutput->viewport()->installEventFilter(this);

    // load search widget and hide it
    QUiLoader loader;
    QFile file(":/searchwidget.ui");
    file.open(QFile::ReadOnly);
    search_widget = loader.load(&file, ui->mainOutput);
    Q_ASSERT_X(search_widget, "MainWindow::MainWindow", "error while loading searchwidget.ui");

    search_input = search_widget->findChild<QLineEdit*>("searchInput");
    Q_ASSERT_X(search_input, "MainWindow::MainWindow", "didn't find searchInput");

    search_prev_button = search_widget->findChild<QToolButton*>("previousButton");
    search_next_button = search_widget->findChild<QToolButton*>("nextButton");
    Q_ASSERT_X(search_prev_button, "MainWindow::MainWindow", "didn't find previousButton");
    Q_ASSERT_X(search_next_button, "MainWindow::MainWindow", "didn't find nextButton");

    file.close();
    search_widget->hide();

    // create the search results highlighter and connect search-related signals/slots
    SearchHighlighter *search_highlighter = new SearchHighlighter(ui->mainOutput->document());
    connect(ui->searchButton, &QToolButton::toggled, this, &MainWindow::showSearchWidget);
    connect(search_input, &QLineEdit::textChanged, search_highlighter, &SearchHighlighter::setSearchString);
    connect(search_prev_button, &QToolButton::clicked, search_highlighter, &SearchHighlighter::previousOccurence);
    connect(search_next_button, &QToolButton::clicked, search_highlighter, &SearchHighlighter::nextOccurence);
    connect(search_highlighter, &SearchHighlighter::cursorPosChanged, this, &MainWindow::handleCursosPosChanged);
    connect(search_highlighter, &SearchHighlighter::totalOccurencesChanged, this, &MainWindow::handleTotalOccurencesChanged);

    search_input->installEventFilter(this);
    ui->mainOutput->viewport()->installEventFilter(this);
    installEventFilter(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::handleNewInput(QString entry)
{
    // if session is not open, this also keeps user input
    if (session_mgr->isSessionOpen())
    {
        entry.append(LINE_ENDING);
        session_mgr->sendToSerial(entry.toLocal8Bit());
        ui->inputBox->clearEditText();
    }
}

void MainWindow::addDataToView(const QString & textdata)
{
    // problem : QTextEdit interprets a '\r' as a new line, so if a buffer ending
    //           with '\r\n' happens to be cut in the middle, there will be 1 extra
    //           line jump in the QTextEdit. To prevent we remove ending '\r' and
    //           prepend them to the next received buffer

    // flag indicating that the previously received buffer ended with CR
    static bool prev_ends_with_CR = false;

    QString newdata;
    if (prev_ends_with_CR)
    {
        // CR was removed at the previous buffer, so now we prepend it
        newdata.append('\r');
        prev_ends_with_CR = false;
    }

    if (textdata.length() > 0)
    {
        QString::const_iterator end_cit = textdata.cend();
        if (textdata.endsWith('\r'))
        {
            // if buffer ends with CR, we don't copy it
            end_cit--;
            prev_ends_with_CR = true;
        }
        std::copy(textdata.begin(), end_cit, std::back_inserter(newdata));
    }

    // record end cursor position before adding text
    QTextCursor prev_end_cursor(ui->mainOutput->document());
    prev_end_cursor.movePosition(QTextCursor::End);

    if (ui->bottomOutput->isVisible())
    {
        // append text to the top output and stay at current position
        QTextCursor cursor(ui->mainOutput->document());
        cursor.movePosition(QTextCursor::End);
        cursor.insertText(newdata);
    }
    else
    {
        // append text to the top output and scroll down
        ui->mainOutput->moveCursor(QTextCursor::End);
        ui->mainOutput->insertPlainText(newdata);
    }

    // append text to bottom output and scroll
    ui->bottomOutput->moveCursor(QTextCursor::End);
    ui->bottomOutput->insertPlainText(newdata);
}

void MainWindow::handleDataReceived(const QByteArray &data)
{
    (*output_mgr) << data;
}

void MainWindow::toggleOutputSplitter()
{
    ui->bottomOutput->setVisible(!ui->bottomOutput->isVisible());
}

bool MainWindow::eventFilter(QObject *target, QEvent *event)
{
    if (target == ui->mainOutput->viewport())
    {
        if (event->type() == QEvent::Resize)
        {
            // re position search widget when main output inner size changes
            // this takes into account existence of vertical scrollbar
            QResizeEvent *resizeEvent = static_cast<QResizeEvent*>(event);
            search_widget->move(resizeEvent->size().width() - search_widget->width(), 0);
        }
        else if (event->type() == QEvent::Wheel)
        {
            // allow mouse wheel usage only in 'browsing mode'
            if (!ui->bottomOutput->isVisible())
                return true;
        }
    }
    else
    {
        if (event->type() == QEvent::KeyPress)
        {
            QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
            if (ui->searchButton->isChecked())
            {
                // hide search widget on Escape key press
                if (keyEvent->key() == Qt::Key_Escape)
                    emit ui->searchButton->toggle();
            }
            else
            {
                // show search widget on Ctrl-F
                if (keyEvent->key() == Qt::Key_F && keyEvent->modifiers() == Qt::ControlModifier)
                    emit ui->searchButton->toggle();
            }
            if (target == search_input)
            {
                if (keyEvent->key() == Qt::Key_Return)
                {
                    if (keyEvent->modifiers() == Qt::ShiftModifier)
                        emit search_prev_button->click();
                    else
                        emit search_next_button->click();
                }
            }

        }
    }

    // base class behaviour
    return QMainWindow::eventFilter(target, event);
}

void MainWindow::showSearchWidget(bool show)
{
    // record which widget had focus before showing search widget, in
    // to return focus to it when search widget is hidden
    static QWidget *prevFocus = 0;

    QPropertyAnimation *animation = new QPropertyAnimation(search_widget, "geometry");
    animation->setDuration(150);

    // arbitrary offset chosen to be way bigger than any scrollbar width, on any platform
    const QRect rect(search_widget->geometry());
    QRect showed_pos(ui->mainOutput->viewport()->width() - rect.width(), 0, rect.width(), rect.height());
    QRect hidden_pos(ui->mainOutput->viewport()->width() - rect.width(), -rect.height(), rect.width(), rect.height());

    animation->setStartValue(show ? hidden_pos : showed_pos);
    animation->setEndValue(show ? showed_pos : hidden_pos);

    if (show)
    {
        prevFocus = QApplication::focusWidget();
        search_widget->setVisible(show);
        search_input->setFocus();
    }
    else
    {
        connect(animation, &QPropertyAnimation::destroyed, search_widget, &QWidget::hide);
        prevFocus->setFocus();
    }
    animation->start(QAbstractAnimation::DeleteWhenStopped);
}

void MainWindow::handleCursosPosChanged(int pos)
{
    // only in browsing mode
    if (ui->bottomOutput->isVisible())
    {
        // move cursor
        QTextCursor text_cursor = ui->mainOutput->textCursor();
        text_cursor.setPosition(pos);

        // ensure search result cursor is visible
        ui->mainOutput->ensureCursorVisible();
        ui->mainOutput->setTextCursor(text_cursor);
    }
}

void MainWindow::handleTotalOccurencesChanged(int total_occurences)
{
    if (total_occurences == 0)
        search_input->setStyleSheet("QLineEdit{background-color: red;}");
    else
        search_input->setStyleSheet("");
}
<|endoftext|>


<commit_before>#include "PythonInteractor.h"
#include "Scene.h"

#include <SofaPython/PythonCommon.h>
#include <SofaPython/PythonEnvironment.h>
#include <SofaPython/ScriptEnvironment.h>
#include <SofaPython/PythonMacros.h>
#include <SofaPython/PythonScriptController.h>
#include <SofaPython/PythonScriptFunction.h>

#include <qqml.h>
#include <QDebug>
#include <QSequentialIterable>
#include <vector>

PythonInteractor::PythonInteractor(QObject *parent) : QObject(parent), QQmlParserStatus(),
	myScene(0),
	myPythonScriptControllers()
{
	connect(this, &PythonInteractor::sceneChanged, this, &PythonInteractor::handleSceneChanged);
}

PythonInteractor::~PythonInteractor()
{

}

void PythonInteractor::classBegin()
{

}

void PythonInteractor::componentComplete()
{
	if(!myScene)
		setScene(qobject_cast<Scene*>(parent()));
}

void PythonInteractor::setScene(Scene* newScene)
{
	if(newScene == myScene)
		return;

	myScene = newScene;

	sceneChanged(newScene);
}

void PythonInteractor::handleSceneChanged(Scene* scene)
{
	if(scene)
	{
		if(scene->isReady())
			retrievePythonScriptControllers();

		connect(scene, &Scene::loaded, this, &PythonInteractor::retrievePythonScriptControllers);
	}
}

void PythonInteractor::retrievePythonScriptControllers()
{
	myPythonScriptControllers.clear();

	if(!myScene || !myScene->isReady())
		return;

	std::vector<PythonScriptController*> pythonScriptControllers;
	myScene->sofaSimulation()->GetRoot()->get<PythonScriptController>(&pythonScriptControllers, sofa::core::objectmodel::BaseContext::SearchDown);

	for(size_t i = 0; i < pythonScriptControllers.size(); ++i)
		myPythonScriptControllers.insert(pythonScriptControllers[i]->m_classname.getValue().c_str(), pythonScriptControllers[i]);
}

static PyObject* PythonBuildValueHelper(const QVariant& parameter)
{
	PyObject* value = 0;
	if(!parameter.isNull())
	{
		switch(parameter.type())
		{
		case QVariant::Bool:
			value = Py_BuildValue("b", parameter.toBool());
			break;
		case QVariant::Int:
			value = Py_BuildValue("i", parameter.toInt());
			break;
		case QVariant::UInt:
			value = Py_BuildValue("I", parameter.toUInt());
			break;
		case QVariant::Double:
			value = Py_BuildValue("d", parameter.toDouble());
			break;
		case QVariant::String:
			value = Py_BuildValue("s", parameter.toString().toLatin1().constData());
			break;
		default:
			value = Py_BuildValue("");
			qDebug() << "ERROR: buildPythonParameterHelper, type not supported:" << parameter.typeName();
			break;
		}
	}

	return value;
}

static PyObject* PythonBuildTupleHelper(const QVariant& parameter, bool mustBeTuple)
{
	PyObject* tuple = 0;

	if(!parameter.isNull())
	{
		if(parameter.canConvert<QVariantList>())
		{
			QSequentialIterable parameterIterable = parameter.value<QSequentialIterable>();
			tuple = PyTuple_New(parameterIterable.size());

			int count = 0;
			for(const QVariant& i : parameterIterable)
				PyTuple_SetItem(tuple, count++, PythonBuildTupleHelper(i, false));
		}
		else
		{
			if(mustBeTuple)
			{
				tuple = PyTuple_New(1);
				PyTuple_SetItem(tuple, 0, PythonBuildValueHelper(parameter));
			}
			else
			{
				tuple = PythonBuildValueHelper(parameter);
			}
		}
	}

	return tuple;
}

static QVariant ExtractPythonValueHelper(PyObject* parameter)
{
	QVariant value;

	if(parameter)
	{
		if(PyBool_Check(parameter))
			value = (Py_False != parameter);
		else if(PyInt_Check(parameter))
            value = (int)PyInt_AsLong(parameter);
		else if(PyFloat_Check(parameter))
			value = PyFloat_AsDouble(parameter);
		else if(PyString_Check(parameter))
			value = PyString_AsString(parameter);
	}

	return value;
}

static QVariant ExtractPythonTupleHelper(PyObject* parameter)
{
	QVariant value;

	if(!parameter)
		return value;

	if(PyTuple_Check(parameter) || PyList_Check(parameter))
	{
		QVariantList tuple;

		if(PyList_Check(parameter))
			qDebug() << "length:" << PyList_Size(parameter);
		else
			qDebug() << "length:" << PyTuple_Size(parameter);

		PyObject *iterator = PyObject_GetIter(parameter);
		PyObject *item;

		if(!iterator)
		{
			qDebug() << "ERROR: Python tuple/list is empty";
			return value;
		}

		while(item = PyIter_Next(iterator))
		{
			tuple.append(ExtractPythonTupleHelper(item));

			Py_DECREF(item);
		}
		Py_DECREF(iterator);

		if(PyErr_Occurred())
			qDebug() << "ERROR: during python tuple/list iteration";

		return tuple;
	}

	value = ExtractPythonValueHelper(parameter);

	return value;
}

QVariant PythonInteractor::call(const QString& pythonClassName, const QString& funcName, const QVariant& parameter)
{
	QVariant result;

	if(!myScene)
	{
		qDebug() << "ERROR: cannot call Python function on a null scene";
		return result;
	}

	if(!myScene->isReady())
	{
		qDebug() << "ERROR: cannot call Python function on a scene that is still loading";
		return result;
	}

	if(pythonClassName.isEmpty())
	{
		qDebug() << "ERROR: cannot call Python function without a valid python class name";
		return result;
	}

	if(funcName.isEmpty())
	{
		qDebug() << "ERROR: cannot call Python function without a valid python function name";
		return result;
	}

	auto pythonScriptControllerIterator = myPythonScriptControllers.find(pythonClassName);
	if(myPythonScriptControllers.end() == pythonScriptControllerIterator)
	{
		qDebug() << "ERROR: cannot send Python event on an unknown script controller:" << pythonClassName;
		if(myPythonScriptControllers.isEmpty())
		{
			qDebug() << "There is no PythonScriptController";
		}
		else
		{
			qDebug() << "Known PythonScriptController(s):";
			for(const QString& pythonScriptControllerName : myPythonScriptControllers.keys())
				qDebug() << "-" << pythonScriptControllerName;
		}

		return result;
	}

	PythonScriptController* pythonScriptController = pythonScriptControllerIterator.value();
	if(pythonScriptController)
	{
		PyObject* pyCallableObject = PyObject_GetAttrString(pythonScriptController->scriptControllerInstance(), funcName.toLatin1().constData());
		if(!pyCallableObject)
		{
			qDebug() << "ERROR: cannot call Python function without a valid python class and function name";
		}
		else
		{
			PythonScriptFunction pythonScriptFunction(pyCallableObject, true);
			PythonScriptFunctionParameter pythonScriptParameter(PythonBuildTupleHelper(parameter, true), true);
			PythonScriptFunctionResult pythonScriptResult;

			pythonScriptFunction(&pythonScriptParameter, &pythonScriptResult);

			result = ExtractPythonTupleHelper(pythonScriptResult.data());
		}
	}

	return result;
}

void PythonInteractor::sendEvent(const QString& pythonClassName, const QString& eventName, const QVariant& parameter)
{
	if(!myScene)
	{
		qDebug() << "ERROR: cannot send Python event on a null scene";
		return;
	}

	if(!myScene->isReady())
	{
		qDebug() << "ERROR: cannot send Python event on a scene that is still loading";
		return;
	}

	auto pythonScriptControllerIterator = myPythonScriptControllers.find(pythonClassName);
	if(myPythonScriptControllers.end() == pythonScriptControllerIterator)
	{
		qDebug() << "ERROR: cannot send Python event on an unknown script controller:" << pythonClassName;
		if(myPythonScriptControllers.isEmpty())
		{
			qDebug() << "There is no PythonScriptController";
		}
		else
		{
			qDebug() << "Known PythonScriptController(s):";
			for(const QString& pythonScriptControllerName : myPythonScriptControllers.keys())
				qDebug() << "-" << pythonScriptControllerName;
		}

		return;
	}

	PythonScriptController* pythonScriptController = pythonScriptControllerIterator.value();

	PyObject* pyParameter = PythonBuildValueHelper(parameter);
	if(!pyParameter)
		pyParameter = Py_BuildValue("");

	sofa::core::objectmodel::PythonScriptEvent pythonScriptEvent(myScene->sofaSimulation()->GetRoot(), eventName.toLatin1().constData(), pyParameter);
	pythonScriptController->handleEvent(&pythonScriptEvent);
}

void PythonInteractor::sendEventToAll(const QString& eventName, const QVariant& parameter)
{
	for(const QString& pythonClassName : myPythonScriptControllers.keys())
		sendEvent(pythonClassName, eventName, parameter);
}
<commit_msg>ADD: SofaQtQuickGUI - PythonInteractor: support for JS/Python dictionaries<commit_after>#include "PythonInteractor.h"
#include "Scene.h"

#include <SofaPython/PythonCommon.h>
#include <SofaPython/PythonEnvironment.h>
#include <SofaPython/ScriptEnvironment.h>
#include <SofaPython/PythonMacros.h>
#include <SofaPython/PythonScriptController.h>
#include <SofaPython/PythonScriptFunction.h>

#include <qqml.h>
#include <QDebug>
#include <QSequentialIterable>
#include <vector>

PythonInteractor::PythonInteractor(QObject *parent) : QObject(parent), QQmlParserStatus(),
	myScene(0),
	myPythonScriptControllers()
{
	connect(this, &PythonInteractor::sceneChanged, this, &PythonInteractor::handleSceneChanged);
}

PythonInteractor::~PythonInteractor()
{

}

void PythonInteractor::classBegin()
{

}

void PythonInteractor::componentComplete()
{
	if(!myScene)
		setScene(qobject_cast<Scene*>(parent()));
}

void PythonInteractor::setScene(Scene* newScene)
{
	if(newScene == myScene)
		return;

	myScene = newScene;

	sceneChanged(newScene);
}

void PythonInteractor::handleSceneChanged(Scene* scene)
{
	if(scene)
	{
		if(scene->isReady())
			retrievePythonScriptControllers();

		connect(scene, &Scene::loaded, this, &PythonInteractor::retrievePythonScriptControllers);
	}
}

void PythonInteractor::retrievePythonScriptControllers()
{
	myPythonScriptControllers.clear();

	if(!myScene || !myScene->isReady())
		return;

	std::vector<PythonScriptController*> pythonScriptControllers;
	myScene->sofaSimulation()->GetRoot()->get<PythonScriptController>(&pythonScriptControllers, sofa::core::objectmodel::BaseContext::SearchDown);

	for(size_t i = 0; i < pythonScriptControllers.size(); ++i)
		myPythonScriptControllers.insert(pythonScriptControllers[i]->m_classname.getValue().c_str(), pythonScriptControllers[i]);
}

static PyObject* PythonBuildValueHelper(const QVariant& parameter)
{
	PyObject* value = 0;
	if(!parameter.isNull())
	{
		switch(parameter.type())
		{
		case QVariant::Bool:
			value = Py_BuildValue("b", parameter.toBool());
			break;
		case QVariant::Int:
			value = Py_BuildValue("i", parameter.toInt());
			break;
		case QVariant::UInt:
			value = Py_BuildValue("I", parameter.toUInt());
			break;
		case QVariant::Double:
			value = Py_BuildValue("d", parameter.toDouble());
			break;
		case QVariant::String:
			value = Py_BuildValue("s", parameter.toString().toLatin1().constData());
			break;
		default:
			value = Py_BuildValue("");
			qDebug() << "ERROR: buildPythonParameterHelper, type not supported:" << parameter.typeName();
			break;
		}
	}

	return value;
}

static PyObject* PythonBuildTupleHelper(const QVariant& parameter, bool mustBeTuple)
{
	PyObject* tuple = 0;

	if(!parameter.isNull())
	{
		if(QVariant::List == parameter.type())
		{
			QSequentialIterable parameterIterable = parameter.value<QSequentialIterable>();
			tuple = PyTuple_New(parameterIterable.size());

			int count = 0;
			for(const QVariant& i : parameterIterable)
				PyTuple_SetItem(tuple, count++, PythonBuildTupleHelper(i, false));
		}
		else if(QVariant::Map == parameter.type())
		{
			tuple = PyDict_New();

			QVariantMap map = parameter.value<QVariantMap>();

			for(QVariantMap::const_iterator i = map.begin(); i != map.end(); ++i)
				PyDict_SetItemString(tuple, i.key().toLatin1().constData(), PythonBuildTupleHelper(i.value(), false));
		}
		else
		{
			if(mustBeTuple)
			{
				tuple = PyTuple_New(1);
				PyTuple_SetItem(tuple, 0, PythonBuildValueHelper(parameter));
			}
			else
			{
				tuple = PythonBuildValueHelper(parameter);
			}
		}
	}

	return tuple;
}

static QVariant ExtractPythonValueHelper(PyObject* parameter)
{
	QVariant value;

	if(parameter)
	{
		if(PyBool_Check(parameter))
			value = (Py_False != parameter);
		else if(PyInt_Check(parameter))
            value = (int)PyInt_AsLong(parameter);
		else if(PyFloat_Check(parameter))
			value = PyFloat_AsDouble(parameter);
		else if(PyString_Check(parameter))
			value = PyString_AsString(parameter);
	}

	return value;
}

static QVariant ExtractPythonTupleHelper(PyObject* parameter)
{
	QVariant value;

	if(!parameter)
		return value;

	if(PyTuple_Check(parameter) || PyList_Check(parameter))
	{
		QVariantList tuple;

		PyObject *iterator = PyObject_GetIter(parameter);
		PyObject *item;

		if(!iterator)
			return value;

		while(item = PyIter_Next(iterator))
		{
			tuple.append(ExtractPythonTupleHelper(item));

			Py_DECREF(item);
		}
		Py_DECREF(iterator);

		if(PyErr_Occurred())
			qDebug() << "ERROR: during python tuple/list iteration";

		return tuple;
	}
	else if(PyDict_Check(parameter))
	{
		QVariantMap map;

		PyObject* key;
		PyObject* item;
		Py_ssize_t pos = 0;

		while(PyDict_Next(parameter, &pos, &key, &item))
			map.insert(PyString_AsString(key), ExtractPythonTupleHelper(item));

		if(PyErr_Occurred())
			qDebug() << "ERROR: during python dictionary iteration";

		return map;
	}
	else
	{
		value = ExtractPythonValueHelper(parameter);
	}

	return value;
}

QVariant PythonInteractor::call(const QString& pythonClassName, const QString& funcName, const QVariant& parameter)
{
	QVariant result;

	if(!myScene)
	{
		qDebug() << "ERROR: cannot call Python function on a null scene";
		return result;
	}

	if(!myScene->isReady())
	{
		qDebug() << "ERROR: cannot call Python function on a scene that is still loading";
		return result;
	}

	if(pythonClassName.isEmpty())
	{
		qDebug() << "ERROR: cannot call Python function without a valid python class name";
		return result;
	}

	if(funcName.isEmpty())
	{
		qDebug() << "ERROR: cannot call Python function without a valid python function name";
		return result;
	}

	auto pythonScriptControllerIterator = myPythonScriptControllers.find(pythonClassName);
	if(myPythonScriptControllers.end() == pythonScriptControllerIterator)
	{
		qDebug() << "ERROR: cannot send Python event on an unknown script controller:" << pythonClassName;
		if(myPythonScriptControllers.isEmpty())
		{
			qDebug() << "There is no PythonScriptController";
		}
		else
		{
			qDebug() << "Known PythonScriptController(s):";
			for(const QString& pythonScriptControllerName : myPythonScriptControllers.keys())
				qDebug() << "-" << pythonScriptControllerName;
		}

		return result;
	}

	PythonScriptController* pythonScriptController = pythonScriptControllerIterator.value();
	if(pythonScriptController)
	{
		PyObject* pyCallableObject = PyObject_GetAttrString(pythonScriptController->scriptControllerInstance(), funcName.toLatin1().constData());
		if(!pyCallableObject)
		{
			qDebug() << "ERROR: cannot call Python function without a valid python class and function name";
		}
		else
		{
			PythonScriptFunction pythonScriptFunction(pyCallableObject, true);
			PythonScriptFunctionParameter pythonScriptParameter(PythonBuildTupleHelper(parameter, true), true);
			PythonScriptFunctionResult pythonScriptResult;

			pythonScriptFunction(&pythonScriptParameter, &pythonScriptResult);

			result = ExtractPythonTupleHelper(pythonScriptResult.data());
		}
	}

	return result;
}

void PythonInteractor::sendEvent(const QString& pythonClassName, const QString& eventName, const QVariant& parameter)
{
	if(!myScene)
	{
		qDebug() << "ERROR: cannot send Python event on a null scene";
		return;
	}

	if(!myScene->isReady())
	{
		qDebug() << "ERROR: cannot send Python event on a scene that is still loading";
		return;
	}

	auto pythonScriptControllerIterator = myPythonScriptControllers.find(pythonClassName);
	if(myPythonScriptControllers.end() == pythonScriptControllerIterator)
	{
		qDebug() << "ERROR: cannot send Python event on an unknown script controller:" << pythonClassName;
		if(myPythonScriptControllers.isEmpty())
		{
			qDebug() << "There is no PythonScriptController";
		}
		else
		{
			qDebug() << "Known PythonScriptController(s):";
			for(const QString& pythonScriptControllerName : myPythonScriptControllers.keys())
				qDebug() << "-" << pythonScriptControllerName;
		}

		return;
	}

	PythonScriptController* pythonScriptController = pythonScriptControllerIterator.value();

	PyObject* pyParameter = PythonBuildValueHelper(parameter);
	if(!pyParameter)
		pyParameter = Py_BuildValue("");

	sofa::core::objectmodel::PythonScriptEvent pythonScriptEvent(myScene->sofaSimulation()->GetRoot(), eventName.toLatin1().constData(), pyParameter);
	pythonScriptController->handleEvent(&pythonScriptEvent);
}

void PythonInteractor::sendEventToAll(const QString& eventName, const QVariant& parameter)
{
	for(const QString& pythonClassName : myPythonScriptControllers.keys())
		sendEvent(pythonClassName, eventName, parameter);
}
<|endoftext|>


<commit_before>#include <gtest/gtest.h>

TEST (basic, basic)
{
    ASSERT_TRUE (true);
}<commit_msg>Adding asan trip test case.<commit_after>#include <gtest/gtest.h>

TEST (basic, basic)
{
    ASSERT_TRUE (true);
}

TEST (asan, DISABLED_memory)
{
	uint8_t array [1];
	auto value (array [-0x800000]);
}<|endoftext|>


<commit_before>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/utilities/CDirEntry.cpp,v $
   $Revision: 1.19 $
   $Name:  $
   $Author: shoops $
   $Date: 2006/09/08 14:14:59 $
   End CVS Header */

// Copyright  2005 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc. and EML Research, gGmbH.
// All rights reserved.

#include <sys/types.h>
#include <sys/stat.h>

#ifdef WIN32
# include <io.h>
# include <direct.h>
# define stat _stat
# define S_IFREG _S_IFREG
# define S_IFDIR _S_IFDIR
# define access _access
# define mkdir _mkdir
# define rmdir _rmdir
#else
# include <dirent.h>
# include <unistd.h>
#endif // WIN32

#include "copasi.h"

#include "CDirEntry.h"
#include "utility.h"
#include "CCopasiMessage.h"

#include "randomGenerator/CRandom.h"

#ifdef WIN32
const std::string CDirEntry::Separator = "\\";
#else
const std::string CDirEntry::Separator = "/";
#endif

bool CDirEntry::isFile(const std::string & path)
{
  struct stat st;
  if (stat(utf8ToLocale(path).c_str(), & st) == -1) return false;

#ifdef WIN32
  return ((st.st_mode & S_IFREG) == S_IFREG);
#else
  return S_ISREG(st.st_mode);
#endif
}

bool CDirEntry::isDir(const std::string & path)
{
  struct stat st;
  if (stat(utf8ToLocale(path).c_str(), & st) == -1) return false;

#ifdef WIN32
  return ((st.st_mode & S_IFDIR) == S_IFDIR);
#else
  return S_ISDIR(st.st_mode);
#endif
}

bool CDirEntry::exist(const std::string & path)
{
  struct stat st;
  if (stat(utf8ToLocale(path).c_str(), & st) == -1) return false;

#ifdef WIN32
  return ((st.st_mode & S_IFREG) == S_IFREG ||
          (st.st_mode & S_IFDIR) == S_IFDIR);
#else
  return (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode));
#endif
}

bool CDirEntry::isReadable(const std::string & path)
{return (access(utf8ToLocale(path).c_str(), 0x4) == 0);}

bool CDirEntry::isWritable(const std::string & path)
{return (access(utf8ToLocale(path).c_str(), 0x2) == 0);}

std::string CDirEntry::baseName(const std::string & path)
{
  std::string::size_type start = path.find_last_of(Separator);
#ifdef WIN32 // WIN32 also understands '/' as the separator.
  if (start == std::string::npos)
    start = path.find_last_of("/");
#endif

  if (start == std::string::npos) start = 0;
  else start++; // We do not want the separator.

  std::string::size_type end = path.find_last_of(".");
  if (end == std::string::npos || end < start)
    end = path.length();

  return path.substr(start, end - start);
}

std::string CDirEntry::fileName(const std::string & path)
{
  std::string::size_type start = path.find_last_of(Separator);
#ifdef WIN32 // WIN32 also understands '/' as the separator.
  if (start == std::string::npos)
    start = path.find_last_of("/");
#endif

  if (start == std::string::npos) start = 0;
  else start++; // We do not want the separator.

  return path.substr(start);
}

std::string CDirEntry::dirName(const std::string & path)
{
  if (path == "") return path;
#ifdef WIN32 // WIN32 also understands '/' as the separator.
  std::string::size_type end = path.find_last_of(Separator + "/");
#else
  std::string::size_type end = path.find_last_of(Separator);
#endif

  if (end == path.length() - 1)
    {
#ifdef WIN32 // WIN32 also understands '/' as the separator.
      end = path.find_last_of(Separator + "/", end);
#else
      end = path.find_last_of(Separator, end);
#endif
    }

  if (end == std::string::npos) return "";

  return path.substr(0, end);
}

std::string CDirEntry::suffix(const std::string & path)
{
  std::string::size_type start = path.find_last_of(Separator);
#ifdef WIN32 // WIN32 also understands '/' as the separator.
  if (start == std::string::npos)
    start = path.find_last_of("/");
#endif

  if (start == std::string::npos) start = 0;
  else start++; // We do not want the separator.

  std::string::size_type end = path.find_last_of(".");
  if (end == std::string::npos || end < start)
    return "";
  else
    return path.substr(end);
}

bool CDirEntry::createDir(const std::string & dir,
                          const std::string & parent)
{
  std::string Dir;
  if (parent != "") Dir = parent + Separator;
  Dir += dir;

  // Check whether the directory already exists and is writable.
  if (isDir(Dir) && isWritable(Dir)) return true;

  // Check whether the parent directory exists and is writable.
  if (!isDir(parent) || !isWritable(parent)) return false;

#ifdef WIN32
  return (mkdir(utf8ToLocale(Dir).c_str()) == 0);
#else
  return (mkdir(utf8ToLocale(Dir).c_str(), S_IRWXU | S_IRWXG | S_IRWXO) == 0);
#endif
}

std::string CDirEntry::createTmpName(const std::string & dir,
                                     const std::string & suffix)
{
  CRandom * pRandom = CRandom::createGenerator();

  std::string RandomName;

  do
    {
      RandomName = dir + Separator;
      unsigned C_INT32 Char;

      for (unsigned C_INT32 i = 0; i < 8; i++)
        {
          Char = pRandom->getRandomU(35);
          if (Char < 10)
            RandomName += '0' + Char;
          else
            RandomName += 'a' - 10 + Char;
        }

      RandomName += suffix;
    }
  while (exist(RandomName));

  return RandomName;
}

bool CDirEntry::move(const std::string & from,
                     const std::string & to)
{
  if (!isFile(from)) return false;

  std::string To = to;

  // Check whether To is a directory and append the
  // filename of from
  if (isDir(To))
    To += Separator + fileName(from);

  bool success =
    (rename(utf8ToLocale(from).c_str(), utf8ToLocale(To).c_str()) == 0);

  if (!success)
    {
      {
        std::ifstream in(utf8ToLocale(from).c_str());
        std::ofstream out(utf8ToLocale(To).c_str());

        out << in.rdbuf();

        success = out.good();
      }

      remove(from);
    }

  return success;
}

bool CDirEntry::remove(const std::string & path)
{
  if (isDir(path))
    return (rmdir(utf8ToLocale(path).c_str()) == 0);
  else if (isFile(path))
    return (::remove(utf8ToLocale(path).c_str()) == 0);

  return false;
}

bool CDirEntry::removeFiles(const std::string & pattern,
                            const std::string & path)
{
  bool success = true;
  std::vector< std::string > PatternList;

  PatternList = compilePattern(pattern);

#ifdef WIN32

  // We want the same pattern matching behaviour for all platforms.
  // Therefore, we do not use the MS provided one and list all files instead.
  std::string FilePattern = path + "\\*";

  // Open directory stream and try read info about first entry
  struct _finddata_t Entry;
  C_INT32 hList = _findfirst(utf8ToLocale(FilePattern).c_str(), &Entry);

  if (hList == -1) return success;

  do
    {
      if (match(localeToUtf8(Entry.name), PatternList))
        {
          if (Entry.attrib | _A_NORMAL)
            {
              if (::remove((utf8ToLocale(path + Separator) + Entry.name).c_str()) != 0) success = false;
            }
          else
            {
              if (rmdir((utf8ToLocale(path + Separator) + Entry.name).c_str()) != 0) success = false;
            }
        }
    }
  while (_findnext(hList, &Entry) == 0);

  _findclose(hList);

#else

  DIR * pDir = opendir(utf8ToLocale(path).c_str());
  if (!pDir) return false;

  struct dirent * pEntry;

  while ((pEntry = readdir(pDir)) != NULL)
    {
      if (match(localeToUtf8(pEntry->d_name), PatternList))
        {
          if (isDir(localeToUtf8(pEntry->d_name)))
            {
              if (rmdir((utf8ToLocale(path + Separator) + pEntry->d_name).c_str()) != 0)
                success = false;
            }
          else
            {
              if (::remove((utf8ToLocale(path + Separator) + pEntry->d_name).c_str()) != 0)
                success = false;
            }
        }
    }

  closedir(pDir);

#endif // WIN32

  return success;
}

std::vector< std::string > CDirEntry::compilePattern(const std::string & pattern)
{
  std::string::size_type pos = 0;
  std::string::size_type start = 0;
  std::string::size_type end = 0;
  std::vector< std::string > PatternList;

  while (pos != std::string::npos)
    {
      start = pos;
      pos = pattern.find_first_of("*?", pos);

      end = std::min(pos, pattern.length());

      if (start != end)
        PatternList.push_back(pattern.substr(start, end - start));
      else
        {
          PatternList.push_back(pattern.substr(start, 1));
          pos++;
        }
    };

  return PatternList;
}

bool CDirEntry::match(const std::string & name,
                      const std::vector< std::string > & patternList)
{
  std::vector< std::string >::const_iterator it = patternList.begin();
  std::vector< std::string >::const_iterator end = patternList.end();
  std::string::size_type at = 0;
  std::string::size_type after = 0;

  bool Match = true;
  while (it != end && Match)
    Match = matchInternal(name, *it++, at, after);

  return Match;
}

bool CDirEntry::isRelativePath(const std::string & path)
{
#ifdef WIN32
  return path[1] != ':';
#else
  return path[0] != '/';
#endif
}

bool CDirEntry::makePathRelative(std::string & absolutePath,
                                 const std::string & relativeTo)
{
  if (isRelativePath(absolutePath) ||
      isRelativePath(relativeTo)) return false; // Nothing can be done.

  std:: string RelativeTo = relativeTo;
  if (isFile(RelativeTo)) RelativeTo = dirName(RelativeTo);

  if (!isDir(RelativeTo)) return false;

  unsigned C_INT32 i, imax = std::min(absolutePath.length(), RelativeTo.length());

  for (i = 0; i < imax; i++)
    if (absolutePath[i] != RelativeTo[i]) break;

#ifdef WIN32
  if (i == 0) return false; // A different drive letter we cannot do anything
#endif

  RelativeTo = RelativeTo.substr(i);

  std::string relativePath;
  while (RelativeTo != "")
    {
      relativePath += "../";
      RelativeTo = dirName(RelativeTo);
    }

  if (relativePath != "")
    absolutePath = relativePath + absolutePath.substr(i);
  else
    absolutePath = absolutePath.substr(i + 1);

#ifdef WIN32
  for (i = 0, imax = absolutePath.length(); i < imax; i++)
    if (absolutePath[i] == '\\') absolutePath[i] = '/';
#endif

  return true;
}

bool CDirEntry::makePathAbsolute(std::string & relativePath,
                                 const std::string & absoluteTo)
{
  if (!isRelativePath(relativePath) ||
      isRelativePath(absoluteTo)) return false; // Nothing can be done.

  std:: string AbsoluteTo = absoluteTo;
  if (isFile(AbsoluteTo)) AbsoluteTo = dirName(AbsoluteTo);

  if (!isDir(AbsoluteTo)) return false;

  while (!relativePath.compare(0, 2, ".."))
    {
      AbsoluteTo = dirName(AbsoluteTo);
      relativePath = relativePath.substr(3);
    }

  relativePath = AbsoluteTo + Separator + relativePath;

  return true;
}

bool CDirEntry::matchInternal(const std::string & name,
                              const std::string pattern,
                              std::string::size_type & at,
                              std::string::size_type & after)
{
  bool Match = true;

  switch (pattern[0])
    {
    case '*':
      if (at != std::string::npos)
        {
          after = at;
          at = std::string::npos;
        }
      break;

    case '?':
      if (at != std::string::npos)
        {
          ++at;
          Match = (name.length() >= at);
        }
      else
        {
          ++after;
          Match = (name.length() >= after);
        }
      break;

    default:
      if (at != std::string::npos)
        {
          Match = (name.compare(at, pattern.length(), pattern) == 0);
          at += pattern.length();
        }
      else
        {
          at = name.find(pattern, after);
          Match = (at != std::string::npos);
          at += pattern.length();
        }

      break;
    }

  return Match;
}
<commit_msg>Enhanced isRelative() to deal with an empty string.<commit_after>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/utilities/CDirEntry.cpp,v $
   $Revision: 1.20 $
   $Name:  $
   $Author: shoops $
   $Date: 2006/09/14 18:25:29 $
   End CVS Header */

// Copyright  2005 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc. and EML Research, gGmbH.
// All rights reserved.

#include <sys/types.h>
#include <sys/stat.h>

#ifdef WIN32
# include <io.h>
# include <direct.h>
# define stat _stat
# define S_IFREG _S_IFREG
# define S_IFDIR _S_IFDIR
# define access _access
# define mkdir _mkdir
# define rmdir _rmdir
#else
# include <dirent.h>
# include <unistd.h>
#endif // WIN32

#include "copasi.h"

#include "CDirEntry.h"
#include "utility.h"
#include "CCopasiMessage.h"

#include "randomGenerator/CRandom.h"

#ifdef WIN32
const std::string CDirEntry::Separator = "\\";
#else
const std::string CDirEntry::Separator = "/";
#endif

bool CDirEntry::isFile(const std::string & path)
{
  struct stat st;
  if (stat(utf8ToLocale(path).c_str(), & st) == -1) return false;

#ifdef WIN32
  return ((st.st_mode & S_IFREG) == S_IFREG);
#else
  return S_ISREG(st.st_mode);
#endif
}

bool CDirEntry::isDir(const std::string & path)
{
  struct stat st;
  if (stat(utf8ToLocale(path).c_str(), & st) == -1) return false;

#ifdef WIN32
  return ((st.st_mode & S_IFDIR) == S_IFDIR);
#else
  return S_ISDIR(st.st_mode);
#endif
}

bool CDirEntry::exist(const std::string & path)
{
  struct stat st;
  if (stat(utf8ToLocale(path).c_str(), & st) == -1) return false;

#ifdef WIN32
  return ((st.st_mode & S_IFREG) == S_IFREG ||
          (st.st_mode & S_IFDIR) == S_IFDIR);
#else
  return (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode));
#endif
}

bool CDirEntry::isReadable(const std::string & path)
{return (access(utf8ToLocale(path).c_str(), 0x4) == 0);}

bool CDirEntry::isWritable(const std::string & path)
{return (access(utf8ToLocale(path).c_str(), 0x2) == 0);}

std::string CDirEntry::baseName(const std::string & path)
{
  std::string::size_type start = path.find_last_of(Separator);
#ifdef WIN32 // WIN32 also understands '/' as the separator.
  if (start == std::string::npos)
    start = path.find_last_of("/");
#endif

  if (start == std::string::npos) start = 0;
  else start++; // We do not want the separator.

  std::string::size_type end = path.find_last_of(".");
  if (end == std::string::npos || end < start)
    end = path.length();

  return path.substr(start, end - start);
}

std::string CDirEntry::fileName(const std::string & path)
{
  std::string::size_type start = path.find_last_of(Separator);
#ifdef WIN32 // WIN32 also understands '/' as the separator.
  if (start == std::string::npos)
    start = path.find_last_of("/");
#endif

  if (start == std::string::npos) start = 0;
  else start++; // We do not want the separator.

  return path.substr(start);
}

std::string CDirEntry::dirName(const std::string & path)
{
  if (path == "") return path;
#ifdef WIN32 // WIN32 also understands '/' as the separator.
  std::string::size_type end = path.find_last_of(Separator + "/");
#else
  std::string::size_type end = path.find_last_of(Separator);
#endif

  if (end == path.length() - 1)
    {
#ifdef WIN32 // WIN32 also understands '/' as the separator.
      end = path.find_last_of(Separator + "/", end);
#else
      end = path.find_last_of(Separator, end);
#endif
    }

  if (end == std::string::npos) return "";

  return path.substr(0, end);
}

std::string CDirEntry::suffix(const std::string & path)
{
  std::string::size_type start = path.find_last_of(Separator);
#ifdef WIN32 // WIN32 also understands '/' as the separator.
  if (start == std::string::npos)
    start = path.find_last_of("/");
#endif

  if (start == std::string::npos) start = 0;
  else start++; // We do not want the separator.

  std::string::size_type end = path.find_last_of(".");
  if (end == std::string::npos || end < start)
    return "";
  else
    return path.substr(end);
}

bool CDirEntry::createDir(const std::string & dir,
                          const std::string & parent)
{
  std::string Dir;
  if (parent != "") Dir = parent + Separator;
  Dir += dir;

  // Check whether the directory already exists and is writable.
  if (isDir(Dir) && isWritable(Dir)) return true;

  // Check whether the parent directory exists and is writable.
  if (!isDir(parent) || !isWritable(parent)) return false;

#ifdef WIN32
  return (mkdir(utf8ToLocale(Dir).c_str()) == 0);
#else
  return (mkdir(utf8ToLocale(Dir).c_str(), S_IRWXU | S_IRWXG | S_IRWXO) == 0);
#endif
}

std::string CDirEntry::createTmpName(const std::string & dir,
                                     const std::string & suffix)
{
  CRandom * pRandom = CRandom::createGenerator();

  std::string RandomName;

  do
    {
      RandomName = dir + Separator;
      unsigned C_INT32 Char;

      for (unsigned C_INT32 i = 0; i < 8; i++)
        {
          Char = pRandom->getRandomU(35);
          if (Char < 10)
            RandomName += '0' + Char;
          else
            RandomName += 'a' - 10 + Char;
        }

      RandomName += suffix;
    }
  while (exist(RandomName));

  return RandomName;
}

bool CDirEntry::move(const std::string & from,
                     const std::string & to)
{
  if (!isFile(from)) return false;

  std::string To = to;

  // Check whether To is a directory and append the
  // filename of from
  if (isDir(To))
    To += Separator + fileName(from);

  bool success =
    (rename(utf8ToLocale(from).c_str(), utf8ToLocale(To).c_str()) == 0);

  if (!success)
    {
      {
        std::ifstream in(utf8ToLocale(from).c_str());
        std::ofstream out(utf8ToLocale(To).c_str());

        out << in.rdbuf();

        success = out.good();
      }

      remove(from);
    }

  return success;
}

bool CDirEntry::remove(const std::string & path)
{
  if (isDir(path))
    return (rmdir(utf8ToLocale(path).c_str()) == 0);
  else if (isFile(path))
    return (::remove(utf8ToLocale(path).c_str()) == 0);

  return false;
}

bool CDirEntry::removeFiles(const std::string & pattern,
                            const std::string & path)
{
  bool success = true;
  std::vector< std::string > PatternList;

  PatternList = compilePattern(pattern);

#ifdef WIN32

  // We want the same pattern matching behaviour for all platforms.
  // Therefore, we do not use the MS provided one and list all files instead.
  std::string FilePattern = path + "\\*";

  // Open directory stream and try read info about first entry
  struct _finddata_t Entry;
  C_INT32 hList = _findfirst(utf8ToLocale(FilePattern).c_str(), &Entry);

  if (hList == -1) return success;

  do
    {
      if (match(localeToUtf8(Entry.name), PatternList))
        {
          if (Entry.attrib | _A_NORMAL)
            {
              if (::remove((utf8ToLocale(path + Separator) + Entry.name).c_str()) != 0) success = false;
            }
          else
            {
              if (rmdir((utf8ToLocale(path + Separator) + Entry.name).c_str()) != 0) success = false;
            }
        }
    }
  while (_findnext(hList, &Entry) == 0);

  _findclose(hList);

#else

  DIR * pDir = opendir(utf8ToLocale(path).c_str());
  if (!pDir) return false;

  struct dirent * pEntry;

  while ((pEntry = readdir(pDir)) != NULL)
    {
      if (match(localeToUtf8(pEntry->d_name), PatternList))
        {
          if (isDir(localeToUtf8(pEntry->d_name)))
            {
              if (rmdir((utf8ToLocale(path + Separator) + pEntry->d_name).c_str()) != 0)
                success = false;
            }
          else
            {
              if (::remove((utf8ToLocale(path + Separator) + pEntry->d_name).c_str()) != 0)
                success = false;
            }
        }
    }

  closedir(pDir);

#endif // WIN32

  return success;
}

std::vector< std::string > CDirEntry::compilePattern(const std::string & pattern)
{
  std::string::size_type pos = 0;
  std::string::size_type start = 0;
  std::string::size_type end = 0;
  std::vector< std::string > PatternList;

  while (pos != std::string::npos)
    {
      start = pos;
      pos = pattern.find_first_of("*?", pos);

      end = std::min(pos, pattern.length());

      if (start != end)
        PatternList.push_back(pattern.substr(start, end - start));
      else
        {
          PatternList.push_back(pattern.substr(start, 1));
          pos++;
        }
    };

  return PatternList;
}

bool CDirEntry::match(const std::string & name,
                      const std::vector< std::string > & patternList)
{
  std::vector< std::string >::const_iterator it = patternList.begin();
  std::vector< std::string >::const_iterator end = patternList.end();
  std::string::size_type at = 0;
  std::string::size_type after = 0;

  bool Match = true;
  while (it != end && Match)
    Match = matchInternal(name, *it++, at, after);

  return Match;
}

bool CDirEntry::isRelativePath(const std::string & path)
{
#ifdef WIN32
  return (path.length() < 2 || path[1] != ':');
#else
  return (path.length() < 1 || path[0] != '/');
#endif
}

bool CDirEntry::makePathRelative(std::string & absolutePath,
                                 const std::string & relativeTo)
{
  if (isRelativePath(absolutePath) ||
      isRelativePath(relativeTo)) return false; // Nothing can be done.

  std:: string RelativeTo = relativeTo;
  if (isFile(RelativeTo)) RelativeTo = dirName(RelativeTo);

  if (!isDir(RelativeTo)) return false;

  unsigned C_INT32 i, imax = std::min(absolutePath.length(), RelativeTo.length());

  for (i = 0; i < imax; i++)
    if (absolutePath[i] != RelativeTo[i]) break;

#ifdef WIN32
  if (i == 0) return false; // A different drive letter we cannot do anything
#endif

  RelativeTo = RelativeTo.substr(i);

  std::string relativePath;
  while (RelativeTo != "")
    {
      relativePath += "../";
      RelativeTo = dirName(RelativeTo);
    }

  if (relativePath != "")
    absolutePath = relativePath + absolutePath.substr(i);
  else
    absolutePath = absolutePath.substr(i + 1);

#ifdef WIN32
  for (i = 0, imax = absolutePath.length(); i < imax; i++)
    if (absolutePath[i] == '\\') absolutePath[i] = '/';
#endif

  return true;
}

bool CDirEntry::makePathAbsolute(std::string & relativePath,
                                 const std::string & absoluteTo)
{
  if (!isRelativePath(relativePath) ||
      isRelativePath(absoluteTo)) return false; // Nothing can be done.

  std:: string AbsoluteTo = absoluteTo;
  if (isFile(AbsoluteTo)) AbsoluteTo = dirName(AbsoluteTo);

  if (!isDir(AbsoluteTo)) return false;

  while (!relativePath.compare(0, 2, ".."))
    {
      AbsoluteTo = dirName(AbsoluteTo);
      relativePath = relativePath.substr(3);
    }

  relativePath = AbsoluteTo + Separator + relativePath;

#ifdef WIN32
  unsigned C_INT32 i, imax;
  for (i = 0, imax = relativePath.length(); i < imax; i++)
    if (relativePath[i] == '\\') relativePath[i] = '/';
#endif

  return true;
}

bool CDirEntry::matchInternal(const std::string & name,
                              const std::string pattern,
                              std::string::size_type & at,
                              std::string::size_type & after)
{
  bool Match = true;

  switch (pattern[0])
    {
    case '*':
      if (at != std::string::npos)
        {
          after = at;
          at = std::string::npos;
        }
      break;

    case '?':
      if (at != std::string::npos)
        {
          ++at;
          Match = (name.length() >= at);
        }
      else
        {
          ++after;
          Match = (name.length() >= after);
        }
      break;

    default:
      if (at != std::string::npos)
        {
          Match = (name.compare(at, pattern.length(), pattern) == 0);
          at += pattern.length();
        }
      else
        {
          at = name.find(pattern, after);
          Match = (at != std::string::npos);
          at += pattern.length();
        }

      break;
    }

  return Match;
}
<|endoftext|>


<commit_before><commit_msg>[core] fix clang-tidy in TApplication (#7412)<commit_after><|endoftext|>