NS_IMETHODIMP nsDeviceContextSpecQt::GetSurfaceForPrinter(
        gfxASurface** aSurface)
{
    NS_ENSURE_ARG_POINTER(aSurface);
    *aSurface = nullptr;

    double width, height;
    mPrintSettings->GetEffectivePageSize(&width, &height);

    // If we're in landscape mode, we'll be rotating the output --
    // need to swap width & height.
    int32_t orientation;
    mPrintSettings->GetOrientation(&orientation);
    if (nsIPrintSettings::kLandscapeOrientation == orientation) {
        double tmp = width;
        width = height;
        height = tmp;
    }

    // convert twips to points
    width  /= TWIPS_PER_POINT_FLOAT;
    height /= TWIPS_PER_POINT_FLOAT;

    DO_PR_DEBUG_LOG(("\"%s\", %f, %f\n", mPath, width, height));

    QTemporaryFile file;
    if(!file.open()) {
        return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE;
    }
    file.setAutoRemove(false);

    nsresult rv = NS_NewNativeLocalFile(
            nsDependentCString(file.fileName().toUtf8().constData()),
            false,
            getter_AddRefs(mSpoolFile));
    if (NS_FAILED(rv)) {
        file.remove();
        return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE;
    }

    mSpoolName = file.fileName().toUtf8().constData();

    mSpoolFile->SetPermissions(0600);

    nsCOMPtr<nsIFileOutputStream> stream =
        do_CreateInstance("@mozilla.org/network/file-output-stream;1");

    rv = stream->Init(mSpoolFile, -1, -1, 0);
    if (NS_FAILED(rv))
        return rv;

    int16_t format;
    mPrintSettings->GetOutputFormat(&format);

    nsRefPtr<gfxASurface> surface;
    gfxSize surfaceSize(width, height);

    if (format == nsIPrintSettings::kOutputFormatNative) {
        if (mIsPPreview) {
            // There is nothing to detect on Print Preview, use PS.
            // TODO: implement for Qt?
            //format = nsIPrintSettings::kOutputFormatPS;
            return NS_ERROR_NOT_IMPLEMENTED;
        }
        format = nsIPrintSettings::kOutputFormatPDF;
    }
    if (format == nsIPrintSettings::kOutputFormatPDF) {
        surface = new gfxPDFSurface(stream, surfaceSize);
    } else {
        return NS_ERROR_NOT_IMPLEMENTED;
    }

    NS_ABORT_IF_FALSE(surface, "valid address expected");

    surface.swap(*aSurface);
    return NS_OK;
}
void runRdb( uint flags )
{
  // Obtain the application palette that is about to be set.
  bool exportColors      = flags & KRdbExportColors;
  bool exportQtColors    = flags & KRdbExportQtColors;
  bool exportQtSettings  = flags & KRdbExportQtSettings;
  bool exportXftSettings = flags & KRdbExportXftSettings;
  bool exportGtkTheme    = flags & KRdbExportGtkTheme;

  KSharedConfigPtr kglobalcfg = KSharedConfig::openConfig( QStringLiteral("kdeglobals") );
  KConfigGroup kglobals(kglobalcfg, "KDE");
  QPalette newPal = KColorScheme::createApplicationPalette(kglobalcfg);

  QTemporaryFile tmpFile;
  if (!tmpFile.open())
  {
    qDebug() << "Couldn't open temp file";
    exit(0);
  }


  KConfigGroup generalCfgGroup(kglobalcfg, "General");

  QString gtkTheme;
  if (kglobals.hasKey("widgetStyle"))
    gtkTheme = kglobals.readEntry("widgetStyle");
  else
    gtkTheme = QStringLiteral("oxygen");

  createGtkrc( exportColors, newPal, exportGtkTheme, gtkTheme, 1 );
  createGtkrc( exportColors, newPal, exportGtkTheme, gtkTheme, 2 );

  // Export colors to non-(KDE/Qt) apps (e.g. Motif, GTK+ apps)
  if (exportColors)
  {
    KConfigGroup g(KSharedConfig::openConfig(), "WM");
    QString preproc;
    QColor backCol = newPal.color( QPalette::Active, QPalette::Background );
    addColorDef(preproc, "FOREGROUND"         , newPal.color( QPalette::Active, QPalette::Foreground ) );
    addColorDef(preproc, "BACKGROUND"         , backCol);
    addColorDef(preproc, "HIGHLIGHT"          , backCol.light(100+(2*KColorScheme::contrast()+4)*16/1));
    addColorDef(preproc, "LOWLIGHT"           , backCol.dark(100+(2*KColorScheme::contrast()+4)*10));
    addColorDef(preproc, "SELECT_BACKGROUND"  , newPal.color( QPalette::Active, QPalette::Highlight));
    addColorDef(preproc, "SELECT_FOREGROUND"  , newPal.color( QPalette::Active, QPalette::HighlightedText));
    addColorDef(preproc, "WINDOW_BACKGROUND"  , newPal.color( QPalette::Active, QPalette::Base ) );
    addColorDef(preproc, "WINDOW_FOREGROUND"  , newPal.color( QPalette::Active, QPalette::Text ) );
    addColorDef(preproc, "INACTIVE_BACKGROUND", g.readEntry("inactiveBackground", QColor(224, 223, 222)));
    addColorDef(preproc, "INACTIVE_FOREGROUND", g.readEntry("inactiveBackground", QColor(224, 223, 222)));
    addColorDef(preproc, "ACTIVE_BACKGROUND"  , g.readEntry("activeBackground", QColor(48, 174, 232)));
    addColorDef(preproc, "ACTIVE_FOREGROUND"  , g.readEntry("activeBackground", QColor(48, 174, 232)));
    //---------------------------------------------------------------

    tmpFile.write( preproc.toLatin1(), preproc.length() );

    QStringList list;

    const QStringList adPaths = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation,
        QStringLiteral("kdisplay/app-defaults/"), QStandardPaths::LocateDirectory);
    for (QStringList::ConstIterator it = adPaths.constBegin(); it != adPaths.constEnd(); ++it) {
      QDir dSys( *it );

      if ( dSys.exists() ) {
        dSys.setFilter( QDir::Files );
        dSys.setSorting( QDir::Name );
        dSys.setNameFilters(QStringList(QStringLiteral("*.ad")));
        list += dSys.entryList();
      }
    }

    for (QStringList::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it)
      copyFile(tmpFile, QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kdisplay/app-defaults/"+(*it)), true);
  }

  // Merge ~/.Xresources or fallback to ~/.Xdefaults
  QString homeDir = QDir::homePath();
  QString xResources = homeDir + "/.Xresources";

  // very primitive support for ~/.Xresources by appending it
  if ( QFile::exists( xResources ) )
    copyFile(tmpFile, xResources, true);
  else
    copyFile(tmpFile, homeDir + "/.Xdefaults", true);

  // Export the Xcursor theme & size settings
  KConfigGroup mousecfg(KSharedConfig::openConfig( QStringLiteral("kcminputrc") ), "Mouse" );
  QString theme = mousecfg.readEntry("cursorTheme", QString());
  QString size  = mousecfg.readEntry("cursorSize", QString());
  QString contents;

  if (!theme.isNull())
    contents = "Xcursor.theme: " + theme + '\n';

  if (!size.isNull())
    contents += "Xcursor.size: " + size + '\n';

  if (exportXftSettings)
  {
    if (generalCfgGroup.hasKey("XftAntialias"))
    {
      contents += QLatin1String("Xft.antialias: ");
      if(generalCfgGroup.readEntry("XftAntialias", true))
        contents += QLatin1String("1\n");
      else
        contents += QLatin1String("0\n");
    }

    if (generalCfgGroup.hasKey("XftHintStyle"))
    {
      QString hintStyle = generalCfgGroup.readEntry("XftHintStyle", "hintmedium");
      contents += QLatin1String("Xft.hinting: ");
      if(hintStyle.isEmpty())
        contents += QLatin1String("-1\n");
      else
      {
        if(hintStyle!=QLatin1String("hintnone"))
          contents += QLatin1String("1\n");
        else
          contents += QLatin1String("0\n");
        contents += "Xft.hintstyle: " + hintStyle + '\n';
      }
    }

    if (generalCfgGroup.hasKey("XftSubPixel"))
    {
      QString subPixel = generalCfgGroup.readEntry("XftSubPixel");
      if(!subPixel.isEmpty())
        contents += "Xft.rgba: " + subPixel + '\n';
    }

    KConfig _cfgfonts( QStringLiteral("kcmfonts") );
    KConfigGroup cfgfonts(&_cfgfonts, "General");

    if( cfgfonts.readEntry( "forceFontDPI", 0 ) != 0 )
      contents += "Xft.dpi: " + cfgfonts.readEntry( "forceFontDPI" ) + '\n';
    else
    {
      KProcess proc;
      proc << QStringLiteral("xrdb") << QStringLiteral("-quiet") << QStringLiteral("-remove") << QStringLiteral("-nocpp");
      proc.start();
      if (proc.waitForStarted())
      {
        proc.write( QByteArray( "Xft.dpi\n" ) );
        proc.closeWriteChannel();
        proc.waitForFinished();
      }
    }
  }

  if (contents.length() > 0)
    tmpFile.write( contents.toLatin1(), contents.length() );

  tmpFile.flush();

  KProcess proc;
#ifndef NDEBUG
  proc << QStringLiteral("xrdb") << QStringLiteral("-merge") << tmpFile.fileName();
#else
  proc << "xrdb" << "-quiet" << "-merge" << tmpFile.fileName();
#endif
  proc.execute();

  applyGtkStyles(exportColors, 1);
  applyGtkStyles(exportColors, 2);

  /* Qt exports */
  if ( exportQtColors || exportQtSettings )
  {
    QSettings* settings = new QSettings(QStringLiteral("Trolltech"));

    if ( exportQtColors )
      applyQtColors( kglobalcfg, *settings, newPal );    // For kcmcolors

    if ( exportQtSettings )
      applyQtSettings( kglobalcfg, *settings );          // For kcmstyle

    delete settings;
    QApplication::flush();
#if HAVE_X11
    if (qApp->platformName() == QStringLiteral("xcb")) {
        // We let KIPC take care of ourselves, as we are in a KDE app with
        // QApp::setDesktopSettingsAware(false);
        // Instead of calling QApp::x11_apply_settings() directly, we instead
        // modify the timestamp which propagates the settings changes onto
        // Qt-only apps without adversely affecting ourselves.

        // Cheat and use the current timestamp, since we just saved to qtrc.
        QDateTime settingsstamp = QDateTime::currentDateTime();

        static Atom qt_settings_timestamp = 0;
        if (!qt_settings_timestamp) {
            QString atomname(QStringLiteral("_QT_SETTINGS_TIMESTAMP_"));
            atomname += XDisplayName( 0 ); // Use the $DISPLAY envvar.
            qt_settings_timestamp = XInternAtom( QX11Info::display(), atomname.toLatin1(), False);
        }

        QBuffer stamp;
        QDataStream s(&stamp.buffer(), QIODevice::WriteOnly);
        s << settingsstamp;
        XChangeProperty( QX11Info::display(), QX11Info::appRootWindow(), qt_settings_timestamp,
                        qt_settings_timestamp, 8, PropModeReplace,
                        (unsigned char*) stamp.buffer().data(),
                        stamp.buffer().size() );
        QApplication::flush();
    }
#endif
  }

  //Legacy support:
  //Try to sync kde4 settings with ours

  Kdelibs4Migration migration;
  //kf5 congig groups for general and icons
  KConfigGroup generalGroup(kglobalcfg, "General");
  KConfigGroup iconsGroup(kglobalcfg, "Icons");

  const QString colorSchemeName = generalGroup.readEntry("ColorScheme", QString());
  //if no valid color scheme saved, something weird is going on, abort
  if (colorSchemeName.isEmpty()) {
      return;
  }
  //fix filename, copied from ColorsCM::saveScheme()
  QString colorSchemeFilename = colorSchemeName;
  colorSchemeFilename.remove('\''); // So Foo's does not become FooS
  QRegExp fixer(QStringLiteral("[\\W,.-]+(.?)"));
  int offset;
  while ((offset = fixer.indexIn(colorSchemeFilename)) >= 0)
      colorSchemeFilename.replace(offset, fixer.matchedLength(), fixer.cap(1).toUpper());
  colorSchemeFilename.replace(0, 1, colorSchemeFilename.at(0).toUpper());

  //clone the color scheme
  QString src = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "color-schemes/" +  colorSchemeFilename + ".colors");
  QString dest = migration.saveLocation("data", QStringLiteral("color-schemes")) + colorSchemeName + ".colors";

  QFile::remove(dest);
  QFile::copy(src, dest);

  //Apply the color scheme
  QString configFilePath = migration.saveLocation("config") + "kdeglobals";

  if (configFilePath.isEmpty()) {
      return;
  }

  KConfig kde4config(configFilePath, KConfig::SimpleConfig);

  KConfigGroup kde4generalGroup(&kde4config, "General");
  kde4generalGroup.writeEntry("ColorScheme", colorSchemeName);

  //fonts
  QString font = generalGroup.readEntry("font", QString());
  if (!font.isEmpty()) {
      kde4generalGroup.writeEntry("font", font);
  }
  font = generalGroup.readEntry("desktopFont", QString());
  if (!font.isEmpty()) {
      kde4generalGroup.writeEntry("desktopFont", font);
  }
  font = generalGroup.readEntry("menuFont", QString());
  if (!font.isEmpty()) {
      kde4generalGroup.writeEntry("menuFont", font);
  }
  font = generalGroup.readEntry("smallestReadableFont", QString());
  if (!font.isEmpty()) {
      kde4generalGroup.writeEntry("smallestReadableFont", font);
  }
  font = generalGroup.readEntry("taskbarFont", QString());
  if (!font.isEmpty()) {
      kde4generalGroup.writeEntry("taskbarFont", font);
  }
  font = generalGroup.readEntry("toolBarFont", QString());
  if (!font.isEmpty()) {
      kde4generalGroup.writeEntry("toolBarFont", font);
  }

  //TODO: does exist any way to check if a qt4 widget style is present from a qt5 app?
  //kde4generalGroup.writeEntry("widgetStyle", "qtcurve");
  kde4generalGroup.sync();

  KConfigGroup kde4IconGroup(&kde4config, "Icons");
  QString iconTheme = iconsGroup.readEntry("Theme", QString());
  if (!iconTheme.isEmpty()) {
      kde4IconGroup.writeEntry("Theme", iconTheme);
  }
  kde4IconGroup.sync();

  //copy all the groups in the color scheme in kdeglobals
  KSharedConfigPtr kde4ColorConfig = KSharedConfig::openConfig(src, KConfig::SimpleConfig);

  foreach (const QString &grp, kde4ColorConfig->groupList()) {
      KConfigGroup cg(kde4ColorConfig, grp);
      KConfigGroup cg2(&kde4config, grp);
      cg.copyTo(&cg2);
  }

  //widgets settings
  KConfigGroup kglobals4(&kde4config, "KDE");
  kglobals4.writeEntry("ShowIconsInMenuItems", kglobals.readEntry("ShowIconsInMenuItems", true));
  kglobals4.writeEntry("ShowIconsOnPushButtons", kglobals.readEntry("ShowIconsOnPushButtons", true));
  kglobals4.writeEntry("contrast", kglobals.readEntry("contrast", 4));
  //FIXME: this should somehow check if the kde4 version of the style is installed
  kde4generalGroup.writeEntry("widgetStyle", kglobals.readEntry("widgetStyle", "breeze"));

  //toolbar style
  KConfigGroup toolbars4(&kde4config, "Toolbar style");
  KConfigGroup toolbars5(kglobalcfg, "Toolbar style");
  toolbars4.writeEntry("ToolButtonStyle", toolbars5.readEntry("ToolButtonStyle", "TextBesideIcon"));
  toolbars4.writeEntry("ToolButtonStyleOtherToolbars", toolbars5.readEntry("ToolButtonStyleOtherToolbars", "TextBesideIcon"));
}
Example #3
0
QByteArray* QgsWCSServer::getCoverage()
{
  QStringList wcsLayersId = mConfigParser->wcsLayers();

  QList<QgsMapLayer*> layerList;

  QStringList mErrors = QStringList();

  //defining coverage name
  QString coveName = "";
  //read COVERAGE
  QMap<QString, QString>::const_iterator cove_name_it = mParameters.find( "COVERAGE" );
  if ( cove_name_it != mParameters.end() )
  {
    coveName = cove_name_it.value();
  }
  if ( coveName == "" )
  {
    QMap<QString, QString>::const_iterator cove_name_it = mParameters.find( "IDENTIFIER" );
    if ( cove_name_it != mParameters.end() )
    {
      coveName = cove_name_it.value();
    }
  }

  if ( coveName == "" )
  {
    mErrors << QString( "COVERAGE is mandatory" );
  }

  layerList = mConfigParser->mapLayerFromCoverage( coveName );
  if ( layerList.size() < 1 )
  {
    mErrors << QString( "The layer for the COVERAGE '%1' is not found" ).arg( coveName );
  }

  bool conversionSuccess;
  // BBOX
  bool bboxOk = false;
  double minx = 0.0, miny = 0.0, maxx = 0.0, maxy = 0.0;
  // WIDTh and HEIGHT
  int width = 0, height = 0;
  // CRS
  QString crs = "";

  // read BBOX
  QMap<QString, QString>::const_iterator bbIt = mParameters.find( "BBOX" );
  if ( bbIt == mParameters.end() )
  {
    minx = 0; miny = 0; maxx = 0; maxy = 0;
  }
  else
  {
    bboxOk = true;
    QString bbString = bbIt.value();
    minx = bbString.section( ",", 0, 0 ).toDouble( &conversionSuccess );
    if ( !conversionSuccess ) {bboxOk = false;}
    miny = bbString.section( ",", 1, 1 ).toDouble( &conversionSuccess );
    if ( !conversionSuccess ) {bboxOk = false;}
    maxx = bbString.section( ",", 2, 2 ).toDouble( &conversionSuccess );
    if ( !conversionSuccess ) {bboxOk = false;}
    maxy = bbString.section( ",", 3, 3 ).toDouble( &conversionSuccess );
    if ( !conversionSuccess ) {bboxOk = false;}
  }
  if ( !bboxOk )
  {
    mErrors << QString( "The BBOX is mandatory and has to be xx.xxx,yy.yyy,xx.xxx,yy.yyy" );
  }

  // read WIDTH
  width = mParameters.value( "WIDTH", "0" ).toInt( &conversionSuccess );
  if ( !conversionSuccess )
    width = 0;
  // read HEIGHT
  height = mParameters.value( "HEIGHT", "0" ).toInt( &conversionSuccess );
  if ( !conversionSuccess )
  {
    height = 0;
  }

  if ( width < 0 || height < 0 )
  {
    mErrors << QString( "The WIDTH and HEIGHT are mandatory and have to be integer" );
  }

  crs = mParameters.value( "CRS", "" );
  if ( crs == "" )
  {
    mErrors << QString( "The CRS is mandatory" );
  }

  if ( mErrors.count() != 0 )
  {
    throw QgsMapServiceException( "RequestNotWellFormed", mErrors.join( ". " ) );
  }

  QgsCoordinateReferenceSystem requestCRS = QgsCRSCache::instance()->crsByAuthId( crs );
  if ( !requestCRS.isValid() )
  {
    mErrors << QString( "Could not create request CRS" );
    throw QgsMapServiceException( "RequestNotWellFormed", mErrors.join( ". " ) );
  }

  QgsRectangle rect( minx, miny, maxx, maxy );

  QgsMapLayer* layer = layerList.at( 0 );
  QgsRasterLayer* rLayer = dynamic_cast<QgsRasterLayer*>( layer );
  if ( rLayer && wcsLayersId.contains( rLayer->id() ) )
  {
    // RESPONSE_CRS
    QgsCoordinateReferenceSystem responseCRS = rLayer->crs();
    crs = mParameters.value( "RESPONSE_CRS", "" );
    if ( crs != "" )
    {
      responseCRS = QgsCRSCache::instance()->crsByAuthId( crs );
      if ( !responseCRS.isValid() )
      {
        responseCRS = rLayer->crs();
      }
    }

    // transform rect
    if ( requestCRS != rLayer->crs() )
    {
      QgsCoordinateTransform t( requestCRS, rLayer->crs() );
      rect = t.transformBoundingBox( rect );
    }

    QTemporaryFile tempFile;
    tempFile.open();
    QgsRasterFileWriter fileWriter( tempFile.fileName() );

    // clone pipe/provider
    QgsRasterPipe* pipe = new QgsRasterPipe();
    if ( !pipe->set( rLayer->dataProvider()->clone() ) )
    {
      mErrors << QString( "Cannot set pipe provider" );
      throw QgsMapServiceException( "RequestNotWellFormed", mErrors.join( ". " ) );
    }

    // add projector if necessary
    if ( responseCRS != rLayer->crs() )
    {
      QgsRasterProjector * projector = new QgsRasterProjector;
      projector->setCRS( rLayer->crs(), responseCRS );
      if ( !pipe->insert( 2, projector ) )
      {
        mErrors << QString( "Cannot set pipe projector" );
        throw QgsMapServiceException( "RequestNotWellFormed", mErrors.join( ". " ) );
      }
    }

    QgsRasterFileWriter::WriterError err = fileWriter.writeRaster( pipe, width, height, rect, responseCRS );
    if ( err != QgsRasterFileWriter::NoError )
    {
      mErrors << QString( "Cannot write raster error code: %1" ).arg( err );
      throw QgsMapServiceException( "RequestNotWellFormed", mErrors.join( ". " ) );
    }
    delete pipe;
    QByteArray* ba = 0;
    ba = new QByteArray();
    *ba = tempFile.readAll();

    return ba;
  }
  return 0;
}
Example #4
0
void WBHistoryManager::save()
{
    QSettings settings;
    settings.beginGroup(QLatin1String("history"));
    settings.setValue(QLatin1String("historyLimit"), m_historyLimit);

    bool saveAll = m_lastSavedUrl.isEmpty();
    int first = m_history.count() - 1;
    if (!saveAll)
    {
        // find the first one to save
        for (int i = 0; i < m_history.count(); ++i)
        {
            if (m_history.at(i).url == m_lastSavedUrl)
            {
                first = i - 1;
                break;
            }
        }
    }
    if (first == m_history.count() - 1)
        saveAll = true;

    QString directory = UBSettings::userDataDirectory();
    if (directory.isEmpty())
        directory = QDir::homePath() + QLatin1String("/.") + QCoreApplication::applicationName();
    if (!QFile::exists(directory))
    {
        QDir dir;
        dir.mkpath(directory);
    }

    QFile historyFile(directory + QLatin1String("/history"));
    // When saving everything use a temporary file to prevent possible data loss.
    QTemporaryFile tempFile;
    tempFile.setAutoRemove(false);
    bool open = false;
    if (saveAll)
    {
        open = tempFile.open();
    } else {
        open = historyFile.open(QFile::Append);
    }

    if (!open)
    {
        qWarning() << "Unable to open history file for saving"
                   << (saveAll ? tempFile.fileName() : historyFile.fileName());
        return;
    }

    QDataStream out(saveAll ? &tempFile : &historyFile);
    for (int i = first; i >= 0; --i)
    {
        QByteArray data;
        QDataStream stream(&data, QIODevice::WriteOnly);
        WBHistoryItem item = m_history.at(i);
        stream << HISTORY_VERSION << item.url << item.dateTime << item.title;
        out << data;
    }
    tempFile.close();

    if (saveAll)
    {
        if (historyFile.exists() && !historyFile.remove())
            qWarning() << "History: error removing old history." << historyFile.errorString();
        if (!tempFile.rename(historyFile.fileName()))
            qWarning() << "History: error moving new history over old." << tempFile.errorString() << historyFile.fileName();
    }
    m_lastSavedUrl = m_history.value(0).url;
}
Example #5
0
void ut_file::testRevertRestore()
{
   QTemporaryFile testFile;
   testFile.open();

   QuillImage image = Unittests::generatePaletteImage();
   image.save(testFile.fileName(), "png");

   QuillImageFilter *filter =
       QuillImageFilterFactory::createImageFilter(QuillImageFilter::Name_BrightnessContrast);
   QVERIFY(filter);
   filter->setOption(QuillImageFilter::Brightness, QVariant(20));
   QuillImage imageAfter = filter->apply(image);

   QuillFile *file = new QuillFile(testFile.fileName(), Strings::png);
   QVERIFY(file->setDisplayLevel(0));
   QCOMPARE(file->canRestore(),false);
   QCOMPARE(file->canRevert(),false);
   file->runFilter(filter);
   Quill::releaseAndWait();
   Quill::releaseAndWait();
   QCOMPARE(file->canRestore(),false);
   QCOMPARE(file->canRevert(),true);
   QuillImageFilter *filter1 =
       QuillImageFilterFactory::createImageFilter(QuillImageFilter::Name_Rotate);

   filter1->setOption(QuillImageFilter::Angle, QVariant(-90));
   QuillImage imageAfter1 = filter1->apply(imageAfter);
   file->runFilter(filter1);
   Quill::releaseAndWait();
   Quill::releaseAndWait();
   QCOMPARE(file->canRestore(),false);
   QCOMPARE(file->canRevert(),true);

   //Test revert
   file->revert();
   Quill::releaseAndWait();
   Quill::releaseAndWait();
   QCOMPARE(file->canRestore(),true);
   QCOMPARE(file->canRevert(),false);
   QCOMPARE(file->internalFile()->m_stack->revertIndex(),3);
   QVERIFY(Unittests::compareImage(file->image(), image));
   file->save();
   Quill::releaseAndWait();
   Quill::releaseAndWait();

   //Test restore
   file->restore();
   Quill::releaseAndWait();
   Quill::releaseAndWait();
   QCOMPARE(file->canRestore(),false);
   QCOMPARE(file->canRevert(),true);
   QCOMPARE(file->internalFile()->m_stack->revertIndex(),0);
   QVERIFY(Unittests::compareImage(file->image(), imageAfter1));

   //Test redo with revert and restore
   file->revert();
   Quill::releaseAndWait();
   Quill::releaseAndWait();
   QCOMPARE(file->canRestore(),true);
   QCOMPARE(file->canRevert(),false);
   QCOMPARE(file->internalFile()->m_stack->revertIndex(),3);
   file->redo();
   QCOMPARE(file->canRestore(),false);
   QCOMPARE(file->canRevert(),true);
   QCOMPARE(file->internalFile()->m_stack->revertIndex(),0);

   //Test one additional operation after revert
   file->revert();
   Quill::releaseAndWait();
   Quill::releaseAndWait();
   QCOMPARE(file->canRestore(),true);
   QCOMPARE(file->canRevert(),false);
   QCOMPARE(file->internalFile()->m_stack->revertIndex(),2);
   QuillImageFilter *filter2 =
       QuillImageFilterFactory::createImageFilter(QuillImageFilter::Name_Rotate);

   filter2->setOption(QuillImageFilter::Angle, QVariant(-90));
   file->runFilter(filter2);
   QCOMPARE(file->canRestore(),false);
   QCOMPARE(file->canRevert(),true);
   QCOMPARE(file->internalFile()->m_stack->revertIndex(),0);

   delete file;
}
Example #6
0
int TorrentPlugin::AddJob (Entity e)
{
    QString suggestedFname;

    if (e.Entity_.canConvert<QUrl> ())
    {
        QUrl resource = e.Entity_.toUrl ();
        if (resource.scheme () == "magnet")
        {
            QString at = XmlSettingsManager::Instance ()->
                         property ("AutomaticTags").toString ();
            QStringList tags = e.Additional_ [" Tags"].toStringList ();
            Q_FOREACH (QString tag, Core::Instance ()->GetProxy ()->
                       GetTagsManager ()->Split (at))
                tags << Core::Instance ()->GetProxy ()->
                     GetTagsManager ()->GetID (tag);

            QList<QPair<QString, QString> > queryItems = resource.queryItems ();
            for (QList<QPair<QString, QString> >::const_iterator i = queryItems.begin (),
                    end = queryItems.end (); i != end; ++i)
                if (i->first == "kt")
                {
                    QStringList humanReadable = i->second
                                                .split ('+', QString::SkipEmptyParts);
                    Q_FOREACH (QString hr, humanReadable)
                        tags += Core::Instance ()->GetProxy ()->
                                GetTagsManager ()->GetID (hr);
                }

            return Core::Instance ()->AddMagnet (resource.toString (),
                                                 e.Location_,
                                                 tags,
                                                 e.Parameters_);
        }
        else if (resource.scheme () == "file")
            suggestedFname = resource.toLocalFile ();
    }

    QByteArray entity = e.Entity_.toByteArray ();

    QFile file (suggestedFname);
    if ((!file.exists () ||
            !file.open (QIODevice::ReadOnly)) &&
            Core::Instance ()->IsValidTorrent (entity))
    {
        QTemporaryFile file ("lctemporarybittorrentfile.XXXXXX");
        if (!file.open  ())
            return -1;
        file.write (entity);
        suggestedFname = file.fileName ().toUtf8 ();
        file.setAutoRemove (false);
    }

    AddTorrentDialog_->Reinit ();
    AddTorrentDialog_->SetFilename (suggestedFname);
    if (!e.Location_.isEmpty ())
        AddTorrentDialog_->SetSavePath (e.Location_);

    QString path;
    QStringList tags = e.Additional_ [" Tags"].toStringList ();
    QVector<bool> files;
    QString fname;
    bool tryLive = e.Additional_ ["TryToStreamLive"].toBool ();
    if (e.Parameters_ & FromUserInitiated)
    {
        if (!tags.isEmpty ())
            AddTorrentDialog_->SetTags (tags);

        if (AddTorrentDialog_->exec () == QDialog::Rejected)
            return -1;

        fname = AddTorrentDialog_->GetFilename (),
        path = AddTorrentDialog_->GetSavePath ();
        tryLive = AddTorrentDialog_->GetTryLive ();
        files = AddTorrentDialog_->GetSelectedFiles ();
        tags = AddTorrentDialog_->GetTags ();
        if (AddTorrentDialog_->GetAddType () == Core::Started)
            e.Parameters_ &= ~NoAutostart;
        else
            e.Parameters_ |= NoAutostart;
    }
    else
    {
        fname = suggestedFname;
        path = e.Location_;
        QString at = XmlSettingsManager::Instance ()->
                     property ("AutomaticTags").toString ();
        Q_FOREACH (QString tag, Core::Instance ()->GetProxy ()->
                   GetTagsManager ()->Split (at))
            tags << Core::Instance ()->GetProxy ()->
                 GetTagsManager ()->GetID (tag);
    }
    int result = Core::Instance ()->AddFile (fname,
                 path,
                 tags,
                 tryLive,
                 files,
                 e.Parameters_);
    setActionsEnabled ();
    file.remove ();
    return result;
}
void doTests() {

  KstVectorPtr vp = new KstVector(KstObjectTag::fromString("tempVector"), 10);
  for (int i = 0; i < 10; i++){
    vp->value()[i] = i;
  }

  KstPSDPtr psd = new KstPSD(QString("psdTest"), vp, 0.0, false, 10, false, false, QString("vUnits"), QString("rUnits"), WindowUndefined, 0.0, PSDUndefined);
  doTest(psd->tagName() == "psdTest");
  doTest(psd->vTag() == "tempVector");
  doTest(psd->output() == PSDUndefined);
  doTest(!psd->apodize());
  doTest(!psd->removeMean());
  doTest(!psd->average());
  doTest(psd->freq() == 0.0);
  doTest(psd->apodizeFxn() == WindowUndefined);
  doTest(psd->gaussianSigma() == 0);
  KstVectorPtr vpVX = psd->vX();
  KstVectorPtr vpVY = psd->vY();

  doTest(vpVX->length() == 1);
  doTest(vpVX->value()[0] != vpVX->value()[0]);
  doTest(vpVY->length() == 1);
  doTest(vpVY->value()[0] != vpVY->value()[0]);

  psd->writeLock();
  doTest(psd->update(0) == KstObject::UPDATE);
  psd->unlock();
 
  for(int j = 0; j < vpVX->length(); j++){
      doTest(vpVX->value()[j] == 0);
  }

  psd->setOutput(PSDAmplitudeSpectralDensity);
  psd->setApodize(true);
  psd->setRemoveMean(true);
  psd->setAverage(true);
  psd->setFreq(0.1);
  psd->setApodizeFxn(WindowOriginal);
  psd->setGaussianSigma(0.2);

  doTest(psd->tagName() == "psdTest");
  doTest(psd->vTag() == "tempVector");
  doTest(psd->output() == PSDAmplitudeSpectralDensity);
  doTest(psd->apodize());
  doTest(psd->removeMean());
  doTest(psd->average());
  doTest(psd->freq() == 0.1);
  doTest(psd->apodizeFxn() == WindowOriginal);
  doTest(psd->gaussianSigma() == 0.2);
  
//   doTest(psd->update(0) == KstObject::UPDATE);
//   QString ps = "PSD: " + psd->vTag();
//   doTest(psd->propertyString() == ps);
//    doTest(!psd->curveHints().curveName() == "");
//   printf("Curve name [%s]", kstCHL[0].curveName());
//   printf("X Vector name [%s]", kstCHL[0].xVectorName());
//   printf("Y Vector name [%s]", kstCHL[0].yVectorName());

  QTemporaryFile tf;
  tf.open();
  QTextStream ts(&tf);
  psd->save(ts, "");
  QFile::remove(tf.fileName());

  QDomNode n = makeDOMElement("psdDOMPsd", "psdDOMVector").firstChild();
  QDomElement e = n.toElement();
  KstPSDPtr psdDOM = new KstPSD(e);

  doTest(psdDOM->tagName() == "psdDOMPsd");
  doTest(psdDOM->output() == PSDAmplitudeSpectralDensity);
  doTest(psdDOM->apodize());
  doTest(psdDOM->removeMean());
  doTest(psdDOM->average());
  doTest(psdDOM->freq() == 128);
  doTest(psdDOM->apodizeFxn() == WindowOriginal);
  doTest(psdDOM->gaussianSigma() == 0.01);

//   KstVectorPtr vpVX = psdDOM->vX();
//   for(int j = 0; j < vpVX->length(); j++){
//       printf("[%d][%lf]", j, vpVX->value()[j]);
//   }
//   KstVectorPtr vpVY = psdDOM->vY();
}
Example #8
0
int process( const QDir &input, const QDir &output, const QString &xml )
{
    QSqlDatabase database = QSqlDatabase::addDatabase( "QSQLITE" );
    database.setDatabaseName( input.filePath( "speakers.db" ) );
    if ( !database.open() ) {
        qDebug() << "Failed to connect to database " << input.filePath( "speakers.db" );
        return 3;
    }

    output.mkdir( "files.kde.org" );
    QSqlQuery query( "SELECT * FROM speakers ORDER BY Id" );

    QFile xmlFile( xml );
    if ( !xmlFile.open( QFile::WriteOnly | QFile::Truncate ) ) {
        qDebug() << "Failed to write to " << xmlFile.fileName();
        return 3;
    }

    QTextStream xmlOut( &xmlFile );
    xmlOut << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
    xmlOut << "<!DOCTYPE knewstuff SYSTEM \"knewstuff.dtd\">\n";
    xmlOut << "<?xml-stylesheet type=\"text/xsl\" href=\"speakers.xsl\" ?>\n";
    xmlOut << "<knewstuff>\n";

    int index = 71;
    while (query.next()) {
        QString const name = query.value(1).toString();
        QString const email = query.value(2).toString();
        QString const nick = query.value(3).toString();
        QString const gender = query.value(4).toString();
        QString const language = query.value(5).toString();
        QString const lang = language.mid(0, language.indexOf(QLatin1Char('(')) - 1).replace(QLatin1Char(' '), QLatin1Char('-'));
        QString const description = query.value(6).toString();
        QString const token = query.value(7).toString();
        QString const date = query.value(8).toString();
        QString const zip = input.filePath( token );
        QTemporaryFile tmpFile;
        tmpFile.open();
        QString const extracted = tmpFile.fileName();
        tmpFile.remove();
        QDir::root().mkdir( extracted );
        qDebug() << "Name: " << name;

        QString const simpleNick = QString( nick ).replace( QLatin1Char(' '), QLatin1Char('-') );
        QString const nickDir = output.filePath("files.kde.org") + QLatin1Char('/') + simpleNick;
        QDir::root().mkdir( nickDir );
        extract( zip, extracted );
        normalize( extracted );
        createLegalFiles( extracted, name, email );
        QFile::copy(extracted + QLatin1String("/Marble.ogg"), nickDir + QLatin1Char('/') + lang + QLatin1Char('-') + simpleNick + QLatin1String(".ogg"));
        convertToMarbleFormat(extracted, nickDir + QLatin1Char('/') + lang + QLatin1Char('-') + simpleNick + QLatin1String(".zip"));
        convertToTomTomFormat(extracted, nickDir, nick, simpleNick, index, gender == QLatin1String("male"), lang);
        convertToNewStuffFormat(extracted, nickDir + QLatin1Char('/') + lang + QLatin1Char('-') + simpleNick + QLatin1String(".tar.gz"));

        xmlOut << "  <stuff category=\"marble/data/audio\">\n";
        xmlOut << "    <name lang=\"en\">" << language << " - " << nick << " (" <<  gender << ")" << "</name>\n";
        xmlOut << "    <author>" << name << "</author>\n";
        xmlOut << "    <licence>CC-By-SA 3.0</licence>\n";
        xmlOut << "    <summary lang=\"en\">" << description << "</summary>\n";
        xmlOut << "    <version>0.1</version>\n";
        xmlOut << "    <releasedate>" << date << "</releasedate>\n";
        xmlOut << "    <preview lang=\"en\">http://edu.kde.org/marble/speaker-" << gender << ".png</preview>\n";
        xmlOut << "    <payload lang=\"en\">http://files.kde.org/marble/audio/speakers/" << simpleNick << "/" << lang << "-" << simpleNick << ".tar.gz</payload>\n";
        xmlOut << "    <payload lang=\"ogg\">http://files.kde.org/marble/audio/speakers/" << simpleNick << "/" << lang << "-" << simpleNick << ".ogg</payload>\n";
        xmlOut << "    <payload lang=\"zip\">http://files.kde.org/marble/audio/speakers/" << simpleNick << "/" << lang << "-" << simpleNick << ".zip</payload>\n";
        xmlOut << "    <payload lang=\"tomtom\">http://files.kde.org/marble/audio/speakers/" << simpleNick << "/" << lang << "-" << simpleNick << "-TomTom.zip</payload>\n";
        xmlOut << "  </stuff>\n";

        ++index;
    }

    xmlOut << "</knewstuff>\n";
    xmlFile.close();
    return 0;
}
Example #9
0
/**
 * generate layout and apply it to the given diagram.
 *
 * @return true if generating succeeded
*/
bool LayoutGenerator::generate(UMLScene *scene, const QString &variant)
{
    QTemporaryFile in;
    QTemporaryFile out;
    QTemporaryFile xdotOut;
    if (!isEnabled()) {
        uWarning() << "Could not apply autolayout because graphviz installation has not been found.";
        return false;
    }

#ifdef LAYOUTGENERATOR_DEBUG
    in.setAutoRemove(false);
    out.setAutoRemove(false);
    xdotOut.setAutoRemove(false);
#endif

    // generate filenames
    in.open();
    in.close();
    out.open();
    out.close();
    xdotOut.open();
    xdotOut.close();

#ifdef LAYOUTGENERATOR_DEBUG
    qDebug() << textViewer() << in.fileName();
    qDebug() << textViewer() << out.fileName();
    qDebug() << textViewer() << xdotOut.fileName();
#endif

    if (!createDotFile(scene, in.fileName(), variant))
        return false;

    QString executable = m_dotPath + QLatin1Char('/') + m_generator;

    QProcess p;
    QStringList args;
    args << QLatin1String("-o") << out.fileName() << QLatin1String("-Tplain-ext") << in.fileName();
    p.start(executable, args);
    p.waitForFinished();

    args.clear();
    args << QLatin1String("-o") << xdotOut.fileName() << QLatin1String("-Txdot") << in.fileName();
    p.start(executable, args);
    p.waitForFinished();

#ifdef LAYOUTGENERATOR_DEBUG
    QTemporaryFile pngFile;
    pngFile.setAutoRemove(false);
    pngFile.setFileTemplate(QDir::tempPath() + QLatin1String("/umbrello-layoutgenerator-XXXXXX.png"));
    pngFile.open();
    pngFile.close();
    qDebug() << pngViewer() << pngFile.fileName();
    args.clear();
    args << QLatin1String("-o") << pngFile.fileName() << QLatin1String("-Tpng") << in.fileName();
    p.start(executable, args);
    p.waitForFinished();
#endif
#ifndef USE_XDOT
    if (!readGeneratedDotFile(out.fileName()))
#else
    if (!readGeneratedDotFile(xdotOut.fileName()))
#endif
        return false;

    return true;
}
Example #10
0
bool Packaging::ExtractTar(QTemporaryFile& tarFile, PackageData *packageData)
{
	TarHeader tarHeader;

	if (!tarFile.open())
	{
		Alerts::DisplayError(QString("Error opening temporary TAR archive:\n%1").arg(tarFile.fileName()));
		return (false);
	}

	bool previousEmpty = false;

	QProgressDialog progressDialog("Extracting files...", "Cancel", 0, tarFile.size());
	progressDialog.setWindowModality(Qt::ApplicationModal);
	progressDialog.setWindowTitle("Heimdall Frontend");

	while (!tarFile.atEnd())
	{
		qint64 dataRead = tarFile.read(tarHeader.buffer, TarHeader::kBlockLength);

		if (dataRead != TarHeader::kBlockLength)
		{
			progressDialog.close();
			Alerts::DisplayError("Package's TAR archive is malformed.");

			tarFile.close();

			return (false);
		}

		progressDialog.setValue(tarFile.pos());

		if (progressDialog.wasCanceled())
		{
			tarFile.close();
			progressDialog.close();

			return (false);
		}

		//bool ustarFormat = strcmp(tarHeader.fields.magic, ustarMagic) == 0;
		bool empty = true;

		for (int i = 0; i < TarHeader::kBlockLength; i++)
		{
			if (tarHeader.buffer[i] != 0)
			{
				empty = false;
				break;
			}
		}

		if (empty)
		{
			if (previousEmpty)
			{
				// Two empty blocks in a row means we've reached the end of the archive.
				break;
			}
		}
		else
		{
			int checksum = 0;

			for (char *bufferIndex = tarHeader.buffer; bufferIndex < tarHeader.fields.checksum; bufferIndex++)
				checksum += static_cast<unsigned char>(*bufferIndex);

			checksum += 8 * ' ';
			checksum += static_cast<unsigned char>(tarHeader.fields.typeFlag);

			// Both the TAR and USTAR formats have terrible documentation, it's not clear if the following code is required.
			/*if (ustarFormat)
			{
				for (char *bufferIndex = tarHeader.fields.linkName; bufferIndex < tarHeader.fields.prefix + 155; bufferIndex++)
					checksum += static_cast<unsigned char>(*bufferIndex);
			}*/

			bool parsed = false;
		
			// The size field is not always null terminated, so we must create a copy and null terminate it for parsing.
			char fileSizeString[13];
			memcpy(fileSizeString, tarHeader.fields.size, 12);
			fileSizeString[12] = '\0';

			qulonglong fileSize = QString(fileSizeString).toULongLong(&parsed, 8);

			if (!parsed)
			{
				progressDialog.close();
				Alerts::DisplayError("Tar header contained an invalid file size.");

				tarFile.close();

				return (false);
			}

			if (fileSize > 0 && tarHeader.fields.typeFlag == '0')
			{
				// We're working with a file.
				QString filename = QString::fromUtf8(tarHeader.fields.name);

				QTemporaryFile *outputFile = new QTemporaryFile("XXXXXX-" + filename);
				packageData->GetFiles().append(outputFile);

				if (!outputFile->open())
				{
					progressDialog.close();
					Alerts::DisplayError(QString("Failed to open output file: \n%1").arg(outputFile->fileName()));

					tarFile.close();

					return (false);
				}

				qulonglong dataRemaining = fileSize;
				char readBuffer[TarHeader::kBlockReadCount * TarHeader::kBlockLength];

				// Copy the file contents from tarFile to outputFile
				while (dataRemaining > 0)
				{
					qint64 fileDataToRead = (dataRemaining < TarHeader::kBlockReadCount * TarHeader::kBlockLength)
						? dataRemaining : TarHeader::kBlockReadCount * TarHeader::kBlockLength;

					qint64 dataRead = tarFile.read(readBuffer, fileDataToRead + (TarHeader::kBlockLength - fileDataToRead % TarHeader::kBlockLength) % TarHeader::kBlockLength);

					if (dataRead < fileDataToRead || dataRead % TarHeader::kBlockLength != 0)
					{
						progressDialog.close();
						Alerts::DisplayError("Unexpected read error whilst extracting package files.");

						tarFile.close();
						outputFile->close();

						remove(outputFile->fileName().toStdString().c_str());

						return (false);
					}

					outputFile->write(readBuffer, fileDataToRead);

					dataRemaining -= fileDataToRead;

					progressDialog.setValue(tarFile.pos());

					if (progressDialog.wasCanceled())
					{
						tarFile.close();
						outputFile->close();

						remove(outputFile->fileName().toStdString().c_str());

						progressDialog.close();

						return (false);
					}
				}

				outputFile->close();
			}
			else
			{
				progressDialog.close();
				Alerts::DisplayError("Heimdall packages shouldn't contain links or directories.");

				tarFile.close();

				return (false);
			}
		}

		previousEmpty = empty;
	}

	progressDialog.close();
	tarFile.close();

	return (true);
}
Example #11
0
QString createObjectsAndTypesPage(PandaDocument* document)
{
    static QTemporaryFile file(QDir::tempPath() + "/pandaRef_XXXXXX.html");
    file.open();
    file.resize(0);

    QTextStream out(&file);
    out << "<!DOCTYPE html>\n"
        "<html lang=\"en\">\n"
        " <head>\n"
        "  <meta charset=\"utf-8\">\n"
        "  <title>List of available objects and types for Panda</title>\n"
        " </head>\n"
        " <body>\n";

    out << "  <h1>Types</h1>\n";

    auto dataEntriesList = DataFactory::entries();
    std::sort(dataEntriesList.begin(), dataEntriesList.end(), dataTypeIdLessThan);

    std::vector<EnrichedDataEntry> dataEntries;
    // Copy entries and get additional info
    for(auto d : dataEntriesList)
    {
        EnrichedDataEntry e = *d;
        auto tmpData = DataFactory::create(d->fullType, "", "", nullptr);
        if(tmpData)
        {
            e.description = tmpData->getDescription();
            e.trait = tmpData->getDataTrait();
        }

        dataEntries.push_back(e);
    }

    for(const auto& d : dataEntries)
    {
        out << "   <h2>" << QString::fromStdString(d.description) << "</h2>\n"
            << "    <p>Type: " << toHtml(d.className) << "</p>\n"
            << "    <p>Id: " << d.fullType << "</p>\n";

        bool hasConversions = false;
        for(const auto& d2 : dataEntries)
        {
            if(d.fullType == d2.fullType)
                continue;

            if(!d.trait || !d2.trait)
                continue;

            if(canConvert(d.trait, d2.trait))
            {
                if(!hasConversions)
                {
                    out << "    <p>Can be converted to: ";
                    hasConversions = true;
                }
                else
                    out << ", ";
                out << QString::fromStdString(d2.description);
            }
        }
        if(!hasConversions)
            out << "    <p>Has no known conversion";
        out << "</p>\n";

        auto widgets = DataWidgetFactory::getInstance()->getWidgetNames(d.fullType);
        if(widgets.empty())
            out << "    <p>No widgets for this type</p>\n";
        else
        {
            out << "    <p>Widgets available: ";
            bool first = true;
            for(const auto& w : widgets)
            {
                if(first)
                    first = false;
                else
                    out << ", ";
                out << w;
            }
            out << "</p>\n";
        }
    }

    out << "  <h1>Objects</h1>\n";

    std::vector<ObjectFactory::ClassEntry> objectsEntries;
    for(const auto& object : ObjectFactory::registryMap())
        objectsEntries.push_back(object.second);
    std::sort(objectsEntries.begin(), objectsEntries.end(), objectsMenuLessThan);

    for(const auto& o : objectsEntries)
    {
        out << "   <h2>" << QString::fromStdString(o.menuDisplay) << "</h2>\n";
        out << "	<p>In module: " << toHtml(o.moduleName) << "</p>\n";
        out << "    <p>Type: " << toHtml(o.className) << "</p>\n";
        out << "    <p>" << QString::fromStdString(o.description) << "</p>\n";

        if(o.creator)
        {
            auto object = o.creator->create(document);

            auto datas = object->getDatas();
            if(!datas.empty())
                out << "    <h3>Datas</h3>\n";
            for(auto d : datas)
            {
                out << "     <p>" << QString::fromStdString(d->getName()) << ": "
                    << QString::fromStdString(d->getDescription()) << ". "
                    << QString::fromStdString(d->getHelp()) << "</p>\n";
            }
        }
    }

    out << " </body>\n"
        "</html>\n";

    return file.fileName();
}