Qt4 - add ifdef if someone compiles vlc without vlm support
[vlc.git] / modules / gui / qt4 / dialogs / vlm.cpp
1 /*****************************************************************************
2  * vlm.cpp : VLM Management
3  ****************************************************************************
4  * Copyright ( C ) 2006 the VideoLAN team
5  * $Id: sout.cpp 21875 2007-09-08 16:01:33Z jb $
6  *
7  * Authors: Jean-Baptiste Kempf <jb@videolan.org>
8  *          Jean-François Massol <jf.massol -at- gmail.com>
9  *          Clément Sténac <zorglub@videolan.org>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * ( at your option ) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin street, Fifth Floor, Boston MA 02110-1301, USA.
24  *****************************************************************************/
25
26 #ifdef ENABLE_VLM
27
28 #include "dialogs/vlm.hpp"
29 #include "dialogs/open.hpp"
30 #include "dialogs/sout.hpp"
31
32 #include <QString>
33 #include <QComboBox>
34 #include <QVBoxLayout>
35 #include <QStackedWidget>
36 #include <QLabel>
37 #include <QWidget>
38 #include <QGridLayout>
39 #include <QLineEdit>
40 #include <QCheckBox>
41 #include <QToolButton>
42 #include <QGroupBox>
43 #include <QPushButton>
44 #include <QHBoxLayout>
45 #include <QDateTimeEdit>
46 #include <QSpinBox>
47 #include <QHeaderView>
48 #include <QScrollArea>
49
50 static const char *psz_type[] = { "Broadcast", "Schedule", "VOD" };
51
52 VLMDialog *VLMDialog::instance = NULL;
53
54 VLMDialog::VLMDialog( intf_thread_t *_p_intf ) : QVLCFrame( _p_intf )
55 {
56     p_vlm = vlm_New( p_intf );
57
58     if( !p_vlm )
59     {
60         msg_Warn( p_intf, "Couldn't build VLM object ");
61         return;
62     }
63     vlmWrapper = new VLMWrapper( p_vlm );
64
65     // UI stuff
66     ui.setupUi( this );
67     ui.saveButton->hide();
68
69 #define ADDMEDIATYPES( str, type ) ui.mediaType->addItem( qtr( str ), QVariant( type ) );
70     ADDMEDIATYPES( "Broadcast", QVLM_Broadcast );
71     ADDMEDIATYPES( "Schedule", QVLM_Schedule );
72     ADDMEDIATYPES( "Video On Demand ( VOD )", QVLM_VOD );
73 #undef ADDMEDIATYPES
74
75     /* Schedule Stuffs */
76     QGridLayout *schetimelayout = new QGridLayout( ui.schedBox );
77     QLabel *schetimelabel = new QLabel( qtr( "Hours/Minutes/Seconds:" ) );
78     schetimelayout->addWidget( schetimelabel, 0, 0 );
79     QLabel *schedatelabel = new QLabel( qtr( "Day Month Year:" ) );
80     schetimelayout->addWidget( schedatelabel, 1, 0 );
81     QLabel *scherepeatLabel = new QLabel( qtr( "Repeat:" ) );
82     schetimelayout->addWidget( scherepeatLabel, 2, 0 );
83     QLabel *scherepeatTimeLabel = new QLabel( qtr( "Repeat delay:" ) );
84     schetimelayout->addWidget( scherepeatTimeLabel, 3, 0 );
85
86     time = new QDateTimeEdit( QTime::currentTime() );
87     time->setAlignment( Qt::AlignRight );
88     schetimelayout->addWidget( time, 0, 1, 1, 3 );
89
90     date = new QDateTimeEdit( QDate::currentDate() );
91     date->setAlignment( Qt::AlignRight );
92     date->setCalendarPopup( true );
93 #ifdef WIN32
94     date->setDisplayFormat( "dd MM yyyy" );
95 #else
96     date->setDisplayFormat( "dd MMMM yyyy" );
97 #endif
98     schetimelayout->addWidget( date, 1, 1, 1, 3 );
99
100     scherepeatnumber = new QSpinBox;
101     scherepeatnumber->setAlignment( Qt::AlignRight );
102     schetimelayout->addWidget( scherepeatnumber, 2, 1, 1, 3 );
103
104     repeatDays = new QSpinBox;
105     repeatDays->setAlignment( Qt::AlignRight );
106     schetimelayout->addWidget( repeatDays, 3, 1, 1, 1 );
107     repeatDays->setSuffix( qtr(" days") );
108
109     repeatTime = new QDateTimeEdit;
110     repeatTime->setAlignment( Qt::AlignRight );
111     schetimelayout->addWidget( repeatTime, 3, 2, 1, 2 );
112     repeatTime->setDisplayFormat( "hh:mm:ss" );
113
114     /* scrollArea */
115     ui.vlmItemScroll->setFrameStyle( QFrame::NoFrame );
116     ui.vlmItemScroll->setWidgetResizable( true );
117     vlmItemWidget = new QWidget;
118     vlmItemLayout = new QVBoxLayout( vlmItemWidget );
119     vlmItemWidget->setLayout( vlmItemLayout );
120     ui.vlmItemScroll->setWidget( vlmItemWidget );
121
122     QSpacerItem *spacer =
123         new QSpacerItem( 10, 10, QSizePolicy::Minimum, QSizePolicy::Expanding);
124     vlmItemLayout->addItem( spacer );
125
126     QPushButton *closeButton = new QPushButton( qtr( "Close" ) );
127     ui.buttonBox->addButton( closeButton, QDialogButtonBox::AcceptRole );
128
129     showScheduleWidget( QVLM_Broadcast );
130
131     /* Connect the comboBox to show the right Widgets */
132     CONNECT( ui.mediaType, currentIndexChanged( int ),
133              this, showScheduleWidget( int ) );
134
135     /* Connect the leftList to show the good VLMItem */
136     CONNECT( ui.vlmListItem, currentRowChanged( int ),
137              this, selectVLMItem( int ) );
138
139     BUTTONACT( closeButton, close() );
140     BUTTONACT( ui.addButton, addVLMItem() );
141     BUTTONACT( ui.clearButton, clearWidgets() );
142     BUTTONACT( ui.saveButton, saveModifications() );
143     BUTTONACT( ui.inputButton, selectInput() );
144     BUTTONACT( ui.outputButton, selectOutput() );
145 }
146
147 VLMDialog::~VLMDialog()
148 {
149    /* FIXME :you have to destroy vlm here to close
150     * but we shouldn't destroy vlm here in case somebody else wants it */
151     if( p_vlm )
152         vlm_Delete( p_vlm );
153 }
154
155 void VLMDialog::showScheduleWidget( int i )
156 {
157     ui.schedBox->setVisible( ( i == QVLM_Schedule ) );
158     ui.loopBCast->setVisible( ( i == QVLM_Broadcast ) );
159     ui.vodBox->setVisible( ( i == QVLM_VOD ) );
160 }
161
162 void VLMDialog::selectVLMItem( int i )
163 {
164     ui.vlmItemScroll->ensureWidgetVisible( vlmItems.at( i ) );
165 }
166
167 bool VLMDialog::isNameGenuine( QString name )
168 {
169     for( int i = 0; i < vlmItems.size(); i++ )
170     {
171         if( vlmItems.at( i )->name == name )
172             return false;
173     }
174     return true;
175 }
176
177 void VLMDialog::addVLMItem()
178 {
179     int vlmItemCount = vlmItems.size();
180
181     /* Take the name and Check it */
182     QString name = ui.nameLedit->text();
183     if( name.isEmpty() || !isNameGenuine( name ) )
184     {
185         msg_Dbg( p_intf, "VLM Name is empty or already exists, I can't do it" );
186         return;
187     }
188
189     int type = ui.mediaType->itemData( ui.mediaType->currentIndex() ).toInt();
190
191     QString typeShortName;
192     QString inputText = ui.inputLedit->text();
193     QString outputText = ui.outputLedit->text();
194     bool b_checked = ui.enableCheck->isChecked();
195     bool b_looped = ui.loopBCast->isChecked();
196
197     VLMAWidget * vlmAwidget;
198
199     switch( type )
200     {
201     case QVLM_Broadcast:
202         typeShortName = "Bcast";
203         vlmAwidget = new VLMBroadcast( name, inputText, outputText,
204                                   b_checked, b_looped, this );
205         VLMWrapper::AddBroadcast( name, inputText, outputText, b_checked, b_looped );
206     break;
207     case QVLM_VOD:
208         typeShortName = "VOD";
209         vlmAwidget = new VLMVod( name, inputText, outputText,
210                                  b_checked, ui.muxLedit->text(), this );
211         VLMWrapper::AddVod( name, inputText, outputText, b_checked );
212         break;
213     case QVLM_Schedule:
214         typeShortName = "Sched";
215         vlmAwidget = new VLMSchedule( name, inputText, outputText,
216                                       b_checked, this );
217         break;
218     default:
219         msg_Warn( p_intf, "Something bad happened" );
220         return;
221     }
222
223     /* Add an Item of the Side List */
224     ui.vlmListItem->addItem( typeShortName + " : " + name );
225     ui.vlmListItem->setCurrentRow( vlmItemCount - 1 );
226
227     /* Add a new VLMAWidget on the main List */
228
229     vlmItemLayout->insertWidget( vlmItemCount, vlmAwidget );
230     vlmItems.append( vlmAwidget );
231 }
232
233 void VLMDialog::clearWidgets()
234 {
235     ui.nameLedit->clear();
236     ui.inputLedit->clear();
237     ui.outputLedit->clear();
238     time->setTime( QTime::currentTime() );
239     date->setDate( QDate::currentDate() );
240     ui.enableCheck->setChecked( true );
241     ui.nameLedit->setReadOnly( false );
242     ui.loopBCast->setChecked( false );
243     ui.muxLedit->clear();
244     ui.saveButton->hide();
245     ui.addButton->show();
246 }
247
248 void VLMDialog::selectInput()
249 {
250     OpenDialog *o = OpenDialog::getInstance( this, p_intf, 0, true );
251     o->exec();
252     ui.inputLedit->setText( o->getMRL() );
253 }
254
255 void VLMDialog::selectOutput()
256 {
257     SoutDialog *s = SoutDialog::getInstance( this, p_intf, false );
258     if( s->exec() == QDialog::Accepted )
259         ui.outputLedit->setText( s->getMrl() );
260 }
261
262 /* Object Modification */
263 void VLMDialog::removeVLMItem( VLMAWidget *vlmObj )
264 {
265     int index = vlmItems.indexOf( vlmObj );
266     if( index < 0 ) return;
267
268     //FIXME, this is going to segfault if the focus in on the ListWidget
269     delete ui.vlmListItem->takeItem( index );
270     vlmItems.removeAt( index );
271     delete vlmObj;
272
273     /* HERE BE DRAGONS VLM REQUEST */
274 }
275
276 void VLMDialog::startModifyVLMItem( VLMAWidget *vlmObj )
277 {
278     currentIndex = vlmItems.indexOf( vlmObj );
279     if( currentIndex < 0 ) return;
280
281     msg_Dbg( p_intf, "Type: %i", vlmObj->type );
282     ui.vlmListItem->setCurrentRow( currentIndex );
283     ui.nameLedit->setText( vlmObj->name );
284     ui.inputLedit->setText( vlmObj->input );
285     ui.outputLedit->setText( vlmObj->output );
286     ui.enableCheck->setChecked( vlmObj->b_enabled );
287
288     switch( vlmObj->type )
289     {
290     case QVLM_Broadcast:
291         ui.loopBCast->setChecked( (qobject_cast<VLMBroadcast *>(vlmObj))->b_looped );
292         break;
293     case QVLM_VOD:
294         ui.muxLedit->setText( (qobject_cast<VLMVod *>(vlmObj))->mux );
295         break;
296     case QVLM_Schedule:
297         //(qobject_cast<VLMSchedule *>)
298         break;
299     }
300
301     ui.nameLedit->setReadOnly( true );
302     ui.addButton->hide();
303     ui.saveButton->show();
304 }
305
306 void VLMDialog::saveModifications()
307 {
308     VLMAWidget *vlmObj = vlmItems.at( currentIndex );
309     if( vlmObj )
310     {
311         vlmObj->input = ui.inputLedit->text();
312         vlmObj->output = ui.outputLedit->text();
313         vlmObj->setChecked( ui.enableCheck->isChecked() );
314         vlmObj->b_enabled = ui.enableCheck->isChecked();
315         switch( vlmObj->type )
316         {
317         case QVLM_Broadcast:
318             (qobject_cast<VLMBroadcast *>(vlmObj))->b_looped = ui.loopBCast->isChecked();
319             break;
320         case QVLM_VOD:
321             (qobject_cast<VLMVod *>(vlmObj))->mux = ui.muxLedit->text();
322             break;
323         case QVLM_Schedule:
324             break;
325            //           vlmObj->
326         }
327         vlmObj->update(); /* It should call the correct function is VLMAWidget
328                              is abstract, but I am far from sure... FIXME ? */
329     }
330     clearWidgets();
331 }
332
333 /*********************************
334  * VLMAWidget - Abstract class
335  ********************************/
336
337 VLMAWidget::VLMAWidget( QString _name,
338                         QString _input,
339                         QString _output,
340                         bool _enabled,
341                         VLMDialog *_parent,
342                         int _type )
343                       : QGroupBox( _name, _parent )
344 {
345     parent = _parent;
346     name = _name;
347     input = _input;
348     output = _output;
349     b_enabled = _enabled;
350     type = _type;
351
352     setCheckable( true );
353     setChecked( b_enabled );
354
355     objLayout = new QGridLayout( this );
356     setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Maximum );
357
358     nameLabel = new QLabel;
359     objLayout->addWidget( nameLabel, 0, 0, 1, 4 );
360
361     /*QLabel *time = new QLabel( "--:--/--:--" );
362     objLayout->addWidget( time, 1, 3, 1, 2 );*/
363
364     QToolButton *modifyButton = new QToolButton;
365     modifyButton->setIcon( QIcon( QPixmap( ":/pixmaps/menus_settings_16px.png" ) ) );
366     objLayout->addWidget( modifyButton, 0, 5 );
367
368     QToolButton *deleteButton = new QToolButton;
369     deleteButton->setIcon( QIcon( QPixmap( ":/pixmaps/menus_quit_16px.png" ) ) );
370     objLayout->addWidget( deleteButton, 0, 6 );
371
372     BUTTONACT( modifyButton, modify() );
373     BUTTONACT( deleteButton, del() );
374     CONNECT( this, clicked( bool ), this, toggleEnabled( bool ) );
375 }
376
377 void VLMAWidget::modify()
378 {
379     parent->startModifyVLMItem( this );
380 }
381
382 void VLMAWidget::del()
383 {
384     parent->removeVLMItem( this );
385 }
386
387 //FIXME, remove me before release
388 void VLMAWidget::enterEvent( QEvent *event )
389 {
390     printf( "test" );
391 }
392
393 void VLMAWidget::toggleEnabled( bool b_enable )
394 {
395     VLMWrapper::EnableItem( name, b_enable );
396 }
397
398 /****************
399  * VLMBroadcast
400  ****************/
401 VLMBroadcast::VLMBroadcast( QString _name, QString _input, QString _output,
402                             bool _enabled, bool _looped, VLMDialog *_parent)
403                           : VLMAWidget( _name, _input, _output,
404                                         _enabled, _parent, QVLM_Broadcast )
405 {
406     nameLabel->setText( "Broadcast: " + name );
407     type = QVLM_Broadcast;
408     b_looped = _looped;
409
410     playButton = new QToolButton;
411     playButton->setIcon( QIcon( QPixmap( ":/pixmaps/play_16px.png" ) ) );
412     objLayout->addWidget( playButton, 1, 0 );
413     b_playing = true;
414
415     QToolButton *stopButton = new QToolButton;
416     stopButton->setIcon( QIcon( QPixmap( ":/pixmaps/stop_16px.png" ) ) );
417     objLayout->addWidget( stopButton, 1, 1 );
418
419     loopButton = new QToolButton;
420     objLayout->addWidget( loopButton, 1, 2 );
421
422     BUTTONACT( playButton, togglePlayPause() );
423     BUTTONACT( stopButton, stop() );
424     BUTTONACT( loopButton, toggleLoop() );
425
426     update();
427 }
428
429 void VLMBroadcast::update()
430 {
431     VLMWrapper::EditBroadcast( name, input, output, b_enabled, b_looped );
432     if( b_looped )
433         loopButton->setIcon( QIcon( QPixmap( ":/pixmaps/playlist_repeat_all.png" ) ) );
434     else
435         loopButton->setIcon( QIcon( QPixmap( ":/pixmaps/playlist_repeat_off.png" ) ) );
436 }
437
438 void VLMBroadcast::togglePlayPause()
439 {
440     if( b_playing = true )
441     {
442         VLMWrapper::ControlBroadcast( name, ControlBroadcastPause );
443         playButton->setIcon( QIcon( QPixmap( ":/pixmaps/pause_16px.png" ) ) );
444     }
445     else
446     {
447         VLMWrapper::ControlBroadcast( name, ControlBroadcastPlay );
448         playButton->setIcon( QIcon( QPixmap( ":/pixmaps/play_16px.png" ) ) );
449     }
450     b_playing = !b_playing;
451 }
452
453 void VLMBroadcast::toggleLoop()
454 {
455     b_enabled = !b_enabled;
456     update();
457 }
458
459 void VLMBroadcast::stop()
460 {
461     VLMWrapper::ControlBroadcast( name, ControlBroadcastStop );
462     playButton->setIcon( QIcon( QPixmap( ":/pixmaps/play_16px.png" ) ) );
463 }
464
465 /****************
466  * VLMSchedule
467  ****************/
468 VLMSchedule::VLMSchedule( QString name, QString input, QString output,
469                             bool enabled, VLMDialog *parent)
470             : VLMAWidget( name, input, output, enabled, parent, QVLM_Schedule )
471 {
472     nameLabel->setText( "Schedule: " + name );
473 }
474
475 void VLMSchedule::update()
476 {
477 }
478
479 /****************
480  * VLMVOD
481  ****************/
482 VLMVod::VLMVod( QString name, QString input, QString output,
483                 bool enabled, QString _mux, VLMDialog *parent)
484        : VLMAWidget( name, input, output, enabled, parent, QVLM_VOD )
485 {
486     nameLabel->setText( "VOD:" + name );
487
488     mux = _mux;
489     muxLabel = new QLabel;
490     objLayout->addWidget( muxLabel, 1, 0 );
491
492     update();
493 }
494
495 void VLMVod::update()
496 {
497     muxLabel->setText( mux );
498     VLMWrapper::EditVod( name, input, output, b_enabled, mux );
499 }
500
501
502 /*******************
503  * VLMWrapper
504  *******************/
505 vlm_t * VLMWrapper::p_vlm = NULL;
506
507 VLMWrapper::VLMWrapper( vlm_t *_p_vlm )
508 {
509     p_vlm = _p_vlm;
510 }
511
512 VLMWrapper::~VLMWrapper()
513 {}
514
515 void VLMWrapper::AddBroadcast( const QString name, QString input,
516                                QString output,
517                                bool b_enabled, bool b_loop  )
518 {
519     vlm_message_t *message;
520     QString command = "new \"" + name + "\" broadcast";
521     vlm_ExecuteCommand( p_vlm, qtu( command ), &message );
522     vlm_MessageDelete( message );
523     EditBroadcast( name, input, output, b_enabled, b_loop );
524 }
525
526 void VLMWrapper::EditBroadcast( const QString name, const QString input,
527                                 const QString output,
528                                 bool b_enabled, bool b_loop  )
529 {
530     vlm_message_t *message;
531     QString command;
532
533     command = "setup \"" + name + "\" inputdel all";
534     vlm_ExecuteCommand( p_vlm, qtu( command ), &message );
535     vlm_MessageDelete( message );
536     command = "setup \"" + name + "\" input \"" + input + "\"";
537     vlm_ExecuteCommand( p_vlm, qtu( command ), &message );
538     vlm_MessageDelete( message );
539     if( !output.isEmpty() )
540     {
541         command = "setup \"" + name + "\" output \"" + output + "\"";
542         vlm_ExecuteCommand( p_vlm, qtu( command ), &message );
543         vlm_MessageDelete( message );
544     }
545     if( b_enabled )
546     {
547         command = "setup \"" + name + "\" enabled";
548         vlm_ExecuteCommand( p_vlm, qtu( command ), &message );
549         vlm_MessageDelete( message );
550     }
551     if( b_loop )
552     {
553         command = "setup \"" + name + "\" loop";
554         vlm_ExecuteCommand( p_vlm, qtu( command ), &message );
555         vlm_MessageDelete( message );
556     }
557 }
558
559 void VLMWrapper::EnableItem( const QString name, bool b_enable )
560 {
561     vlm_message_t *message;
562     QString command = "setup \"" + name + ( b_enable ? " enable" : " disable" );
563 }
564
565 void VLMWrapper::ControlBroadcast( const QString name, int BroadcastStatus,
566                                    unsigned int seek )
567 {
568     vlm_message_t *message;
569
570     QString command = "control \"" + name;
571     switch( BroadcastStatus )
572     {
573     case ControlBroadcastPlay:
574         command += " play";
575         break;
576     case ControlBroadcastPause:
577         command += " pause";
578         break;
579     case ControlBroadcastStop:
580         command += " stop";
581         break;
582     case ControlBroadcastSeek:
583         command += " seek" + seek;
584         break;
585     }
586     vlm_ExecuteCommand( p_vlm, qtu( command ), &message );
587     vlm_MessageDelete( message );
588 }
589
590 void VLMWrapper::AddVod( const QString name, const QString input,
591                          const QString output,
592                          bool b_enabled, const QString mux )
593 {
594     vlm_message_t *message;
595     QString command = "new \"" + name + "\" vod";
596     vlm_ExecuteCommand( p_vlm, qtu( command ), &message );
597     vlm_MessageDelete( message );
598     EditVod(  name, input, output, b_enabled, mux );
599 }
600
601 void VLMWrapper::EditVod( const QString name, const QString input,
602                           const QString output,
603                           bool b_enabled,
604                           const QString mux )
605 {
606     vlm_message_t *message;
607     QString command = "setup \"" + name + "\" input \"" + input + "\"";
608     vlm_ExecuteCommand( p_vlm, qtu( command ), &message );
609     vlm_MessageDelete( message );
610     if( !output.isEmpty() )
611     {
612         command = "setup \"" + name + "\" output \"" + output + "\"";
613         vlm_ExecuteCommand( p_vlm, qtu( command ), &message );
614         vlm_MessageDelete( message );
615     }
616     if( b_enabled )
617     {
618         command = "setup \"" + name + "\" enabled";
619         vlm_ExecuteCommand( p_vlm, qtu( command ), &message );
620         vlm_MessageDelete( message );
621     }
622     if( !mux.isEmpty() )
623     {
624         command = "setup \"" + name + "\" mux \"" + mux + "\"";
625         vlm_ExecuteCommand( p_vlm, qtu( command ), &message );
626         vlm_MessageDelete( message );
627     }
628 }
629
630 #endif