void IPProcessList::addProcessItem(QString processID, QString text, QString keywords, IPLProcess::IPLProcessCategory category)
{
    // load icon from png file and add background color based on the process category

    QFileInfo iconFile(_mainWindow->processIconPath(processID));

    if(!iconFile.exists())
    {
        iconFile = QFileInfo(_mainWindow->processIconPath("Plugin"));
    }

    QPixmap transparentIcon(iconFile.absoluteFilePath());
    QPixmap finalIcon(25,25);

    QPainter painter(&finalIcon);
    painter.fillRect(0,0,25,25,_categoryColors.at(category));
    painter.drawPixmap(0,0,25,25,transparentIcon);

    QListWidgetItem* newItem = new QListWidgetItem(finalIcon, text);
    newItem->setToolTip(processID);
    newItem->setStatusTip(keywords);
    newItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled);

    addItem(newItem);
}
String APP::desktopText()     { return String("[Desktop Entry]\r\n")                                  +
                                              "Name=AvCaster\r\n"                                     +
                                              "GenericName=\r\n"                                      +
                                              "Comment=Desktop, webcam, and audio streaming tool\r\n" +
                                              "Categories=AudioVideo;\r\n"                            +
                                              "Exec=" + binFile() .getFullPathName() + "\r\n" +       +
                                              "Icon=" + iconFile().getFullPathName() + "\r\n" +       +
                                              "StartupNotify=true\r\n"                                +
                                              "Terminal=false\r\n"                                    +
                                              "Type=Application\r\n"                                  ; }
SchemeGuiHeader::SchemeGuiHeader(QString schemeFile)
{
	QDomElement root = MidiMappingGui::openXMLFile(schemeFile, "schemeGuiHeader");

	if (root.isNull())
		return;
	m_id = QFileInfo(schemeFile).absoluteFilePath();
	m_description = root.firstChildElement(SCHEME_DESCTIPTION).text();
	QFileInfo iconFile(root.firstChildElement(SCHEME_ICON48).text());
	if (iconFile.exists())
		m_iconFilePath = iconFile.absoluteFilePath();
}
Exemple #4
0
void buddyPicture::saveAvatar(quint16 length)
{
	quint8 uinLength = convertToInt8(buffer->read(1));
	length -= 1;
	
	
	QString uin = QString::fromUtf8(buffer->read(uinLength));
	length -= uinLength;
	
	
	buffer->read(4);
	
	length -= 4;
	
	QByteArray hash = buffer->read(16);
	
	length -= 16;
	
	buffer->read(21);
	
	length -= 21;
	
	quint16 iconLength = convertToInt16(buffer->read(2));
	length -= 2;
	
	if ( iconLength )
	{
                QSettings settings(QSettings::NativeFormat, QSettings::UserScope, "qutim/qutim."+m_profile_name+"/ICQ."+m_mine_uin, "contactlist");
		settings.beginGroup(uin);
		settings.setValue("iconhash", hash.toHex());
		settings.endGroup();
		
		QString iconPath = settings.fileName().section('/', 0, -3) + "/icqicons";
		
		QDir iconDir(iconPath);
			if ( !iconDir.exists() )
				iconDir.mkpath(iconPath);
		
		QFile iconFile(iconPath + "/" + hash.toHex());
		
		
		if ( iconFile.open(QIODevice::WriteOnly) )
		{
			iconFile.write(buffer->read(iconLength));
		}
			
		emit updateAvatar(uin, hash);
	}
	length -= iconLength;
	
	if ( length )
		buffer->read(length);
}
Exemple #5
0
wxBitmap t4p::AutoCompleteImageAsset(wxString imageName) {
    if (!wxImage::FindHandler(wxBITMAP_TYPE_XPM)) {
        wxImage::AddHandler(new wxXPMHandler);
    }
    wxFileName asset = AssetRootDir();
    asset.AppendDir(wxT("auto_complete"));
    wxFileName iconFile(asset.GetPath(), imageName + wxT(".xpm"));

    wxASSERT(iconFile.IsOk());
    wxBitmap bitmap;
    bool loaded = bitmap.LoadFile(iconFile.GetFullPath(), wxBITMAP_TYPE_XPM);
    wxUnusedVar(loaded);
    wxASSERT_MSG(loaded, wxT("failed to load: ") + iconFile.GetFullPath());
    return bitmap;
}
Exemple #6
0
wxIcon t4p::IconImageAsset(wxString imageName) {
    if (!wxImage::FindHandler(wxBITMAP_TYPE_ICO)) {
        wxImage::AddHandler(new wxICOHandler());
    }
    wxFileName asset = AssetRootDir();
    asset.AppendDir(wxT("icons"));
    wxFileName iconFile(asset.GetPath(), imageName + wxT(".ico"));

    wxASSERT(iconFile.IsOk());
    wxIcon icon;
    bool loaded = icon.LoadFile(iconFile.GetFullPath(), wxBITMAP_TYPE_ICO);
    wxUnusedVar(loaded);
    wxASSERT_MSG(loaded, wxT("failed to load: ") + iconFile.GetFullPath());
    return icon;
}
Exemple #7
0
wxBitmap t4p::BitmapImageAsset(wxString imageName) {
    if (!wxImage::FindHandler(wxBITMAP_TYPE_PNG)) {
        wxImage::AddHandler(new wxPNGHandler());
    }
    wxFileName asset = AssetRootDir();
    asset.AppendDir(wxT("icons"));
    wxFileName iconFile(asset.GetPath(), imageName + wxT(".png"));

    wxASSERT(iconFile.IsOk());
    wxBitmap bitmap;
    bool loaded = bitmap.LoadFile(iconFile.GetFullPath(), wxBITMAP_TYPE_PNG);
    wxUnusedVar(loaded);
    wxASSERT_MSG(loaded, wxT("failed to load: ") + iconFile.GetFullPath());
    return bitmap;
}
PythonUploader::PythonUploader(QString name, QString shortname, QString className, QString iconFilename, QObject *parent) :
    Uploader(parent)
{
    this->workingDir = PluginManager::pluginPath() + shortname;
    this->shortname = shortname;
    this->name = name;
    this->className = className;
    this->filename = QString();
    QFile iconFile(workingDir + QDir::separator() + iconFilename);
    if(iconFile.exists())
    {
        this->icon = QIcon(iconFile.fileName());
    }
    QFile mainScriptFile(workingDir + QDir::separator() + "main.py");
    if(!mainScriptFile.exists())
    {
        QMessageBox::critical(0, "Error", "Failed to load plugin \"" + shortname + "\". Script file \"main.py\" does not exist.");
        return;
    }
    if (!mainScriptFile.open(QIODevice::ReadOnly | QIODevice::Text))
    {
      QMessageBox::critical(0, "Error", "Failed to load plugin \"" + shortname + "\". File main.py exists, but is not readable.");
      return;
    }
    hadPythonErr = false;
    connect(PythonQt::self(), SIGNAL(pythonStdErr(QString)), this, SLOT(pythonError(QString)));
    PythonQt::self()->addSysPath(workingDir + QDir::separator() + "modules");
    moduleObj = PythonQt::self()->createModuleFromScript(shortname + "_uploader");
    moduleObj.addVariable("workingDir", workingDir);
    moduleObj.evalScript(QString(mainScriptFile.readAll()));
    if(hadPythonErr)
    {
        PythonQt::self()->handleError();
        WARNING("Error while parsing script file " + mainScriptFile.fileName());
        QMessageBox::critical(NULL, "Script error in plugin '" + shortname + "'", "Error in file: " + mainScriptFile.fileName() + "\n" + lastPythonErr);
        lastPythonErr.clear();
        hadPythonErr = false;
    }
    pythonContext = PythonQt::self()->getMainModule();
    pythonContext.evalScript("from " + shortname + "_uploader import " + className);
    pythonContext.evalScript(shortname + "_u = " + className + "()");
    disconnect(PythonQt::self(), SIGNAL(pythonStdErr(QString)), this, SLOT(pythonError(QString)));
}
QIcon HiFiIconProvider::icon(const QFileInfo &info) const {
    const QString ext = info.suffix().toLower();

    if (info.isDir()) {
        if (info.absoluteFilePath() == QDir::homePath()) {
            return QIcon(Application::resourcesPath() + "icons/home.svg");
        } else if (info.absoluteFilePath() == QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)) {
            return QIcon(Application::resourcesPath() + "icons/desktop.svg");
        } else if (info.absoluteFilePath() == QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)) {
            return QIcon(Application::resourcesPath() + "icons/documents.svg");
        }
        return QIcon(Application::resourcesPath() + "icons/folder.svg");
    }

    QFileInfo iconFile(Application::resourcesPath() + "icons/" + iconsMap[ext]);
    if (iconFile.exists() && iconFile.isFile()) {
        return QIcon(iconFile.filePath());
    }

    return QIcon(Application::resourcesPath() + "icons/file.svg");
}
bool HsBookmarkPublishClient::saveFavicon(const QString Url, const QString iconFileName)
{
    QIcon icon;
    QDir iconDir(BEDROCK_PROVISIONING::BedrockProvisioning::createBedrockProvisioning()->valueAsString("DataBaseDirectory"));
    QUrl url(Url);
    
    // Retrieve the favicon and check its exsistance
    icon = QWebSettings::iconForUrl(url);
    if (icon.isNull())
        return false;
	
    QString iconPath = iconDir.filePath(iconFileName);
    QFile iconFile(iconPath);
    iconFile.open(QIODevice::WriteOnly);
    
    QPixmap pixmap = icon.pixmap(30, 30);
    pixmap.save(&iconFile, "PNG");
    
    iconFile.close();
    
    return true;
}
Exemple #11
0
QIcon HiFiIconProvider::icon(const QFileInfo &info) const {
    switchToResourcesParentIfRequired();
    const QString ext = info.suffix().toLower();

    if (info.isDir()) {
        if (info.absoluteFilePath() == QDir::homePath()) {
            return QIcon("resources/icons/home.svg");
        } else if (info.absoluteFilePath() == DESKTOP_LOCATION) {
            return QIcon("resources/icons/desktop.svg");
        } else if (info.absoluteFilePath() == QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)) {
            return QIcon("resources/icons/documents.svg");
        }
        return QIcon("resources/icons/folder.svg");
    }

    QFileInfo iconFile("resources/icons/" + iconsMap[ext]);
    if (iconFile.exists() && iconFile.isFile()) {
        return QIcon(iconFile.filePath());
    }

    return QIcon("resources/icons/file.svg");
}
Exemple #12
0
wxBitmap t4p::BitmapImageButtonPrepAsset(wxString imageName) {
    if (!wxImage::FindHandler(wxBITMAP_TYPE_PNG)) {
        wxImage::AddHandler(new wxPNGHandler());
    }
    wxFileName asset = AssetRootDir();
    asset.AppendDir(wxT("icons"));
    wxFileName iconFile(asset.GetPath(), imageName + wxT(".png"));

    wxASSERT(iconFile.IsOk());
    wxBitmap bitmap;
    bool loaded = bitmap.LoadFile(iconFile.GetFullPath(), wxBITMAP_TYPE_PNG);
    wxUnusedVar(loaded);
    wxASSERT_MSG(loaded, wxT("failed to load: ") + iconFile.GetFullPath());

#ifdef __WXMAC__

    // make images bigger, that way buttons have extra padding
    // on retina screens, the buttons look ugly
    bitmap.SetWidth(24);
    bitmap.SetHeight(24);
#endif
    return bitmap;
}
Exemple #13
0
void buddyPicture::uploadIcon(const QString &iconPath)
{
	if ( QFile::exists(iconPath))
	{
		QFile iconFile(iconPath);
		if ( iconFile.open(QIODevice::ReadOnly))
		{
			QByteArray packet;
			packet[0] = 0x2a;
			packet[1] = 0x02;
			packet.append(convertToByteArray((quint16)flapSeqNum));
						
			incFlapSeq();
			
			
			
			
			packet.append(convertToByteArray((quint16)(14 + iconFile.size())));
			snac snac1002;
			snac1002.setFamily(0x0010);
			snac1002.setSubType(0x0002);
			snac1002.setReqId(snacSeqNum);
		
			packet.append(snac1002.getData());
			incSnacSeq();
			
			packet.append(convertToByteArray((quint16)0x0001));
			refNum++;
			packet.append(convertToByteArray((quint16)iconFile.size()));
			packet.append(iconFile.readAll());

			
			tcpSocket->write(packet);
		}
	}
}
Exemple #14
0
//
// Step 6
// Extract icon and create .desktop files
//
bool InstallWindow::Step6CreateShortcuts()
{
    PrintStep(tr("Prepare desktop shortcut"));

    QDir desktopDir(DESKTOP_ENTRY_PATH),
            iconDir(ICONS_PATH),
            dbusDir(DBUS_PATH);

    if (!desktopDir.exists())
    {
        if (!desktopDir.mkpath(DESKTOP_ENTRY_PATH))
            return Failed(tr("Cannot create directory %1")
                       .arg(desktopDir.path()));

    }

    if (!iconDir.exists())
    {
        if (!iconDir.mkpath(ICONS_PATH))
            return Failed(tr("Cannot create directory %1")
                       .arg(iconDir.path()));
    }
    if (!dbusDir.exists())
    {
        if (!dbusDir.mkpath(DBUS_PATH))
            return Failed(tr("Cannot create directory %1")
                       .arg(dbusDir.path()));
    }

    // Icon path
    QString fullDataDir(_game->DataPath() +
                        "/usr/palm/applications/" +
                        _game->JsonID() + "/");
    QFile iconFile(fullDataDir + _game->JsonIcon());
    QString saneName =_game->JsonTitle().toLower();
    QString newName(QString(ICONS_PATH) +
                    QString("/") +
                    saneName + ".png");
    if (iconFile.exists() && !QFile::exists(newName))
    {
            if (!iconFile.copy(newName))
            {
                return Failed(tr("Cannot copy icon ") +
                              iconFile.fileName() +
                              "to " + ICONS_PATH + "/" + saneName + ".png");
            }
    }


    QString desktopEntry  =
            "[Desktop Entry]\n"
            "Encoding=UTF-8\n"
            "Version=1.0\n"
            "Type=Application\n"
            "Name=" + _game->JsonTitle() + "\n"
            "Exec=" + _game->Exec() + "\n"
            "X-Osso-Type=application/x-executable\n"
            "X-Osso-Service=" + _game->DBusName() + "\n"
            "X-Preenv-Generated=true\n"
            "X-Preenv-Vendor=" + _game->JsonVendor() + "\n"
            "X-Maemo-Category=Games\n"
            "Icon=" + saneName + "\n";

    QFile desktopFile(QString(DESKTOP_ENTRY_PATH) + QString("/") +
                      saneName  + ".desktop");
    if (!desktopFile.open(QFile::WriteOnly | QFile::Text))
        return Failed(tr("Cannot create .desktop file ") +
                   desktopFile.fileName());
    desktopFile.write(desktopEntry.toLocal8Bit());
    desktopFile.close();

    QString dbusEntry =
            "[D-BUS Service]\n"
            "Name=" + _game->DBusName() + "\n"
            "Exec=" + _game->Exec() + "\n";

    QFile dbusFile(QString(DBUS_PATH) + QString("/")
                   + saneName  + ".service");
    if (!dbusFile.open(QFile::WriteOnly | QFile::Text))
        return Failed(tr("Cannot create DBUS .service file ") +
                      dbusFile.fileName());

    dbusFile.write(dbusEntry.toLocal8Bit());
    dbusFile.close();

    PrintOK();
    return Step7PostInstall();
}
Exemple #15
0
int main(int argc, char **argv)
{
    QApplication application(argc, argv);

    application.setApplicationName("HTML Message Box");
    application.setApplicationVersion("0.2.0");

    QTextCodec::setCodecForLocale(QTextCodec::codecForName ("UTF8"));

    int windowWidth = 400;
    int windowHeigth = 200;
    int timeoutSeconds = 0;

    // Read command line arguments:
    QStringList arguments = QCoreApplication::arguments();

    foreach (QString argument, arguments) {
        if (argument.contains("--help")) {
            std::cout << " " << std::endl;
            std::cout << qApp->applicationName().toLatin1().constData()
                      << " version "
                      << qApp->applicationVersion().toLatin1().constData()
                      << std::endl;
            std::cout << "Executable: "
                      << (QDir::toNativeSeparators (
                              QApplication::applicationFilePath())
                          .toLatin1().constData())
                      << std::endl;
            std::cout << "Qt version: " << QT_VERSION_STR << std::endl;
            std::cout << " " << std::endl;
            std::cout << "Usage:" << std::endl;
            std::cout << "  htmlmsg --option=value -o=value" << std::endl;
            std::cout << " " << std::endl;
            std::cout << "Options:" << std::endl;
            std::cout << "  --width   -w    "
                      << "message width in points. Minimum: 200 points"
                      << std::endl;
            std::cout << "  --heigth  -h    "
                      << "message heigth in points. Minimum: 200 points"
                      << std::endl;
            std::cout << "  --timeout -t    "
                      << "timeout in seconds. "
                      << "Less than 3 seconds means no timeout."
                      << std::endl;
            std::cout << "  --help          this help"
                      << std::endl;
            std::cout << " " << std::endl;
            return 0;
        }

        if (argument.contains("--width") or argument.contains ("-w")) {
            if (argument.section ("=", 1, 1).toInt() > 200) {
                windowWidth = argument.section ("=", 1, 1).toInt();
                application.setProperty("windowWidth", windowWidth);
            }
        }

        if (argument.contains("--heigth") or argument.contains ("-h")) {
            if (argument.section ("=", 1, 1).toInt() > 200) {
                windowHeigth = argument.section ("=", 1, 1).toInt();
                application.setProperty("windowHeigth", windowHeigth);
            }
        }

        if (argument.contains("--timeout") or argument.contains ("-t")) {
            if (argument.section ("=", 1, 1).toInt() > 3) {
                timeoutSeconds = argument.section ("=", 1, 1).toInt();
                application.setProperty("timeoutSeconds", timeoutSeconds);
            }
        }
    }

    // Message box icon:
    QString externalIconFilePath =
            application.applicationDirPath() +
            QDir::separator() + "htmlmsg.png";
    QFile iconFile(externalIconFilePath);
    QPixmap icon(32, 32);

    if (iconFile.exists()) {
        // Set the external icon:
        icon.load(externalIconFilePath);
        QApplication::setWindowIcon(icon);
    } else {
        // Set the embedded icon:
        icon.load(":/htmlmsg.png");
        QApplication::setWindowIcon(icon);
    }

    // HTML message template:
    QString htmlFolder =
            application.applicationDirPath() + QDir::separator() + "msgbox";
    QString htmlFilePath =
            htmlFolder + QDir::separator() + "htmlmsg.html";
    QFile htmlFile(htmlFilePath);
    QString htmlContent;

    if (htmlFile.exists()) {
        // Load the external HTML message template:
        QFileReader *resourceReader =
                new QFileReader(htmlFilePath);
        htmlContent = resourceReader->fileContents;

        htmlContent.replace("local://",
                            QString(
                                "file://" + htmlFolder + QDir::separator()));
    } else {
        // Load the embedded HTML message template:
        QFileReader *resourceReader =
                new QFileReader(QString(":/htmlmsg.html"));
        htmlContent = resourceReader->fileContents;
    }

    // Initiate the message box and load the HTML message:
    QView window;
    window.mainPage->mainFrame()->setHtml(htmlContent);

    // Read any initial STDIN data:
    if (isatty(fileno(stdin))) {
        window.qReadStdin();
    }

    // Set the message box dimensions and center it on screen:
    window.setFixedSize (windowWidth, windowHeigth);
    QRect screenRect = QDesktopWidget().screen()->rect();
    window.move (QPoint(
                       screenRect.width()/2 - windowWidth/2,
                       screenRect.height()/2 - windowHeigth/2));

    // Display the message box:
    window.show();

    // Set the message box timeout:
    if (timeoutSeconds > 0) {
        int timeoutMilliseconds = timeoutSeconds * 1000;
        QTimer *timer = new QTimer();
        timer->singleShot (timeoutMilliseconds,
                           &window, SLOT (qCloseApplicationSlot()));
    }

    // Set the STDIN watcher:
    QSocketNotifier *stdinNotifier =
            new QSocketNotifier(fileno(stdin), QSocketNotifier::Read);
    QObject::connect(stdinNotifier, SIGNAL(activated(int)),
                     &window, SLOT(qReadStdin()));

    if (isatty(fileno(stdin))) {
        stdinNotifier->setEnabled(true);
    }

    application.exec();
}
Exemple #16
0
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainWindow) {
  ui->setupUi(this);

  QFile styleFile(":/style.css");
  styleFile.open(QFile::ReadOnly);
  QString styleSheet = QLatin1String(styleFile.readAll());
  qApp->setStyleSheet(styleSheet);

  QPixmap window_icon;
  QFile iconFile(":/icon.png");
  iconFile.open(QFile::ReadOnly);
  QByteArray icon_data = iconFile.readAll();
  window_icon.loadFromData(icon_data);
  qApp->setWindowIcon(QIcon(window_icon));

  awesome = new QtAwesome(qApp);
  settings = new Settings(this);
  window_watcher = new WindowWatcher(this);
  anitomy = new AnitomyWrapper();
  event_timer = new QTimer(this);
  watch_timer = new QTimer(this);
  uptime_timer = new QElapsedTimer;
  progress_bar = new QProgressBar(ui->statusBar);
  over = new Overlay(this);
  torrent_refresh_time = 0;
  user_refresh_time =
      settings->getValue(Settings::UserRefreshTime, D_USER_REFRESH_TIME)
          .toInt();
  download_rule = 0;
  download_count = 0;
  hasUser = false;

  uptime_timer->start();
  watch_timer->setSingleShot(true);

  awesome->initFontAwesome();

  bool check_for_updates =
      settings->getValue(Settings::CheckUpdates, D_CHECK_FOR_UPDATES).toBool();

  if (check_for_updates) {
    connect(FvUpdater::sharedUpdater(), &FvUpdater::restartRequested,
            [&]() {  // NOLINT
              QString app = QApplication::applicationFilePath();
              QStringList arguments = QApplication::arguments();
              QString wd = QDir::currentPath();
              QProcess::startDetached(app, arguments, wd);
              elegantClose(true);
            });

    FvUpdater::sharedUpdater()->CheckForUpdatesSilent();
  }

  QFont font = ui->listTabs->tabBar()->font();
  font.setCapitalization(QFont::Capitalize);
  ui->listTabs->tabBar()->setFont(font);

  int currentYear = QDate::currentDate().year();
  int lowerYear = currentYear - 10;

  while (currentYear > lowerYear) {
    ui->comboYear->addItem(QString::number(currentYear));
    currentYear--;
  }

  QWidget *container = new QWidget(ui->scrollArea);
  layout = new FlowLayout(container);
  ui->scrollArea->setWidget(container);
  container->setLayout(layout);

  QWidget *container2 = new QWidget(ui->scrollArea_2);
  layout2 = new FlowLayout(container2);
  layout2->disableSort();
  ui->scrollArea_2->setWidget(container2);
  container2->setLayout(layout2);

  QVariantMap black;
  black.insert("color", QColor(0, 0, 0));
  black.insert("color-active", QColor(0, 0, 0));
  black.insert("color-disabled", QColor(0, 0, 0));
  black.insert("color-selected", QColor(0, 0, 0));

  ui->airingButton->setIcon(awesome->icon(fa::clocko, black));
  ui->torrentsButton->setIcon(awesome->icon(fa::rss, black));
  ui->animeButton->setIcon(awesome->icon(fa::bars, black));
  ui->seasonsButton->setIcon(awesome->icon(fa::th, black));
  ui->statisticsButton->setIcon(awesome->icon(fa::piechart, black));

  ui->tabWidget->tabBar()->hide();
  ui->tabWidget->setCurrentIndex(UserTabs::tAnime);
  ui->listTabs->setCurrentIndex(0);

  ui->statusBar->addWidget(progress_bar);
  ui->statusBar->layout()->setContentsMargins(1, 0, 0, 0);
  progress_bar->setRange(0, 100);
  progress_bar->setValue(5);
  progress_bar->setFormat("Authorizing");

  QSettings s;
  restoreGeometry(s.value("mainWindowGeometry").toByteArray());
  restoreState(s.value("mainWindowState").toByteArray());

  connect(&user_future_watcher, SIGNAL(finished()), SLOT(userLoaded()));
  connect(&user_list_future_watcher, SIGNAL(finished()),
          SLOT(userListLoaded()));

  connect(ui->animeButton, SIGNAL(clicked()), SLOT(showAnimeTab()));
  connect(ui->airingButton, SIGNAL(clicked()), SLOT(showAiringTab()));
  connect(ui->torrentsButton, SIGNAL(clicked()), SLOT(showTorrentsTab()));
  connect(ui->seasonsButton, SIGNAL(clicked()), SLOT(showBrowseTab()));
  connect(ui->actionSettings, SIGNAL(triggered()), SLOT(showSettings()));
  connect(ui->statisticsButton, SIGNAL(clicked()), SLOT(showStatisticsTab()));

  connect(ui->actionExit, &QAction::triggered, [&, this]() {  // NOLINT
    this->elegantClose();
  });

  connect(ui->actionAbout, &QAction::triggered, [&, this]() {  // NOLINT
    About *about = new About(this);
    about->show();
  });

  connect(ui->actionHelp, &QAction::triggered, [&, this]() {  // NOLINT
    QDesktopServices::openUrl(QUrl("http://app.shinjiru.me/support.php"));
  });

  connect(ui->actionRL, &QAction::triggered, [&, this]() {  // NOLINT
    loadUser();
  });

  connect(ui->actionAS, &QAction::triggered, [&]() {  // NOLINT
    SearchPanel *sp = new SearchPanel(this);
    sp->show();
  });

  connect(ui->actionARR, &QAction::triggered, [&, this]() {  // NOLINT
    SettingsDialog *s = new SettingsDialog(this);
    s->showSmartTitles();

    connect(s, &QDialog::accepted, [&, this]() {  // NOLINT
      Settings set;

      toggleAnimeRecognition(
          set.getValue(Settings::AnimeRecognitionEnabled, D_ANIME_RECOGNITION)
              .toBool());

      torrents_enabled =
          set.getValue(Settings::TorrentsEnabled, D_TORRENTS_ENABLED).toBool();

      reloadSmartTitles();
      reloadRules();
    });
  });

  connect(qApp, SIGNAL(aboutToQuit()), SLOT(elegantClose()));

  connect(ui->actionVAL, SIGNAL(triggered()), SLOT(viewAnimeList()));
  connect(ui->actionVD, SIGNAL(triggered()), SLOT(viewDashboard()));
  connect(ui->actionVP, SIGNAL(triggered()), SLOT(viewProfile()));
  connect(ui->actionEAR, SIGNAL(triggered(bool)),
          SLOT(toggleAnimeRecognition(bool)));
  connect(ui->actionExport, SIGNAL(triggered()), SLOT(exportListJSON()));
  connect(ui->actionUpdate, SIGNAL(triggered()), FvUpdater::sharedUpdater(),
          SLOT(CheckForUpdatesNotSilent()));

  connect(window_watcher, SIGNAL(title_found(QString)), SLOT(watch(QString)));
  connect(watch_timer, SIGNAL(timeout()), SLOT(updateEpisode()));
  connect(event_timer, SIGNAL(timeout()), SLOT(eventTick()));

  connect(ui->torrentTable, SIGNAL(customContextMenuRequested(QPoint)),
          SLOT(torrentContextMenu(QPoint)));
  connect(ui->torrentFilter, SIGNAL(textChanged(QString)),
          SLOT(filterTorrents(QString)));
  connect(ui->chkHideUnknown, SIGNAL(toggled(bool)),
          SLOT(filterTorrents(bool)));
  connect(ui->refreshButton, SIGNAL(clicked()), SLOT(refreshTorrentListing()));

  connect(ui->actionEAR, SIGNAL(toggled(bool)), SLOT(applyEAR()));

  connect(ui->tabWidget, &QTabWidget::currentChanged, [&, this](  // NOLINT
                                                          int tab) {
    if (tab != 0) {
      this->over->removeDrawing("blank_table");
      this->over->removeDrawing("no anime");
      ui->listTabs->show();
      ui->listFilterLineEdit->show();
    } else {
      this->filterList(3);

      if (hasUser && (User::sharedUser()->getAnimeList().count() == 0)) {
        this->addNoAnimePrompt();
      }
    }
  });

  ui->actionEAR->setChecked(
      settings->getValue(Settings::AnimeRecognitionEnabled, D_ANIME_RECOGNITION)
          .toBool());

  this->toggleAnimeRecognition(ui->actionEAR->isChecked());

  QString genrelist =
      "Action, Adult, Adventure, Cars, Comedy, Dementia, Demons, Doujinshi, "
      "Drama, Ecchi, Fantasy, Game, Gender Bender, Harem, Hentai, Historical, "
      "Horror, Josei, Kids, Magic, Martial Arts, Mature, Mecha, Military, "
      "Motion Comic, Music, Mystery, Mythological , Parody, Police, "
      "Psychological, Romance, Samurai, School, Sci-Fi, Seinen, Shoujo, Shoujo "
      "Ai, Shounen, Shounen Ai, Slice of Life, Space, Sports, Super Power, "
      "Supernatural, Thriller, Tragedy, Vampire, Yaoi, Yuri";
  QStringList genres = genrelist.split(", ");

  for (QString genre : genres) {
    QCheckBox *chk = new QCheckBox();

    chk->setText(genre);
    chk->setTristate(true);

    ui->genreList->addWidget(chk);
  }

  connect(ui->listFilterLineEdit, SIGNAL(textChanged(QString)),
          SLOT(filterList(QString)));
  connect(ui->listFilterLineEdit, SIGNAL(returnPressed()), SLOT(showSearch()));
  connect(ui->listTabs, SIGNAL(currentChanged(int)), SLOT(filterList(int)));

  connect(ui->browseButton, SIGNAL(clicked()), SLOT(loadBrowserData()));

  this->show();
  createActions();
  initTray();
  trayIcon->show();

  int result = API::sharedAPI()->verifyAPI();

  if (result == AniListAPI::OK) {
    connect(API::sharedAPI()->sharedAniListAPI(), &AniListAPI::access_granted,
            [&, this]() {  // NOLINT
              progress_bar->setValue(10);
              progress_bar->setFormat("Access granted");
              loadUser();

              event_timer->start(1000);
            });

    connect(API::sharedAPI()->sharedAniListAPI(), &AniListAPI::access_denied,
            [&, this](QString error) {  // NOLINT
              qCritical() << error;

              if (isVisible()) {
                QMessageBox::critical(this, "Shinjiru", tr("Error: ") + error);
              }
            });
  } else if (result == AniListAPI::NO_CONNECTION) {
    qDebug() << "Starting Shinjiru in offline mode";
    hasUser = User::sharedUser()->loadLocal();
  }

  reloadRules();
}
Exemple #17
0
NATRON_NAMESPACE_ENTER


// those parameters should be ignored (they are always secret in Natron)
#define kOCIOParamInputSpace "ocioInputSpace"
#define kOCIOParamOutputSpace "ocioOutputSpace"

// those parameters should not have their options in the help file if generating markdown,
// because the options are dinamlically constructed at run-time from the OCIO config.
#define kOCIOParamInputSpaceChoice "ocioInputSpaceIndex"
#define kOCIOParamOutputSpaceChoice "ocioOutputSpaceIndex"

#define kOCIODisplayPluginIdentifier "fr.inria.openfx.OCIODisplay"
#define kOCIODisplayParamDisplay "display"
#define kOCIODisplayParamDisplayChoice "displayIndex"
#define kOCIODisplayParamView "view"
#define kOCIODisplayParamViewChoice "viewIndex"

// not yet implemented (see OCIOCDLTransform.cpp)
//#define kOCIOCDLTransformPluginIdentifier "fr.inria.openfx.OCIOCDLTransform"
//#define kOCIOCDLTransformParamCCCID "cccId"
//#define kOCIOCDLTransformParamCCCIDChoice "cccIdIndex"

#define kOCIOFileTransformPluginIdentifier "fr.inria.openfx.OCIOFileTransform"
#define kOCIOFileTransformParamCCCID "cccId"
#define kOCIOFileTransformParamCCCIDChoice "cccIdIndex"

// genHTML: true for live HTML output for the internal web-server, false for markdown output
QString
Node::makeDocumentation(bool genHTML) const
{
    QString ret;
    QString markdown;
    QTextStream ts(&ret);
    QTextStream ms(&markdown);

    QString pluginID, pluginLabel, pluginDescription, pluginIcon;
    int majorVersion = getMajorVersion();
    int minorVersion = getMinorVersion();
    std::vector<std::string> pluginGroup;
    bool pluginDescriptionIsMarkdown = false;
    QVector<QStringList> inputs;
    QVector<QStringList> items;

    {
        PluginPtr plugin = getPlugin();
        assert(plugin);

        pluginID = QString::fromUtf8(plugin->getPluginID().c_str());
        pluginLabel =  QString::fromUtf8( Plugin::makeLabelWithoutSuffix( plugin->getPluginLabel() ).c_str());
        pluginDescription =  QString::fromUtf8( plugin->getPropertyUnsafe<std::string>(kNatronPluginPropDescription).c_str() );
        pluginIcon = QString::fromUtf8(plugin->getPropertyUnsafe<std::string>(kNatronPluginPropIconFilePath).c_str());
        pluginGroup = plugin->getPropertyNUnsafe<std::string>(kNatronPluginPropGrouping);
        pluginDescriptionIsMarkdown = plugin->getPropertyUnsafe<bool>(kNatronPluginPropDescriptionIsMarkdown);


        for (int i = 0; i < _imp->effect->getNInputs(); ++i) {
            QStringList input;
            input << convertFromPlainTextToMarkdown( QString::fromStdString( getInputLabel(i) ), genHTML, true );
            input << convertFromPlainTextToMarkdown( QString::fromStdString( getInputHint(i) ), genHTML, true );
            input << ( isInputOptional(i) ? tr("Yes") : tr("No") );
            inputs.push_back(input);

            // Don't show more than doc for 4 inputs otherwise it will just clutter the page
            if (i == 3) {
                break;
            }
        }
    }

    // check for plugin icon
    QString pluginIconUrl;
    if ( !pluginIcon.isEmpty() ) {
        QFile iconFile(pluginIcon);
        if ( iconFile.exists() ) {
            if (genHTML) {
                pluginIconUrl.append( QString::fromUtf8("/LOCAL_FILE/") );
                pluginIconUrl.append(pluginIcon);
                pluginIconUrl.replace( QString::fromUtf8("\\"), QString::fromUtf8("/") );
            } else {
                pluginIconUrl.append(pluginID);
                pluginIconUrl.append(QString::fromUtf8(".png"));
            }
        }
    }

    // check for extra markdown file
    QString extraMarkdown;
    QString pluginMD = pluginIcon;
    pluginMD.replace( QString::fromUtf8(".png"), QString::fromUtf8(".md") );
    QFile pluginMarkdownFile(pluginMD);
    if ( pluginMarkdownFile.exists() ) {
        if ( pluginMarkdownFile.open(QIODevice::ReadOnly | QIODevice::Text) ) {
            extraMarkdown = QString::fromUtf8( pluginMarkdownFile.readAll() );
            pluginMarkdownFile.close();
        }
    }

    // generate knobs info
    KnobsVec knobs = getEffectInstance()->getKnobs_mt_safe();
    for (KnobsVec::const_iterator it = knobs.begin(); it != knobs.end(); ++it) {

#pragma message WARN("TODO: restore getDefaultIsSecret from RB-2.2")
        //if ( (*it)->getDefaultIsSecret() ) {
        if ( (*it)->getIsSecret() ) {
            continue;
        }

        if ((*it)->getKnobDeclarationType() != KnobI::eKnobDeclarationTypePlugin) {
            continue;
        }

        // do not escape characters in the scriptName, since it will be put between backquotes
        QString knobScriptName = /*NATRON_NAMESPACE::convertFromPlainTextToMarkdown(*/ QString::fromUtf8( (*it)->getName().c_str() )/*, genHTML, true)*/;
        QString knobLabel = NATRON_NAMESPACE::convertFromPlainTextToMarkdown( QString::fromUtf8( (*it)->getLabel().c_str() ), genHTML, true);
        QString knobHint = NATRON_NAMESPACE::convertFromPlainTextToMarkdown( QString::fromUtf8( (*it)->getHintToolTip().c_str() ), genHTML, true);

        // totally ignore the documentation for these parameters (which are always secret in Natron)
        if ( knobScriptName.startsWith( QString::fromUtf8("NatronOfxParam") ) ||
             knobScriptName == QString::fromUtf8("exportAsPyPlug") ||
             knobScriptName == QString::fromUtf8(kOCIOParamInputSpace) ||
             knobScriptName == QString::fromUtf8(kOCIOParamOutputSpace) ||
             ( ( pluginID == QString::fromUtf8(kOCIODisplayPluginIdentifier) ) &&
               ( knobScriptName == QString::fromUtf8(kOCIODisplayParamDisplay) ) ) ||
             ( ( pluginID == QString::fromUtf8(kOCIODisplayPluginIdentifier) ) &&
               ( knobScriptName == QString::fromUtf8(kOCIODisplayParamView) ) ) ||
             //( ( pluginID == QString::fromUtf8(kOCIOCDLTransformPluginIdentifier) ) &&
             //  ( knobScriptName == QString::fromUtf8(kOCIOCDLTransformParamCCCID) ) ) ||
             ( ( pluginID == QString::fromUtf8(kOCIOFileTransformPluginIdentifier) ) &&
               ( knobScriptName == QString::fromUtf8(kOCIOFileTransformParamCCCID) ) ) ||
             false) {
            continue;
        }

        QString defValuesStr, knobType;
        std::vector<std::pair<QString, QString> > dimsDefaultValueStr;
        KnobIntPtr isInt = toKnobInt(*it);
        KnobChoicePtr isChoice = toKnobChoice(*it);
        KnobBoolPtr isBool = toKnobBool(*it);
        KnobDoublePtr isDbl = toKnobDouble(*it);
        KnobStringPtr isString = toKnobString(*it);
        bool isLabel = isString && isString->isLabel();
        KnobSeparatorPtr isSep = toKnobSeparator(*it);
        KnobButtonPtr isBtn = toKnobButton(*it);
        KnobParametricPtr isParametric = toKnobParametric(*it);
        KnobGroupPtr isGroup = toKnobGroup(*it);
        KnobPagePtr isPage = toKnobPage(*it);
        KnobColorPtr isColor = toKnobColor(*it);

        if (isInt) {
            knobType = tr("Integer");
        } else if (isChoice) {
            knobType = tr("Choice");
        } else if (isBool) {
            knobType = tr("Boolean");
        } else if (isDbl) {
            knobType = tr("Double");
        } else if (isString) {
            if (isLabel) {
                knobType = tr("Label");
            } else {
                knobType = tr("String");
            }
        } else if (isSep) {
            knobType = tr("Separator");
        } else if (isBtn) {
            knobType = tr("Button");
        } else if (isParametric) {
            knobType = tr("Parametric");
        } else if (isGroup) {
            knobType = tr("Group");
        } else if (isPage) {
            knobType = tr("Page");
        } else if (isColor) {
            knobType = tr("Color");
        } else {
            knobType = tr("N/A");
        }

        if (!isGroup && !isPage) {
            for (int i = 0; i < (*it)->getNDimensions(); ++i) {
                QString valueStr;

                if (!isBtn && !isSep && !isParametric) {
                    // If this is a ChoiceParam and we are not generating live HTML doc,
                    // only add the list of entries and their halp if this node should not be
                    // ignored (eg. OCIO colorspace knobs).
                    if ( isChoice &&
                         (genHTML || !( knobScriptName == QString::fromUtf8(kOCIOParamInputSpaceChoice) ||
                                        knobScriptName == QString::fromUtf8(kOCIOParamOutputSpaceChoice) ||
                                        ( ( pluginID == QString::fromUtf8(kOCIODisplayPluginIdentifier) ) &&
                                          ( knobScriptName == QString::fromUtf8(kOCIODisplayParamDisplayChoice) ) ) ||
                                        ( ( pluginID == QString::fromUtf8(kOCIODisplayPluginIdentifier) ) &&
                                          ( knobScriptName == QString::fromUtf8(kOCIODisplayParamViewChoice) ) ) ||
                                        //( ( pluginID == QString::fromUtf8(kOCIOCDLTransformPluginIdentifier) ) &&
                                        //   ( knobScriptName == QString::fromUtf8(kOCIOCDLTransformParamCCCIDChoice) ) ) ||
                                        ( ( pluginID == QString::fromUtf8(kOCIOFileTransformPluginIdentifier) ) &&
                                          ( knobScriptName == QString::fromUtf8(kOCIOFileTransformParamCCCIDChoice) ) ) ||
                                        ( ( pluginID == QString::fromUtf8("net.fxarena.openfx.Text") ) &&
                                          ( knobScriptName == QString::fromUtf8("name") ) ) || // font family from Text plugin
                                        ( ( pluginID == QString::fromUtf8("net.fxarena.openfx.Polaroid") ) &&
                                          ( knobScriptName == QString::fromUtf8("font") ) ) || // font family from Polaroid plugin
                                        ( ( pluginID == QString::fromUtf8(PLUGINID_NATRON_PRECOMP) ) &&
                                          ( knobScriptName == QString::fromUtf8("writeNode") ) ) ||
                                        ( ( pluginID == QString::fromUtf8(PLUGINID_NATRON_ONEVIEW) ) &&
                                          ( knobScriptName == QString::fromUtf8("view") ) ) ) ) ) {
                        // see also KnobChoice::getHintToolTipFull()
                        int index = isChoice->getDefaultValue(DimIdx(i));
                        std::vector<ChoiceOption> entries = isChoice->getEntries();
                        if ( (index >= 0) && ( index < (int)entries.size() ) ) {
                            valueStr = QString::fromUtf8( entries[index].id.c_str() );
                        }
                        bool first = true;
                        for (size_t i = 0; i < entries.size(); i++) {
                            QString entryHelp = QString::fromUtf8( entries[i].tooltip.c_str() );
                            QString entry;
                            if (entries[i].id != entries[i].label) {
                                entry = QString::fromUtf8( "%1 (%2)" ).arg(QString::fromUtf8( entries[i].label.c_str() )).arg(QString::fromUtf8( entries[i].id.c_str() ));
                            } else {
                                entry = QString::fromUtf8( entries[i].label.c_str() );
                            }
                            if (!entry.isEmpty()) {
                                if (first) {
                                    // empty line before the option descriptions
                                    if (genHTML) {
                                        if ( !knobHint.isEmpty() ) {
                                            knobHint.append( QString::fromUtf8("<br />") );
                                        }
                                        knobHint.append( tr("Possible values:") + QString::fromUtf8("<br />") );
                                    } else {
                                        // we do a hack for multiline elements, because the markdown->rst conversion by pandoc doesn't use the line block syntax.
                                        // what we do here is put a supplementary dot at the beginning of each line, which is then converted to a pipe '|' in the
                                        // genStaticDocs.sh script by a simple sed command after converting to RsT
                                        if ( !knobHint.isEmpty() ) {
                                            if (!knobHint.startsWith( QString::fromUtf8(". ") )) {
                                                knobHint.prepend( QString::fromUtf8(". ") );
                                            }
                                            knobHint.append( QString::fromUtf8("\\\n") );
                                        }
                                        knobHint.append( QString::fromUtf8(". ") + tr("Possible values:") +  QString::fromUtf8("\\\n") );
                                    }
                                    first = false;
                                }
                                if (genHTML) {
                                    knobHint.append( QString::fromUtf8("<br />") );
                                } else {
                                    knobHint.append( QString::fromUtf8("\\\n") );
                                    // we do a hack for multiline elements, because the markdown->rst conversion by pandoc doesn't use the line block syntax.
                                    // what we do here is put a supplementary dot at the beginning of each line, which is then converted to a pipe '|' in the
                                    // genStaticDocs.sh script by a simple sed command after converting to RsT
                                    knobHint.append( QString::fromUtf8(". ") );
                                }
                                if (entryHelp.isEmpty()) {
                                    knobHint.append( QString::fromUtf8("**%1**").arg( convertFromPlainTextToMarkdown(entry, genHTML, true) ) );
                                } else {
                                    knobHint.append( QString::fromUtf8("**%1**: %2").arg( convertFromPlainTextToMarkdown(entry, genHTML, true) ).arg( convertFromPlainTextToMarkdown(entryHelp, genHTML, true) ) );
                                }
                            }
                        }
                    } else if (isInt) {
                        valueStr = QString::number( isInt->getDefaultValue( DimIdx(i) ) );
                    } else if (isDbl) {
                        valueStr = QString::number( isDbl->getDefaultValue( DimIdx(i) ) );
                    } else if (isBool) {
                        valueStr = isBool->getDefaultValue( DimIdx(i) ) ? tr("On") : tr("Off");
                    } else if (isString) {
                        valueStr = QString::fromUtf8( isString->getDefaultValue( DimIdx(i) ).c_str() );
                    } else if (isColor) {
                        valueStr = QString::number( isColor->getDefaultValue( DimIdx(i) ) );
                    }
                }

                dimsDefaultValueStr.push_back( std::make_pair(convertFromPlainTextToMarkdown( QString::fromUtf8( (*it)->getDimensionName( DimIdx(i) ).c_str() ), genHTML, true ),
                                                              convertFromPlainTextToMarkdown(valueStr, genHTML, true)) );
            }

            for (std::size_t i = 0; i < dimsDefaultValueStr.size(); ++i) {
                if ( !dimsDefaultValueStr[i].second.isEmpty() ) {
                    if (dimsDefaultValueStr.size() > 1) {
                        defValuesStr.append(dimsDefaultValueStr[i].first);
                        defValuesStr.append( QString::fromUtf8(": ") );
                    }
                    defValuesStr.append(dimsDefaultValueStr[i].second);
                    if (i < dimsDefaultValueStr.size() - 1) {
                        defValuesStr.append( QString::fromUtf8(" ") );
                    }
                }
            }
            if ( defValuesStr.isEmpty() ) {
                defValuesStr = tr("N/A");
            }
        }

        if (!isPage && !isSep && !isGroup && !isLabel) {
            QStringList row;
            row << knobLabel << knobScriptName << knobType << defValuesStr << knobHint;
            items.append(row);
        }
    } // for (KnobsVec::const_iterator it = knobs.begin(); it!=knobs.end(); ++it) {


    // generate plugin info
    ms << tr("%1 node").arg(pluginLabel) << "\n==========\n\n";

    // a hack to avoid repeating the documentation for the various merge plugins
    if ( pluginID.startsWith( QString::fromUtf8("net.sf.openfx.Merge") ) ) {
        std::string id = pluginID.toStdString();
        std::string op;
        if (id == PLUGINID_OFX_MERGE) {
            // do nothing
        } else if (id == "net.sf.openfx.MergeDifference") {
            op = "difference (a.k.a. absminus)";
        } else if (id == "net.sf.openfx.MergeIn") {
            op = "in";
        } else if (id == "net.sf.openfx.MergeMatte") {
            op = "matte";
        } else if (id == "net.sf.openfx.MergeMax") {
            op = "max";
        } else if (id == "net.sf.openfx.MergeMin") {
            op = "min";
        } else if (id == "net.sf.openfx.MergeMultiply") {
            op = "multiply";
        } else if (id == "net.sf.openfx.MergeOut") {
            op = "out";
        } else if (id == "net.sf.openfx.MergePlus") {
            op = "plus";
        } else if (id == "net.sf.openfx.MergeScreen") {
            op = "screen";
        }
        if ( !op.empty() ) {
            // we should use the custom link "[Merge node](|http::/plugins/" PLUGINID_OFX_MERGE ".html||rst::net.sf.openfx.MergePlugin|)"
            // but pandoc borks it
            ms << tr("The *%1* node is a convenience node identical to the %2, except that the operator is set to *%3* by default.")
            .arg(pluginLabel)
            .arg(genHTML ? QString::fromUtf8("<a href=\"" PLUGINID_OFX_MERGE ".html\">Merge node</a>") :
                 QString::fromUtf8(":ref:`" PLUGINID_OFX_MERGE "`")
                 //QString::fromUtf8("[Merge node](http::/plugins/" PLUGINID_OFX_MERGE ".html)")
                 )
            .arg( QString::fromUtf8( op.c_str() ) );
            goto OUTPUT;
        }

    }

    if (!pluginIconUrl.isEmpty()) {
        // add a nonbreaking space so that pandoc doesn't use the alt-text as a caption
        // http://pandoc.org/MANUAL.html#images
        ms << "![pluginIcon](" << pluginIconUrl << ")";
        if (!genHTML) {
            // specify image width for pandoc-generated printed doc
            // (for hoedown-generated HTML, this handled by the CSS using the alt=pluginIcon attribute)
            // see http://pandoc.org/MANUAL.html#images
            // note that only % units are understood both by pandox and sphinx
            ms << "{ width=10% }";
        }
        ms << "&nbsp;\n\n"; // &nbsp; required so that there is no legend when converted to rst by pandoc
    }
    ms << tr("*This documentation is for version %2.%3 of %1.*").arg(pluginLabel).arg(majorVersion).arg(minorVersion) << "\n\n";

    ms << "\n" << tr("Description") << "\n--------------------------------------------------------------------------------\n\n";

    if (!pluginDescriptionIsMarkdown) {
        if (genHTML) {
            pluginDescription = NATRON_NAMESPACE::convertFromPlainText(pluginDescription, NATRON_NAMESPACE::WhiteSpaceNormal);

            // replace URLs with links
            QRegExp re( QString::fromUtf8("((http|ftp|https)://([\\w_-]+(?:(?:\\.[\\w_-]+)+))([\\w.,@?^=%&:/~+#-]*[\\w@?^=%&/~+#-])?)") );
            pluginDescription.replace( re, QString::fromUtf8("<a href=\"\\1\">\\1</a>") );
        } else {
            pluginDescription = convertFromPlainTextToMarkdown(pluginDescription, genHTML, false);
        }
    }

    ms << pluginDescription << "\n";

    // create markdown table
    ms << "\n" << tr("Inputs") << "\n--------------------------------------------------------------------------------\n\n";
    ms << tr("Input") << " | " << tr("Description") << " | " << tr("Optional") << "\n";
    ms << "--- | --- | ---\n";
    if (inputs.size() > 0) {
        Q_FOREACH(const QStringList &input, inputs) {
            QString inputName = input.at(0);
            QString inputDesc = input.at(1);
            QString inputOpt = input.at(2);

            ms << inputName << " | " << inputDesc << " | " << inputOpt << "\n";
        }
	inline void CNotificationManager::updateDeviceIcon(CUIDevice * uiDevice) {
		QSystemTrayIcon * trayIcon = m_UIDeviceIcons[uiDevice];
		trayIcon->setToolTip(shortSummary(uiDevice->device()));
		trayIcon->setIcon(QIcon(iconFile(uiDevice->device())));
	}