<commit_before>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software
 * Foundation.  See file COPYING.
 *
 */

#include "msg/SimpleMessenger.h"
#include "messages/MMonGetMap.h"
#include "messages/MMonMap.h"
#include "messages/MClientMount.h"

#include "include/nstring.h"

#include "messages/MClientMountAck.h"
#include "messages/MMonSubscribe.h"
#include "messages/MMonSubscribeAck.h"
#include "common/ConfUtils.h"

#include "MonClient.h"
#include "MonMap.h"

#include "config.h"

#define DOUT_SUBSYS monc
#undef dout_prefix
#define dout_prefix *_dout << dbeginl << "monclient: "

/*
 * build an initial monmap with any known monitor
 * addresses.
 */
int MonClient::build_initial_monmap()
{
  // file?
  if (g_conf.monmap) {
    const char *monmap_fn = g_conf.monmap;
    int r = monmap.read(monmap_fn);
    if (r >= 0)
      return 0;
    char buf[80];
    cerr << "unable to read monmap from " << monmap_fn << ": " << strerror_r(errno, buf, sizeof(buf)) << std::endl;
  }

  // -m foo?
  if (g_conf.mon_host) {
    vector<entity_addr_t> addrs;
    if (parse_ip_port_vec(g_conf.mon_host, addrs)) {
      for (unsigned i=0; i<addrs.size(); i++) {
	entity_inst_t inst;
	inst.name = entity_name_t::MON(i);
	inst.addr = addrs[i];
	monmap.add_mon(inst);
      }
      return 0;
    }
    cerr << "unable to parse addrs in '" << g_conf.mon_host << "'" << std::endl;
  }

  // config file?
  ConfFile a(g_conf.conf);
  ConfFile b("ceph.conf");
  ConfFile *c = 0;

  if (a.parse())
    c = &a;
  else if (b.parse())
    c = &b;
  if (c) {
    static string monstr;
    for (int i=0; i<15; i++) {
      char monname[20];
      char *val = 0;
      sprintf(monname, "mon%d", i);
      c->read(monname, "mon addr", &val, 0);
      if (!val || !val[0])
	break;

      entity_inst_t inst;
      if (!parse_ip_port(val, inst.addr)) {
	cerr << "unable to parse conf's addr for " << monname << " (" << val << ")" << std::endl;
	continue;
      }
      inst.name = entity_name_t::MON(monmap.mon_inst.size());
      monmap.add_mon(inst);
    }
    if (monmap.size())
      return 0;
    cerr << "unable to find any monitors in conf" << std::endl;
    return -EINVAL;
  }

  cerr << "please specify monitors via -m monaddr or -c ceph.conf" << std::endl;
  return -ENOENT;
}

int MonClient::get_monmap()
{
  dout(10) << "get_monmap" << dendl;
  Mutex::Locker l(monc_lock);

  want_monmap = true;
  if (cur_mon < 0)
    _reopen_session();

  while (want_monmap)
    map_cond.Wait(monc_lock);

  dout(10) << "get_monmap done" << dendl;

  return 0;
}

int MonClient::get_monmap_privately()
{
  dout(10) << "get_monmap_privately" << dendl;
  Mutex::Locker l(monc_lock);

  SimpleMessenger *rank = NULL;
  bool temp_msgr = false;
  if (!messenger) {
    rank = new SimpleMessenger;
    rank->bind();
    rank->set_policy(entity_name_t::TYPE_MON, SimpleMessenger::Policy::lossy_fast_fail());
    messenger = rank->register_entity(entity_name_t::CLIENT(-1));
    messenger->add_dispatcher_head(this);
    rank->start(true);  // do not daemonize!
    temp_msgr = true;
  }

  int attempt = 10;
  int i = 0;
  srand(getpid());

  dout(10) << "have " << monmap.epoch << dendl;

  while (monmap.epoch == 0) {
    i = rand() % monmap.mon_inst.size();
    dout(10) << "querying " << monmap.mon_inst[i] << dendl;
    messenger->send_message(new MMonGetMap, monmap.mon_inst[i]);

    if (--attempt == 0)
      break;

    utime_t interval(1, 0);
    map_cond.WaitInterval(monc_lock, interval);
  }

  if (temp_msgr) {
    messenger->shutdown();
    rank->wait();
    messenger->destroy();
    messenger = 0;
  }

  if (monmap.epoch)
    return 0;
  return -1;
}

bool MonClient::ms_dispatch(Message *m)
{
  dout(10) << "dispatch " << *m << dendl;

  if (my_addr == entity_addr_t())
    my_addr = messenger->get_myaddr();

  switch (m->get_type()) {
  case CEPH_MSG_MON_MAP:
    handle_monmap((MMonMap*)m);
    return true;

  case CEPH_MSG_CLIENT_MOUNT_ACK:
    handle_mount_ack((MClientMountAck*)m);
    return true;

  case CEPH_MSG_MON_SUBSCRIBE_ACK:
    handle_subscribe_ack((MMonSubscribeAck*)m);
    return true;
  }

  return false;
}

void MonClient::handle_monmap(MMonMap *m)
{
  dout(10) << "handle_monmap " << *m << dendl;
  monc_lock.Lock();

  _finish_hunting();

  bufferlist::iterator p = m->monmapbl.begin();
  ::decode(monmap, p);

  _sub_got("monmap", monmap.get_epoch());

  map_cond.Signal();
  want_monmap = false;

  monc_lock.Unlock();
  delete m;
}

// -------------------
// MOUNT

void MonClient::_send_mount()
{
  dout(10) << "_send_mount" << dendl;
  _send_mon_message(new MClientMount);
  mount_started = g_clock.now();
}

void MonClient::init()
{
  dout(10) << "init" << dendl;
  messenger->add_dispatcher_head(this);

  Mutex::Locker l(monc_lock);
  timer.add_event_after(10.0, new C_Tick(this));
}

void MonClient::shutdown()
{
  timer.cancel_all_events();
}

int MonClient::mount(double mount_timeout)
{
  Mutex::Locker lock(monc_lock);

  if (clientid >= 0) {
    dout(5) << "already mounted" << dendl;;
    return 0;
  }

  // only first mounter does the work
  mounting++;
  if (mounting == 1) {
    if (cur_mon < 0)
      _reopen_session();
    else
      _send_mount();
  }
  while (clientid < 0 && !mount_err)
    mount_cond.Wait(monc_lock);
  mounting--;

  if (clientid >= 0) {
    dout(5) << "mount success, client" << clientid << dendl;

    _sub_want("monmap", monmap.get_epoch());
  }

  return mount_err;
}

void MonClient::handle_mount_ack(MClientMountAck* m)
{
  dout(10) << "handle_mount_ack " << *m << dendl;

  _finish_hunting();

  // monmap
  bufferlist::iterator p = m->monmap_bl.begin();
  ::decode(monmap, p);

  clientid = m->client;
  messenger->set_myname(entity_name_t::CLIENT(m->client.v));

  mount_cond.SignalAll();

  delete m;
}

// ---------

void MonClient::_send_mon_message(Message *m)
{
  assert(cur_mon >= 0);
  messenger->send_message(m, monmap.mon_inst[cur_mon]);
}

void MonClient::_pick_new_mon()
{
  if (cur_mon >= 0)
    messenger->mark_down(monmap.get_inst(cur_mon).addr);
  cur_mon = monmap.pick_mon(true);
  dout(10) << "_pick_new_mon picked mon" << cur_mon << dendl;
}

void MonClient::_reopen_session()
{
  dout(10) << "_reopen_session" << dendl;
  _pick_new_mon();
  if (mounting)
    _send_mount();
  if (!sub_have.empty())
    _renew_subs();
  if (!mounting && sub_have.empty()) {
    _send_mon_message(new MMonGetMap);
  }
}

bool MonClient::ms_handle_reset(Connection *con, const entity_addr_t& peer)
{
  dout(10) << "ms_handle_reset " << peer << dendl;
  if (hunting)
    return true;

  dout(0) << "hunting for new mon" << dendl;
  hunting = true;
  _reopen_session();
  return false;
}

void MonClient::_finish_hunting()
{
  if (hunting) {
    dout(0) << "found mon" << cur_mon << dendl;
    hunting = false;
  }
}

void MonClient::tick()
{
  dout(10) << "tick" << dendl;

  if (hunting) {
    dout(0) << "continuing hunt" << dendl;
    _reopen_session();
  } else {
    // just renew as needed
    utime_t now = g_clock.now();
    if (now > sub_renew_after)
      _renew_subs();

    int oldmon = monmap.pick_mon();
    messenger->send_keepalive(monmap.mon_inst[oldmon]);
  }

  timer.add_event_after(10.0, new C_Tick(this));
}

// ---------

void MonClient::_renew_subs()
{
  if (sub_have.empty()) {
    dout(10) << "renew_subs - empty" << dendl;
    return;
  }

  dout(10) << "renew_subs" << dendl;

  if (sub_renew_sent == utime_t())
    sub_renew_sent = g_clock.now();

  MMonSubscribe *m = new MMonSubscribe;
  m->what = sub_have;
  if (cur_mon < 0)
    _reopen_session();
  _send_mon_message(m);
}

void MonClient::handle_subscribe_ack(MMonSubscribeAck *m)
{
  _finish_hunting();

  if (sub_renew_sent != utime_t()) {
    sub_renew_after = sub_renew_sent;
    sub_renew_after += m->interval / 2.0;
    dout(10) << "handle_subscribe_ack sent " << sub_renew_sent << " renew after " << sub_renew_after << dendl;
    sub_renew_sent = utime_t();
  } else {
    dout(10) << "handle_subscribe_ack sent " << sub_renew_sent << ", ignoring" << dendl;
  }
}

<commit_msg>monclient: avoid dup subscribe messages<commit_after>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software
 * Foundation.  See file COPYING.
 *
 */

#include "msg/SimpleMessenger.h"
#include "messages/MMonGetMap.h"
#include "messages/MMonMap.h"
#include "messages/MClientMount.h"

#include "include/nstring.h"

#include "messages/MClientMountAck.h"
#include "messages/MMonSubscribe.h"
#include "messages/MMonSubscribeAck.h"
#include "common/ConfUtils.h"

#include "MonClient.h"
#include "MonMap.h"

#include "config.h"

#define DOUT_SUBSYS monc
#undef dout_prefix
#define dout_prefix *_dout << dbeginl << "monclient: "

/*
 * build an initial monmap with any known monitor
 * addresses.
 */
int MonClient::build_initial_monmap()
{
  // file?
  if (g_conf.monmap) {
    const char *monmap_fn = g_conf.monmap;
    int r = monmap.read(monmap_fn);
    if (r >= 0)
      return 0;
    char buf[80];
    cerr << "unable to read monmap from " << monmap_fn << ": " << strerror_r(errno, buf, sizeof(buf)) << std::endl;
  }

  // -m foo?
  if (g_conf.mon_host) {
    vector<entity_addr_t> addrs;
    if (parse_ip_port_vec(g_conf.mon_host, addrs)) {
      for (unsigned i=0; i<addrs.size(); i++) {
	entity_inst_t inst;
	inst.name = entity_name_t::MON(i);
	inst.addr = addrs[i];
	monmap.add_mon(inst);
      }
      return 0;
    }
    cerr << "unable to parse addrs in '" << g_conf.mon_host << "'" << std::endl;
  }

  // config file?
  ConfFile a(g_conf.conf);
  ConfFile b("ceph.conf");
  ConfFile *c = 0;

  if (a.parse())
    c = &a;
  else if (b.parse())
    c = &b;
  if (c) {
    static string monstr;
    for (int i=0; i<15; i++) {
      char monname[20];
      char *val = 0;
      sprintf(monname, "mon%d", i);
      c->read(monname, "mon addr", &val, 0);
      if (!val || !val[0])
	break;

      entity_inst_t inst;
      if (!parse_ip_port(val, inst.addr)) {
	cerr << "unable to parse conf's addr for " << monname << " (" << val << ")" << std::endl;
	continue;
      }
      inst.name = entity_name_t::MON(monmap.mon_inst.size());
      monmap.add_mon(inst);
    }
    if (monmap.size())
      return 0;
    cerr << "unable to find any monitors in conf" << std::endl;
    return -EINVAL;
  }

  cerr << "please specify monitors via -m monaddr or -c ceph.conf" << std::endl;
  return -ENOENT;
}

int MonClient::get_monmap()
{
  dout(10) << "get_monmap" << dendl;
  Mutex::Locker l(monc_lock);

  want_monmap = true;
  if (cur_mon < 0)
    _reopen_session();

  while (want_monmap)
    map_cond.Wait(monc_lock);

  dout(10) << "get_monmap done" << dendl;

  return 0;
}

int MonClient::get_monmap_privately()
{
  dout(10) << "get_monmap_privately" << dendl;
  Mutex::Locker l(monc_lock);

  SimpleMessenger *rank = NULL;
  bool temp_msgr = false;
  if (!messenger) {
    rank = new SimpleMessenger;
    rank->bind();
    rank->set_policy(entity_name_t::TYPE_MON, SimpleMessenger::Policy::lossy_fast_fail());
    messenger = rank->register_entity(entity_name_t::CLIENT(-1));
    messenger->add_dispatcher_head(this);
    rank->start(true);  // do not daemonize!
    temp_msgr = true;
  }

  int attempt = 10;
  int i = 0;
  srand(getpid());

  dout(10) << "have " << monmap.epoch << dendl;

  while (monmap.epoch == 0) {
    i = rand() % monmap.mon_inst.size();
    dout(10) << "querying " << monmap.mon_inst[i] << dendl;
    messenger->send_message(new MMonGetMap, monmap.mon_inst[i]);

    if (--attempt == 0)
      break;

    utime_t interval(1, 0);
    map_cond.WaitInterval(monc_lock, interval);
  }

  if (temp_msgr) {
    messenger->shutdown();
    rank->wait();
    messenger->destroy();
    messenger = 0;
  }

  if (monmap.epoch)
    return 0;
  return -1;
}

bool MonClient::ms_dispatch(Message *m)
{
  dout(10) << "dispatch " << *m << dendl;

  if (my_addr == entity_addr_t())
    my_addr = messenger->get_myaddr();

  switch (m->get_type()) {
  case CEPH_MSG_MON_MAP:
    handle_monmap((MMonMap*)m);
    return true;

  case CEPH_MSG_CLIENT_MOUNT_ACK:
    handle_mount_ack((MClientMountAck*)m);
    return true;

  case CEPH_MSG_MON_SUBSCRIBE_ACK:
    handle_subscribe_ack((MMonSubscribeAck*)m);
    return true;
  }

  return false;
}

void MonClient::handle_monmap(MMonMap *m)
{
  dout(10) << "handle_monmap " << *m << dendl;
  monc_lock.Lock();

  _finish_hunting();

  bufferlist::iterator p = m->monmapbl.begin();
  ::decode(monmap, p);

  _sub_got("monmap", monmap.get_epoch());

  map_cond.Signal();
  want_monmap = false;

  monc_lock.Unlock();
  delete m;
}

// -------------------
// MOUNT

void MonClient::_send_mount()
{
  dout(10) << "_send_mount" << dendl;
  _send_mon_message(new MClientMount);
  mount_started = g_clock.now();
}

void MonClient::init()
{
  dout(10) << "init" << dendl;
  messenger->add_dispatcher_head(this);

  Mutex::Locker l(monc_lock);
  timer.add_event_after(10.0, new C_Tick(this));
}

void MonClient::shutdown()
{
  timer.cancel_all_events();
}

int MonClient::mount(double mount_timeout)
{
  Mutex::Locker lock(monc_lock);

  if (clientid >= 0) {
    dout(5) << "already mounted" << dendl;;
    return 0;
  }

  // only first mounter does the work
  mounting++;
  if (mounting == 1) {
    if (cur_mon < 0)
      _reopen_session();
    else
      _send_mount();
  }
  while (clientid < 0 && !mount_err)
    mount_cond.Wait(monc_lock);
  mounting--;

  if (clientid >= 0) {
    dout(5) << "mount success, client" << clientid << dendl;

    _sub_want("monmap", monmap.get_epoch());
  }

  return mount_err;
}

void MonClient::handle_mount_ack(MClientMountAck* m)
{
  dout(10) << "handle_mount_ack " << *m << dendl;

  _finish_hunting();

  // monmap
  bufferlist::iterator p = m->monmap_bl.begin();
  ::decode(monmap, p);

  clientid = m->client;
  messenger->set_myname(entity_name_t::CLIENT(m->client.v));

  mount_cond.SignalAll();

  delete m;
}

// ---------

void MonClient::_send_mon_message(Message *m)
{
  assert(cur_mon >= 0);
  messenger->send_message(m, monmap.mon_inst[cur_mon]);
}

void MonClient::_pick_new_mon()
{
  if (cur_mon >= 0)
    messenger->mark_down(monmap.get_inst(cur_mon).addr);
  cur_mon = monmap.pick_mon(true);
  dout(10) << "_pick_new_mon picked mon" << cur_mon << dendl;
}

void MonClient::_reopen_session()
{
  dout(10) << "_reopen_session" << dendl;
  _pick_new_mon();
  if (mounting)
    _send_mount();
  if (!sub_have.empty())
    _renew_subs();
  if (!mounting && sub_have.empty()) {
    _send_mon_message(new MMonGetMap);
  }
}

bool MonClient::ms_handle_reset(Connection *con, const entity_addr_t& peer)
{
  dout(10) << "ms_handle_reset " << peer << dendl;
  if (hunting)
    return true;

  dout(0) << "hunting for new mon" << dendl;
  hunting = true;
  _reopen_session();
  return false;
}

void MonClient::_finish_hunting()
{
  if (hunting) {
    dout(0) << "found mon" << cur_mon << dendl;
    hunting = false;
  }
}

void MonClient::tick()
{
  dout(10) << "tick" << dendl;

  if (hunting) {
    dout(0) << "continuing hunt" << dendl;
    _reopen_session();
  } else {
    // just renew as needed
    utime_t now = g_clock.now();
    if (now > sub_renew_after)
      _renew_subs();

    int oldmon = monmap.pick_mon();
    messenger->send_keepalive(monmap.mon_inst[oldmon]);
  }

  timer.add_event_after(10.0, new C_Tick(this));
}

// ---------

void MonClient::_renew_subs()
{
  if (sub_have.empty()) {
    dout(10) << "renew_subs - empty" << dendl;
    return;
  }

  dout(10) << "renew_subs" << dendl;
  if (cur_mon < 0)
    _reopen_session();
  else {
    if (sub_renew_sent == utime_t())
      sub_renew_sent = g_clock.now();

    MMonSubscribe *m = new MMonSubscribe;
    m->what = sub_have;
    _send_mon_message(m);
  }
}

void MonClient::handle_subscribe_ack(MMonSubscribeAck *m)
{
  _finish_hunting();

  if (sub_renew_sent != utime_t()) {
    sub_renew_after = sub_renew_sent;
    sub_renew_after += m->interval / 2.0;
    dout(10) << "handle_subscribe_ack sent " << sub_renew_sent << " renew after " << sub_renew_after << dendl;
    sub_renew_sent = utime_t();
  } else {
    dout(10) << "handle_subscribe_ack sent " << sub_renew_sent << ", ignoring" << dendl;
  }
}

<|endoftext|>


<commit_before>/*
 * Copyright 2011 Intel Corporation.
 *
 * This program is licensed under the terms and conditions of the
 * Apache License, version 2.0.  The full text of the Apache License is at
 * http://www.apache.org/licenses/LICENSE-2.0
 */

#include <QApplication>
#include <QDBusConnection>
#include <QDBusError>
#include <QDBusInterface>
#include <QDeclarativeEngine>
#include <QDeclarativeView>
#include <QGraphicsItem>
#include <QDeclarativeContext>
#include <QDeclarativeNetworkAccessManagerFactory>
#include <QDesktopWidget>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QGLFormat>
#include <QLibraryInfo>
#include <QNetworkAccessManager>
#include <QNetworkDiskCache>
#include <QNetworkProxy>
#include <QResizeEvent>
#include <QSettings>
#include <QTimer>
#include <QTextStream>
#include <QTranslator>
#include <QVariant>
#include <QX11Info>
#include <MGConfItem>
#include <QInputContext>

#include "launcherwindow.h"
#include "launcheratoms.h"
#include "launcherapp.h"

#include <QX11Info>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <unistd.h>

class NetworkAccessManagerFactory : public QDeclarativeNetworkAccessManagerFactory
{
public:
    virtual QNetworkAccessManager *create(QObject *parent);
};

QNetworkAccessManager *NetworkAccessManagerFactory::create(QObject *parent)
{
    QUrl httpProxy(getenv("http_proxy"));
    QNetworkAccessManager *nam = new QNetworkAccessManager(parent);
    if (!httpProxy.isEmpty())
    {
        QNetworkProxy proxy(QNetworkProxy::HttpCachingProxy,
                            httpProxy.host(),
                            httpProxy.port());
        nam->setProxy(proxy);
    }

    QNetworkDiskCache *cache = new QNetworkDiskCache();
    cache->setCacheDirectory(QDir::homePath() + "/.cache/" + qApp->applicationName());
    nam->setCache(cache);

    return nam;
}

LauncherWindow::LauncherWindow(bool fullscreen, int width, int height, bool opengl, bool setSource, QWidget *parent) :
    QWidget(parent),
    m_inhibitScreenSaver(false)
{
    LauncherApp *app = static_cast<LauncherApp *>(qApp);

    setWindowTitle(app->applicationName());
    setWindowIconText(app->applicationName());

    int screenWidth;
    int screenHeight;
    if (fullscreen)
    {
        screenWidth = qApp->desktop()->rect().width();
        screenHeight = qApp->desktop()->rect().height();
        setWindowFlags(Qt::FramelessWindowHint);
    }
    else
    {
        screenWidth = width;
        screenHeight = height;
    }

    view = new QDeclarativeView(this);
    view->engine()->setNetworkAccessManagerFactory(new NetworkAccessManagerFactory);
    connect(view->engine(), SIGNAL(quit()), qApp, SLOT(closeAllWindows()));
    connect((const QObject*)qApp->inputContext(), SIGNAL(inputMethodAreaChanged(QRect)),
            this, SLOT(handleInputMethodAreaChanged(QRect)));
    connect(qApp, SIGNAL(dismissKeyboard()), this, SLOT(dismissKeyboard()));

    QDeclarativeContext *context = view->rootContext();
    context->setContextProperty("screenWidth", screenWidth);
    context->setContextProperty("screenHeight", screenHeight);
    context->setContextProperty("qApp", qApp);
    context->setContextProperty("mainWindow", this);
    context->setContextProperty("theme_name", MGConfItem("/meego/ux/theme").value().toString());
    foreach (QString key, app->themeConfig->allKeys())
    {
        if (key.contains("Size") || key.contains("Padding") ||
            key.contains("Width") ||key.contains("Height") ||
            key.contains("Margin") || key.contains("Thickness"))
        {
            context->setContextProperty("theme_" + key, app->themeConfig->value(key).toInt());
        }
        else if (key.contains("Opacity"))
        {
            context->setContextProperty("theme_" + key, app->themeConfig->value(key).toDouble());
        }
        else
        {
            context->setContextProperty("theme_" + key, app->themeConfig->value(key));
        }
    }

    if (setSource) {
      sharePath = QString("/usr/share/") + app->applicationName() + "/";
      if (!QFile::exists(sharePath + "main.qml"))
      {
        qFatal("%s does not exist!", sharePath.toUtf8().data());
      }
    }

    loadTranslators();
    connect(app, SIGNAL(localeSettingsChanged()), this, SLOT(loadTranslators()));

    // Qt will search each translator for a string translation, starting with
    // the last translator installed working back to the first translator.
    // The first translation found wins.
    app->installTranslator(&qtTranslator);     // General Qt translations
    app->installTranslator(&commonTranslator); // Common Components translations
    app->installTranslator(&mediaTranslator);  // Common Media translations
    app->installTranslator(&appTranslator);    // App specific translations

    if (setSource)
    {
      view->setSource(QUrl(sharePath + "main.qml"));
    }

    if (opengl)
    {
        QGLFormat format = QGLFormat::defaultFormat();
        format.setSampleBuffers(false);
        view->setViewport(new QGLWidget(format));
    }

    setGeometry(QRect(0, 0, screenWidth, screenHeight));
}

LauncherWindow::~LauncherWindow()
{
}

void LauncherWindow::loadTranslators()
{
    LauncherApp *app = static_cast<LauncherApp *>(qApp);

    qtTranslator.load("qt_" + QLocale::system().name() + ".qm",
                      QLibraryInfo::location(QLibraryInfo::TranslationsPath));
    commonTranslator.load("meegolabs-ux-components_" + QLocale::system().name() + ".qm",
                          QLibraryInfo::location(QLibraryInfo::TranslationsPath));
    mediaTranslator.load("meego-ux-media-qml_" + QLocale::system().name() + ".qm",
                         QLibraryInfo::location(QLibraryInfo::TranslationsPath));
    appTranslator.load(app->applicationName() + "_" + QLocale::system().name() + ".qm",
                       QLibraryInfo::location(QLibraryInfo::TranslationsPath));
}

void LauncherWindow::triggerSystemUIMenu()
{
    QDBusInterface iface("com.nokia.systemui","/statusindicatormenu","com.meego.core.MStatusIndicatorMenu");
    if(iface.isValid()) iface.call("open");
}

void LauncherWindow::goHome()
{
    setWindowState(windowState() ^ Qt::WindowMinimized);
}

// Called by LauncherApplication when it wants to dismiss the
// keyboard.  hideOnFocusOut() is a slot on MInputContext, that seems
// to be required, it doesn't get it right if you just drop the focus
// (bug in MInputContext?)
void LauncherWindow::dismissKeyboard()
{
    if(view->scene() && view->scene()->focusItem())
    {
        if (QMetaObject::invokeMethod(qApp->inputContext(), "hideOnFocusOut"))
        {
            view->scene()->focusItem()->clearFocus();
        }
    }
}

void LauncherWindow::forwardCall(const QStringList& parameters)
{
    m_call = parameters;
    emit call(parameters);
    emit callChanged();
}

void LauncherWindow::setActualOrientation(int orientation)
{
    m_actualOrientation = orientation;

    if (!winId())
    {
        return;
    }

    Atom orientationAtom = XInternAtom(QX11Info::display(), "_MEEGO_ORIENTATION", false);
    XChangeProperty(QX11Info::display(), winId(), orientationAtom, XA_CARDINAL, 32,
                    PropModeReplace, (unsigned char*)&m_actualOrientation, 1);
}

bool LauncherWindow::event (QEvent * event)
{
    if (event->type() == QEvent::Show)
    {
        setActualOrientation(m_actualOrientation);
    }
    return QWidget::event(event);
}

void LauncherWindow::setInhibitScreenSaver(bool inhibit)
{
    m_inhibitScreenSaver = inhibit;

    Atom inhibitAtom = XInternAtom(QX11Info::display(), "_MEEGO_INHIBIT_SCREENSAVER", false);
    if (inhibit)
    {
        XChangeProperty(QX11Info::display(), winId(), inhibitAtom, XA_CARDINAL, 32,
                        PropModeReplace, (unsigned char*)&m_inhibitScreenSaver, 1);
    }
    else
    {
        XDeleteProperty(QX11Info::display(), winId(), inhibitAtom);
    }
}
<commit_msg>Settings of attributes for better performance<commit_after>/*
 * Copyright 2011 Intel Corporation.
 *
 * This program is licensed under the terms and conditions of the
 * Apache License, version 2.0.  The full text of the Apache License is at
 * http://www.apache.org/licenses/LICENSE-2.0
 */

#include <QApplication>
#include <QDBusConnection>
#include <QDBusError>
#include <QDBusInterface>
#include <QDeclarativeEngine>
#include <QDeclarativeView>
#include <QGraphicsItem>
#include <QDeclarativeContext>
#include <QDeclarativeNetworkAccessManagerFactory>
#include <QDesktopWidget>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QGLFormat>
#include <QLibraryInfo>
#include <QNetworkAccessManager>
#include <QNetworkDiskCache>
#include <QNetworkProxy>
#include <QResizeEvent>
#include <QSettings>
#include <QTimer>
#include <QTextStream>
#include <QTranslator>
#include <QVariant>
#include <QX11Info>
#include <MGConfItem>
#include <QInputContext>

#include "launcherwindow.h"
#include "launcheratoms.h"
#include "launcherapp.h"

#include <QX11Info>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <unistd.h>

class NetworkAccessManagerFactory : public QDeclarativeNetworkAccessManagerFactory
{
public:
    virtual QNetworkAccessManager *create(QObject *parent);
};

QNetworkAccessManager *NetworkAccessManagerFactory::create(QObject *parent)
{
    QUrl httpProxy(getenv("http_proxy"));
    QNetworkAccessManager *nam = new QNetworkAccessManager(parent);
    if (!httpProxy.isEmpty())
    {
        QNetworkProxy proxy(QNetworkProxy::HttpCachingProxy,
                            httpProxy.host(),
                            httpProxy.port());
        nam->setProxy(proxy);
    }

    QNetworkDiskCache *cache = new QNetworkDiskCache();
    cache->setCacheDirectory(QDir::homePath() + "/.cache/" + qApp->applicationName());
    nam->setCache(cache);

    return nam;
}

LauncherWindow::LauncherWindow(bool fullscreen, int width, int height, bool opengl, bool setSource, QWidget *parent) :
    QWidget(parent),
    m_inhibitScreenSaver(false)
{
    LauncherApp *app = static_cast<LauncherApp *>(qApp);

    setWindowTitle(app->applicationName());
    setWindowIconText(app->applicationName());

    int screenWidth;
    int screenHeight;
    if (fullscreen)
    {
        screenWidth = qApp->desktop()->rect().width();
        screenHeight = qApp->desktop()->rect().height();
        setWindowFlags(Qt::FramelessWindowHint);
    }
    else
    {
        screenWidth = width;
        screenHeight = height;
    }

    view = new QDeclarativeView(this);
    view->setAttribute(Qt::WA_OpaquePaintEvent);
    view->setAttribute(Qt::WA_NoSystemBackground);
    view->viewport()->setAttribute(Qt::WA_OpaquePaintEvent);
    view->viewport()->setAttribute(Qt::WA_NoSystemBackground);
    view->engine()->setNetworkAccessManagerFactory(new NetworkAccessManagerFactory);
    connect(view->engine(), SIGNAL(quit()), qApp, SLOT(closeAllWindows()));
    connect((const QObject*)qApp->inputContext(), SIGNAL(inputMethodAreaChanged(QRect)),
            this, SLOT(handleInputMethodAreaChanged(QRect)));
    connect(qApp, SIGNAL(dismissKeyboard()), this, SLOT(dismissKeyboard()));

    QDeclarativeContext *context = view->rootContext();
    context->setContextProperty("screenWidth", screenWidth);
    context->setContextProperty("screenHeight", screenHeight);
    context->setContextProperty("qApp", qApp);
    context->setContextProperty("mainWindow", this);
    context->setContextProperty("theme_name", MGConfItem("/meego/ux/theme").value().toString());
    foreach (QString key, app->themeConfig->allKeys())
    {
        if (key.contains("Size") || key.contains("Padding") ||
            key.contains("Width") ||key.contains("Height") ||
            key.contains("Margin") || key.contains("Thickness"))
        {
            context->setContextProperty("theme_" + key, app->themeConfig->value(key).toInt());
        }
        else if (key.contains("Opacity"))
        {
            context->setContextProperty("theme_" + key, app->themeConfig->value(key).toDouble());
        }
        else
        {
            context->setContextProperty("theme_" + key, app->themeConfig->value(key));
        }
    }

    if (setSource) {
      sharePath = QString("/usr/share/") + app->applicationName() + "/";
      if (!QFile::exists(sharePath + "main.qml"))
      {
        qFatal("%s does not exist!", sharePath.toUtf8().data());
      }
    }

    loadTranslators();
    connect(app, SIGNAL(localeSettingsChanged()), this, SLOT(loadTranslators()));

    // Qt will search each translator for a string translation, starting with
    // the last translator installed working back to the first translator.
    // The first translation found wins.
    app->installTranslator(&qtTranslator);     // General Qt translations
    app->installTranslator(&commonTranslator); // Common Components translations
    app->installTranslator(&mediaTranslator);  // Common Media translations
    app->installTranslator(&appTranslator);    // App specific translations

    if (setSource)
    {
      view->setSource(QUrl(sharePath + "main.qml"));
    }

    if (opengl)
    {
        QGLFormat format = QGLFormat::defaultFormat();
        format.setSampleBuffers(false);
        view->setViewport(new QGLWidget(format));
        view->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
        view->viewport()->setAttribute(Qt::WA_OpaquePaintEvent);
        view->viewport()->setAttribute(Qt::WA_NoSystemBackground);
        //view->viewport()->setAutoFillBackground(false);
    }

    setGeometry(QRect(0, 0, screenWidth, screenHeight));
}

LauncherWindow::~LauncherWindow()
{
}

void LauncherWindow::loadTranslators()
{
    LauncherApp *app = static_cast<LauncherApp *>(qApp);

    qtTranslator.load("qt_" + QLocale::system().name() + ".qm",
                      QLibraryInfo::location(QLibraryInfo::TranslationsPath));
    commonTranslator.load("meegolabs-ux-components_" + QLocale::system().name() + ".qm",
                          QLibraryInfo::location(QLibraryInfo::TranslationsPath));
    mediaTranslator.load("meego-ux-media-qml_" + QLocale::system().name() + ".qm",
                         QLibraryInfo::location(QLibraryInfo::TranslationsPath));
    appTranslator.load(app->applicationName() + "_" + QLocale::system().name() + ".qm",
                       QLibraryInfo::location(QLibraryInfo::TranslationsPath));
}

void LauncherWindow::triggerSystemUIMenu()
{
    QDBusInterface iface("com.nokia.systemui","/statusindicatormenu","com.meego.core.MStatusIndicatorMenu");
    if(iface.isValid()) iface.call("open");
}

void LauncherWindow::goHome()
{
    setWindowState(windowState() ^ Qt::WindowMinimized);
}

// Called by LauncherApplication when it wants to dismiss the
// keyboard.  hideOnFocusOut() is a slot on MInputContext, that seems
// to be required, it doesn't get it right if you just drop the focus
// (bug in MInputContext?)
void LauncherWindow::dismissKeyboard()
{
    if(view->scene() && view->scene()->focusItem())
    {
        if (QMetaObject::invokeMethod(qApp->inputContext(), "hideOnFocusOut"))
        {
            view->scene()->focusItem()->clearFocus();
        }
    }
}

void LauncherWindow::forwardCall(const QStringList& parameters)
{
    m_call = parameters;
    emit call(parameters);
    emit callChanged();
}

void LauncherWindow::setActualOrientation(int orientation)
{
    m_actualOrientation = orientation;

    if (!winId())
    {
        return;
    }

    Atom orientationAtom = XInternAtom(QX11Info::display(), "_MEEGO_ORIENTATION", false);
    XChangeProperty(QX11Info::display(), winId(), orientationAtom, XA_CARDINAL, 32,
                    PropModeReplace, (unsigned char*)&m_actualOrientation, 1);
}

bool LauncherWindow::event (QEvent * event)
{
    if (event->type() == QEvent::Show)
    {
        setActualOrientation(m_actualOrientation);
    }
    return QWidget::event(event);
}

void LauncherWindow::setInhibitScreenSaver(bool inhibit)
{
    m_inhibitScreenSaver = inhibit;

    Atom inhibitAtom = XInternAtom(QX11Info::display(), "_MEEGO_INHIBIT_SCREENSAVER", false);
    if (inhibit)
    {
        XChangeProperty(QX11Info::display(), winId(), inhibitAtom, XA_CARDINAL, 32,
                        PropModeReplace, (unsigned char*)&m_inhibitScreenSaver, 1);
    }
    else
    {
        XDeleteProperty(QX11Info::display(), winId(), inhibitAtom);
    }
}
<|endoftext|>


<commit_before>//
// GraphInterface.hpp
//
// Copyright (c) 2012 Jun Kawahara
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
// and associated documentation files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#ifndef GRAPHINTERFACE_HPP
#define GRAPHINTERFACE_HPP

#include <iostream>

namespace frontier_dd {

//*************************************************************************************************
// GraphInterface: Graph と HyperGraph の共通部分のインターフェース
class GraphInterface {
protected:
    int number_of_vertices_;
    int number_of_edges_;

public:
    GraphInterface() : number_of_vertices_(0), number_of_edges_(0) { }

    int GetNumberOfVertices() const
    {
        return number_of_vertices_;
    }

    int GetNumberOfEdges() const
    {
        return number_of_edges_;
    }

    virtual void LoadAdjacencyList(std::istream& ist, bool is_simple = false,
        bool is_directed = false) = 0;
    virtual void LoadAdjacencyMatrix(std::istream& ist, bool is_simple = false,
        bool is_directed = false) = 0;
    virtual void LoadIncidenceMatrix(std::istream& ist, bool is_simple = false,
        bool is_directed = false) = 0;
    virtual void LoadEdgeList(std::istream& ist, bool is_simple = false,
        bool is_directed = false) = 0;

    virtual void SetWeightToEach(std::istream& ist) = 0;

    virtual void PrintAdjacencyList(std::ostream& ost) const = 0;
    virtual void PrintAdjacencyMatrix(std::ostream& ost) const = 0;
    virtual void PrintIncidenceMatrix(std::ostream& ost) const = 0;
    virtual void PrintEdgeList(std::ostream& ost) const = 0;
    virtual void PrintForGraphviz(std::ostream& ost) const = 0;
    virtual void PrintForGraphviz(std::ostream& ost,
        const std::vector<int>& bold_edge_list) const = 0;
};

} // the end of the namespace

#endif // GRAPHINTERFACE_HPP
<commit_msg>Add a virtual destructor in GraphInterface<commit_after>//
// GraphInterface.hpp
//
// Copyright (c) 2012 Jun Kawahara
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
// and associated documentation files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#ifndef GRAPHINTERFACE_HPP
#define GRAPHINTERFACE_HPP

#include <iostream>

namespace frontier_dd {

//*************************************************************************************************
// GraphInterface: Graph と HyperGraph の共通部分のインターフェース
class GraphInterface {
protected:
    int number_of_vertices_;
    int number_of_edges_;

public:
    GraphInterface() : number_of_vertices_(0), number_of_edges_(0) { }
    virtual ~GraphInterface() { }

    int GetNumberOfVertices() const
    {
        return number_of_vertices_;
    }

    int GetNumberOfEdges() const
    {
        return number_of_edges_;
    }

    virtual void LoadAdjacencyList(std::istream& ist, bool is_simple = false,
        bool is_directed = false) = 0;
    virtual void LoadAdjacencyMatrix(std::istream& ist, bool is_simple = false,
        bool is_directed = false) = 0;
    virtual void LoadIncidenceMatrix(std::istream& ist, bool is_simple = false,
        bool is_directed = false) = 0;
    virtual void LoadEdgeList(std::istream& ist, bool is_simple = false,
        bool is_directed = false) = 0;

    virtual void SetWeightToEach(std::istream& ist) = 0;

    virtual void PrintAdjacencyList(std::ostream& ost) const = 0;
    virtual void PrintAdjacencyMatrix(std::ostream& ost) const = 0;
    virtual void PrintIncidenceMatrix(std::ostream& ost) const = 0;
    virtual void PrintEdgeList(std::ostream& ost) const = 0;
    virtual void PrintForGraphviz(std::ostream& ost) const = 0;
    virtual void PrintForGraphviz(std::ostream& ost,
        const std::vector<int>& bold_edge_list) const = 0;
};

} // the end of the namespace

#endif // GRAPHINTERFACE_HPP
<|endoftext|>


<commit_before>/* This file is part of the KDE project
   Copyright (C) 2008 Omat Holding B.V. <info@omat.nl>

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

#include "dock.h"

#include <QMenu>
#include <QSystemTrayIcon>
#include <QDBusInterface>
#include <QDBusConnectionInterface>
#include <QMouseEvent>

#include <KComponentData>
#include <KDebug>
#include <KIcon>
#include <KIconLoader>
#include <KLocale>
#include <KNotifyConfigWidget>
#include <KStandardShortcut>
#include <KSystemTrayIcon>

#include <akonadi/control.h>

Dock::Dock()
        : QSystemTrayIcon( KIcon("dummy"), 0 )
{
    QMenu *menu = new QMenu("text");
    menu->setTitle("Akonadi");
    menu->addAction( i18n( "&Stop Akonadi" ),
                     this, SLOT( slotStopAkonadi() ) );
    menu->addAction( i18n( "&Start Akonadi" ),
                     this, SLOT( slotStartAkonadi() ) );
    menu->addSeparator();
    menu->addAction( /*SmallIcon( "knotify" ),*/ i18n( "Configure &Notifications..." ),
                     this, SLOT( slotConfigureNotifications() ) );
    menu->addAction( KIcon( "application-exit" ), i18n( "Quit" ), this, SLOT( slotQuit() ),
                     KStandardShortcut::shortcut( KStandardShortcut::Quit ).primary() );
    menu->exec();
    setContextMenu( menu );
    show();

    connect( this, SIGNAL( activated ( QSystemTrayIcon::ActivationReason ) ),
		    SLOT( slotActivated()));
}

Dock::~Dock()
{
}

void Dock::slotConfigureNotifications()
{
    KNotifyConfigWidget::configure( 0 );
}

void Dock::slotStopAkonadi()
{
     QDBusInterface dbus( "org.kde.Akonadi.Control", "/ControlManager", "org.kde.Akonadi.ControlManager" );
     dbus.call( "shutdown" );
}

void Dock::slotStartAkonadi()
{
     Akonadi::Control::start();
}

void Dock::slotActivated()
{
    bool registered = QDBusConnection::sessionBus().interface()->isServiceRegistered( "org.kde.Akonadi.Control" );
    registered ? contextMenu()->setTitle( i18n( "Akonadi is running" ) )
	        : contextMenu()->setTitle( i18n( "Akonadi is not running" ) );
    contextMenu()->exec( QCursor::pos() );
}

void Dock::slotQuit()
{
    exit( 0 );
}

#include "dock.moc"
<commit_msg>Still looking for the reason the title does not show up.<commit_after>/* This file is part of the KDE project
   Copyright (C) 2008 Omat Holding B.V. <info@omat.nl>

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

#include "dock.h"

#include <QMenu>
#include <QSystemTrayIcon>
#include <QDBusInterface>
#include <QDBusConnectionInterface>
#include <QMouseEvent>

#include <KComponentData>
#include <KDebug>
#include <KIcon>
#include <KIconLoader>
#include <KLocale>
#include <KNotifyConfigWidget>
#include <KStandardShortcut>
#include <KSystemTrayIcon>

#include <akonadi/control.h>

Dock::Dock()
        : QSystemTrayIcon( KIcon("dummy"), 0 )
{
    QMenu *menu = new QMenu();
    menu->addAction( i18n( "&Stop Akonadi" ),
                     this, SLOT( slotStopAkonadi() ) );
    menu->addAction( i18n( "&Start Akonadi" ),
                     this, SLOT( slotStartAkonadi() ) );
    menu->addSeparator();
    menu->addAction( /*SmallIcon( "knotify" ),*/ i18n( "Configure &Notifications..." ),
                     this, SLOT( slotConfigureNotifications() ) );
    menu->addAction( KIcon( "application-exit" ), i18n( "Quit" ), this, SLOT( slotQuit() ),
                     KStandardShortcut::shortcut( KStandardShortcut::Quit ).primary() );
    menu->setTitle("Akonadi");
    setContextMenu( menu );
    connect( menu, SIGNAL( aboutToShow() ), SLOT( slotActivated() ) );
    show();
}

Dock::~Dock()
{
}

void Dock::slotConfigureNotifications()
{
    KNotifyConfigWidget::configure( 0 );
}

void Dock::slotStopAkonadi()
{
     QDBusInterface dbus( "org.kde.Akonadi.Control", "/ControlManager", "org.kde.Akonadi.ControlManager" );
     dbus.call( "shutdown" );
}

void Dock::slotStartAkonadi()
{
     Akonadi::Control::start();
}

void Dock::slotActivated()
{
    kDebug();
    bool registered = QDBusConnection::sessionBus().interface()->isServiceRegistered( "org.kde.Akonadi.Control" );
    registered ? contextMenu()->setTitle( i18n( "Akonadi is running" ) )
	        : contextMenu()->setTitle( i18n( "Akonadi is not running" ) );
}

void Dock::slotQuit()
{
    exit( 0 );
}

#include "dock.moc"
<|endoftext|>


<commit_before>/* libvisio
 * Copyright (C) 2011 Fridrich Strba <fridrich.strba@bluewin.ch>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA  02111-1301 USA
 */

#include "VSDXStyles.h"

#define NOMASTER 0xffffffff

libvisio::VSDXStyles::VSDXStyles()
{
}

libvisio::VSDXStyles::~VSDXStyles()
{
}

void libvisio::VSDXStyles::addLineStyle(unsigned lineStyleIndex, VSDXLineStyle *lineStyle, unsigned lineStyleMaster)
{
  if (lineStyle)
    m_lineStyles[lineStyleIndex] = *lineStyle;
  m_lineStyleMasters[lineStyleIndex] = lineStyleMaster;
}

void libvisio::VSDXStyles::addFillStyle(unsigned fillStyleIndex, VSDXFillStyle *fillStyle, unsigned fillStyleMaster)
{
  if (fillStyle)
    m_fillStyles[fillStyleIndex] = *fillStyle;
  m_fillStyleMasters[fillStyleIndex] = fillStyleMaster;
}

void libvisio::VSDXStyles::addTextStyle(unsigned textStyleIndex, VSDXTextStyle *textStyle, unsigned textStyleMaster)
{
  if (textStyle)
    m_textStyles[textStyleIndex] = *textStyle;
  m_textStyleMasters[textStyleIndex] = textStyleMaster;
}

const libvisio::VSDXLineStyle libvisio::VSDXStyles::getLineStyle(unsigned lineStyleIndex) const
{
  unsigned tmpIndex = lineStyleIndex;
  while (true)
  {
    std::map<unsigned, unsigned>::const_iterator iter = m_lineStyleMasters.find(tmpIndex);
    if (iter != m_lineStyleMasters.end() && iter->second != NOMASTER)
      tmpIndex = iter->second;
    else
      break;
  }
  std::map<unsigned, VSDXLineStyle>::const_iterator iterStyle = m_lineStyles.find(tmpIndex);
  if (iterStyle != m_lineStyles.end())
    return iterStyle->second;

  return libvisio::VSDXLineStyle();
}

const libvisio::VSDXFillStyle libvisio::VSDXStyles::getFillStyle(unsigned fillStyleIndex) const
{
  unsigned tmpIndex = fillStyleIndex;
  while (true)
  {
    std::map<unsigned, unsigned>::const_iterator iter = m_fillStyleMasters.find(tmpIndex);
    if (iter != m_fillStyleMasters.end() && iter->second != NOMASTER)
      tmpIndex = iter->second;
    else
      break;
  }
  std::map<unsigned, VSDXFillStyle>::const_iterator iterStyle = m_fillStyles.find(tmpIndex);
  if (iterStyle != m_fillStyles.end())
    return iterStyle->second;

  return libvisio::VSDXFillStyle();
}

const libvisio::VSDXTextStyle libvisio::VSDXStyles::getTextStyle(unsigned textStyleIndex) const
{
  unsigned tmpIndex = textStyleIndex;
  while (true)
  {
    std::map<unsigned, unsigned>::const_iterator iter = m_textStyleMasters.find(tmpIndex);
    if (iter != m_textStyleMasters.end() && iter->second != NOMASTER)
      tmpIndex = iter->second;
    else
      break;
  }
  std::map<unsigned, VSDXTextStyle>::const_iterator iterStyle = m_textStyles.find(tmpIndex);
  if (iterStyle != m_textStyles.end())
    return iterStyle->second;

  return libvisio::VSDXTextStyle();
}
<commit_msg>Recurse in the styles until the first override is found<commit_after>/* libvisio
 * Copyright (C) 2011 Fridrich Strba <fridrich.strba@bluewin.ch>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA  02111-1301 USA
 */

#include "VSDXStyles.h"

#define NOMASTER 0xffffffff

libvisio::VSDXStyles::VSDXStyles()
{
}

libvisio::VSDXStyles::~VSDXStyles()
{
}

void libvisio::VSDXStyles::addLineStyle(unsigned lineStyleIndex, VSDXLineStyle *lineStyle, unsigned lineStyleMaster)
{
  if (lineStyle)
    m_lineStyles[lineStyleIndex] = *lineStyle;
  m_lineStyleMasters[lineStyleIndex] = lineStyleMaster;
}

void libvisio::VSDXStyles::addFillStyle(unsigned fillStyleIndex, VSDXFillStyle *fillStyle, unsigned fillStyleMaster)
{
  if (fillStyle)
    m_fillStyles[fillStyleIndex] = *fillStyle;
  m_fillStyleMasters[fillStyleIndex] = fillStyleMaster;
}

void libvisio::VSDXStyles::addTextStyle(unsigned textStyleIndex, VSDXTextStyle *textStyle, unsigned textStyleMaster)
{
  if (textStyle)
    m_textStyles[textStyleIndex] = *textStyle;
  m_textStyleMasters[textStyleIndex] = textStyleMaster;
}

const libvisio::VSDXLineStyle libvisio::VSDXStyles::getLineStyle(unsigned lineStyleIndex) const
{
  unsigned tmpIndex = lineStyleIndex;
  while (true)
  {
    std::map<unsigned, VSDXLineStyle>::const_iterator iterStyle = m_lineStyles.find(tmpIndex);
	if (iterStyle != m_lineStyles.end())
	  return iterStyle->second;
    std::map<unsigned, unsigned>::const_iterator iter = m_lineStyleMasters.find(tmpIndex);
    if (iter != m_lineStyleMasters.end() && iter->second != NOMASTER)
      tmpIndex = iter->second;
    else
      break;
  }

  return libvisio::VSDXLineStyle();
}

const libvisio::VSDXFillStyle libvisio::VSDXStyles::getFillStyle(unsigned fillStyleIndex) const
{
  unsigned tmpIndex = fillStyleIndex;
  while (true)
  {
    std::map<unsigned, VSDXFillStyle>::const_iterator iterStyle = m_fillStyles.find(tmpIndex);
	if (iterStyle != m_fillStyles.end())
	  return iterStyle->second;
    std::map<unsigned, unsigned>::const_iterator iter = m_fillStyleMasters.find(tmpIndex);
    if (iter != m_fillStyleMasters.end() && iter->second != NOMASTER)
      tmpIndex = iter->second;
    else
      break;
  }

  return libvisio::VSDXFillStyle();
}

const libvisio::VSDXTextStyle libvisio::VSDXStyles::getTextStyle(unsigned textStyleIndex) const
{
  unsigned tmpIndex = textStyleIndex;
  while (true)
  {
    std::map<unsigned, VSDXTextStyle>::const_iterator iterStyle = m_textStyles.find(tmpIndex);
	if (iterStyle != m_textStyles.end())
	  return iterStyle->second;
    std::map<unsigned, unsigned>::const_iterator iter = m_textStyleMasters.find(tmpIndex);
    if (iter != m_textStyleMasters.end() && iter->second != NOMASTER)
      tmpIndex = iter->second;
    else
      break;
  }

  return libvisio::VSDXTextStyle();
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

//TESTED_COMPONENT=src/documentgallery

#include <qdocumentgallery.h>

#include <QtTest/QtTest>

QTM_USE_NAMESPACE

Q_DECLARE_METATYPE(QGalleryProperty::Attributes)

class tst_QDocumentGallery : public QObject
{
    Q_OBJECT
private Q_SLOTS:
    void isRequestSupported();
    void itemTypeProperties_data();
    void itemTypeProperties();
    void propertyAttributes_data();
    void propertyAttributes();

private:
    QDocumentGallery gallery;
};

void tst_QDocumentGallery::isRequestSupported()
{
#if defined(Q_OS_UNIX) && !defined(QT_NO_DBUS) || defined (Q_OS_SYMBIAN)
    const bool platformSupported = true;
#else
    const bool platformSupported = false;
#endif

    QCOMPARE(gallery.isRequestSupported(QGalleryAbstractRequest::QueryRequest), platformSupported);
    QCOMPARE(gallery.isRequestSupported(QGalleryAbstractRequest::ItemRequest), platformSupported);
    QCOMPARE(gallery.isRequestSupported(QGalleryAbstractRequest::TypeRequest), platformSupported);
    QCOMPARE(gallery.isRequestSupported(QGalleryAbstractRequest::RequestType(1000)), false);
}

void tst_QDocumentGallery::itemTypeProperties_data()
{
    QTest::addColumn<QString>("itemType");
    QTest::addColumn<QStringList>("propertyNames");

    QTest::newRow("null item type") << QString() << QStringList();
    QTest::newRow("non-existent item type") << QString::fromLatin1("Hello") << QStringList();

    const QStringList fileProperties = QStringList()
#if defined(Q_OS_UNIX) && !defined(QT_NO_DBUS)
            << QDocumentGallery::copyright
            << QDocumentGallery::fileName
            << QDocumentGallery::path
            << QDocumentGallery::filePath
            << QDocumentGallery::url
            << QDocumentGallery::fileSize
            << QDocumentGallery::language
            << QDocumentGallery::lastAccessed
            << QDocumentGallery::lastModified
            << QDocumentGallery::mimeType;
#elif defined (Q_OS_SYMBIAN)
            << QDocumentGallery::url
            << QDocumentGallery::fileName
            << QDocumentGallery::filePath
            << QDocumentGallery::fileSize
            << QDocumentGallery::lastModified
            << QDocumentGallery::title
            << QDocumentGallery::mimeType
            << QDocumentGallery::author
            << QDocumentGallery::copyright
            << QDocumentGallery::description
            << QDocumentGallery::comments
            << QDocumentGallery::rating
#endif
            ;
    QTest::newRow("File") << QString(QDocumentGallery::File) << (QStringList(fileProperties)
#if defined(Q_OS_UNIX) && !defined(QT_NO_DBUS)
            << QDocumentGallery::author
            << QDocumentGallery::description
            << QDocumentGallery::keywords
            << QDocumentGallery::rating
            << QDocumentGallery::subject
            << QDocumentGallery::title
#endif
        );

    QTest::newRow("Audio") << QString(QDocumentGallery::Audio) << (QStringList(fileProperties)
#if defined(Q_OS_UNIX) && !defined(QT_NO_DBUS)
            << QDocumentGallery::albumArtist
            << QDocumentGallery::albumTitle
            << QDocumentGallery::artist
            << QDocumentGallery::audioBitRate
            << QDocumentGallery::audioCodec
            << QDocumentGallery::channelCount
            << QDocumentGallery::description
            << QDocumentGallery::discNumber
            << QDocumentGallery::duration
            << QDocumentGallery::genre
            << QDocumentGallery::lastPlayed
            << QDocumentGallery::lyrics
            << QDocumentGallery::performer
            << QDocumentGallery::playCount
            << QDocumentGallery::sampleRate
            << QDocumentGallery::title
            << QDocumentGallery::trackNumber
#elif defined (Q_OS_SYMBIAN)
            << QDocumentGallery::duration
            << QDocumentGallery::performer
            << QDocumentGallery::audioCodec
            << QDocumentGallery::audioBitRate
            << QDocumentGallery::playCount
            << QDocumentGallery::sampleRate
            << QDocumentGallery::albumTitle
            << QDocumentGallery::trackNumber
            << QDocumentGallery::albumArtist
            << QDocumentGallery::artist
            << QDocumentGallery::composer
            << QDocumentGallery::genre
#endif
    );

    QTest::newRow("Album") << QString(QDocumentGallery::Album) << (QStringList()
#if defined(Q_OS_UNIX) && !defined(QT_NO_DBUS)
            << QDocumentGallery::albumArtist
            << QDocumentGallery::albumTitle
            << QDocumentGallery::artist
            << QDocumentGallery::duration
            << QDocumentGallery::title
            << QDocumentGallery::trackCount
#endif
    );
    QTest::newRow("PhotoAlbum") << QString(QDocumentGallery::PhotoAlbum) << (QStringList()
#if defined(Q_OS_UNIX) && !defined(QT_NO_DBUS)
                << QDocumentGallery::title
                << QDocumentGallery::trackCount
#elif defined (Q_OS_SYMBIAN)
                << QDocumentGallery::url
                << QDocumentGallery::fileSize
                << QDocumentGallery::lastModified
                << QDocumentGallery::title
                << QDocumentGallery::mimeType
#endif
    );

#if defined (Q_OS_SYMBIAN)
    QTest::newRow("Image") << QString(QDocumentGallery::Image) << (QStringList(fileProperties)
            << QDocumentGallery::duration
            << QDocumentGallery::performer
            << QDocumentGallery::playCount
            << QDocumentGallery::width
            << QDocumentGallery::height
            << QDocumentGallery::orientation
            << QDocumentGallery::dateTaken
            << QDocumentGallery::cameraManufacturer
            << QDocumentGallery::cameraModel
            << QDocumentGallery::exposureProgram
            << QDocumentGallery::exposureTime
            << QDocumentGallery::fNumber
            << QDocumentGallery::flashEnabled
            << QDocumentGallery::focalLength
            << QDocumentGallery::meteringMode
            << QDocumentGallery::whiteBalance
    );
    QTest::newRow("Video") << QString(QDocumentGallery::Video) << (QStringList(fileProperties)
            << QDocumentGallery::duration
            << QDocumentGallery::performer
            << QDocumentGallery::videoBitRate
            << QDocumentGallery::playCount
            << QDocumentGallery::width
            << QDocumentGallery::height
            << QDocumentGallery::language
            << QDocumentGallery::frameRate
            << QDocumentGallery::resumePosition
    );
#endif

}

void tst_QDocumentGallery::itemTypeProperties()
{
    QFETCH(QString, itemType);
    QFETCH(QStringList, propertyNames);

    QStringList galleryPropertyNames = gallery.itemTypePropertyNames(itemType);
    propertyNames.sort();
    galleryPropertyNames.sort();

    QCOMPARE(galleryPropertyNames, propertyNames);
}

void tst_QDocumentGallery::propertyAttributes_data()
{
    QTest::addColumn<QString>("itemType");
    QTest::addColumn<QString>("propertyName");
    QTest::addColumn<QGalleryProperty::Attributes>("propertyAttributes");

    QTest::newRow("Null itemType, propertyName")
            << QString()
            << QString()
            << QGalleryProperty::Attributes();
    QTest::newRow("Null itemType, invalid propertyName")
            << QString()
            << QString::fromLatin1("Goodbye")
            << QGalleryProperty::Attributes();
    QTest::newRow("Null itemType, valid propertyName")
            << QString()
            << QString(QDocumentGallery::fileName)
            << QGalleryProperty::Attributes();
    QTest::newRow("Invalid itemType, invalid propertyName")
            << QString::fromLatin1("Hello")
            << QString::fromLatin1("Goodbye")
            << QGalleryProperty::Attributes();
    QTest::newRow("Invalid itemType, valid propertyName")
            << QString::fromLatin1("Hello")
            << QString(QDocumentGallery::fileName)
            << QGalleryProperty::Attributes();
    QTest::newRow("Valid itemType, invalid propertyName")
            << QString(QDocumentGallery::File)
            << QString::fromLatin1("Goodbye")
            << QGalleryProperty::Attributes();
    QTest::newRow("File.fileName")
            << QString(QDocumentGallery::File)
            << QString(QDocumentGallery::fileName)
#if defined(Q_OS_UNIX) && !defined(QT_NO_DBUS) || defined (Q_OS_SYMBIAN)
            << (QGalleryProperty::CanRead
                    | QGalleryProperty::CanFilter
                    | QGalleryProperty::CanSort);
#else
            << QGalleryProperty::Attributes();
#endif
    QTest::newRow("File.filePath")
                    << QString(QDocumentGallery::File)
                    << QString(QDocumentGallery::filePath)
#if defined(Q_OS_UNIX) && !defined(QT_NO_DBUS) || defined (Q_OS_SYMBIAN)
                    << (QGalleryProperty::CanRead | QGalleryProperty::CanFilter);
#else
                    << QGalleryProperty::Attributes();
#endif

    QTest::newRow("Audio.albumTitle")
            << QString(QDocumentGallery::Audio)
            << QString(QDocumentGallery::albumTitle)
#if defined(Q_OS_UNIX) && !defined(QT_NO_DBUS) || defined (Q_OS_SYMBIAN)
            << (QGalleryProperty::CanRead
                    | QGalleryProperty::CanWrite
                    | QGalleryProperty::CanFilter
                    | QGalleryProperty::CanSort);
#else
            << QGalleryProperty::Attributes();
#endif
    QTest::newRow("Album.duration")
            << QString(QDocumentGallery::Album)
            << QString(QDocumentGallery::duration)
#if defined(Q_OS_UNIX) && !defined(QT_NO_DBUS)
            << QGalleryProperty::Attributes(QGalleryProperty::CanRead);
#else
#ifdef Q_OS_SYMBIAN
            << QGalleryProperty::Attributes();
#else
            << (QGalleryProperty::CanRead
                | QGalleryProperty::CanWrite
                | QGalleryProperty::CanFilter
                | QGalleryProperty::CanSort);
#endif
#endif
}

void tst_QDocumentGallery::propertyAttributes()
{
    QFETCH(QString, itemType);
    QFETCH(QString, propertyName);
    QFETCH(QGalleryProperty::Attributes, propertyAttributes);

    QCOMPARE(int(gallery.propertyAttributes(propertyName, itemType)), int(propertyAttributes));
}

#include "tst_qdocumentgallery.moc"

QTEST_MAIN(tst_QDocumentGallery)
<commit_msg>Fix document gallery test failure on unsupported platforms.<commit_after>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

//TESTED_COMPONENT=src/documentgallery

#include <qdocumentgallery.h>

#include <QtTest/QtTest>

QTM_USE_NAMESPACE

Q_DECLARE_METATYPE(QGalleryProperty::Attributes)

class tst_QDocumentGallery : public QObject
{
    Q_OBJECT
private Q_SLOTS:
    void isRequestSupported();
    void itemTypeProperties_data();
    void itemTypeProperties();
    void propertyAttributes_data();
    void propertyAttributes();

private:
    QDocumentGallery gallery;
};

void tst_QDocumentGallery::isRequestSupported()
{
#if defined(Q_OS_UNIX) && !defined(QT_NO_DBUS) || defined (Q_OS_SYMBIAN)
    const bool platformSupported = true;
#else
    const bool platformSupported = false;
#endif

    QCOMPARE(gallery.isRequestSupported(QGalleryAbstractRequest::QueryRequest), platformSupported);
    QCOMPARE(gallery.isRequestSupported(QGalleryAbstractRequest::ItemRequest), platformSupported);
    QCOMPARE(gallery.isRequestSupported(QGalleryAbstractRequest::TypeRequest), platformSupported);
    QCOMPARE(gallery.isRequestSupported(QGalleryAbstractRequest::RequestType(1000)), false);
}

void tst_QDocumentGallery::itemTypeProperties_data()
{
    QTest::addColumn<QString>("itemType");
    QTest::addColumn<QStringList>("propertyNames");

    QTest::newRow("null item type") << QString() << QStringList();
    QTest::newRow("non-existent item type") << QString::fromLatin1("Hello") << QStringList();

    const QStringList fileProperties = QStringList()
#if defined(Q_OS_UNIX) && !defined(QT_NO_DBUS)
            << QDocumentGallery::copyright
            << QDocumentGallery::fileName
            << QDocumentGallery::path
            << QDocumentGallery::filePath
            << QDocumentGallery::url
            << QDocumentGallery::fileSize
            << QDocumentGallery::language
            << QDocumentGallery::lastAccessed
            << QDocumentGallery::lastModified
            << QDocumentGallery::mimeType;
#elif defined (Q_OS_SYMBIAN)
            << QDocumentGallery::url
            << QDocumentGallery::fileName
            << QDocumentGallery::filePath
            << QDocumentGallery::fileSize
            << QDocumentGallery::lastModified
            << QDocumentGallery::title
            << QDocumentGallery::mimeType
            << QDocumentGallery::author
            << QDocumentGallery::copyright
            << QDocumentGallery::description
            << QDocumentGallery::comments
            << QDocumentGallery::rating
#endif
            ;
    QTest::newRow("File") << QString(QDocumentGallery::File) << (QStringList(fileProperties)
#if defined(Q_OS_UNIX) && !defined(QT_NO_DBUS)
            << QDocumentGallery::author
            << QDocumentGallery::description
            << QDocumentGallery::keywords
            << QDocumentGallery::rating
            << QDocumentGallery::subject
            << QDocumentGallery::title
#endif
        );

    QTest::newRow("Audio") << QString(QDocumentGallery::Audio) << (QStringList(fileProperties)
#if defined(Q_OS_UNIX) && !defined(QT_NO_DBUS)
            << QDocumentGallery::albumArtist
            << QDocumentGallery::albumTitle
            << QDocumentGallery::artist
            << QDocumentGallery::audioBitRate
            << QDocumentGallery::audioCodec
            << QDocumentGallery::channelCount
            << QDocumentGallery::description
            << QDocumentGallery::discNumber
            << QDocumentGallery::duration
            << QDocumentGallery::genre
            << QDocumentGallery::lastPlayed
            << QDocumentGallery::lyrics
            << QDocumentGallery::performer
            << QDocumentGallery::playCount
            << QDocumentGallery::sampleRate
            << QDocumentGallery::title
            << QDocumentGallery::trackNumber
#elif defined (Q_OS_SYMBIAN)
            << QDocumentGallery::duration
            << QDocumentGallery::performer
            << QDocumentGallery::audioCodec
            << QDocumentGallery::audioBitRate
            << QDocumentGallery::playCount
            << QDocumentGallery::sampleRate
            << QDocumentGallery::albumTitle
            << QDocumentGallery::trackNumber
            << QDocumentGallery::albumArtist
            << QDocumentGallery::artist
            << QDocumentGallery::composer
            << QDocumentGallery::genre
#endif
    );

    QTest::newRow("Album") << QString(QDocumentGallery::Album) << (QStringList()
#if defined(Q_OS_UNIX) && !defined(QT_NO_DBUS)
            << QDocumentGallery::albumArtist
            << QDocumentGallery::albumTitle
            << QDocumentGallery::artist
            << QDocumentGallery::duration
            << QDocumentGallery::title
            << QDocumentGallery::trackCount
#endif
    );
    QTest::newRow("PhotoAlbum") << QString(QDocumentGallery::PhotoAlbum) << (QStringList()
#if defined(Q_OS_UNIX) && !defined(QT_NO_DBUS)
                << QDocumentGallery::title
                << QDocumentGallery::trackCount
#elif defined (Q_OS_SYMBIAN)
                << QDocumentGallery::url
                << QDocumentGallery::fileSize
                << QDocumentGallery::lastModified
                << QDocumentGallery::title
                << QDocumentGallery::mimeType
#endif
    );

#if defined (Q_OS_SYMBIAN)
    QTest::newRow("Image") << QString(QDocumentGallery::Image) << (QStringList(fileProperties)
            << QDocumentGallery::duration
            << QDocumentGallery::performer
            << QDocumentGallery::playCount
            << QDocumentGallery::width
            << QDocumentGallery::height
            << QDocumentGallery::orientation
            << QDocumentGallery::dateTaken
            << QDocumentGallery::cameraManufacturer
            << QDocumentGallery::cameraModel
            << QDocumentGallery::exposureProgram
            << QDocumentGallery::exposureTime
            << QDocumentGallery::fNumber
            << QDocumentGallery::flashEnabled
            << QDocumentGallery::focalLength
            << QDocumentGallery::meteringMode
            << QDocumentGallery::whiteBalance
    );
    QTest::newRow("Video") << QString(QDocumentGallery::Video) << (QStringList(fileProperties)
            << QDocumentGallery::duration
            << QDocumentGallery::performer
            << QDocumentGallery::videoBitRate
            << QDocumentGallery::playCount
            << QDocumentGallery::width
            << QDocumentGallery::height
            << QDocumentGallery::language
            << QDocumentGallery::frameRate
            << QDocumentGallery::resumePosition
    );
#endif

}

void tst_QDocumentGallery::itemTypeProperties()
{
    QFETCH(QString, itemType);
    QFETCH(QStringList, propertyNames);

    QStringList galleryPropertyNames = gallery.itemTypePropertyNames(itemType);
    propertyNames.sort();
    galleryPropertyNames.sort();

    QCOMPARE(galleryPropertyNames, propertyNames);
}

void tst_QDocumentGallery::propertyAttributes_data()
{
    QTest::addColumn<QString>("itemType");
    QTest::addColumn<QString>("propertyName");
    QTest::addColumn<QGalleryProperty::Attributes>("propertyAttributes");

    QTest::newRow("Null itemType, propertyName")
            << QString()
            << QString()
            << QGalleryProperty::Attributes();
    QTest::newRow("Null itemType, invalid propertyName")
            << QString()
            << QString::fromLatin1("Goodbye")
            << QGalleryProperty::Attributes();
    QTest::newRow("Null itemType, valid propertyName")
            << QString()
            << QString(QDocumentGallery::fileName)
            << QGalleryProperty::Attributes();
    QTest::newRow("Invalid itemType, invalid propertyName")
            << QString::fromLatin1("Hello")
            << QString::fromLatin1("Goodbye")
            << QGalleryProperty::Attributes();
    QTest::newRow("Invalid itemType, valid propertyName")
            << QString::fromLatin1("Hello")
            << QString(QDocumentGallery::fileName)
            << QGalleryProperty::Attributes();
    QTest::newRow("Valid itemType, invalid propertyName")
            << QString(QDocumentGallery::File)
            << QString::fromLatin1("Goodbye")
            << QGalleryProperty::Attributes();
    QTest::newRow("File.fileName")
            << QString(QDocumentGallery::File)
            << QString(QDocumentGallery::fileName)
#if defined(Q_OS_UNIX) && !defined(QT_NO_DBUS) || defined (Q_OS_SYMBIAN)
            << (QGalleryProperty::CanRead
                    | QGalleryProperty::CanFilter
                    | QGalleryProperty::CanSort);
#else
            << QGalleryProperty::Attributes();
#endif
    QTest::newRow("File.filePath")
                    << QString(QDocumentGallery::File)
                    << QString(QDocumentGallery::filePath)
#if defined(Q_OS_UNIX) && !defined(QT_NO_DBUS) || defined (Q_OS_SYMBIAN)
                    << (QGalleryProperty::CanRead | QGalleryProperty::CanFilter);
#else
                    << QGalleryProperty::Attributes();
#endif

    QTest::newRow("Audio.albumTitle")
            << QString(QDocumentGallery::Audio)
            << QString(QDocumentGallery::albumTitle)
#if defined(Q_OS_UNIX) && !defined(QT_NO_DBUS) || defined (Q_OS_SYMBIAN)
            << (QGalleryProperty::CanRead
                    | QGalleryProperty::CanWrite
                    | QGalleryProperty::CanFilter
                    | QGalleryProperty::CanSort);
#else
            << QGalleryProperty::Attributes();
#endif
    QTest::newRow("Album.duration")
            << QString(QDocumentGallery::Album)
            << QString(QDocumentGallery::duration)
#if defined(Q_OS_UNIX) && !defined(QT_NO_DBUS)
            << QGalleryProperty::Attributes(QGalleryProperty::CanRead);
#else
            << QGalleryProperty::Attributes();
#endif
}

void tst_QDocumentGallery::propertyAttributes()
{
    QFETCH(QString, itemType);
    QFETCH(QString, propertyName);
    QFETCH(QGalleryProperty::Attributes, propertyAttributes);

    QCOMPARE(int(gallery.propertyAttributes(propertyName, itemType)), int(propertyAttributes));
}

#include "tst_qdocumentgallery.moc"

QTEST_MAIN(tst_QDocumentGallery)
<|endoftext|>


<commit_before>#include "./object_manager.h"
#include <QLoggingCategory>
#include <vector>
#include <map>
#include <algorithm>
#include "./gl.h"
#include "./buffer_manager.h"
#include "./texture_manager.h"
#include "./shader_manager.h"

namespace Graphics
{

QLoggingCategory omChan("Graphics.ObjectManager");

ObjectManager::ObjectManager(std::shared_ptr<TextureManager> textureManager,
                             std::shared_ptr<ShaderManager> shaderManager)
  : bufferManager(std::make_shared<BufferManager>()),
    textureManager(textureManager), shaderManager(shaderManager),
    transformBuffer(GL_SHADER_STORAGE_BUFFER),
    customBuffer(GL_SHADER_STORAGE_BUFFER),
    commandsBuffer(GL_DRAW_INDIRECT_BUFFER)

{
}

ObjectManager::~ObjectManager()
{
}

void ObjectManager::initialize(Gl *gl, uint maxObjectCount, uint bufferSize)
{
  this->gl = gl;

  bufferManager->initialize(gl, maxObjectCount, bufferSize);

  commandsBuffer.initialize(gl, 3 * maxObjectCount, CREATE_FLAGS, MAP_FLAGS);
  transformBuffer.initialize(gl, 3 * maxObjectCount, CREATE_FLAGS, MAP_FLAGS);
  customBuffer.initialize(gl, 12 * maxObjectCount, CREATE_FLAGS, MAP_FLAGS);
}

ObjectData ObjectManager::addObject(const std::vector<float> &vertices,
                                    const std::vector<float> &normals,
                                    const std::vector<float> &colors,
                                    const std::vector<float> &texCoords,
                                    const std::vector<uint> &indices,
                                    int shaderProgramId, int primitiveType)
{
  auto bufferInformation =
      bufferManager->addObject(vertices, normals, colors, texCoords, indices);

  ObjectData object;
  object.vertexOffset = bufferInformation.vertexBufferOffset;
  object.vertexSize = bufferInformation.vertexCount;
  object.indexOffset = bufferInformation.indexBufferOffset;
  object.indexSize = indices.size();
  object.customBufferSize = 0;
  object.setBuffer = nullptr;
  object.transform = Eigen::Matrix4f::Identity();
  object.shaderProgramId = shaderProgramId;
  object.primitiveType = primitiveType;

  return object;
}

int ObjectManager::addShader(std::string vertexShaderPath,
                             std::string fragmentShaderPath)
{
  auto id = shaderManager->addShader(vertexShaderPath, fragmentShaderPath);

  qCDebug(omChan) << "Added" << vertexShaderPath.c_str() << "|"
                  << fragmentShaderPath.c_str() << "which got id" << id;

  return id;
}

int ObjectManager::addTexture(std::string path)
{
  return textureManager->addTexture(path);
}

TextureAddress ObjectManager::getAddressFor(int textureId)
{
  return textureManager->getAddressFor(textureId);
}

void ObjectManager::render(const RenderData &renderData)
{
  std::map<int, std::vector<ObjectData>> objectsByShader;
  for (auto &object : objectsForFrame)
  {
    objectsByShader[object.shaderProgramId].push_back(object);
  }

  for (auto &shaderObjectPair : objectsByShader)
  {
    qCDebug(omChan) << "Render objects with shader" << shaderObjectPair.first
                    << "with" << shaderObjectPair.second.size() << "objects";

    shaderManager->bind(shaderObjectPair.first, renderData);

    std::map<int, std::vector<ObjectData>> objectsByPrimitiveType;
    for (auto &object : shaderObjectPair.second)
    {
      objectsByPrimitiveType[object.primitiveType].push_back(object);
    }

    for (auto pair : objectsByPrimitiveType)
    {
      renderObjects(objectsByPrimitiveType[pair.first]);
    }
  }

  objectsForFrame.clear();
}

void ObjectManager::renderImmediately(ObjectData objectData)
{
  std::vector<ObjectData> objs = { objectData };

  renderObjects(objs);
}

void ObjectManager::renderLater(ObjectData object)
{
  objectsForFrame.push_back(object);
}

void ObjectManager::renderObjects(std::vector<ObjectData> objects)
{
  bufferManager->bind();

  // prepare per object buffers
  uint objectCount = objects.size();
  DrawElementsIndirectCommand *commands = commandsBuffer.reserve(objectCount);
  auto *matrices = transformBuffer.reserve(objectCount);
  int customBufferSize = objects[0].customBufferSize * objectCount;

  void *custom = nullptr;
  if (customBufferSize)
    custom = customBuffer.reserve(customBufferSize);

  qCDebug(omChan) << "customBufferSize" << customBufferSize << "custom"
                  << custom << "matrices" << matrices;

  int counter = 0;
  for (auto &objectData : objects)
  {
    commands[counter] = createDrawCommand(objectData, counter);

    auto *transform = &matrices[counter];
    memcpy(transform, objectData.transform.data(), sizeof(float[16]));

    if (objectData.setBuffer && customBufferSize)
    {
      objectData.setBuffer(static_cast<char *>(custom) +
                           counter * objectData.customBufferSize);
    }

    ++counter;
  }

  qCDebug(omChan, "objectcount: %u/%ld", objectCount, commandsBuffer.size());

  int mapRange = objectCount;

  mapRange = std::min(128, ((mapRange / 4) + 1) * 4);
  transformBuffer.bindBufferRange(0, mapRange);
  if (customBufferSize)
    customBuffer.bindBufferRange(1, customBufferSize);

  // We didn't use MAP_COHERENT here - make sure data is on the gpu
  glAssert(gl->glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT));

  // draw
  qCDebug(omChan, "head: %ld headoffset %p objectcount: %un",
          commandsBuffer.getHead(), commandsBuffer.headOffset(), objectCount);

  glAssert(gl->glMultiDrawElementsIndirect(
      objects[0].primitiveType, GL_UNSIGNED_INT, commandsBuffer.headOffset(),
      objectCount, 0));

  bufferManager->unbind();

  commandsBuffer.onUsageComplete(mapRange);
  transformBuffer.onUsageComplete(mapRange);
  if (customBufferSize)
    customBuffer.onUsageComplete(customBufferSize);
}

DrawElementsIndirectCommand
ObjectManager::createDrawCommand(const ObjectData &objectData, int counter)
{
  DrawElementsIndirectCommand command;

  command.count = objectData.indexSize;
  command.instanceCount = 1;
  command.firstIndex = objectData.indexOffset;
  command.baseVertex = objectData.vertexOffset;
  command.baseInstance = counter;

  qCDebug(omChan, "counter: %d count: %u firstIndex: %u baseVertex: %u",
          counter, command.count, command.firstIndex, command.baseVertex);

  return command;
}

}  // namespace Graphics
<commit_msg>Align custom buffer range to 16 bytes.<commit_after>#include "./object_manager.h"
#include <QLoggingCategory>
#include <vector>
#include <map>
#include <algorithm>
#include "./gl.h"
#include "./buffer_manager.h"
#include "./texture_manager.h"
#include "./shader_manager.h"

namespace Graphics
{

QLoggingCategory omChan("Graphics.ObjectManager");

ObjectManager::ObjectManager(std::shared_ptr<TextureManager> textureManager,
                             std::shared_ptr<ShaderManager> shaderManager)
  : bufferManager(std::make_shared<BufferManager>()),
    textureManager(textureManager), shaderManager(shaderManager),
    transformBuffer(GL_SHADER_STORAGE_BUFFER),
    customBuffer(GL_SHADER_STORAGE_BUFFER),
    commandsBuffer(GL_DRAW_INDIRECT_BUFFER)

{
}

ObjectManager::~ObjectManager()
{
}

void ObjectManager::initialize(Gl *gl, uint maxObjectCount, uint bufferSize)
{
  this->gl = gl;

  bufferManager->initialize(gl, maxObjectCount, bufferSize);

  commandsBuffer.initialize(gl, 3 * maxObjectCount, CREATE_FLAGS, MAP_FLAGS);
  transformBuffer.initialize(gl, 3 * maxObjectCount, CREATE_FLAGS, MAP_FLAGS);
  customBuffer.initialize(gl, 12 * maxObjectCount, CREATE_FLAGS, MAP_FLAGS);
}

ObjectData ObjectManager::addObject(const std::vector<float> &vertices,
                                    const std::vector<float> &normals,
                                    const std::vector<float> &colors,
                                    const std::vector<float> &texCoords,
                                    const std::vector<uint> &indices,
                                    int shaderProgramId, int primitiveType)
{
  auto bufferInformation =
      bufferManager->addObject(vertices, normals, colors, texCoords, indices);

  ObjectData object;
  object.vertexOffset = bufferInformation.vertexBufferOffset;
  object.vertexSize = bufferInformation.vertexCount;
  object.indexOffset = bufferInformation.indexBufferOffset;
  object.indexSize = indices.size();
  object.customBufferSize = 0;
  object.setBuffer = nullptr;
  object.transform = Eigen::Matrix4f::Identity();
  object.shaderProgramId = shaderProgramId;
  object.primitiveType = primitiveType;

  return object;
}

int ObjectManager::addShader(std::string vertexShaderPath,
                             std::string fragmentShaderPath)
{
  auto id = shaderManager->addShader(vertexShaderPath, fragmentShaderPath);

  qCDebug(omChan) << "Added" << vertexShaderPath.c_str() << "|"
                  << fragmentShaderPath.c_str() << "which got id" << id;

  return id;
}

int ObjectManager::addTexture(std::string path)
{
  return textureManager->addTexture(path);
}

TextureAddress ObjectManager::getAddressFor(int textureId)
{
  return textureManager->getAddressFor(textureId);
}

void ObjectManager::render(const RenderData &renderData)
{
  std::map<int, std::vector<ObjectData>> objectsByShader;
  for (auto &object : objectsForFrame)
  {
    objectsByShader[object.shaderProgramId].push_back(object);
  }

  for (auto &shaderObjectPair : objectsByShader)
  {
    qCDebug(omChan) << "Render objects with shader" << shaderObjectPair.first
                    << "with" << shaderObjectPair.second.size() << "objects";

    shaderManager->bind(shaderObjectPair.first, renderData);

    std::map<int, std::vector<ObjectData>> objectsByPrimitiveType;
    for (auto &object : shaderObjectPair.second)
    {
      objectsByPrimitiveType[object.primitiveType].push_back(object);
    }

    for (auto pair : objectsByPrimitiveType)
    {
      renderObjects(objectsByPrimitiveType[pair.first]);
    }
  }

  objectsForFrame.clear();
}

void ObjectManager::renderImmediately(ObjectData objectData)
{
  std::vector<ObjectData> objs = { objectData };

  renderObjects(objs);
}

void ObjectManager::renderLater(ObjectData object)
{
  objectsForFrame.push_back(object);
}

void ObjectManager::renderObjects(std::vector<ObjectData> objects)
{
  bufferManager->bind();

  // prepare per object buffers
  uint objectCount = objects.size();
  DrawElementsIndirectCommand *commands = commandsBuffer.reserve(objectCount);
  auto *matrices = transformBuffer.reserve(objectCount);
  int customBufferSize = objects[0].customBufferSize * objectCount;

  void *custom = nullptr;
  if (customBufferSize)
    custom = customBuffer.reserve(customBufferSize);

  qCDebug(omChan) << "customBufferSize" << customBufferSize << "custom"
                  << custom << "matrices" << matrices;

  int counter = 0;
  for (auto &objectData : objects)
  {
    commands[counter] = createDrawCommand(objectData, counter);

    auto *transform = &matrices[counter];
    memcpy(transform, objectData.transform.data(), sizeof(float[16]));

    if (objectData.setBuffer && customBufferSize)
    {
      objectData.setBuffer(static_cast<char *>(custom) +
                           counter * objectData.customBufferSize);
    }

    ++counter;
  }

  qCDebug(omChan, "objectcount: %u/%ld", objectCount, commandsBuffer.size());

  int mapRange = objectCount;

  mapRange = std::max(128, ((mapRange / 4) + 1) * 4);
  transformBuffer.bindBufferRange(0, mapRange);
  int customMapRange = ((customBufferSize / 16) + 1) * 16;
  if (customBufferSize)
    customBuffer.bindBufferRange(1, customMapRange);

  // We didn't use MAP_COHERENT here - make sure data is on the gpu
  glAssert(gl->glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT));

  // draw
  qCDebug(omChan, "head: %ld headoffset %p objectcount: %un",
          commandsBuffer.getHead(), commandsBuffer.headOffset(), objectCount);

  glAssert(gl->glMultiDrawElementsIndirect(
      objects[0].primitiveType, GL_UNSIGNED_INT, commandsBuffer.headOffset(),
      objectCount, 0));

  bufferManager->unbind();

  commandsBuffer.onUsageComplete(mapRange);
  transformBuffer.onUsageComplete(mapRange);
  if (customBufferSize)
    customBuffer.onUsageComplete(customMapRange);
}

DrawElementsIndirectCommand
ObjectManager::createDrawCommand(const ObjectData &objectData, int counter)
{
  DrawElementsIndirectCommand command;

  command.count = objectData.indexSize;
  command.instanceCount = 1;
  command.firstIndex = objectData.indexOffset;
  command.baseVertex = objectData.vertexOffset;
  command.baseInstance = counter;

  qCDebug(omChan, "counter: %d count: %u firstIndex: %u baseVertex: %u",
          counter, command.count, command.firstIndex, command.baseVertex);

  return command;
}

}  // namespace Graphics
<|endoftext|>