dialogs_provider.cpp 20.5 KB
Newer Older
Clément Stenac's avatar
Clément Stenac committed
1
/*****************************************************************************
2
 * dialogs_provider.cpp : Dialog Provider
3
 *****************************************************************************
4
 * Copyright (C) 2006-2008 the VideoLAN team
5
 * $Id$
Clément Stenac's avatar
Clément Stenac committed
6 7
 *
 * Authors: Clément Stenac <zorglub@videolan.org>
8
 *          Jean-Baptiste Kempf <jb@videolan.org>
Clément Stenac's avatar
Clément Stenac committed
9 10 11 12 13 14 15 16 17 18 19 20 21
 *
 * 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
22 23
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
24

25 26 27
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
28

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
29 30
#include <vlc_intf_strings.h>

31
#include "qt4.hpp"
32
#include "dialogs_provider.hpp"
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
33
#include "input_manager.hpp" /* Load Subtitles */
34
#include "menus.hpp"
Ludovic Fauvet's avatar
Ludovic Fauvet committed
35
#include "recents.hpp"
36
#include "util/qt_dirs.hpp"
37 38

/* The dialogs */
Clément Stenac's avatar
Clément Stenac committed
39
#include "dialogs/playlist.hpp"
40
#include "dialogs/bookmarks.hpp"
41
#include "dialogs/preferences.hpp"
42
#include "dialogs/mediainfo.hpp"
43
#include "dialogs/messages.hpp"
44
#include "dialogs/extended.hpp"
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
45
#include "dialogs/vlm.hpp"
Clément Stenac's avatar
Clément Stenac committed
46
#include "dialogs/sout.hpp"
47
#include "dialogs/convert.hpp"
48
#include "dialogs/open.hpp"
49
#include "dialogs/openurl.hpp"
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
50
#include "dialogs/help.hpp"
51
#include "dialogs/gototime.hpp"
52
#include "dialogs/podcast_configuration.hpp"
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
53
#include "dialogs/toolbar.hpp"
54
#include "dialogs/plugins.hpp"
Clément Stenac's avatar
Clément Stenac committed
55

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
56 57 58 59 60 61
#include <QEvent>
#include <QApplication>
#include <QSignalMapper>
#include <QFileDialog>


Clément Stenac's avatar
Clément Stenac committed
62 63
DialogsProvider* DialogsProvider::instance = NULL;

64
DialogsProvider::DialogsProvider( intf_thread_t *_p_intf ) :
65
                                  QObject( NULL ), p_intf( _p_intf )
Clément Stenac's avatar
Clément Stenac committed
66
{
67
    b_isDying = false;
68

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
69
    /* Various signal mappers for the menus */
70
    menusMapper = new QSignalMapper();
71
    CONNECT( menusMapper, mapped(QObject *), this, menuAction( QObject *) );
72

73
    menusUpdateMapper = new QSignalMapper();
74 75
    CONNECT( menusUpdateMapper, mapped(QObject *),
             this, menuUpdateAction( QObject *) );
Clément Stenac's avatar
Clément Stenac committed
76 77 78

    SDMapper = new QSignalMapper();
    CONNECT( SDMapper, mapped (QString), this, SDMenuAction( QString ) );
Clément Stenac's avatar
Clément Stenac committed
79
}
80

Clément Stenac's avatar
Clément Stenac committed
81 82 83
DialogsProvider::~DialogsProvider()
{
    PlaylistDialog::killInstance();
84
    MediaInfoDialog::killInstance();
85
    MessagesDialog::killInstance();
86
    ExtendedDialog::killInstance();
87
    BookmarksDialog::killInstance();
88
    HelpDialog::killInstance();
89
#ifdef UPDATE_CHECK
90
    UpdateDialog::killInstance();
91
#endif
92
    ToolbarEditDialog::killInstance();
93

94 95 96
    delete menusMapper;
    delete menusUpdateMapper;
    delete SDMapper;
Clément Stenac's avatar
Clément Stenac committed
97 98
}

99 100
void DialogsProvider::quit()
{
101
    b_isDying = true;
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
102
    libvlc_Quit( p_intf->p_libvlc );
103 104
}

Clément Stenac's avatar
Clément Stenac committed
105 106
void DialogsProvider::customEvent( QEvent *event )
{
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
107
    if( event->type() == (int)DialogEvent_Type )
Clément Stenac's avatar
Clément Stenac committed
108
    {
109
        DialogEvent *de = static_cast<DialogEvent*>(event);
Clément Stenac's avatar
Clément Stenac committed
110 111
        switch( de->i_dialog )
        {
112 113 114
        case INTF_DIALOG_FILE_SIMPLE:
        case INTF_DIALOG_FILE:
            openDialog(); break;
115 116
        case INTF_DIALOG_FILE_GENERIC:
            openFileGenericDialog( de->p_arg ); break;
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
        case INTF_DIALOG_DISC:
            openDiscDialog(); break;
        case INTF_DIALOG_NET:
            openNetDialog(); break;
        case INTF_DIALOG_SAT:
        case INTF_DIALOG_CAPTURE:
            openCaptureDialog(); break;
        case INTF_DIALOG_DIRECTORY:
            PLAppendDir(); break;
        case INTF_DIALOG_PLAYLIST:
            playlistDialog(); break;
        case INTF_DIALOG_MESSAGES:
            messagesDialog(); break;
        case INTF_DIALOG_FILEINFO:
           mediaInfoDialog(); break;
        case INTF_DIALOG_PREFS:
           prefsDialog(); break;
        case INTF_DIALOG_BOOKMARKS:
           bookmarksDialog(); break;
        case INTF_DIALOG_EXTENDED:
           extendedDialog(); break;
138
#ifdef ENABLE_VLM
139 140
        case INTF_DIALOG_VLM:
           vlmDialog(); break;
141
#endif
142 143 144 145 146 147 148 149 150 151
        case INTF_DIALOG_POPUPMENU:
           QVLCMenu::PopupMenu( p_intf, (de->i_arg != 0) ); break;
        case INTF_DIALOG_AUDIOPOPUPMENU:
           QVLCMenu::AudioPopupMenu( p_intf ); break;
        case INTF_DIALOG_VIDEOPOPUPMENU:
           QVLCMenu::VideoPopupMenu( p_intf ); break;
        case INTF_DIALOG_MISCPOPUPMENU:
           QVLCMenu::MiscPopupMenu( p_intf ); break;
        case INTF_DIALOG_WIZARD:
        case INTF_DIALOG_STREAMWIZARD:
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
152
            openAndStreamingDialogs(); break;
Rafaël Carré's avatar
Rafaël Carré committed
153
#ifdef UPDATE_CHECK
154
        case INTF_DIALOG_UPDATEVLC:
155
            updateDialog(); break;
Rafaël Carré's avatar
Rafaël Carré committed
156
#endif
157
        case INTF_DIALOG_EXIT:
158
            quit(); break;
159 160
        default:
           msg_Warn( p_intf, "unimplemented dialog" );
Clément Stenac's avatar
Clément Stenac committed
161 162 163 164
        }
    }
}

165 166 167
/****************************************************************************
 * Individual simple dialogs
 ****************************************************************************/
Clément Stenac's avatar
Clément Stenac committed
168 169 170 171 172
void DialogsProvider::playlistDialog()
{
    PlaylistDialog::getInstance( p_intf )->toggleVisible();
}

173 174 175 176
void DialogsProvider::prefsDialog()
{
    PrefsDialog::getInstance( p_intf )->toggleVisible();
}
177

178 179 180 181 182
void DialogsProvider::extendedDialog()
{
    ExtendedDialog::getInstance( p_intf )->toggleVisible();
}

183 184 185 186 187
void DialogsProvider::synchroDialog()
{
    ExtendedDialog::getInstance( p_intf )->showTab( 2 );
}

188 189 190 191 192
void DialogsProvider::messagesDialog()
{
    MessagesDialog::getInstance( p_intf )->toggleVisible();
}

193 194 195 196 197
void DialogsProvider::gotoTimeDialog()
{
    GotoTimeDialog::getInstance( p_intf )->toggleVisible();
}

198
#ifdef ENABLE_VLM
199 200
void DialogsProvider::vlmDialog()
{
201
    VLMDialog::getInstance( p_intf )->toggleVisible();
202
}
203
#endif
204

205 206 207 208 209
void DialogsProvider::helpDialog()
{
    HelpDialog::getInstance( p_intf )->toggleVisible();
}

Rafaël Carré's avatar
Rafaël Carré committed
210
#ifdef UPDATE_CHECK
211 212 213
void DialogsProvider::updateDialog()
{
    UpdateDialog::getInstance( p_intf )->toggleVisible();
214
}
Rafaël Carré's avatar
Rafaël Carré committed
215
#endif
216

217 218 219 220 221 222 223 224 225 226
void DialogsProvider::aboutDialog()
{
    AboutDialog::getInstance( p_intf )->toggleVisible();
}

void DialogsProvider::mediaInfoDialog()
{
    MediaInfoDialog::getInstance( p_intf )->toggleVisible();
}

227 228
void DialogsProvider::mediaCodecDialog()
{
229
    MediaInfoDialog::getInstance( p_intf )->showTab( 2 );
230 231
}

232 233
void DialogsProvider::bookmarksDialog()
{
234
    BookmarksDialog::getInstance( p_intf )->toggleVisible();
235 236
}

237 238 239 240 241
void DialogsProvider::podcastConfigureDialog()
{
    PodcastConfigDialog::getInstance( p_intf )->toggleVisible();
}

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
242 243 244 245 246
void DialogsProvider::toolbarDialog()
{
    ToolbarEditDialog::getInstance( p_intf )->toggleVisible();
}

247 248 249 250 251 252
void DialogsProvider::pluginDialog()
{
    PluginDialog *diag = new PluginDialog( p_intf );
    diag->show();
}

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
253
/* Generic open file */
254 255 256 257
void DialogsProvider::openFileGenericDialog( intf_dialog_args_t *p_arg )
{
    if( p_arg == NULL )
    {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
258
        msg_Warn( p_intf, "openFileGenericDialog() called with NULL arg" );
259 260
        return;
    }
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
261 262

    /* Replace the extensions to a Qt format */
263 264 265 266 267 268 269 270 271 272 273
    int i = 0;
    QString extensions = qfu( p_arg->psz_extensions );
    while ( ( i = extensions.indexOf( "|", i ) ) != -1 )
    {
        if( ( extensions.count( "|" ) % 2 ) == 0 )
            extensions.replace( i, 1, ");;" );
        else
            extensions.replace( i, 1, "(" );
    }
    extensions.replace(QString(";*"), QString(" *"));
    extensions.append( ")" );
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
274 275

    /* Save */
276 277
    if( p_arg->b_save )
    {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
278 279
        QString file = QFileDialog::getSaveFileName( NULL, p_arg->psz_title,
                            qfu( p_intf->p_sys->psz_filepath ), extensions );
280 281 282
        if( !file.isEmpty() )
        {
            p_arg->i_results = 1;
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
283
            p_arg->psz_results = (char **)malloc( p_arg->i_results * sizeof( char * ) );
284
            p_arg->psz_results[0] = strdup( qtu( toNativeSepNoSlash( file ) ) );
285 286 287 288
        }
        else
            p_arg->i_results = 0;
    }
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
289
    else /* non-save mode */
290
    {
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
291 292 293
        QStringList files = QFileDialog::getOpenFileNames( NULL,
                p_arg->psz_title, qfu( p_intf->p_sys->psz_filepath ),
                extensions );
294
        p_arg->i_results = files.count();
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
295
        p_arg->psz_results = (char **)malloc( p_arg->i_results * sizeof( char * ) );
296
        i = 0;
297
        foreach( const QString &file, files )
298
            p_arg->psz_results[i++] = strdup( qtu( toNativeSepNoSlash( file ) ) );
299
    }
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
300 301

    /* Callback */
302 303
    if( p_arg->pf_callback )
        p_arg->pf_callback( p_arg );
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
304 305

    /* Clean afterwards */
306 307 308 309 310 311 312 313 314 315
    if( p_arg->psz_results )
    {
        for( i = 0; i < p_arg->i_results; i++ )
            free( p_arg->psz_results[i] );
        free( p_arg->psz_results );
    }
    free( p_arg->psz_title );
    free( p_arg->psz_extensions );
    free( p_arg );
}
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
316 317 318 319
/****************************************************************************
 * All the open/add stuff
 * Open Dialog first - Simple Open then
 ****************************************************************************/
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
320

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
321 322 323 324 325 326 327 328
void DialogsProvider::openDialog( int i_tab )
{
    OpenDialog::getInstance( p_intf->p_sys->p_mi , p_intf )->showTab( i_tab );
}
void DialogsProvider::openDialog()
{
    openDialog( OPEN_FILE_TAB );
}
329 330
void DialogsProvider::openFileDialog()
{
331
    openDialog( OPEN_FILE_TAB );
332
}
333
void DialogsProvider::openDiscDialog()
Clément Stenac's avatar
Clément Stenac committed
334
{
335
    openDialog( OPEN_DISC_TAB );
Clément Stenac's avatar
Clément Stenac committed
336
}
337
void DialogsProvider::openNetDialog()
Clément Stenac's avatar
Clément Stenac committed
338
{
339
    openDialog( OPEN_NETWORK_TAB );
Clément Stenac's avatar
Clément Stenac committed
340
}
341 342
void DialogsProvider::openCaptureDialog()
{
343
    openDialog( OPEN_CAPTURE_TAB );
344
}
Clément Stenac's avatar
Clément Stenac committed
345

346
/* Same as the open one, but force the enqueue */
347 348
void DialogsProvider::PLAppendDialog()
{
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
349 350
    OpenDialog::getInstance( p_intf->p_sys->p_mi, p_intf, false,
                             OPEN_AND_ENQUEUE )->showTab( OPEN_FILE_TAB );
351
}
352

353
void DialogsProvider::MLAppendDialog()
354 355 356 357 358
{
    OpenDialog::getInstance( p_intf->p_sys->p_mi, p_intf, false,
                            OPEN_AND_ENQUEUE, false, false )
                                    ->showTab( OPEN_FILE_TAB );
}
359

360 361 362 363 364
/**
 * Simple open
 ***/
QStringList DialogsProvider::showSimpleOpen( QString help,
                                             int filters,
365
                                             QString path )
366
{
367
    QString fileTypes = "";
368
    if( filters & EXT_FILTER_MEDIA ) {
369
        ADD_FILTER_MEDIA( fileTypes );
370
    }
371
    if( filters & EXT_FILTER_VIDEO ) {
372
        ADD_FILTER_VIDEO( fileTypes );
373
    }
374
    if( filters & EXT_FILTER_AUDIO ) {
375
        ADD_FILTER_AUDIO( fileTypes );
376
    }
377
    if( filters & EXT_FILTER_PLAYLIST ) {
378
        ADD_FILTER_PLAYLIST( fileTypes );
379
    }
380
    if( filters & EXT_FILTER_SUBTITLE ) {
381 382
        ADD_FILTER_SUBTITLE( fileTypes );
    }
383
    ADD_FILTER_ALL( fileTypes );
384
    fileTypes.replace(QString(";*"), QString(" *"));
385

386
    return QFileDialog::getOpenFileNames( NULL,
387
        help.isEmpty() ? qtr(I_OP_SEL_FILES ) : help,
388
        path.isEmpty() ? qfu( p_intf->p_sys->psz_filepath ) : path,
389
        fileTypes );
390 391
}

392 393 394 395 396
/**
 * Open a file,
 * pl helps you to choose from playlist or media library,
 * go to start or enqueue
 **/
397 398 399 400
void DialogsProvider::addFromSimple( bool pl, bool go)
{
    QStringList files = DialogsProvider::showSimpleOpen();
    int i = 0;
401
    foreach( const QString &file, files )
402
    {
403
        playlist_Add( THEPL, qtu( toNativeSeparators( file ) ), NULL,
404 405 406 407
                      go ? ( PLAYLIST_APPEND | ( i ? 0 : PLAYLIST_GO ) |
                                               ( i ? PLAYLIST_PREPARSE : 0 ) )
                         : ( PLAYLIST_APPEND | PLAYLIST_PREPARSE ),
                      PLAYLIST_END,
408
                      pl ? true : false, false );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
409 410
        RecentsMRL::getInstance( p_intf )->addRecent(
                toNativeSeparators( file ) );
411
        i++;
412 413 414
    }
}

415 416 417 418 419
void DialogsProvider::simpleOpenDialog()
{
    addFromSimple( true, true ); /* Playlist and Go */
}

420
void DialogsProvider::simplePLAppendDialog()
Clément Stenac's avatar
Clément Stenac committed
421
{
422
    addFromSimple( true, false );
Clément Stenac's avatar
Clément Stenac committed
423 424
}

425
void DialogsProvider::simpleMLAppendDialog()
426
{
427 428 429
    addFromSimple( false, false );
}

430 431 432 433 434 435 436 437 438 439 440 441 442 443
/* Url & Clipboard */
/**
 * Open a MRL.
 * If the clipboard contains URLs, the first is automatically 'preselected'.
 **/
void DialogsProvider::openUrlDialog()
{
    OpenUrlDialog *oud = OpenUrlDialog::getInstance( p_intf->p_sys->p_mi,
                                                     p_intf );
    if( oud->exec() == QDialog::Accepted )
    {
        QString url = oud->url();
        if( !url.isEmpty() )
        {
444
            playlist_Add( THEPL, qtu( url ),
445 446 447 448
                          NULL, !oud->shouldEnqueue() ?
                                  ( PLAYLIST_APPEND | PLAYLIST_GO )
                                : ( PLAYLIST_APPEND | PLAYLIST_PREPARSE ),
                          PLAYLIST_END, true, false );
449
            RecentsMRL::getInstance( p_intf )->addRecent( url );
450 451 452 453
        }
    }
}

454 455 456 457 458 459
/* Directory */
/**
 * Open a directory,
 * pl helps you to choose from playlist or media library,
 * go to start or enqueue
 **/
460
static void openDirectory( intf_thread_t *p_intf, bool pl, bool go )
461
{
462 463 464 465
    QString dir = QFileDialog::getExistingDirectory( NULL, qtr("Open Directory") );

    if (!dir.isEmpty() )
    {
466 467
        QString mrl = dir.endsWith( "VIDEO_TS", Qt::CaseInsensitive ) ?
            "dvd://" : "directory://" + toNativeSeparators( dir );
468
        input_item_t *p_input = input_item_New( THEPL, qtu( mrl ), NULL );
469

470
        /* FIXME: playlist_AddInput() can fail */
471 472
        playlist_AddInput( THEPL, p_input,
                       go ? ( PLAYLIST_APPEND | PLAYLIST_GO ) : PLAYLIST_APPEND,
473
                       PLAYLIST_END, pl, pl_Unlocked );
Ludovic Fauvet's avatar
Ludovic Fauvet committed
474
        RecentsMRL::getInstance( p_intf )->addRecent( mrl );
475
        if( !go )
476
            input_Read( THEPL, p_input, true );
477
        vlc_gc_decref( p_input );
478 479 480
    }
}

481 482 483 484 485
void DialogsProvider::PLOpenDir()
{
    openDirectory( p_intf, true, true );
}

486 487
void DialogsProvider::PLAppendDir()
{
488
    openDirectory( p_intf, true, false );
489 490 491 492 493 494 495
}

void DialogsProvider::MLAppendDir()
{
    openDirectory( p_intf, false , false );
}

496 497 498
/****************
 * Playlist     *
 ****************/
499
void DialogsProvider::openAPlaylist()
500
{
501
    QStringList files = showSimpleOpen( qtr( "Open playlist..." ),
502
                                        EXT_FILTER_PLAYLIST );
503
    foreach( const QString &file, files )
504
    {
505
        playlist_Import( THEPL, qtu( toNativeSeparators( file ) ) );
506 507 508
    }
}

509
void DialogsProvider::saveAPlaylist()
510 511
{
    QFileDialog *qfd = new QFileDialog( NULL,
512
                                   qtr( "Save playlist as..." ),
513
                                   qfu( p_intf->p_sys->psz_filepath ),
514
                                   qtr( "XSPF playlist (*.xspf);; " ) +
515
                                   qtr( "M3U playlist (*.m3u);; " ) +
516
                                   qtr( "HTML playlist (*.html)" ) );
517 518 519 520 521 522 523 524
    qfd->setFileMode( QFileDialog::AnyFile );
    qfd->setAcceptMode( QFileDialog::AcceptSave );
    qfd->setConfirmOverwrite( true );

    if( qfd->exec() == QDialog::Accepted )
    {
        if( qfd->selectedFiles().count() > 0 )
        {
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
525
            static const char psz_xspf[] = "export-xspf",
526 527
                              psz_m3u[] = "export-m3u",
                              psz_html[] = "export-html";
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
528
            const char *psz_module;
529 530 531 532

            QString file = qfd->selectedFiles().first();
            QString filter = qfd->selectedFilter();

533
            if( file.contains( ".xsp" ) || filter.contains( "XSPF" ) )
534 535 536 537 538
            {
                psz_module = psz_xspf;
                if( !file.contains( ".xsp" ) )
                    file.append( ".xspf" );
            }
539
            else if( file.contains( ".m3u" )  || filter.contains( "M3U" ) )
540 541 542 543 544
            {
                psz_module = psz_m3u;
                if( !file.contains( ".m3u" ) )
                    file.append( ".m3u" );
            }
545 546 547 548 549 550 551 552 553 554 555 556
            else if( file.contains(".html" ) || filter.contains( "HTML" ) )
            {
                psz_module = psz_html;
                if( !file.contains( "html" ) )
                    file.append( ".html" );
            }
            else
            {
                msg_Err( p_intf, "Impossible to recognise the file type" );
                delete qfd;
                return;
            }
557

558 559
            playlist_Export( THEPL, qtu( toNativeSeparators( file ) ),
                        THEPL->p_local_category, psz_module);
560 561 562 563 564 565 566 567 568
        }
    }
    delete qfd;
}

/****************************************************************************
 * Sout emulation
 ****************************************************************************/

569 570 571 572
void DialogsProvider::streamingDialog( QWidget *parent,
                                       QString mrl,
                                       bool b_transcode_only,
                                       QStringList options )
573
{
574 575 576
    char *psz_soutoption;

    /* Stream */
577 578
    if( !b_transcode_only )
    {
579
        SoutDialog *s = new SoutDialog( parent, p_intf, mrl );
580
        if( s->exec() == QDialog::Accepted )
581
        {
582
            psz_soutoption = strdup( qtu( s->getMrl() ) );
583 584 585 586
            delete s;
        }
        else
        {
587
            delete s; return;
588 589
        }
    } else {
590
    /* Convert */
591
        ConvertDialog *s = new ConvertDialog( parent, p_intf, mrl );
592
        if( s->exec() == QDialog::Accepted )
593
        {
594
            psz_soutoption = strdup( qtu( s->getMrl() ) );
595 596 597 598
            delete s;
        }
        else
        {
599
            delete s; return;
600
        }
601 602
    }

603 604
    /* Get SoutMRL */
    if( !EMPTY_STR( psz_soutoption ) )
605
    {
606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630
        /* Create Input */
        input_item_t *p_input;
        p_input = input_item_New( p_intf, qtu( mrl ), _("Streaming") );

        /* Add normal Options */
        for( int j = 0; j < options.size(); j++ )
        {
            QString qs = options[j].trimmed();
            if( !qs.isEmpty() )
            {
                input_item_AddOption( p_input, qtu( qs ),
                        VLC_INPUT_OPTION_TRUSTED );
            }
        }

        /* Add SoutMRL */
        msg_Dbg( p_intf, "Streaming MRL is: %s", psz_soutoption );
        input_item_AddOption( p_input, psz_soutoption, VLC_INPUT_OPTION_TRUSTED );

        /* Switch between enqueuing and starting the item */
        /* FIXME: playlist_AddInput() can fail */
        playlist_AddInput( THEPL, p_input,
                PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END, true, pl_Unlocked );
        vlc_gc_decref( p_input );

Ludovic Fauvet's avatar
Ludovic Fauvet committed
631
        RecentsMRL::getInstance( p_intf )->addRecent( mrl );
632 633 634
    }
}

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
635
void DialogsProvider::openAndStreamingDialogs()
636
{
637 638
    OpenDialog::getInstance( p_intf->p_sys->p_mi, p_intf, false, OPEN_AND_STREAM )
                                ->showTab( OPEN_FILE_TAB );
639 640
}

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
641
void DialogsProvider::openAndTranscodingDialogs()
642
{
643 644
    OpenDialog::getInstance( p_intf->p_sys->p_mi , p_intf, false, OPEN_AND_SAVE )
                                ->showTab( OPEN_FILE_TAB );
645 646
}

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664
void DialogsProvider::loadSubtitlesFile()
{
    input_thread_t *p_input = THEMIM->getInput();
    if( !p_input ) return;

    input_item_t *p_item = input_GetItem( p_input );
    if( !p_item ) return;

    char *path = input_item_GetURI( p_item );
    if( !path ) path = strdup( "" );

    char *sep = strrchr( path, DIR_SEP_CHAR );
    if( sep ) *sep = '\0';

    QStringList qsl = showSimpleOpen( qtr( "Open subtitles..." ),
                                      EXT_FILTER_SUBTITLE,
                                      path );
    free( path );
665
    foreach( const QString &qsFile, qsl )
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
666
    {
667
        if( input_AddSubtitle( p_input, qtu( toNativeSeparators( qsFile ) ),
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
668 669 670 671 672 673 674
                    true ) )
            msg_Warn( p_intf, "unable to load subtitles from '%s'",
                      qtu( qsFile ) );
    }
}


675
/****************************************************************************
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
676
 * Menus
677
 ****************************************************************************/
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
678

679 680
void DialogsProvider::menuAction( QObject *data )
{
681
    QVLCMenu::DoAction( data );
682 683
}

684 685
void DialogsProvider::menuUpdateAction( QObject *data )
{
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
686 687 688
    MenuFunc *func = qobject_cast<MenuFunc *>(data);
    assert( func );
    func->doFunc( p_intf );
689 690
}

Clément Stenac's avatar
Clément Stenac committed
691 692
void DialogsProvider::SDMenuAction( QString data )
{
693
    char *psz_sd = strdup( qtu( data ) );
Clément Stenac's avatar
Clément Stenac committed
694 695 696 697
    if( !playlist_IsServicesDiscoveryLoaded( THEPL, psz_sd ) )
        playlist_ServicesDiscoveryAdd( THEPL, psz_sd );
    else
        playlist_ServicesDiscoveryRemove( THEPL, psz_sd );
698
    free( psz_sd );
Clément Stenac's avatar
Clément Stenac committed
699 700
}

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
701 702 703 704 705
/**
 * Play the MRL contained in the Recently played menu.
 **/
void DialogsProvider::playMRL( const QString &mrl )
{
706 707
    playlist_Add( THEPL, qtu( mrl ) , NULL,
           PLAYLIST_APPEND | PLAYLIST_GO , PLAYLIST_END, true, false );
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
708 709 710

    RecentsMRL::getInstance( p_intf )->addRecent( mrl );
}