/*************************************************************************** kmessinterface.cpp - description ------------------- begin : Sun Dec 29 2002 copyright : (C) 2002 by Mike K. Bennett email : mkb137b@hotmail.com ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #include "kmessinterface.h" #ifdef HAVE_NEW_TRAY #include "notification/newsystemtraywidget.h" #else #include "notification/systemtraywidget.h" #endif #include "settings/globalsettingsdialog.h" #include "utils/likeback/likeback.h" #include "utils/kmessconfig.h" #include "utils/kmessshared.h" #include "kmessapplication.h" #include "kmessdebug.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // The constructor KMessInterface::KMessInterface( QWidget *parent ) : KXmlGuiWindow( parent ) , actionCollection_( actionCollection() ) , isErrorStatus_( true ) , initialized_( false ) { setObjectName( "ContactList" ); } // The destructor KMessInterface::~KMessInterface() { delete statusLabel_; #ifdef KMESSDEBUG_KMESSINTERFACE kmDebug() << "DESTROYED."; #endif } // "Add a new contact" was selected from the menu. void KMessInterface::addNewContact() { kmDebug() << "not implemented"; } // Show the chat history dialog and, if requested, that of a specific contact void KMessInterface::showChatHistory( const QString &handle ) { Q_UNUSED( handle ); kmDebug() << "not implemented"; } // "Add a new group" was selected from the menu. void KMessInterface::addNewGroup() { kmDebug() << "not implemented"; } // The application is closing, after queryExit() was approved void KMessInterface::applicationClosing() { kmDebug() << "not implemented"; } // A view pictures mode has been selected from the menu. void KMessInterface::changedListPictureSize( int /*mode*/ ) { kmDebug() << "not implemented"; } // A status was selected from the menu. void KMessInterface::changeStatus( QAction *action ) { Q_UNUSED( action ); kmDebug() << "not implemented"; } // A view mode has been selected from the menu. void KMessInterface::changeViewMode(int /*mode*/) { kmDebug() << "not implemented"; } void KMessInterface::showListExportDialog() { kmDebug() << "not implemented"; } void KMessInterface::showNetworkWindow() { kmDebug() << "not implemented"; } void KMessInterface::showTransferWindow() { kmDebug() << "not implemented"; } // Create the menus void KMessInterface::createMenus() { QAction *close, *quit; QAction *newAccount; QStringList states; QStringList viewModes, listPictureSizes; // Create the actions for "Connect" menu status_ = MsnStatus::getStatusMenu(); connectActionMenu_ = new KActionMenu ( QIcon::fromTheme( "network-connect" ), i18n("&Connect"), this ); disconnect_ = new QAction ( QIcon::fromTheme( "network-disconnect" ), i18n("&Disconnect"), this ); showProfile_ = new QAction ( QIcon::fromTheme( "preferences-desktop-user" ), i18n("Show My &Profile"), this ); close = KStandardAction::close( this, SLOT( menuClose() ), actionCollection_ ); quit = KStandardAction::quit ( this, SLOT( menuQuit() ), actionCollection_ ); // Create the actions for "View" menu showAllowedAction_ = new KToggleAction( i18n("Show &Allowed Contacts"), this ); showOfflineAction_ = new KToggleAction( i18n("Show &Offline Contacts"), this ); showRemovedAction_ = new KToggleAction( i18n("Show &Removed Contacts"), this ); showHistoryBoxAction_ = new KToggleAction( QIcon::fromTheme( "chronometer" ), i18n("Show &History Box"), this ); showSearchAction_ = new KToggleAction( QIcon::fromTheme( "edit-find-user" ), i18n("&Show Search Bar"), this ); showEmptyAction_ = new KToggleAction( i18n("Show &Empty Groups"), this ); listPictureSize_ = new KSelectAction( QIcon::fromTheme( "view-list-tree" ), i18n("&Display Pictures Size"), this ); viewMode_ = new KSelectAction( QIcon::fromTheme( "view-list-tree" ), i18n("&Sort Contacts by"), this ); showTransferAction_ = new QAction ( QIcon::fromTheme( "document-open-remote" ), i18n("Show &Transfer Window..."), this ); showStatusBar_ = KStandardAction::showStatusbar( this, SLOT( showStatusBar() ), this ); showMenuBar_ = KStandardAction::showMenubar ( this, SLOT( showMenuBar() ), this ); // Create the actions for "Actions" menu newContact_ = new QAction( QIcon::fromTheme( "list-add-user" ), i18n("New &Contact..."), this ); newGroup_ = new QAction( QIcon::fromTheme( "user-group-new" ), i18n("New &Group..."), this ); exportList_ = new QAction( QIcon::fromTheme( "document-export" ),i18n("&Export Contact List..."), this ); showHistory_ = new QAction( QIcon::fromTheme( "chronometer" ), i18n("Show Chat &History..."), this ); newAccount = new QAction( QIcon::fromTheme( "user-identity" ), i18n("New &Account..."), this ); showSettingsAction_ = new QAction( QIcon::fromTheme( "configure" ), i18n("Configure Account..."), this ); globalSettings_ = new QAction( QIcon::fromTheme( "kmess" ), i18n("Configure &KMess..."), this ); contextMenuAction_ = new QAction( QIcon::fromTheme( "preferences-contact-list" ), i18n("Show Selection &Menu"), this ); // Populate PictureSize select listPictureSizes << i18n( "Do Not Display" ) << i18n( "Small" ) << i18n( "Medium" ) << i18n( "Large" ); listPictureSize_->setItems( listPictureSizes ); // Populate ViewMode select viewModes << i18n("Group") // Account::VIEW_BYGROUP << i18n("Online/Offline") // Account::VIEW_BYSTATUS << i18n("Mixed"); // Account::VIEW_MIXED viewMode_->setItems(viewModes); // Add shortcut for Search in ContactList actionCollection()->setDefaultShortcut( showSearchAction_, QKeySequence::fromString( tr( "Ctrl+f" ) ) ); // Disable the context menu, because there's no selection on start contextMenuAction_->setEnabled( false ); // Disable the 'Show Account Settings' action, there is no current account on start showSettingsAction_->setEnabled( false ); // Connect slots to signals for "Connect" menu connect( disconnect_, SIGNAL( triggered(bool) ), this, SLOT ( disconnectClicked() ) ); connect( showProfile_, SIGNAL( triggered(bool) ), this, SLOT ( showUserProfile() ) ); connect( status_, SIGNAL( triggered(QAction*) ), this, SLOT ( changeStatus(QAction*) ) ); // Connect slots to signals for "View" menu connect( viewMode_, SIGNAL( indexTriggered(int) ), this, SLOT ( changeViewMode(int) ) ); connect( listPictureSize_, SIGNAL( indexTriggered(int) ), this, SLOT ( changedListPictureSize(int) ) ); connect( showAllowedAction_, SIGNAL( triggered(bool) ), this, SLOT ( toggleShowAllowed(bool) ) ); connect( showOfflineAction_, SIGNAL( triggered(bool) ), this, SLOT ( toggleShowOffline(bool) ) ); connect( showRemovedAction_, SIGNAL( triggered(bool) ), this, SLOT ( toggleShowRemoved(bool) ) ); connect( showEmptyAction_, SIGNAL( triggered(bool) ), this, SLOT ( toggleShowEmpty(bool) ) ); connect( showTransferAction_, SIGNAL( triggered(bool) ), this, SLOT ( showTransferWindow() ) ); // Connect slots to signals for "Actions" menu connect( newContact_, SIGNAL( triggered(bool) ), this, SLOT ( addNewContact() ) ); connect( newGroup_, SIGNAL( triggered(bool) ), this, SLOT ( addNewGroup() ) ); connect( exportList_, SIGNAL( triggered(bool) ), this, SLOT ( showListExportDialog() ) ); connect( showHistoryBoxAction_,SIGNAL( triggered(bool) ), this, SLOT ( toggleShowHistoryBox(bool) ) ); connect( showSearchAction_, SIGNAL( triggered(bool) ), this, SLOT ( toggleShowSearchFrame(bool) ) ); connect( showHistory_, SIGNAL( triggered(bool) ), this, SLOT ( showChatHistory() ) ); connect( newAccount, SIGNAL( triggered(bool) ), this, SLOT ( createNewAccount() ) ); connect( globalSettings_, SIGNAL( triggered(bool) ), this, SLOT ( showGlobalSettings() ) ); connect( contextMenuAction_, SIGNAL( triggered(bool) ), this, SLOT ( showContextMenu() ) ); // Add actions to actionCollection for "Connect" menu actionCollection_->addAction( "status", status_->menuAction() ); actionCollection_->addAction( "connect", connectActionMenu_ ); actionCollection_->addAction( "disconnect", disconnect_ ); actionCollection_->addAction( "showProfile", showProfile_ ); actionCollection_->addAction( "close", close ); actionCollection_->addAction( "quit", quit ); // Add actions to actionCollection for "View" menu actionCollection_->addAction( "showAllowed", showAllowedAction_ ); actionCollection_->addAction( "showOffline", showOfflineAction_ ); actionCollection_->addAction( "showRemoved", showRemovedAction_ ); actionCollection_->addAction( "showEmpty", showEmptyAction_ ); actionCollection_->addAction( "pictureSizes", listPictureSize_ ); actionCollection_->addAction( "viewModes", viewMode_ ); actionCollection_->addAction( "showTransfers", showTransferAction_ ); actionCollection_->addAction( "showMenuBar", showMenuBar_ ); actionCollection_->addAction( "showStatusBar", showStatusBar_ ); // Add actions to actionCollection for "Actions" menu actionCollection_->addAction( "newContact", newContact_ ); actionCollection_->addAction( "newGroup", newGroup_ ); actionCollection_->addAction( "exportList", exportList_ ); actionCollection_->addAction( "showHistoryBox", showHistoryBoxAction_); actionCollection_->addAction( "showSearch", showSearchAction_ ); actionCollection_->addAction( "chatHistory", showHistory_ ); actionCollection_->addAction( "newAccount", newAccount ); actionCollection_->addAction( "settingsAccount", showSettingsAction_ ); actionCollection_->addAction( "settingsGlobal", globalSettings_ ); actionCollection_->addAction( "contextMenu", contextMenuAction_ ); #ifdef KMESS_NETWORK_WINDOW showNetworkAction_ = new QAction( QIcon::fromTheme( "network-workgroup" ), i18n("Show &Network Window..."), this ); connect( showNetworkAction_, SIGNAL( triggered(bool) ), this, SLOT ( showNetworkWindow() ) ); actionCollection_->addAction( "showNetwork", showNetworkAction_ ); #endif } // "Add new account" has been selected from the menu. void KMessInterface::createNewAccount() { kmDebug() << "not implemented"; } // Disconnect was selected from the menu. void KMessInterface::disconnectClicked() { kmDebug() << "not implemented"; } // Enable/disable menus based on whether or not the application is // connected to the server. void KMessInterface::enableMenus(bool connected) { if ( connected ) { disconnect_->setIcon( QIcon::fromTheme( "network-connect" ) ); stateChanged("connected"); } else { disconnect_->setIcon( QIcon::fromTheme( "network-disconnect" ) ); stateChanged("disconnected"); } } // Initialize the class bool KMessInterface::initialize() { #ifdef KMESSDEBUG_KMESSINTERFACE kmDebug() << "initializing"; #endif if ( initialized_ ) { kmDebug() << "already initialized."; return false; } // Initialize the status bar statusLabel_ = new KSqueezedTextLabel( this ); statusBar()->addWidget( statusLabel_, 2 ); statusTimer_ = new QLabel( this ); statusTimer_->setText( "00:00" ); statusBar()->addPermanentWidget( statusTimer_, 0 ); // Only show the status bar when we're connected statusBar()->hide(); // Create the online timer onlineTimer_ = new QTimer( this ); connect( onlineTimer_, SIGNAL( timeout() ), this, SLOT( updateOnlineTimer() ) ); #if KMESS_DISABLE_LIKEBACK == 0 // Enable LikeBack. // The bar will only be enabled by default in debugging builds. bool showLikeBackBar = false; #ifdef KMESSTEST showLikeBackBar = true; #endif LikeBack *likeBack = new LikeBack( LikeBack::AllButtons, showLikeBackBar ); likeBack->setServer( "www.kmess.org", "/likeback/send.php", 80 ); likeBack->setWindowNamesListing( LikeBack::AllWindows ); QStringList acceptedLocales; acceptedLocales << "en" << "nl" << "it" << "de"; likeBack->setAcceptedLanguages( acceptedLocales ); likeBack->createActions( actionCollection() ); #endif // Create the menus createMenus(); // Build the gui from xml (without toolbar support) setupGUI( ( Keys | Create | Save ), "kmessinterfaceui.rc" ); // Autosave all GUI settings setAutoSaveSettings( KMessConfig::instance()->getGlobalConfig( "ContactListWindow" ), true /* save WindowSize */ ); // Autosave all GUI settings setAutoSaveSettings( "KMessInterface", true /* save WindowSize */ ); if ( ! initSystemTrayWidget() ) { kmDebug() << "Couldn't initialize the system tray widget."; return false; } #ifdef KMESSDEBUG_KMESSINTERFACE kmDebug() << "initialized"; #endif return true; } // Initialize the system tray widget bool KMessInterface::initSystemTrayWidget() { // Create the widget systemTrayWidget_ = new SystemTrayWidget( this ) ; if ( systemTrayWidget_ == 0 ) { kmDebug() << "Couldn't create system tray widget."; return false; } // Plug some of the menu actions into the system tray widget's menu. QMenu *menu = systemTrayWidget_->menu(); menu->addAction( connectActionMenu_ ); menu->addAction( disconnect_ ); menu->addSeparator(); menu->addMenu( status_ ); menu->addSeparator(); menu->addAction( showSettingsAction_ ); menu->addAction( globalSettings_ ); #ifndef HAVE_NEW_TRAY // Make the connections for the system tray widget connect( systemTrayWidget_, SIGNAL( quitSelected() ), this, SLOT ( menuQuit() ) ); systemTrayWidget_->show(); #endif return true; } // Close has been selected from the menu. void KMessInterface::menuClose() { #ifdef KMESSDEBUG_KMESSINTERFACE kmDebug() << "'Close' was selected from the menu."; #endif // Hide the window // Tell that KMess is still visible in the tray hide(); systemTrayWidget_->displayCloseMessage(); #ifdef KMESSTEST KMESS_ASSERT( isHidden() ); #endif } // Quit was selected from the menu. void KMessInterface::menuQuit() { #ifdef KMESSDEBUG_KMESSINTERFACE kmDebug() << "'Quit' was selected from the menu."; #endif // Tell the application manager we want to quit KMessApplication *app = static_cast(QApplication::instance()); app->setQuitSelected(true); close(); // Close this window, initiates quit } // Reject quitting unless the quit menu was pressed Called automatically by KMainWindow::closeEvent bool KMessInterface::queryExit() { KMessApplication *kmessApp = static_cast(QApplication::instance()); // With KDE 4 this function is also called when another KMainWindow (like the network window) closes. // Reject an attempt to quit if the user didn't select quit manually, or is logging out from KDE. // If a window still causes KMess to quit, use setAttribute( Qt::WA_QuitOnClose, false ) on it. if( kmessApp->quitSelected() || kmessApp->sessionSaving() ) { #ifdef KMESSDEBUG_KMESSINTERFACE kmDebug() << "Accepting exit request."; #endif return true; } else { // For some reason, KDE keeps bugging us when the chat window closes. // Reject the request again. #ifdef KMESSDEBUG_KMESSINTERFACE kmDebug() << "Rejecting exit request! Keep running with all windows hidden."; #endif return false; } } // Tell the user that KMess hides in the systray Called automatically by KMainWindow::closeEvent bool KMessInterface::queryClose() { KMessApplication *kmessApp = static_cast(QApplication::instance()); // Only allow KMess to quit if: // - the "quit" option was used from the menu // - the session manager wants to quit if( kmessApp->quitSelected() || kmessApp->sessionSaving() ) { #ifdef KMESSDEBUG_KMESSINTERFACE kmDebug() << "Accepting quit request."; #endif // Make sure that substituent also return true kmessApp->setQuitSelected(true); // Make sure the derived class can prepare itself too. applicationClosing(); // Allow the request return true; } else { // Tell that KMess is still visible in the tray systemTrayWidget_->displayCloseMessage(); #ifdef KMESSDEBUG_KMESSINTERFACE kmDebug() << "Rejecting quit request, hiding window"; #endif // Only hide, disallow event hide(); return false; } } // Restore the window properties (called by KMainWindow) void KMessInterface::readProperties( const KConfigGroup &config ) { #ifdef KMESSDEBUG_KMESSINTERFACE kmDebug() << "Reading properties"; #endif KConfigGroup group( config ); // Resize the window to decent dimensions if there's no saved state. resize( 300, 500 ); // Pull in the window size and position QSize windowsize = group.readEntry( "Size", QSize() ); if(!windowsize.isEmpty()) { resize(windowsize); } QPoint position = group.readEntry( "Position", QPoint() ); if(!position.isNull()) { move(position); } bool bViewMenubar = group.readEntry( "ShowMenuBar", true ); showMenuBar_->setChecked( bViewMenubar ); menuBar()->setVisible( bViewMenubar ); // Commented for future work /* // bar status settings bool bViewToolbar = group.readEntry( "Show Toolbar", true ); showToolBar_->setChecked(bViewToolbar); showToolBar(); */ showStatusBar_->setChecked( group.readEntry( "ShowStatusBar", true ) ); showStatusBar(); // bar position settings /* KConfigGroup mainToolBarGroup = group.group( "mainToolBar" ); toolBar( "mainToolBar" )->applySettings( mainToolBarGroup ); toolBar( "mainToolBar" )->setToolBarsLocked( group.readEntry( "Lock Toolbar", false ) );*/ } // Save the window properties (called by KMainWindow) void KMessInterface::saveProperties(KConfigGroup &config) { #ifdef KMESSDEBUG_KMESSINTERFACE kmDebug() << "Saving properties"; #endif KConfigGroup group( config ); group.writeEntry("Size", size() ); group.writeEntry("Position", pos() ); // group.writeEntry("Show Toolbar", showToolBar_->isChecked() ); group.writeEntry("ShowMenuBar", showMenuBar_ ->isChecked() ); group.writeEntry("ShowStatusBar", showStatusBar_->isChecked() ); // save the toolbar settings /* KConfigGroup mainToolBarGroup = group.group( "mainToolBar" ); toolBar( "mainToolBar" )->saveSettings( mainToolBarGroup ); group.writeEntry("Lock Toolbar", toolBar( "mainToolBar" )->toolBarsLocked());*/ #ifdef KMESSDEBUG_KMESSINTERFACE kmDebug() << "Done saving properties"; #endif } // The "Show Global Settings" option was clicked. void KMessInterface::showGlobalSettings() { GlobalSettingsDialog *globalSettingsDialog = GlobalSettingsDialog::instance(); globalSettingsDialog->show(); globalSettingsDialog->raise(); } // "Show menu bar" was toggled. void KMessInterface::showMenuBar() { // Just show the menubar if it was hidden if( ! menuBar()->isVisible() ) { menuBar()->setVisible( true ); return; } // Ask the user if he/she really wants to hide the menubar, to avoid mistakes // TODO: If the user disables the shortcut for the menu action, no shortcuts will be shown int res = KMessageBox::questionTwoActions( this, i18nc( "Question dialog box message", "Are you sure you want to hide the menu bar? " "You will be able to show it again by using this " "keyboard shortcut: %1", showMenuBar_->shortcut().toString( QKeySequence::NativeText ) ), i18nc( "Dialog box caption: hiding the menu bar", "Hiding the Menu" ), KGuiItem( i18n( "Yes" ) ), KGuiItem( i18n( "No" ) ), "hideMenuBarQuestion" ); if( res == KMessageBox::PrimaryAction ) { menuBar()->setVisible( showMenuBar_->isChecked() ); } else { showMenuBar_->setChecked( true ); } } // "Show status bar" was toggled. void KMessInterface::showStatusBar() { statusBar()->setVisible( showStatusBar_->isChecked() ); } // "Show toolbar" was toggled. /*void KMessInterface::showToolBar() { if(!showToolBar_->isChecked()) { toolBar("mainToolBar")->hide(); } else { toolBar("mainToolBar")->show(); } }*/ // Show the user's MSN profile. void KMessInterface::showUserProfile() { kmDebug() << "not implemented"; } // Change the status bar message. void KMessInterface::statusMessage( QString message, bool isError ) { if( message != message_ ) { statusLabel_->setText( message ); message_ = message; #ifdef KMESSDEBUG_KMESSINTERFACE kmDebug() << "Changed message to" << message; #endif } // Do not alter the online timer when the status has not changed if( isError == isErrorStatus_ ) { return; } if( isError ) { onlineTimer_->stop(); statusTimer_->setText( "00:00" ); } else { onlineTime_ = 0; onlineTimer_->start( 60000 ); } isErrorStatus_ = isError; } // The "show allowed contacts" menu item has been toggled. void KMessInterface::toggleShowAllowed(bool /*show*/) { kmDebug() << "not implemented"; } // The "show empty groups" menu item has been toggled. void KMessInterface::toggleShowEmpty(bool /*show*/) { kmDebug() << "not implemented"; } // The "show history box" menu item has been toggled. void KMessInterface::toggleShowHistoryBox(bool /*show*/) { kmDebug() << "not implemented"; } // The "show search in contact list" menu item has been toggled. void KMessInterface::toggleShowSearchFrame(bool /*show*/) { kmDebug() << "not implemented"; } // The "show offline contacts" menu item has been toggled. void KMessInterface::toggleShowOffline(bool /*show*/) { kmDebug() << "not implemented"; } // The "show removed contacts" menu item has been toggled. void KMessInterface::toggleShowRemoved(bool /*show*/) { kmDebug() << "not implemented"; } // Increment and update the online timer. void KMessInterface::updateOnlineTimer() { QString timeText; onlineTime_ ++; timeText = QString::asprintf( "%02i:%02i", onlineTime_ / 60, onlineTime_ % 60 ); statusTimer_->setText( timeText ); }