Невозможно принять удаление файла в OSX Dock или дважды щелкнуть файл и открыть его в программе - PullRequest
0 голосов
/ 03 февраля 2019

Я пытаюсь принять удаление файла в OSX Dock, или программа дважды щелкает и открывает «зарегистрированное» расширение файла, но не увенчалась успехом в том, что в принципе должно быть простым делом.Я много исследовал переполнение стека и другие места в Интернете, но не нашел решения.

Программа написана на C ++ с использованием Qt 5.3 для Mac OSX 10.11.6.

В основной программекод (Test.cpp), я определил фильтр событий, где событие QFileOpenEvent срабатывает, но событие не передается в MainWindow.Тем не менее, события перетаскивания передаются правильно.

В MainWindow.cpp я определил еще один фильтр событий.Он правильно открывает мой файл, когда он перетаскивается в собственно MainWindow, но никогда не получает событие открытия файла из Test.cpp, когда файл перетаскивается в Dock или дважды щелкается из Finder.

Я неЯ не полностью понимаю этот механизм, поэтому любая помощь будет принята с благодарностью.Я, должно быть, делаю что-то в корне неправильно.

Код, которому нужно следовать: Test.cpp, MainWindow.cpp, Info.plist (где, я считаю, я правильно зарегистрировал расширение моего типа файлов.

int main (int argc, char *argv[])
{
    QApplication    qappl   (argc, argv);
    QDesktopWidget  qdesk;
    QRect           qrect;
    MainWindow      qwin;

    Test    *poEventFilter = new Test;
    qappl.installEventFilter((QObject *)poEventFilter);

    qwin.show();
    qwin.setWindowOpacity(0.0);
    qrect = qdesk.availableGeometry(-1);
    qwin.move((qrect.width() - qwin.width()) / 2.0, (qrect.height() - qwin.height()) / 2.0);
    qwin.setWindowOpacity(1.0);

    return qappl.exec();
}

Test::Test (void)
{
    QApplication::setOrganizationName("XYZ");
    QApplication::setApplicationName("Test");
    QApplication::setApplicationVersion("v1.0.0");

    return;
}

Test::~Test (void)
{
    return;
}

void Test::dragEnterEvent (QDragEnterEvent *pqevent)
{
    if (pqevent->mimeData()->hasUrls())
        pqevent->acceptProposedAction();

    return;
}

void Test::dragMoveEvent (QDragMoveEvent *pqevent)
{
    if (pqevent->mimeData()->hasUrls())
        pqevent->acceptProposedAction();

    return;
}

void Test::dropEvent (QDropEvent *pqevent)
{
    if (pqevent->mimeData()->hasUrls())
        pqevent->acceptProposedAction();

    return;
}

bool Test::eventFilter (QObject *pqobj, QEvent *pqevent)
{
    if (pqevent->type() == QEvent::FileOpen)
    {
        QFileOpenEvent *pqopenEvent = static_cast<QFileOpenEvent *>(pqevent);
        qDebug() << "Test FileOpen:" << pqopenEvent->file();
    }
    else
    if (pqevent->type() == QEvent::DragEnter)
        qDebug() << "Test DragEnter";
    else
    if (pqevent->type() == QEvent::DragMove)
        qDebug() << "Test DragMove";
    else
    if (pqevent->type() == QEvent::Drop)
        qDebug() << "Test Drop";

    return QObject::eventFilter(pqobj, pqevent);
}

Вот MainWindow.cpp, где определен другой фильтр событий.

MainWindow::MainWindow (QWidget *pqwgtParent) : 
    QMainWindow(pqwgtParent),
    gpUi(new Ui::MainWindow)
{
    this->setAcceptDrops(true);
    this->installEventFilter(this);

    gpUi->setupUi(this);

    createMenus();
    createToolBars();
    createStatusBar();
    connectWidgets();
    setValidators();
    initWindow();
}

void MainWindow::dragEnterEvent (QDragEnterEvent *pqevent)
{
    if (pqevent->mimeData()->hasUrls())
        pqevent->acceptProposedAction();

    return;
}

void MainWindow::dragMoveEvent (QDragMoveEvent *pqevent)
{
    if (pqevent->mimeData()->hasUrls())
        pqevent->acceptProposedAction();

    return;
}

void MainWindow::dropEvent (QDropEvent *pqevent)
{
    if (pqevent->mimeData()->hasUrls())
        pqevent->acceptProposedAction();

    return;
}

bool MainWindow::eventFilter (QObject *pqobj, QEvent *pqevent)
{
    QList<QUrl> qurlList;
    QObject     *pqobj_;
    QString     qstFileSpec;
    int         i;

    pqobj_ = pqobj;     // Satisfy the compiler

    if (pqevent->type() == QEvent::DragEnter)
    {
        qout << "MainWindow DragEnter Event" << endl;
        pqevent->accept();
    }

    else
    if (pqevent->type() == QEvent::DragMove)
    {
        qout << "MainWindow DragMove Event" << endl;
        pqevent->accept();
    }

    else
    if (pqevent->type() == QEvent::Drop)
    {
        qout << "MainWindow Drop Event" << endl;
        pqevent->accept();

        const QMimeData *pqmimeData = static_cast<QDropEvent *>(pqevent)->mimeData();

        if (pqmimeData->hasUrls())
        {
            qurlList = pqmimeData->urls();

            for (i = 0; i < qurlList.size(); i++)
            {
                qstFileSpec = qurlList.at(i).toLocalFile();
                if (qstFileSpec.endsWith(".xyz"))
                {
                    qout << "MainWindow FileSpec: " << qstFileSpec << endl;
                    doOpenTestFile(qstFileSpec);
                }
            }
        }
    }

    else
    if (pqevent->type() == QEvent::FileOpen)
    {
        qout << "MainWindow FileOpen Event" << endl;
        pqevent->accept();

        QFileOpenEvent *pqopenEvent = static_cast<QFileOpenEvent *>(pqevent);

        qstFileSpec = pqopenEvent->file();
        qout << "MainWindow FileSpec: " << qstFileSpec << endl;
        doOpenTestFile(qstFileSpec);
    }

    else
        return(false);

    return(false);
}

Наконец, вот Info.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>NSPrincipalClass</key>
    <string>NSApplication</string>
    <key>CFBundleIconFile</key>
    <string>Test.icns</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleGetInfoString</key>
    <string>Created by Qt/QMake</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleExecutable</key>
    <string>Test</string>
    <key>CFBundleIdentifier</key>
    <string>ninjei.xyz.Test</string>
    <key>NOTE</key>
    <string>This file was generated by Qt/QMake.</string>
    <key>CFBundleDocumentTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeName</key>
            <string>Test</string>
            <key>CFBundleTypeExtensions</key>
            <array>
                <string>xyz</string>
            </array>
            <key>CFBundleTypeIconFile</key>
            <string>Test.icns</string>
            <key>CFBundleTypeName</key>
            <string>Test file</string>
            <key>CFBundleTypeRole</key>
            <string>Editor</string>
            <key>LSHandlerRank</key>
            <string>Owner</string>
            <key>LSTypeIsPackage</key>
            <false />
            <key>NSPersistentStoreTypeKey</key>
            <string>Binary</string>
        </dict>
    </array>
</dict>
</plist>

В качестве второго (гораздо менее важного) вопроса,есть ли способ добавить qmake в часть CFBundleDocumentTypes через Test.pro?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...