void BTAdvancedDetailsWidget::init()
{
    setWindowTitle(i18n("Advanced Details for %1", m_transfer->source().fileName()));
    resize(500, 400);
    QGridLayout *layout = new QGridLayout();
    KTitleWidget *titleWidget = new KTitleWidget(this);
    titleWidget->setText(i18n("Advanced Details for %1", m_transfer->source().fileName()));
    titleWidget->setPixmap(KIcon("dialog-information"));
    layout->addWidget(titleWidget);
    tabWidget = new KTabWidget(this);
    layout->addWidget(tabWidget);
    setLayout(layout);
    file_view = new FileView(this);
    file_view->changeTC(tc, KGlobal::config());
    tabWidget->insertTab(0, file_view, KIcon("inode-directory"), i18n("Files"));
    //peer_view = new PeerView(this);
    //tabWidget->insertTab(1, peer_view, KIcon("system-users"), i18n("Peers"));
    //cd_view = new ChunkDownloadView(this);
    //cd_view->changeTC(tc);
    //tabWidget->insertTab(2, cd_view, KIcon("preferences-plugin"), i18n("Chunks"));
    tracker_view = new TrackerView(this);
    tracker_view->changeTC(tc);
    tabWidget->insertTab(1, tracker_view, KIcon("network-server"), i18n("Trackers"));
    webseeds_tab = new WebSeedsTab(this);
    webseeds_tab->changeTC(tc);
    tabWidget->insertTab(2, webseeds_tab, KIcon("network-server"), i18n("Webseeds"));
    monitor = new Monitor(tc, 0, 0, file_view);
}
Exemple #2
0
KBugReport::KBugReport( QWidget * _parent, bool modal, const KAboutData *aboutData )
  : KDialog( _parent ), d( new KBugReportPrivate(this) )
{
  setCaption( i18n("Submit Bug Report") );
  setButtons( Ok | Cancel );
  setModal(modal);

  // Use supplied aboutdata, otherwise the one from the active componentData
  // otherwise the KGlobal one. _activeInstance should neved be 0L in theory.
  d->m_aboutData = aboutData ? aboutData
      : (KGlobal::activeComponent().isValid() ? KGlobal::activeComponent().aboutData()
                                  : KGlobal::mainComponent().aboutData());
#ifndef EMSCRIPTEN
  d->m_process = 0;
#endif
  QWidget * parent = new QWidget(this);
  d->submitBugWeb = false;

  if ( d->m_aboutData->bugAddress() == QLatin1String("*****@*****.**") )
  {
    // This is a core KDE application -> redirect to the web form
    d->submitBugWeb = true;
    setButtonGuiItem( Cancel, KStandardGuiItem::close() );
  }

  QLabel * tmpLabel;
  QVBoxLayout * lay = new QVBoxLayout( parent);

  KTitleWidget *title = new KTitleWidget( this );
  title->setText(i18n( "Submit Bug Report" ) );
  title->setPixmap( KIcon( "tools-report-bug" ).pixmap( 32 ) );
  lay->addWidget( title );

  QGridLayout *glay = new QGridLayout();
  lay->addLayout(glay);

  int row = 0;

  if ( !d->submitBugWeb )
  {
    // From
    QString qwtstr = i18n( "Your email address. If incorrect, use the Configure Email button to change it" );
    tmpLabel = new QLabel( i18nc("Email sender address", "From:"), parent );
    glay->addWidget( tmpLabel, row,0 );
    tmpLabel->setWhatsThis(qwtstr );
    d->m_from = new QLabel( parent );
    glay->addWidget( d->m_from, row, 1 );
    d->m_from->setWhatsThis(qwtstr );


    // Configure email button
    d->m_configureEmail = new QPushButton( i18n("Configure Email..."),
                                        parent );
    connect( d->m_configureEmail, SIGNAL(clicked()), this,
             SLOT(_k_slotConfigureEmail()) );
    glay->addWidget( d->m_configureEmail, 0, 2, 3, 1, Qt::AlignTop|Qt::AlignRight );

    // To
    qwtstr = i18n( "The email address this bug report is sent to." );
    tmpLabel = new QLabel( i18nc("Email receiver address", "To:"), parent );
    glay->addWidget( tmpLabel, ++row,0 );
    tmpLabel->setWhatsThis(qwtstr );
    tmpLabel = new QLabel( d->m_aboutData->bugAddress(), parent );
    tmpLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
    glay->addWidget( tmpLabel, row, 1 );
    tmpLabel->setWhatsThis(qwtstr );

    setButtonGuiItem( Ok,  KGuiItem( i18n("&Send"), "mail-send", i18n( "Send bug report." ),
                    i18n( "Send this bug report to %1." ,  d->m_aboutData->bugAddress() ) ) );
    row++;
  }
  else
  {
    d->m_configureEmail = 0;
    d->m_from = 0;
  }

  // Program name
  QString qwtstr = i18n( "The application for which you wish to submit a bug report - if incorrect, please use the Report Bug menu item of the correct application" );
  tmpLabel = new QLabel( i18n("Application: "), parent );
  glay->addWidget( tmpLabel, row, 0 );
  tmpLabel->setWhatsThis(qwtstr );
  d->appcombo = new KComboBox( false, parent );
  d->appcombo->setWhatsThis(qwtstr );
  QStringList packageList;
  for (int c = 0; packages[c]; ++c)
    packageList << QString::fromLatin1(packages[c]);
  d->appcombo->addItems(packageList);
  connect(d->appcombo, SIGNAL(activated(int)), SLOT(_k_appChanged(int)));
  d->appname = d->m_aboutData
                                    ? d->m_aboutData->productName()
                                    : qApp->applicationName() ;
  glay->addWidget( d->appcombo, row, 1 );
  int index = 0;
  for (; index < d->appcombo->count(); index++) {
      if (d->appcombo->itemText(index) == d->appname) {
          break;
      }
  }
  if (index == d->appcombo->count()) { // not present
      d->appcombo->addItem(d->appname);
  }
  d->appcombo->setCurrentIndex(index);

  tmpLabel->setWhatsThis(qwtstr );

  // Version
  qwtstr = i18n( "The version of this application - please make sure that no newer version is available before sending a bug report" );
  tmpLabel = new QLabel( i18n("Version:"), parent );
  glay->addWidget( tmpLabel, ++row, 0 );
  tmpLabel->setWhatsThis(qwtstr );
  if (d->m_aboutData)
      d->m_strVersion = d->m_aboutData->version();
  else
      d->m_strVersion = i18n("no version set (programmer error)");
  d->kde_version = QString::fromLatin1( KDE_VERSION_STRING );
  d->kde_version += ", " + QString::fromLatin1( KDE_DISTRIBUTION_TEXT );
  if ( !d->submitBugWeb )
      d->m_strVersion += ' ' + d->kde_version;
  d->m_version = new QLabel( d->m_strVersion, parent );
  d->m_version->setTextInteractionFlags(Qt::TextBrowserInteraction);
  //glay->addWidget( d->m_version, row, 1 );
  glay->addWidget( d->m_version, row, 1, 1, 2 );
  d->m_version->setWhatsThis(qwtstr );

  tmpLabel = new QLabel(i18n("OS:"), parent);
  glay->addWidget( tmpLabel, ++row, 0 );

  struct utsname unameBuf;
  uname( &unameBuf );
  d->os = QString::fromLatin1( unameBuf.sysname ) +
          " (" + QString::fromLatin1( unameBuf.machine ) + ") "
          "release " + QString::fromLatin1( unameBuf.release );

  tmpLabel = new QLabel(d->os, parent);
  tmpLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
  glay->addWidget( tmpLabel, row, 1, 1, 2 );

  tmpLabel = new QLabel(i18n("Compiler:"), parent);
  glay->addWidget( tmpLabel, ++row, 0 );
  tmpLabel = new QLabel(QString::fromLatin1(KDE_COMPILER_VERSION), parent);
  tmpLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
  glay->addWidget( tmpLabel, row, 1, 1, 2 );

  if ( !d->submitBugWeb )
  {
    // Severity
    d->m_bgSeverity = new QGroupBox( i18n("Se&verity"), parent );
    static const char * const sevNames[5] = { "critical", "grave", "normal", "wishlist", "i18n" };
    const QString sevTexts[5] = { i18n("Critical"), i18n("Grave"), i18nc("normal severity","Normal"), i18n("Wishlist"), i18n("Translation") };
    QHBoxLayout *severityLayout=new QHBoxLayout(d->m_bgSeverity);
    for (int i = 0 ; i < 5 ; i++ )
    {
      // Store the severity string as the name
      QRadioButton *rb = new QRadioButton( sevTexts[i], d->m_bgSeverity);
      rb->setObjectName(sevNames[i] );
      d->severityButtons.append(rb);
      severityLayout->addWidget(rb);
      if (i==2) rb->setChecked(true); // default : "normal"
    }

    lay->addWidget( d->m_bgSeverity );

    // Subject
    QHBoxLayout * hlay = new QHBoxLayout();
    lay->addItem(hlay);
    tmpLabel = new QLabel( i18n("S&ubject: "), parent );
    hlay->addWidget( tmpLabel );
    d->m_subject = new KLineEdit( parent );
    d->m_subject->setClearButtonShown(true);
    d->m_subject->setFocus();
    tmpLabel->setBuddy( d->m_subject );
    hlay->addWidget( d->m_subject );

    QString text = i18n("Enter the text (in English if possible) that you wish to submit for the "
                        "bug report.\n"
                        "If you press \"Send\", a mail message will be sent to the maintainer of "
                        "this program.\n");
    QLabel * label = new QLabel( parent);

    label->setText( text );
    lay->addWidget( label );

    // The multiline-edit
    d->m_lineedit = new KTextEdit( parent);
    d->m_lineedit->setMinimumHeight( 180 ); // make it big
    d->m_lineedit->setWordWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
    d->m_lineedit->setLineWrapMode(QTextEdit::WidgetWidth);
    d->m_lineedit->setCheckSpellingEnabled(true);
    d->m_lineedit->setSpellCheckingLanguage("en");
    lay->addWidget( d->m_lineedit, 10 /*stretch*/ );

    d->_k_slotSetFrom();
  } else {
    // Point to the web form

    lay->addSpacing(10);
    QString text = i18n("<qt>To submit a bug report, click on the button below. This will open a web browser "
                        "window on <a href=\"http://bugs.kde.org\">http://bugs.kde.org</a> where you will find "
                        "a form to fill in. The information displayed above will be transferred to that server.</qt>");
    QLabel * label = new QLabel( text, parent);
    label->setOpenExternalLinks( true );
    label->setTextInteractionFlags( Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard );
    label->setWordWrap( true );
    lay->addWidget( label );
    lay->addSpacing(10);

    d->appcombo->setFocus();

    d->_k_updateUrl();

    setButtonText(Ok, i18n("&Launch Bug Report Wizard"));
    setButtonIcon(Ok, KIcon("tools-report-bug"));
  }
  parent->setMinimumHeight( parent->sizeHint().height() + 20 ); // WORKAROUND: prevent "cropped" kcombobox
  setMainWidget(parent);
}
ExtendedAboutDialog::ExtendedAboutDialog(const KAboutData *aboutData, const OcsData *ocsData, QWidget *parent)
  : KDialog(parent)
  , d(new Private(this))
{
    DEBUG_BLOCK
    if (aboutData == 0)
        aboutData = KGlobal::mainComponent().aboutData();

    d->aboutData = aboutData;

    if (!aboutData) {
        QLabel *errorLabel = new QLabel(i18n("<qt>No information available.<br />"
                                             "The supplied KAboutData object does not exist.</qt>"), this);

        errorLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
        setMainWidget(errorLabel);
        return;
    }
    if( !ocsData )
    {
        QLabel *errorLabel = new QLabel(i18n("<qt>No information available.<br />"
                                             "The supplied OcsData object does not exist.</qt>"), this);

        errorLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
        setMainWidget(errorLabel);
        return;
    }
    m_ocsData = *ocsData;

    setPlainCaption(i18n("About %1", aboutData->programName()));
    setButtons(KDialog::Close);
    setDefaultButton(KDialog::Close);
    setModal(false);


    //Set up the title widget...
    KTitleWidget *titleWidget = new KTitleWidget(this);

    QIcon windowIcon;
    if (!aboutData->programIconName().isEmpty()) {
        windowIcon = KIcon(aboutData->programIconName());
    } else {
        windowIcon = qApp->windowIcon();
    }
    titleWidget->setPixmap(windowIcon.pixmap(64, 64), KTitleWidget::ImageLeft);
    if (aboutData->programLogo().canConvert<QPixmap>())
        titleWidget->setPixmap(aboutData->programLogo().value<QPixmap>(), KTitleWidget::ImageLeft);
    else if (aboutData->programLogo().canConvert<QImage>())
        titleWidget->setPixmap(QPixmap::fromImage(aboutData->programLogo().value<QImage>()), KTitleWidget::ImageLeft);

    titleWidget->setText(i18n("<html><font size=\"5\">%1</font><br /><b>Version %2</b><br />Using KDE %3</html>",
                         aboutData->programName(), aboutData->version(), KDE::versionString()));


    //Now let's add the tab bar...
    QTabWidget *tabWidget = new QTabWidget;
    tabWidget->setUsesScrollButtons(false);


    //Set up the first page...
    QString aboutPageText = aboutData->shortDescription() + '\n';

    if (!aboutData->otherText().isEmpty())
        aboutPageText += '\n' + aboutData->otherText() + '\n';

    if (!aboutData->copyrightStatement().isEmpty())
        aboutPageText += '\n' + aboutData->copyrightStatement() + '\n';

    if (!aboutData->homepage().isEmpty())
        aboutPageText += '\n' + QString("<a href=\"%1\">%1</a>").arg(aboutData->homepage()) + '\n';
    aboutPageText = aboutPageText.trimmed();

    QLabel *aboutLabel = new QLabel;
    aboutLabel->setWordWrap(true);
    aboutLabel->setOpenExternalLinks(true);
    aboutLabel->setText(aboutPageText.replace('\n', "<br />"));
    aboutLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);

    QVBoxLayout *aboutLayout = new QVBoxLayout;
    aboutLayout->addStretch();
    aboutLayout->addWidget(aboutLabel);

    const int licenseCount = aboutData->licenses().count();
    debug()<< "About to show license stuff";
    debug()<< "License count is"<<licenseCount;
    for (int i = 0; i < licenseCount; ++i) {
        const KAboutLicense &license = aboutData->licenses().at(i);

        QLabel *showLicenseLabel = new QLabel;
        showLicenseLabel->setText(QString("<a href=\"%1\">%2</a>").arg(QString::number(i),
                                                                       i18n("License: %1",
                                                                            license.name(KAboutData::FullName))));
        showLicenseLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
        connect(showLicenseLabel, SIGNAL(linkActivated(QString)), this, SLOT(_k_showLicense(QString)));

        aboutLayout->addWidget(showLicenseLabel);
    }
    debug()<<"License widget added";

    aboutLayout->addStretch();

    QWidget *aboutWidget = new QWidget(this);
    aboutWidget->setLayout(aboutLayout);

    tabWidget->addTab(aboutWidget, i18n("&About"));


    //Stuff needed by both Authors and Credits pages:
    QPixmap openDesktopPixmap = QPixmap( KStandardDirs::locate( "data", "amarok/images/opendesktop-22.png" ) );
    QIcon openDesktopIcon = QIcon( openDesktopPixmap );


    //And now, the Authors page:
    const int authorCount = d->aboutData->authors().count();

    if (authorCount)
    {
        m_authorWidget = new QWidget( this );
        QVBoxLayout *authorLayout = new QVBoxLayout( m_authorWidget.data() );

        m_showOcsAuthorButton = new AnimatedBarWidget( openDesktopIcon,
                                     i18n( "Get data from openDesktop.org to learn more about the team" ),
                                     "process-working", m_authorWidget.data() );
        connect( m_showOcsAuthorButton.data(), SIGNAL(clicked()), this, SLOT(switchToOcsWidgets()) );
        authorLayout->addWidget( m_showOcsAuthorButton.data() );

        if (!aboutData->customAuthorTextEnabled() || !aboutData->customAuthorRichText().isEmpty())
        {
            QLabel *bugsLabel = new QLabel( m_authorWidget.data() );
            bugsLabel->setContentsMargins( 4, 2, 0, 4 );
            if (!aboutData->customAuthorTextEnabled())
            {
                if (aboutData->bugAddress().isEmpty() || aboutData->bugAddress() == "*****@*****.**")
                    bugsLabel->setText( i18n("Please use <a href=\"http://bugs.kde.org\">http://bugs.kde.org</a> to report bugs.\n") );
                else
                {
                    if(aboutData->authors().count() == 1 && (aboutData->authors().first().emailAddress() == aboutData->bugAddress()))
                    {
                        bugsLabel->setText( i18n("Please report bugs to <a href=\"mailto:%1\">%2</a>.\n",
                                              aboutData->authors().first().emailAddress(),
                                              aboutData->authors().first().emailAddress()));
                    }
                    else
                    {
                        bugsLabel->setText( i18n("Please report bugs to <a href=\"mailto:%1\">%2</a>.\n",
                                              aboutData->bugAddress(), aboutData->bugAddress()));
                    }
                }
            }
            else
                bugsLabel->setText( aboutData->customAuthorRichText() );
            authorLayout->addWidget( bugsLabel );
        }

        m_authorListWidget = new OcsPersonListWidget( d->aboutData->authors(), m_ocsData.authors(), OcsPersonItem::Author, m_authorWidget.data() );
        connect( m_authorListWidget.data(), SIGNAL(switchedToOcs()), m_showOcsAuthorButton.data(), SLOT(stop()) );
        connect( m_authorListWidget.data(), SIGNAL(switchedToOcs()), m_showOcsAuthorButton.data(), SLOT(fold()) );

        authorLayout->addWidget( m_authorListWidget.data() );
        authorLayout->setMargin( 0 );
        authorLayout->setSpacing( 2 );
        m_authorWidget.data()->setLayout( authorLayout );

        m_authorPageTitle = ( authorCount == 1 ) ? i18n("A&uthor") : i18n("A&uthors");
        tabWidget->addTab(m_authorWidget.data(), m_authorPageTitle);
        m_isOfflineAuthorWidget = true; //is this still used?
    }

    //Then the Credits page:
    const int creditCount = aboutData->credits().count();

    if (creditCount)
    {
        m_creditWidget = new QWidget( this );
        QVBoxLayout *creditLayout = new QVBoxLayout( m_creditWidget.data() );

        m_showOcsCreditButton = new AnimatedBarWidget( openDesktopIcon,
                                     i18n( "Get data from openDesktop.org to learn more about contributors" ),
                                     "process-working", m_creditWidget.data() );
        connect( m_showOcsCreditButton.data(), SIGNAL(clicked()), this, SLOT(switchToOcsWidgets()) );
        creditLayout->addWidget( m_showOcsCreditButton.data() );

        m_creditListWidget = new OcsPersonListWidget( d->aboutData->credits(), m_ocsData.credits(), OcsPersonItem::Contributor, m_creditWidget.data() );
        connect( m_creditListWidget.data(), SIGNAL(switchedToOcs()), m_showOcsCreditButton.data(), SLOT(stop()) );
        connect( m_creditListWidget.data(), SIGNAL(switchedToOcs()), m_showOcsCreditButton.data(), SLOT(fold()) );

        creditLayout->addWidget( m_creditListWidget.data() );
        creditLayout->setMargin( 0 );
        creditLayout->setSpacing( 2 );
        m_creditWidget.data()->setLayout( creditLayout );

        tabWidget->addTab( m_creditWidget.data(), i18n("&Contributors"));
        m_isOfflineCreditWidget = true; //is this still used?
    }

    //Finally, the Donors page:
    const int donorCount = ocsData->donors()->count();

    if (donorCount)
    {
        m_donorWidget = new QWidget( this );
        QVBoxLayout *donorLayout = new QVBoxLayout( m_donorWidget.data() );

        m_showOcsDonorButton = new AnimatedBarWidget( openDesktopIcon,
                                     i18n( "Get data from openDesktop.org to learn more about our generous donors" ),
                                     "process-working", m_donorWidget.data() );
        connect( m_showOcsDonorButton.data(), SIGNAL(clicked()), this, SLOT(switchToOcsWidgets()) );
        donorLayout->addWidget( m_showOcsDonorButton.data() );

        QList< KAboutPerson > donors;
        for( QList< QPair< QString, KAboutPerson > >::const_iterator it = m_ocsData.donors()->constBegin();
             it != m_ocsData.donors()->constEnd(); ++it )
        {
            donors << ( *it ).second;
        }
        m_donorListWidget = new OcsPersonListWidget( donors , m_ocsData.donors(), OcsPersonItem::Contributor, m_donorWidget.data() );
        connect( m_donorListWidget.data(), SIGNAL(switchedToOcs()), m_showOcsDonorButton.data(), SLOT(stop()) );
        connect( m_donorListWidget.data(), SIGNAL(switchedToOcs()), m_showOcsDonorButton.data(), SLOT(fold()) );

        donorLayout->addWidget( m_donorListWidget.data() );
        donorLayout->setMargin( 0 );
        donorLayout->setSpacing( 2 );
        QLabel *roktoberLabel =
            new QLabel(i18n("<p>Each year in October the Amarok team organizes a funding "
                            "drive called <b>Roktober</b>.</p>"
                            "<p>If you want your name mentioned on this list "
                            "<a href=\"http://amarok.kde.org/donations\"> donate "
                            "during Roktober</a> and opt-in.</p>"));
        roktoberLabel->setOpenExternalLinks(true);
        donorLayout->addWidget(roktoberLabel);
        m_donorWidget.data()->setLayout( donorLayout );

        tabWidget->addTab( m_donorWidget.data(), i18n("&Donors"));
        m_isOfflineDonorWidget = true;
    }


    //And the translators:
    QPalette transparentBackgroundPalette;
    transparentBackgroundPalette.setColor( QPalette::Base, Qt::transparent );
    transparentBackgroundPalette.setColor( QPalette::Text, transparentBackgroundPalette.color( QPalette::WindowText ) );


    const QList<KAboutPerson> translatorList = aboutData->translators();

    if(translatorList.count() > 0) {
        QString translatorPageText;

        QList<KAboutPerson>::ConstIterator it;
        for(it = translatorList.begin(); it != translatorList.end(); ++it) {
            translatorPageText += QString("<p style=\"margin: 0px;\">%1</p>").arg((*it).name());
            if (!(*it).emailAddress().isEmpty())
                translatorPageText += QString("<p style=\"margin: 0px; margin-left: 15px;\"><a href=\"mailto:%1\">%1</a></p>").arg((*it).emailAddress());
            translatorPageText += "<p style=\"margin: 0px;\">&nbsp;</p>";
        }

        translatorPageText += KAboutData::aboutTranslationTeam();

        KTextBrowser *translatorTextBrowser = new KTextBrowser;
        translatorTextBrowser->setFrameStyle(QFrame::NoFrame);
        translatorTextBrowser->setPalette(transparentBackgroundPalette);
        translatorTextBrowser->setHtml(translatorPageText);
        tabWidget->addTab(translatorTextBrowser, i18n("T&ranslation"));
    }

    //Jam everything together in a layout:
    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget(titleWidget);
    mainLayout->addWidget(tabWidget);
    mainLayout->setMargin(0);

    QWidget *mainWidget = new QWidget;
    mainWidget->setLayout(mainLayout);
    setMainWidget(mainWidget);
    setInitialSize( QSize( 480, 460 ) );
}
ContactInfoDialog::ContactInfoDialog(const Tp::AccountPtr &account, const Tp::ContactPtr &contact, QWidget *parent)
    : QDialog(parent)
    , d(new Private(this))
{
#if 0   // Editing contacts is not yet supported in TpQt
    /* Whether contact is the user himself */
    d->editable = (contact == account->connection()->selfContact());
#endif
    d->editable = false;
    d->account = account;
    d->contact = KTp::ContactPtr::qObjectCast(contact);

    d->buttonBox = new QDialogButtonBox(this);


    if (d->editable) {
        d->buttonBox->setStandardButtons(QDialogButtonBox::Save | QDialogButtonBox::Close);
    } else {
        d->buttonBox->setStandardButtons(QDialogButtonBox::Close);
    }

    connect(d->buttonBox, &QDialogButtonBox::clicked, this, &ContactInfoDialog::slotButtonClicked);

    setMaximumSize(sizeHint());

    QVBoxLayout *layout = new QVBoxLayout(this);
    layout->setSpacing(30);

    /* Title - presence icon, alias, id */
    KTitleWidget *titleWidget = new KTitleWidget(this);
    KTp::Presence presence(contact->presence());
    titleWidget->setPixmap(presence.icon().pixmap(32, 32), KTitleWidget::ImageLeft);
    titleWidget->setText(contact->alias());
    titleWidget->setComment(contact->id());
    layout->addWidget(titleWidget);

    /* 1st column: avatar; 2nd column: details */
    d->columnsLayout = new QHBoxLayout();
    d->columnsLayout->setSpacing(30);
    layout->addLayout(d->columnsLayout);

    /* Make sure the contact has all neccessary features ready */
    Tp::PendingContacts *op = contact->manager()->upgradeContacts(
            QList<Tp::ContactPtr>() << contact,
            Tp::Features() << Tp::Contact::FeatureAvatarData
                           << Tp::Contact::FeatureInfo);
    connect(op, SIGNAL(finished(Tp::PendingOperation*)), SLOT(onContactUpgraded(Tp::PendingOperation*)));

    /* State Info - there is no point showing this information when it's about ourselves */
    if (!d->editable) {
        d->stateLayout = new QFormLayout();
        d->stateLayout->setSpacing(10);
        layout->addLayout(d->stateLayout);

        // Fetch roster feature, if it is supported, but not loaded
        Tp::ConnectionPtr conn = contact->manager()->connection();
        if(!conn->actualFeatures().contains(Tp::Connection::FeatureRoster) && !conn->missingFeatures().contains(Tp::Connection::FeatureRoster)) {
            Tp::PendingReady *pr = conn->becomeReady(Tp::Features() << Tp::Connection::FeatureRoster);

            connect(pr, SIGNAL(finished(Tp::PendingOperation*)),
                    SLOT(onFeatureRosterReady(Tp::PendingOperation*)));
        } else {
            d->loadStateRows();
        }
    }

    layout->addWidget(d->buttonBox);
}