1
/***************************************************************************
2
* Copyright (C) 2009-2014 by Savoir-Faire Linux *
3
* Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com>*
5
* This program is free software; you can redistribute it and/or modify *
6
* it under the terms of the GNU General Public License as published by *
7
* the Free Software Foundation; either version 3 of the License, or *
8
* (at your option) any later version. *
10
* This program is distributed in the hope that it will be useful, *
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13
* GNU General Public License for more details. *
15
* You should have received a copy of the GNU General Public License *
16
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
17
**************************************************************************/
18
#include "actioncollection.h"
21
#include <QtGui/QAction>
22
#include <QtCore/QPointer>
26
#include <KStandardDirs>
29
#include <KMessageBox>
30
#include <KStandardAction>
31
#include <KShortcutsDialog>
32
#include <KActionCollection>
33
#include <KEditToolBar>
36
#include "extendedaction.h"
38
#include "accountwizard.h"
39
#include "sflphoneview.h"
40
#include "sflphoneaccessibility.h"
41
#include "conf/configurationdialog.h"
42
#include "klib/kcfg_settings.h"
43
#include "klib/helperfunctions.h"
44
#include "klib/macromodel.h"
45
#include "klib/akonadibackend.h"
47
#include <lib/account.h>
48
#include <lib/accountlistmodel.h>
49
#include <lib/callmodel.h>
50
#include <lib/audiosettingsmodel.h>
53
ActionCollection* ActionCollection::m_spInstance = nullptr;
55
ActionCollection* ActionCollection::instance() {
57
m_spInstance = new ActionCollection();
61
ActionCollection::ActionCollection(QObject* parent) : QObject(parent),m_pWizard(nullptr)
63
action_accept = new ExtendedAction(this);
64
action_refuse = new ExtendedAction(this);
65
action_hold = new ExtendedAction(this);
66
action_transfer = new ExtendedAction(this);
67
action_record = new ExtendedAction(this);
68
action_mute_capture = new ExtendedAction(this);
69
action_mute_playback = new ExtendedAction(this);
70
action_hangup = new ExtendedAction(this);
71
action_unhold = new ExtendedAction(this);
72
action_pickup = new ExtendedAction(this);
74
action_transfer->setAltIcon(KStandardDirs::locate("data" , "sflphone-client-kde/transfer_grayscale.png" ));
75
action_record ->setAltIcon(KStandardDirs::locate("data" , "sflphone-client-kde/record_grayscale.png" ));
76
action_hold ->setAltIcon(KStandardDirs::locate("data" , "sflphone-client-kde/hold_grayscale.png" ));
77
action_refuse ->setAltIcon(KStandardDirs::locate("data" , "sflphone-client-kde/refuse_grayscale.png" ));
78
action_mute_capture ->setAltIcon(KStandardDirs::locate("data" , "sflphone-client-kde/mutemic_grayscale.png" ));
79
action_hangup ->setAltIcon(KStandardDirs::locate("data" , "sflphone-client-kde/hangup_grayscale.png" ));
80
action_unhold ->setAltIcon(KStandardDirs::locate("data" , "sflphone-client-kde/unhold_grayscale.png" ));
81
action_pickup ->setAltIcon(KStandardDirs::locate("data" , "sflphone-client-kde/pickup_grayscale.png" ));
82
action_accept ->setAltIcon(KStandardDirs::locate("data" , "sflphone-client-kde/pickup_grayscale.png" ));
84
action_transfer->setText ( i18n( "Transfer" ) );
85
action_record ->setText ( i18n( "Record" ) );
86
action_hold ->setText ( i18n( "Hold" ) );
87
action_refuse ->setText ( i18n( "Refuse" ) );
88
action_hangup ->setText ( i18n( "Hang up" ) );
89
action_unhold ->setText ( i18n( "Unhold" ) );
90
action_pickup ->setText ( i18n( "Pickup" ) );
91
action_mute_capture ->setText ( i18nc("Mute the current audio capture device", "Mute" ) );
92
action_mute_playback ->setText ( i18nc("Mute the current audio playback device", "Mute Playback" ) );
93
action_accept ->setText ( i18n("Dial" ) );
96
action_video_rotate_left = new ExtendedAction(this);
97
action_video_rotate_right = new ExtendedAction(this);
98
action_video_flip_horizontal = new ExtendedAction(this);
99
action_video_flip_vertical = new ExtendedAction(this);
100
action_video_mute = new ExtendedAction(this);
101
action_video_preview = new ExtendedAction(this);
102
action_video_rotate_left ->setText ( i18n( "Rotate left" ) );
103
action_video_rotate_right ->setText ( i18n( "Rotate right" ) );
104
action_video_flip_horizontal ->setText ( i18n( "Flip" ) );
105
action_video_flip_vertical ->setText ( i18n( "Flip" ) );
106
action_video_mute ->setText ( i18n( "Mute" ) );
107
action_video_preview ->setText ( i18n( "Preview" ) );
108
action_video_rotate_left ->setAltIcon(KIcon("object-rotate-left" ));
109
action_video_rotate_right ->setAltIcon(KIcon("object-rotate-right" ));
110
action_video_flip_horizontal ->setAltIcon(KIcon("object-flip-horizontal"));
111
action_video_flip_vertical ->setAltIcon(KIcon("object-flip-vertical" ));
112
action_video_mute ->setAltIcon(KIcon("camera-web" ));
113
action_video_preview ->setAltIcon(KIcon("view-preview" ));
117
ActionCollection::~ActionCollection()
119
delete action_accept ;
120
delete action_refuse ;
122
delete action_transfer ;
123
delete action_record ;
124
delete action_mailBox ;
125
delete action_close ;
127
delete action_displayVolumeControls ;
128
delete action_displayDialpad ;
129
delete action_displayMessageBox ;
130
delete action_configureSflPhone ;
131
delete action_configureShortcut ;
132
delete action_accountCreationWizard ;
133
delete action_pastenumber ;
134
delete action_showContactDock ;
135
delete action_showHistoryDock ;
136
delete action_showBookmarkDock ;
137
delete action_editToolBar ;
138
delete action_mute_playback ;
139
delete action_mute_capture ;
142
void ActionCollection::setupAction()
144
kDebug() << "setupActions";
146
action_mailBox = new KAction(SFLPhone::app());
147
action_accept->setShortcut ( Qt::CTRL + Qt::Key_A );
148
action_refuse->setShortcut ( Qt::CTRL + Qt::Key_D );
149
action_hold->setShortcut ( Qt::CTRL + Qt::Key_H );
150
action_transfer->setShortcut ( Qt::CTRL + Qt::Key_T );
151
action_record->setShortcut ( Qt::CTRL + Qt::Key_R );
152
action_mailBox->setShortcut ( Qt::CTRL + Qt::Key_M );
154
action_screen = new QActionGroup(SFLPhone::app());
155
action_screen->setExclusive(true);
157
action_close = KStandardAction::close(SFLPhone::app(), SLOT(close()), SFLPhone::app());
158
action_quit = KStandardAction::quit(SFLPhone::app(), SLOT(quitButton()), SFLPhone::app());
160
action_configureSflPhone = KStandardAction::preferences(this, SLOT(configureSflPhone()), SFLPhone::app());
161
action_configureSflPhone->setText(i18n("Configure SFLphone"));
163
action_displayDialpad = new KAction(KIcon(QIcon(ICON_DISPLAY_DIALPAD)), i18n("Display dialpad") , this);
164
action_displayMessageBox = new KAction(KIcon("mail-message-new"), i18n("Display text message box") , this);
165
action_displayVolumeControls = new KAction(KIcon(QIcon(ICON_DISPLAY_VOLUME_CONSTROLS)), i18n("Display volume controls"), this);
166
action_pastenumber = new KAction(KIcon("edit-paste"), i18n("Paste") , this);
167
action_showContactDock = new KAction(KIcon("edit-find-user") , i18n("Display Contact") , this);
168
action_showHistoryDock = new KAction(KIcon("view-history") , i18n("Display history") , this);
169
action_showBookmarkDock = new KAction(KIcon("bookmark-new-list"), i18n("Display bookmark") , this);
170
action_editToolBar = new KAction(KIcon("configure-toolbars"), i18n("Configure Toolbars") , this);
171
action_accountCreationWizard = new KAction(i18n("Account creation wizard") , this);
172
action_addContact = new KAction(KIcon("contact-new"),i18n("Add new contact") , this);
174
action_addContact->setShortcut ( Qt::CTRL + Qt::Key_N );
176
action_displayDialpad->setCheckable( true );
177
action_displayDialpad->setChecked ( ConfigurationSkeleton::displayDialpad() );
178
action_configureSflPhone->setText(i18n("Configure SFLphone"));
180
action_displayMessageBox->setCheckable( true );
181
action_displayMessageBox->setChecked ( ConfigurationSkeleton::displayMessageBox() );
183
action_displayVolumeControls->setCheckable( true );
184
action_displayVolumeControls->setChecked ( ConfigurationSkeleton::displayVolume() );
186
action_pastenumber->setShortcut ( Qt::CTRL + Qt::Key_V );
188
action_showContactDock->setCheckable( true );
189
action_showContactDock->setChecked(ConfigurationSkeleton::displayContactDock());
191
action_showHistoryDock->setCheckable( true );
192
action_showHistoryDock->setChecked(ConfigurationSkeleton::displayHistoryDock());
194
action_showBookmarkDock->setCheckable( true );
195
action_showBookmarkDock->setChecked(ConfigurationSkeleton::displayBookmarkDock());
197
action_mute_capture->setCheckable(true);
198
connect(action_mute_capture,SIGNAL(toggled(bool)),AudioSettingsModel::instance(),SLOT(muteCapture(bool)));
199
connect(AudioSettingsModel::instance(),SIGNAL(captureMuted(bool)),action_mute_capture,SLOT(setChecked(bool)));
200
action_mute_playback->setCheckable(true);
201
connect(action_mute_playback,SIGNAL(toggled(bool)),AudioSettingsModel::instance(),SLOT(mutePlayback(bool)));
202
connect(AudioSettingsModel::instance(),SIGNAL(playbackMuted(bool)),action_mute_playback,SLOT(setChecked(bool)));
206
action_configureShortcut = new KAction(KIcon(KIcon("configure-shortcuts")), i18n("Configure Shortcut"), this);
207
// SENDER SIGNAL RECEIVER SLOT /
208
/**/connect(action_accept, SIGNAL(triggered()), this , SLOT(accept()) );
209
/**/connect(action_hangup, SIGNAL(triggered()), this , SLOT(hangup()) );
210
/**/connect(action_refuse, SIGNAL(triggered()), this , SLOT(refuse()) );
211
/**/connect(action_hold, SIGNAL(triggered()), this , SLOT(hold()) );
212
/**/connect(action_unhold, SIGNAL(triggered()), this , SLOT(unhold()) );
213
/**/connect(action_transfer, SIGNAL(triggered()), this , SLOT(transfer()) );
214
/**/connect(action_record, SIGNAL(triggered()), this , SLOT(record()) );
215
/**/connect(action_mailBox, SIGNAL(triggered()), this , SLOT(mailBox()) );
216
/**/connect(action_pickup, SIGNAL(triggered()), this , SLOT(accept()) );
217
/**/connect(action_displayVolumeControls, SIGNAL(toggled(bool)), SFLPhone::view() , SLOT(displayVolumeControls(bool)) );
218
/**/connect(action_displayDialpad, SIGNAL(toggled(bool)), SFLPhone::view() , SLOT(displayDialpad(bool)) );
219
/**/connect(action_displayMessageBox, SIGNAL(toggled(bool)), SFLPhone::view() , SLOT(displayMessageBox(bool)) );
220
/**/connect(action_accountCreationWizard, SIGNAL(triggered()), this , SLOT(accountCreationWizard()) );
221
/**/connect(action_pastenumber, SIGNAL(triggered()), SFLPhone::view() , SLOT(paste()) );
222
/**/connect(action_configureShortcut, SIGNAL(triggered()), this , SLOT(showShortCutEditor()) );
223
/**/connect(action_editToolBar, SIGNAL(triggered()), this , SLOT(editToolBar()) );
224
/**/connect(action_addContact, SIGNAL(triggered()), this , SLOT(slotAddContact()) );
225
/**/connect(MacroModel::instance(), SIGNAL(addAction(KAction*)), this , SLOT(addMacro(KAction*)) );
228
connect(AudioSettingsModel::instance(),SIGNAL(captureVolumeChanged(int)),this,SLOT(updateRecordButton()));
229
connect(AudioSettingsModel::instance(),SIGNAL(playbackVolumeChanged(int)),this,SLOT(updateVolumeButton()));
231
SFLPhone::app()->actionCollection()->addAction("action_accept" , action_accept );
232
SFLPhone::app()->actionCollection()->addAction("action_refuse" , action_refuse );
233
SFLPhone::app()->actionCollection()->addAction("action_hold" , action_hold );
234
SFLPhone::app()->actionCollection()->addAction("action_transfer" , action_transfer );
235
SFLPhone::app()->actionCollection()->addAction("action_record" , action_record );
236
SFLPhone::app()->actionCollection()->addAction("action_mailBox" , action_mailBox );
237
SFLPhone::app()->actionCollection()->addAction("action_close" , action_close );
238
SFLPhone::app()->actionCollection()->addAction("action_quit" , action_quit );
239
SFLPhone::app()->actionCollection()->addAction("action_pickup" , action_pickup );
240
SFLPhone::app()->actionCollection()->addAction("action_displayVolumeControls" , action_displayVolumeControls );
241
SFLPhone::app()->actionCollection()->addAction("action_displayDialpad" , action_displayDialpad );
242
SFLPhone::app()->actionCollection()->addAction("action_displayMessageBox" , action_displayMessageBox );
243
SFLPhone::app()->actionCollection()->addAction("action_configureSflPhone" , action_configureSflPhone );
244
SFLPhone::app()->actionCollection()->addAction("action_accountCreationWizard" , action_accountCreationWizard );
245
SFLPhone::app()->actionCollection()->addAction("action_configureShortcut" , action_configureShortcut );
246
SFLPhone::app()->actionCollection()->addAction("action_pastenumber" , action_pastenumber );
247
SFLPhone::app()->actionCollection()->addAction("action_showContactDock" , action_showContactDock );
248
SFLPhone::app()->actionCollection()->addAction("action_showHistoryDock" , action_showHistoryDock );
249
SFLPhone::app()->actionCollection()->addAction("action_showBookmarkDock" , action_showBookmarkDock );
250
SFLPhone::app()->actionCollection()->addAction("action_editToolBar" , action_editToolBar );
251
SFLPhone::app()->actionCollection()->addAction("action_addContact" , action_addContact );
252
SFLPhone::app()->actionCollection()->addAction("action_mute_capture" , action_mute_capture );
253
SFLPhone::app()->actionCollection()->addAction("action_mute_playback" , action_mute_playback );
255
MacroModel::instance()->initMacros();
257
QList<KAction*> acList = *SFLPhoneAccessibility::instance();
259
foreach(KAction* ac,acList) {
260
SFLPhone::app()->actionCollection()->addAction(ac->objectName() , ac);
263
void updateRecordButton();
264
void updateVolumeButton();
268
void ActionCollection::accept() //TODO dead code?
270
Call* call = SFLPhone::view()->currentCall();// SFLPhone::view()->currentCall();
272
kDebug() << "Calling when no item is selected. Opening an item.";
273
CallModel::instance()->dialingCall();
274
SFLPhone::view()->selectDialingCall();
275
SFLPhone::view()->updateWindowCallState();
278
const Call::State state = call->state();
279
if (state == Call::State::RINGING || state == Call::State::CURRENT || state == Call::State::HOLD
280
|| state == Call::State::BUSY || state == Call::State::FAILURE || state == Call::State::ERROR) {
281
kDebug() << "Calling when item currently ringing, current, hold or busy. Opening an item.";
282
CallModel::instance()->dialingCall();
283
SFLPhone::view()->selectDialingCall();
284
SFLPhone::view()->updateWindowCallState();
288
call->performAction(Call::Action::ACCEPT);
290
catch(const char * msg) {
291
KMessageBox::error(SFLPhone::app(),i18n(msg));
293
emit windowStateChanged();
299
void ActionCollection::hangup()
301
Call* call = SFLPhone::view()->currentCall();
304
call->performAction(Call::Action::REFUSE);
306
catch(const char * msg) {
307
KMessageBox::error(SFLPhone::app(),i18n(msg));
309
emit windowStateChanged();
314
void ActionCollection::refuse()
316
Call* call = SFLPhone::view()->currentCall();
318
kDebug() << "Error : Hanging up when no item selected. Should not happen.";
322
call->performAction(Call::Action::REFUSE);
324
catch(const char * msg) {
325
KMessageBox::error(SFLPhone::app(),i18n(msg));
327
emit windowStateChanged();
332
void ActionCollection::hold()
334
Call* call = SFLPhone::view()->currentCall();
336
kDebug() << "Error : Holding when no item selected. Should not happen.";
340
call->performAction(Call::Action::HOLD);
342
catch(const char * msg) {
343
KMessageBox::error(SFLPhone::app(),i18n(msg));
345
emit windowStateChanged();
349
///Remove call from hold
350
void ActionCollection::unhold()
352
Call* call = SFLPhone::view()->currentCall();
354
kDebug() << "Error : Un-Holding when no item selected. Should not happen.";
358
call->performAction(Call::Action::HOLD);
360
catch(const char * msg) {
361
KMessageBox::error(SFLPhone::app(),i18n(msg));
363
emit windowStateChanged();
368
void ActionCollection::transfer()
370
Call* call = SFLPhone::view()->currentCall();
372
kDebug() << "Error : Transferring when no item selected. Should not happen.";
376
call->performAction(Call::Action::TRANSFER);
378
catch(const char * msg) {
379
KMessageBox::error(SFLPhone::app(),i18n(msg));
381
emit windowStateChanged();
386
void ActionCollection::record()
388
Call* call = SFLPhone::view()->currentCall();
390
kDebug() << "Error : Recording when no item selected. Should not happen.";
394
call->performAction(Call::Action::RECORD);
396
catch(const char * msg) {
397
KMessageBox::error(SFLPhone::app(),i18n(msg));
399
emit windowStateChanged();
403
///Access the voice mail list
404
void ActionCollection::mailBox()
406
Account* account = AccountListModel::currentAccount();
407
const QString mailBoxNumber = account->mailbox();
408
Call* call = CallModel::instance()->dialingCall();
411
call->appendText(mailBoxNumber);
413
call->performAction(Call::Action::ACCEPT);
415
catch(const char * msg) {
416
KMessageBox::error(SFLPhone::app(),i18n(msg));
418
emit windowStateChanged();
421
HelperFunctions::displayNoAccountMessageBox(SFLPhone::view());
425
///Show the configuration dialog
426
void ActionCollection::configureSflPhone()
428
QPointer<ConfigurationDialog> configDialog = new ConfigurationDialog(SFLPhone::view());
429
configDialog->setModal(true);
431
connect(configDialog, SIGNAL(changesApplied()), SFLPhone::view(), SLOT(loadWindow()));
432
configDialog->exec();
433
disconnect(configDialog, SIGNAL(changesApplied()), SFLPhone::view(), SLOT(loadWindow()));
437
///Show the account creation wizard
438
void ActionCollection::accountCreationWizard()
441
m_pWizard = new AccountWizard(SFLPhone::view());
442
m_pWizard->setModal(false);
447
///Display the shortcuts dialog
448
void ActionCollection::showShortCutEditor() {
449
KShortcutsDialog::configure( SFLPhone::app()->actionCollection() );
452
///Show the toolbar editor
453
void ActionCollection::editToolBar()
455
QPointer<KEditToolBar> toolbareditor = new KEditToolBar(SFLPhone::app()->guiFactory());
456
toolbareditor->setModal(true);
457
toolbareditor->exec();
458
toolbareditor->setDefaultToolBar("mainToolBar");
459
delete toolbareditor;
462
///Add a new dynamic action (macro)
463
void ActionCollection::addMacro(KAction* newAction)
465
SFLPhone::app()->actionCollection()->addAction(newAction->objectName() , newAction );
469
/*****************************************************************************
473
****************************************************************************/
475
ExtendedAction* ActionCollection::holdAction ()
480
ExtendedAction* ActionCollection::recordAction ()
482
return action_record;
485
ExtendedAction* ActionCollection::refuseAction ()
487
return action_refuse;
490
ExtendedAction* ActionCollection::muteCaptureAction()
492
return action_mute_capture;
495
ExtendedAction* ActionCollection::mutePlaybackAction()
497
return action_mute_playback;
500
ExtendedAction* ActionCollection::hangupAction ()
502
return action_hangup;
505
ExtendedAction* ActionCollection::unholdAction ()
507
return action_unhold;
510
ExtendedAction* ActionCollection::transferAction()
512
return action_transfer;
515
ExtendedAction* ActionCollection::pickupAction ()
517
return action_pickup;
520
ExtendedAction* ActionCollection::acceptAction ()
522
return action_accept;
525
KAction* ActionCollection::displayVolumeControlsAction()
527
return action_displayVolumeControls;
530
KAction* ActionCollection::displayDialpadAction ()
532
return action_displayDialpad;
535
KAction* ActionCollection::displayMessageBoxAction ()
537
return action_displayMessageBox;
540
KAction* ActionCollection::mailBoxAction ()
542
return action_mailBox;
545
KAction* ActionCollection::showContactDockAction ()
547
return action_showContactDock;
550
KAction* ActionCollection::showHistoryDockAction ()
552
return action_showHistoryDock;
555
KAction* ActionCollection::showBookmarkDockAction ()
557
return action_showBookmarkDock;
560
KAction* ActionCollection::quitAction ()
566
KAction* ActionCollection::addContact()
568
return action_addContact;
571
void ActionCollection::slotAddContact()
573
Contact* aContact = new Contact();
574
AkonadiBackend::instance()->addNewContact(aContact);
577
///Change icon of the record button
578
void ActionCollection::updateRecordButton()
580
double recVol = AudioSettingsModel::instance()->captureVolume();
581
static const QIcon icons[4] = {QIcon(":/images/icons/mic.svg"),QIcon(":/images/icons/mic_25.svg"),
582
QIcon(":/images/icons/mic_50.svg"),QIcon(":/images/icons/mic_75.svg")};
583
const int idx = (recVol/26 < 0 || recVol/26 >= 4)?0:recVol/26;
584
ActionCollection::instance()->muteCaptureAction()->setIcon(icons[idx]);
587
///Update the colunm button icon
588
void ActionCollection::updateVolumeButton()
590
double sndVol = AudioSettingsModel::instance()->playbackVolume();
591
static const QIcon icons[4] = {QIcon(":/images/icons/speaker.svg"),QIcon(":/images/icons/speaker_25.svg"),
592
QIcon(":/images/icons/speaker_50.svg"),QIcon(":/images/icons/speaker_75.svg")};
593
const int idx = (sndVol/26 < 0 || sndVol/26 >= 4)?0:sndVol/26;
594
ActionCollection::instance()->mutePlaybackAction()->setIcon(icons[idx]);
599
ExtendedAction* ActionCollection::videoRotateLeftAction ()
601
return action_video_rotate_left;
604
ExtendedAction* ActionCollection::videoRotateRightAction ()
606
return action_video_rotate_right;
609
ExtendedAction* ActionCollection::videoFlipHorizontalAction ()
611
return action_video_flip_horizontal;
614
ExtendedAction* ActionCollection::videoFlipVerticalAction ()
616
return action_video_flip_vertical;
619
ExtendedAction* ActionCollection::videoMuteAction ()
621
return action_video_mute;
624
ExtendedAction* ActionCollection::videoPreviewAction ()
626
return action_video_preview;