Beispiel #1
0
void
GuiAppInstance::createMainWindow()
{
    boost::shared_ptr<GuiAppInstance> thisShared = toGuiAppInstance( shared_from_this() );
    assert(thisShared);
    _imp->_gui = new Gui(thisShared);
    _imp->_gui->createGui();
    setMainWindowPointer(_imp->_gui);
}
Beispiel #2
0
AppInstancePtr
Gui::openProjectInternal(const std::string & absoluteFileName,
                         bool attemptToLoadAutosave)
{
    QFileInfo file( QString::fromUtf8( absoluteFileName.c_str() ) );

    if ( !file.exists() ) {
        return AppInstancePtr();
    }
    QString fileUnPathed = file.fileName();
    QString path = file.path() + QLatin1Char('/');


    int openedProject = appPTR->isProjectAlreadyOpened(absoluteFileName);

    if (openedProject != -1) {
        AppInstancePtr instance = appPTR->getAppInstance(openedProject);
        if (instance) {
            GuiAppInstancePtr guiApp = toGuiAppInstance(instance);
            if (guiApp) {
                guiApp->getGui()->activateWindow();

                return instance;
            }
        }
    }

    AppInstancePtr ret;
    ProjectPtr project = getApp()->getProject();
    ///if the current graph has no value, just load the project in the same window
    if ( project->isGraphWorthLess() ) {
        bool ok = project->loadProject( path, fileUnPathed, false, attemptToLoadAutosave);
        if (ok) {
            ret = _imp->_appInstance.lock();
        }
    } else {
        CLArgs cl;
        AppInstancePtr newApp = appPTR->newAppInstance(cl, false);
        bool ok  = newApp->getProject()->loadProject( path, fileUnPathed, false, attemptToLoadAutosave);
        if (ok) {
            ret = newApp;
        }
    }

    QSettings settings;
    QStringList recentFiles = settings.value( QString::fromUtf8("recentFileList") ).toStringList();
    recentFiles.removeAll( QString::fromUtf8( absoluteFileName.c_str() ) );
    recentFiles.prepend( QString::fromUtf8( absoluteFileName.c_str() ) );
    while (recentFiles.size() > NATRON_MAX_RECENT_FILES) {
        recentFiles.removeLast();
    }

    settings.setValue(QString::fromUtf8("recentFileList"), recentFiles);
    appPTR->updateAllRecentFileMenus();

    return ret;
} // Gui::openProjectInternal
void
GuiApplicationManagerPrivate::addStandardKeybind(const std::string & grouping,
                                                 const std::string & id,
                                                 const std::string & description,
                                                 QKeySequence::StandardKey key,
                                                 const Qt::KeyboardModifiers & fallbackmodifiers,
                                                 Qt::Key fallbacksymbol)
{
    QString groupingStr = QString::fromUtf8( grouping.c_str() );
    QString idStr = QString::fromUtf8( id.c_str() );
    AppShortcuts::iterator foundGroup = _actionShortcuts.find(groupingStr);

    if ( foundGroup != _actionShortcuts.end() ) {
        GroupShortcuts::iterator foundAction = foundGroup->second.find(idStr);
        if ( foundAction != foundGroup->second.end() ) {
            return;
        }
    }

    Qt::KeyboardModifiers modifiers;
    Qt::Key symbol;

    extractKeySequence(QKeySequence(key), modifiers, symbol);

    if (symbol == (Qt::Key)0) {
        symbol = fallbacksymbol;
        modifiers = fallbackmodifiers;
    }

    KeyBoundAction* kA = new KeyBoundAction;
    kA->grouping = groupingStr;
    kA->description = QString::fromUtf8( description.c_str() );
    kA->defaultModifiers.push_back(modifiers);
    kA->modifiers.push_back(modifiers);
    kA->defaultShortcut.push_back(symbol);
    kA->currentShortcut.push_back(symbol);
    if ( foundGroup != _actionShortcuts.end() ) {
        foundGroup->second.insert( std::make_pair(idStr, kA) );
    } else {
        GroupShortcuts group;
        group.insert( std::make_pair(idStr, kA) );
        _actionShortcuts.insert( std::make_pair(groupingStr, group) );
    }

    GuiAppInstancePtr app = toGuiAppInstance( _publicInterface->getTopLevelInstance() );
    if (app) {
        app->getGui()->addShortcut(kA);
    }
}
void
GuiApplicationManagerPrivate::addKeybindInternal(const QString & grouping,
                                                 const QString & id,
                                                 const QString & description,
                                                 const std::list<Qt::KeyboardModifiers>& modifiersList,
                                                 const std::list<Qt::Key>& symbolsList,
                                                 const Qt::KeyboardModifiers& modifiersMask)
{
    AppShortcuts::iterator foundGroup = _actionShortcuts.find(grouping);

    if ( foundGroup != _actionShortcuts.end() ) {
        GroupShortcuts::iterator foundAction = foundGroup->second.find(id);
        if ( foundAction != foundGroup->second.end() ) {
            return;
        }
    }
    KeyBoundAction* kA = new KeyBoundAction;

    kA->grouping = grouping;
    kA->description = description;

    assert( modifiersList.size() == symbolsList.size() );
    std::list<Qt::KeyboardModifiers>::const_iterator mit = modifiersList.begin();
    for (std::list<Qt::Key>::const_iterator it = symbolsList.begin(); it != symbolsList.end(); ++it, ++mit) {
        if ( (*it) != (Qt::Key)0 ) {
            kA->defaultModifiers.push_back(*mit);
            kA->modifiers.push_back(*mit);
            kA->defaultShortcut.push_back(*it);
            kA->currentShortcut.push_back(*it);
        }
    }

    kA->ignoreMask = modifiersMask;

    kA->actionID = id;
    if ( foundGroup != _actionShortcuts.end() ) {
        foundGroup->second.insert( std::make_pair(id, kA) );
    } else {
        GroupShortcuts group;
        group.insert( std::make_pair(id, kA) );
        _actionShortcuts.insert( std::make_pair(grouping, group) );
    }

    GuiAppInstancePtr app = toGuiAppInstance( _publicInterface->getTopLevelInstance() );
    if (app) {
        app->getGui()->addShortcut(kA);
    }
}
Beispiel #5
0
GuiApp*
PyGuiApplication::getGuiInstance(int idx) const
{
    AppInstancePtr app = appPTR->getAppInstance(idx);

    if (!app) {
        return 0;
    }
    GuiAppInstancePtr guiApp = toGuiAppInstance(app);
    if (!guiApp) {
        return 0;
    }


    // First, try to re-use an existing Effect object that was created for this node.
    // If not found, create one.
    std::stringstream ss;
    ss << kPythonTmpCheckerVariable << " = " << app->getAppIDString() ;
    std::string script = ss.str();
    bool ok = NATRON_PYTHON_NAMESPACE::interpretPythonScript(script, 0, 0);

    // Clear errors if our call to interpretPythonScript failed, we don't want the
    // calling function to fail aswell.
    PyErr_Clear();
    if (ok) {
        PyObject* pyApp = 0;
        PyObject* mainModule = NATRON_PYTHON_NAMESPACE::getMainModule();
        if ( PyObject_HasAttrString(mainModule, kPythonTmpCheckerVariable) ) {
            pyApp = PyObject_GetAttrString(mainModule, kPythonTmpCheckerVariable);
            if (pyApp == Py_None) {
                pyApp = 0;
            }
        }
        GuiApp* cppApp = 0;
        if (pyApp && Shiboken::Object::isValid(pyApp)) {
            cppApp = (GuiApp*)Shiboken::Conversions::cppPointer(SbkNatronGuiTypes[SBK_GUIAPP_IDX], (SbkObject*)pyApp);
        }
        NATRON_PYTHON_NAMESPACE::interpretPythonScript("del " kPythonTmpCheckerVariable, 0, 0);

        if (cppApp) {
            return cppApp;
        }
    }


    return new GuiApp(guiApp);
}
void
GuiApplicationManagerPrivate::addMouseShortcut(const std::string & grouping,
                                               const std::string & id,
                                               const std::string & description,
                                               const Qt::KeyboardModifiers & modifiers,
                                               Qt::MouseButton button)
{
    QString groupingStr = QString::fromUtf8( grouping.c_str() );
    QString idStr = QString::fromUtf8( id.c_str() );
    AppShortcuts::iterator foundGroup = _actionShortcuts.find(groupingStr);

    if ( foundGroup != _actionShortcuts.end() ) {
        GroupShortcuts::iterator foundAction = foundGroup->second.find(idStr);
        if ( foundAction != foundGroup->second.end() ) {
            return;
        }
    }
    MouseAction* mA = new MouseAction;

    mA->grouping = groupingStr;
    mA->description = QString::fromUtf8( description.c_str() );
    mA->defaultModifiers.push_back(modifiers);
    mA->actionID = idStr;
    if ( modifiers & (Qt::AltModifier | Qt::MetaModifier) ) {
        qDebug() << "Warning: mouse shortcut " << groupingStr << '/' << description.c_str() << '(' << idStr << ')' << " uses the Alt or Meta modifier, which is reserved for three-button mouse emulation. Fix this ASAP.";
    }
    mA->modifiers.push_back(modifiers);
    mA->button = button;

    ///Mouse shortcuts are not editable.
    mA->editable = false;

    if ( foundGroup != _actionShortcuts.end() ) {
        foundGroup->second.insert( std::make_pair(idStr, mA) );
    } else {
        GroupShortcuts group;
        group.insert( std::make_pair(idStr, mA) );
        _actionShortcuts.insert( std::make_pair(groupingStr, group) );
    }

    GuiAppInstancePtr app = toGuiAppInstance( _publicInterface->getTopLevelInstance() );
    if (app) {
        app->getGui()->addShortcut(mA);
    }
}
Beispiel #7
0
void
GuiAppInstance::loadInternal(const CLArgs& cl,
                             bool makeEmptyInstance)
{
    if (getAppID() == 0) {
        appPTR->setLoadingStatus( tr("Creating user interface...") );
    }

    try {
        declareCurrentAppVariable_Python();
    } catch (const std::exception& e) {
        throw std::runtime_error( e.what() );
    }

    boost::shared_ptr<GuiAppInstance> thisShared = toGuiAppInstance( shared_from_this() );
    assert(thisShared);
    _imp->_gui = new Gui(thisShared);
    _imp->_gui->createGui();

    printAutoDeclaredVariable(_imp->declareAppAndParamsString);

    ///if the app is interactive, build the plugins toolbuttons from the groups we extracted off the plugins.
    const std::list<PluginGroupNodePtr> & _toolButtons = appPTR->getTopLevelPluginsToolButtons();
    for (std::list<PluginGroupNodePtr  >::const_iterator it = _toolButtons.begin(); it != _toolButtons.end(); ++it) {
        _imp->findOrCreateToolButtonRecursive(*it);
    }
    _imp->_gui->sortAllPluginsToolButtons();

    Q_EMIT pluginsPopulated();

    ///show the gui
    _imp->_gui->show();


    SettingsPtr nSettings = appPTR->getCurrentSettings();
    QObject::connect( getProject().get(), SIGNAL(formatChanged(Format)), this, SLOT(projectFormatChanged(Format)) );

    {
        QSettings settings( QString::fromUtf8(NATRON_ORGANIZATION_NAME), QString::fromUtf8(NATRON_APPLICATION_NAME) );
        if ( !settings.contains( QString::fromUtf8("checkForUpdates") ) ) {
            StandardButtonEnum reply = Dialogs::questionDialog(tr("Updates").toStdString(),
                                                               tr("Do you want %1 to check for updates "
                                                                  "on launch of the application?").arg( QString::fromUtf8(NATRON_APPLICATION_NAME) ).toStdString(), false);
            bool checkForUpdates = reply == eStandardButtonYes;
            nSettings->setCheckUpdatesEnabled(checkForUpdates);
        }

        if ( nSettings->isCheckForUpdatesEnabled() ) {
            appPTR->setLoadingStatus( tr("Checking if updates are available...") );
            checkForNewVersion();
        }
    }

    if ( nSettings->isDefaultAppearanceOutdated() ) {
        StandardButtonEnum reply = Dialogs::questionDialog(tr("Appearance").toStdString(),
                                                           tr("The default appearance of %1 changed since last version.\n"
                                                              "Would you like to use the new default appearance?").arg( QString::fromUtf8(NATRON_APPLICATION_NAME) ).toStdString(), false);
        if (reply == eStandardButtonYes) {
            nSettings->restoreDefaultAppearance();
        }
    }

    /// Create auto-save dir if it does not exists
    QDir dir = Project::autoSavesDir();
    dir.mkpath( QString::fromUtf8(".") );


    if (getAppID() == 0) {
        QString missingOpenGLError;
        if ( !appPTR->hasOpenGLForRequirements(eOpenGLRequirementsTypeViewer, &missingOpenGLError) ) {
            throw std::runtime_error( missingOpenGLError.toStdString() );
        }

        appPTR->getCurrentSettings()->doOCIOStartupCheckIfNeeded();

        if ( !appPTR->isShorcutVersionUpToDate() ) {
            StandardButtonEnum reply = questionDialog(tr("Shortcuts").toStdString(),
                                                      tr("Default shortcuts for %1 have changed, "
                                                         "would you like to set them to their defaults?\n"
                                                         "Clicking no will keep the old shortcuts hence if a new shortcut has been "
                                                         "set to something else than an empty shortcut you will not benefit of it.").arg( QString::fromUtf8(NATRON_APPLICATION_NAME) ).toStdString(),
                                                      false,
                                                      StandardButtons(eStandardButtonYes | eStandardButtonNo),
                                                      eStandardButtonNo);
            if (reply == eStandardButtonYes) {
                appPTR->restoreDefaultShortcuts();
            }
        }
    }

    if (makeEmptyInstance) {
        return;
    }

    /// If this is the first instance of the software, try to load an autosave
    if ( (getAppID() == 0) && cl.getScriptFilename().isEmpty() ) {
        if ( findAndTryLoadUntitledAutoSave() ) {
            ///if we successfully loaded an autosave ignore the specified project in the launch args.
            return;
        }
    }


    QFileInfo info( cl.getScriptFilename() );

    if ( cl.getScriptFilename().isEmpty() || !info.exists() ) {
        getProject()->createViewer();
        execOnProjectCreatedCallback();

        const QString& imageFile = cl.getImageFilename();
        if ( !imageFile.isEmpty() ) {
            handleFileOpenEvent( imageFile.toStdString() );
        }
    } else {
        if ( info.suffix() == QString::fromUtf8("py") ) {
            appPTR->setLoadingStatus( tr("Loading script: ") + cl.getScriptFilename() );

            ///If this is a Python script, execute it
            loadPythonScript(info);
            execOnProjectCreatedCallback();
        } else if ( info.suffix() == QString::fromUtf8(NATRON_PROJECT_FILE_EXT) ) {
            ///Otherwise just load the project specified.
            QString name = info.fileName();
            QString path = info.path();
            Global::ensureLastPathSeparator(path);
            appPTR->setLoadingStatus(tr("Loading project: ") + path + name);
            getProject()->loadProject(path, name);
            ///remove any file open event that might have occured
            appPTR->setFileToOpen( QString() );
        } else {
            Dialogs::errorDialog( tr("Invalid file").toStdString(),
                                  tr("%1 only accepts python scripts or .ntp project files").arg( QString::fromUtf8(NATRON_APPLICATION_NAME) ).toStdString() );
            execOnProjectCreatedCallback();
        }
    }

    const QString& extraOnProjectCreatedScript = cl.getDefaultOnProjectLoadedScript();
    if ( !extraOnProjectCreatedScript.isEmpty() ) {
        QFileInfo cbInfo(extraOnProjectCreatedScript);
        if ( cbInfo.exists() ) {
            loadPythonScript(cbInfo);
        }
    }
} // load