1 /****************************************************************************
3 ** Copyright (C) 2007 Urs Wolfer <uwolfer @ kde.org>
5 ** This file is part of KDE.
7 ** This program is free software; you can redistribute it and/or modify
8 ** it under the terms of the GNU General Public License as published by
9 ** the Free Software Foundation; either version 2 of the License, or
10 ** (at your option) any later version.
12 ** This program is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ** GNU General Public License for more details.
17 ** You should have received a copy of the GNU General Public License
18 ** along with this program; see the file COPYING. If not, write to
19 ** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 ** Boston, MA 02110-1301, USA.
22 ****************************************************************************/
24 #include "mainwindow.h"
26 #include "remoteview.h"
28 #include "config/preferencesdialog.h"
29 #include "floatingtoolbar.h"
30 #include "bookmarkmanager.h"
31 #include "remotedesktopsmodel.h"
32 #include "systemtrayicon.h"
43 #include "zeroconfpage.h"
47 #include <KActionCollection>
48 #include <KActionMenu>
49 #include <KApplication>
51 #include <KEditToolBar>
55 #include <KMessageBox>
56 #include <KNotifyConfigWidget>
57 #include <KPushButton>
59 #include <KShortcutsDialog>
62 #include <KToggleAction>
63 #include <KToggleFullScreenAction>
64 #include <KUrlNavigator>
67 #include <QCloseEvent>
68 #include <QDesktopWidget>
69 #include <QDockWidget>
70 #include <QHeaderView>
73 #include <QScrollArea>
75 #include <QToolButton>
79 MainWindow::MainWindow(QWidget
*parent
)
80 : KXmlGuiWindow(parent
),
81 m_fullscreenWindow(0),
85 m_currentRemoteView(-1),
86 m_showStartPage(false),
92 setStandardToolBarMenuEnabled(true);
94 m_tabWidget
= new KTabWidget(this);
95 m_tabWidget
->setMinimumSize(600, 400);
96 setCentralWidget(m_tabWidget
);
98 QDockWidget
*remoteDesktopsDockWidget
= new QDockWidget(this);
99 remoteDesktopsDockWidget
->setObjectName("remoteDesktopsDockWidget");
100 remoteDesktopsDockWidget
->setWindowTitle("Remote desktops");
101 actionCollection()->addAction("remote_desktop_dockwidget",
102 remoteDesktopsDockWidget
->toggleViewAction());
103 QTreeView
*remoteDesktopsTreeView
= new QTreeView(remoteDesktopsDockWidget
);
104 remoteDesktopsTreeView
->setModel(new RemoteDesktopsModel(this));
105 remoteDesktopsTreeView
->header()->hide();
106 remoteDesktopsTreeView
->expandAll();
107 connect(remoteDesktopsTreeView
, SIGNAL(doubleClicked(const QModelIndex
&)),
108 SLOT(openFromDockWidget(const QModelIndex
&)));
110 remoteDesktopsDockWidget
->setWidget(remoteDesktopsTreeView
);
111 addDockWidget(Qt::LeftDockWidgetArea
, remoteDesktopsDockWidget
);
113 createGUI("krdcui.rc");
115 if (Settings::systemTrayIcon()) {
116 m_systemTrayIcon
= new SystemTrayIcon(this);
117 m_systemTrayIcon
->setVisible(true);
120 connect(m_tabWidget
, SIGNAL(currentChanged(int)), SLOT(tabChanged(int)));
122 statusBar()->showMessage(i18n("KDE Remote Desktop Client started"));
124 updateActionStatus(); // disable remote view actions
126 if (Settings::showStartPage())
129 setAutoSaveSettings(); // e.g toolbar position, mainwindow size, ...
131 if (Settings::rememberSessions()) // give some time to create and show the window first
132 QTimer::singleShot(100, this, SLOT(restoreOpenSessions()));
134 remoteDesktopsDockWidget
->setVisible(false); //TODO: remove when fully implemented
137 MainWindow::~MainWindow()
141 void MainWindow::setupActions()
143 QAction
*vncConnectionAction
= actionCollection()->addAction("new_vnc_connection");
144 vncConnectionAction
->setText(i18n("New VNC Connection..."));
145 vncConnectionAction
->setIcon(KIcon("network-connect"));
146 connect(vncConnectionAction
, SIGNAL(triggered()), SLOT(newVncConnection()));
148 vncConnectionAction
->setVisible(false);
151 QAction
*nxConnectionAction
= actionCollection()->addAction("new_nx_connection");
152 nxConnectionAction
->setText(i18n("New NX Connection..."));
153 nxConnectionAction
->setIcon(KIcon("network-connect"));
154 connect(nxConnectionAction
, SIGNAL(triggered()), SLOT(newNxConnection()));
156 nxConnectionAction
->setVisible(false);
159 QAction
*rdpConnectionAction
= actionCollection()->addAction("new_rdp_connection");
160 rdpConnectionAction
->setText(i18n("New RDP Connection..."));
161 rdpConnectionAction
->setIcon(KIcon("network-connect"));
162 connect(rdpConnectionAction
, SIGNAL(triggered()), SLOT(newRdpConnection()));
164 rdpConnectionAction
->setVisible(false);
167 QAction
*zeroconfAction
= actionCollection()->addAction("zeroconf_page");
168 zeroconfAction
->setText(i18n("Browse Remote Desktop Services on Local Network..."));
169 zeroconfAction
->setIcon(KIcon("network-connect"));
170 connect(zeroconfAction
, SIGNAL(triggered()), SLOT(createZeroconfPage()));
171 #ifndef BUILD_ZEROCONF
172 zeroconfAction
->setVisible(false);
175 QAction
*screenshotAction
= actionCollection()->addAction("take_screenshot");
176 screenshotAction
->setText(i18n("Copy Screenshot to Clipboard"));
177 screenshotAction
->setIcon(KIcon("ksnapshot"));
178 connect(screenshotAction
, SIGNAL(triggered()), SLOT(takeScreenshot()));
180 QAction
*fullscreenAction
= actionCollection()->addAction("switch_fullscreen");
181 fullscreenAction
->setText(i18n("Switch to Fullscreen Mode"));
182 fullscreenAction
->setIcon(KIcon("view-fullscreen"));
183 connect(fullscreenAction
, SIGNAL(triggered()), SLOT(switchFullscreen()));
185 QAction
*viewOnlyAction
= actionCollection()->addAction("view_only");
186 viewOnlyAction
->setCheckable(true);
187 viewOnlyAction
->setText(i18n("View Only"));
188 viewOnlyAction
->setIcon(KIcon("document-preview"));
189 connect(viewOnlyAction
, SIGNAL(triggered(bool)), SLOT(viewOnly(bool)));
191 QAction
*logoutAction
= actionCollection()->addAction("logout");
192 logoutAction
->setText(i18n("Log Out"));
193 logoutAction
->setIcon(KIcon("system-log-out"));
194 connect(logoutAction
, SIGNAL(triggered()), SLOT(logout()));
196 QAction
*showLocalCursorAction
= actionCollection()->addAction("show_local_cursor");
197 showLocalCursorAction
->setCheckable(true);
198 showLocalCursorAction
->setIcon(KIcon("input-mouse"));
199 showLocalCursorAction
->setText(i18n("Show Local Cursor"));
200 connect(showLocalCursorAction
, SIGNAL(triggered(bool)), SLOT(showLocalCursor(bool)));
202 QAction
*grabAllKeysAction
= actionCollection()->addAction("grab_all_keys");
203 grabAllKeysAction
->setCheckable(true);
204 grabAllKeysAction
->setIcon(KIcon("configure-shortcuts"));
205 grabAllKeysAction
->setText(i18n("Grab all possible keys"));
206 connect(grabAllKeysAction
, SIGNAL(triggered(bool)), SLOT(grabAllKeys(bool)));
208 QAction
*scaleAction
= actionCollection()->addAction("scale");
209 scaleAction
->setCheckable(true);
210 scaleAction
->setIcon(KIcon("zoom-fit-best"));
211 scaleAction
->setText(i18n("Scale remote screen to fit window size"));
212 connect(scaleAction
, SIGNAL(triggered(bool)), SLOT(scale(bool)));
214 QAction
*quitAction
= KStandardAction::quit(this, SLOT(quit()), actionCollection());
215 actionCollection()->addAction("quit", quitAction
);
216 QAction
*preferencesAction
= KStandardAction::preferences(this, SLOT(preferences()), actionCollection());
217 actionCollection()->addAction("preferences", preferencesAction
);
218 QAction
*configToolbarAction
= KStandardAction::configureToolbars(this, SLOT(configureToolbars()), actionCollection());
219 actionCollection()->addAction("configure_toolbars", configToolbarAction
);
220 QAction
*keyBindingsAction
= KStandardAction::keyBindings(this, SLOT(configureKeys()), actionCollection());
221 actionCollection()->addAction("configure_keys", keyBindingsAction
);
222 QAction
*cinfigNotifyAction
= KStandardAction::configureNotifications(this, SLOT(configureNotifications()), actionCollection());
223 cinfigNotifyAction
->setVisible(false);
224 actionCollection()->addAction("configure_notifications", cinfigNotifyAction
);
225 m_menubarAction
= KStandardAction::showMenubar(this, SLOT(showMenubar()), actionCollection());
226 m_menubarAction
->setChecked(!menuBar()->isHidden());
227 actionCollection()->addAction("settings_showmenubar", m_menubarAction
);
229 QString initialProtocol
;
231 initialProtocol
= "rdp";
234 initialProtocol
= "nx";
237 initialProtocol
= "vnc";
240 m_addressNavigator
= new KUrlNavigator(0, KUrl(initialProtocol
+ "://"), this);
241 m_addressNavigator
->setCustomProtocols(QStringList()
252 m_addressNavigator
->setUrlEditable(Settings::normalUrlInputLine());
253 connect(m_addressNavigator
, SIGNAL(returnPressed()), SLOT(newConnection()));
255 QLabel
*addressLabel
= new QLabel(i18n("Remote desktop:"), this);
257 QWidget
*addressWidget
= new QWidget(this);
258 QHBoxLayout
*addressLayout
= new QHBoxLayout(addressWidget
);
259 addressLayout
->setMargin(0);
260 addressLayout
->addWidget(addressLabel
);
261 addressLayout
->addWidget(m_addressNavigator
, 1);
263 KAction
*addressLineAction
= new KAction(i18nc("Title for remote address input action", "Address"), this);
264 actionCollection()->addAction("address_line", addressLineAction
);
265 addressLineAction
->setDefaultWidget(addressWidget
);
267 QAction
*gotoAction
= actionCollection()->addAction("goto_address");
268 gotoAction
->setText(i18n("Goto Address"));
269 gotoAction
->setIcon(KIcon("go-jump-locationbar"));
270 connect(gotoAction
, SIGNAL(triggered()), SLOT(newConnection()));
272 KActionMenu
*bookmarkMenu
= new KActionMenu(i18n("Bookmarks"), actionCollection());
273 m_bookmarkManager
= new BookmarkManager(actionCollection(), bookmarkMenu
->menu(), this);
274 actionCollection()->addAction("bookmark" , bookmarkMenu
);
275 connect(m_bookmarkManager
, SIGNAL(openUrl(KUrl
)), SLOT(newConnection(KUrl
)));
278 void MainWindow::restoreOpenSessions()
280 QStringList list
= Settings::openSessions();
281 QStringList::Iterator it
= list
.begin();
282 QStringList::Iterator end
= list
.end();
289 void MainWindow::newConnection(const KUrl
&newUrl
, bool switchFullscreenWhenConnected
)
291 m_switchFullscreenWhenConnected
= switchFullscreenWhenConnected
;
293 KUrl url
= newUrl
.isEmpty() ? m_addressNavigator
->uncommittedUrl() : newUrl
;
295 if (!url
.isValid() || (url
.host().isEmpty() && url
.port() < 0)
296 || !url
.path().isEmpty()) {
297 KMessageBox::error(this,
298 i18n("The entered address does not have the required form."),
299 i18n("Malformed URL"));
303 m_addressNavigator
->setUrl(KUrl(url
.scheme().toLower() + "://"));
308 if (url
.scheme().toLower() == "vnc") {
309 view
= new VncView(this, url
);
314 if (url
.scheme().toLower() == "nx") {
315 view
= new NxView(this, url
);
320 if (url
.scheme().toLower() == "rdp") {
321 view
= new RdpView(this, url
);
325 KMessageBox::error(this,
326 i18n("The entered address cannot be handled."),
327 i18n("Unusable URL"));
331 connect(view
, SIGNAL(changeSize(int, int)), this, SLOT(resizeTabWidget(int, int)));
332 connect(view
, SIGNAL(statusChanged(RemoteView::RemoteStatus
)), this, SLOT(statusChanged(RemoteView::RemoteStatus
)));
334 m_remoteViewList
.append(view
);
338 int numNonRemoteView
= 0;
344 QScrollArea
*scrollArea
= createScrollArea(m_tabWidget
, m_remoteViewList
.at(m_remoteViewList
.count() - 1));
346 int newIndex
= m_tabWidget
->addTab(scrollArea
, KIcon("krdc"), url
.prettyUrl(KUrl::RemoveTrailingSlash
));
347 m_tabWidget
->setCurrentIndex(newIndex
);
348 tabChanged(newIndex
); // force to update m_currentRemoteView (tabChanged is not emitted when start page has been disabled)
353 void MainWindow::openFromDockWidget(const QModelIndex
&index
)
355 if (index
.data(Qt::UserRole
).toBool()) {
356 KUrl
url(index
.data().toString());
357 // first check if url has already been opened; in case show the tab
358 for (int i
= 0; i
< m_remoteViewList
.count(); i
++) {
359 if (m_remoteViewList
.at(i
)->url() == url
) {
360 int numNonRemoteView
= 0;
365 m_tabWidget
->setCurrentIndex(i
+ numNonRemoteView
);
373 void MainWindow::resizeTabWidget(int w
, int h
)
375 kDebug(5010) << "tabwidget resize: w: " << w
<< ", h: " << h
;
377 if (m_topBottomBorder
== 0) { // the values are not cached yet
378 QScrollArea
*tmp
= qobject_cast
<QScrollArea
*>(m_tabWidget
->currentWidget());
380 m_leftRightBorder
= m_tabWidget
->width() - m_tabWidget
->currentWidget()->width() + (2 * tmp
->frameWidth());
381 m_topBottomBorder
= m_tabWidget
->height() - m_tabWidget
->currentWidget()->height() + (2 * tmp
->frameWidth());
383 kDebug(5010) << "tabwidget border: w: " << m_leftRightBorder
<< ", h: " << m_topBottomBorder
;
386 int newTabWidth
= w
+ m_leftRightBorder
;
387 int newTabHeight
= h
+ m_topBottomBorder
;
389 QSize newWindowSize
= size() - m_tabWidget
->size() + QSize(newTabWidth
, newTabHeight
);
391 QSize desktopSize
= QSize(QApplication::desktop()->availableGeometry().width(),
392 QApplication::desktop()->availableGeometry().height());
394 if ((newWindowSize
.height() >= desktopSize
.height()) || (newWindowSize
.width() >= desktopSize
.width())) {
395 kDebug(5010) << "remote desktop needs more place than available -> show window maximized";
396 setWindowState(windowState() | Qt::WindowMaximized
);
400 //WORKAROUND: QTabWidget resize problem. Let's see if there is a clean solution for this issue.
401 m_tabWidget
->setMinimumSize(newTabWidth
, newTabHeight
);
402 m_tabWidget
->adjustSize();
403 QCoreApplication::processEvents();
404 m_tabWidget
->setMinimumSize(500, 400);
407 void MainWindow::statusChanged(RemoteView::RemoteStatus status
)
409 kDebug(5010) << status
;
411 // the remoteview is already deleted, so don't show it; otherwise it would crash
412 if (status
== RemoteView::Disconnecting
|| status
== RemoteView::Disconnected
)
415 QString host
= m_remoteViewList
.at(m_currentRemoteView
)->host();
417 QString iconName
= "krdc";
421 case RemoteView::Connecting
:
422 iconName
= "network-connect";
423 message
= i18n("Connecting to %1", host
);
425 case RemoteView::Authenticating
:
426 iconName
= "dialog-password";
427 message
= i18n("Authenticating at %1", host
);
429 case RemoteView::Preparing
:
430 iconName
= "view-history";
431 message
= i18n("Preparing connection to %1", host
);
433 case RemoteView::Connected
:
435 message
= i18n("Connected to %1", host
);
437 // when started with command line fullscreen argument
438 if (m_switchFullscreenWhenConnected
) {
439 m_switchFullscreenWhenConnected
= false;
443 m_bookmarkManager
->addHistoryBookmark();
451 m_tabWidget
->setTabIcon(m_tabWidget
->currentIndex(), KIcon(iconName
));
452 statusBar()->showMessage(message
);
455 void MainWindow::takeScreenshot()
457 QPixmap snapshot
= QPixmap::grabWidget(m_remoteViewList
.at(m_currentRemoteView
));
459 QApplication::clipboard()->setPixmap(snapshot
);
462 void MainWindow::switchFullscreen()
466 if (m_fullscreenWindow
) {
468 restoreGeometry(m_mainWindowGeometry
);
470 m_fullscreenWindow
->setWindowState(0);
471 m_fullscreenWindow
->hide();
473 QScrollArea
*scrollArea
= createScrollArea(m_tabWidget
, m_remoteViewList
.at(m_currentRemoteView
));
475 int currentTab
= m_tabWidget
->currentIndex();
476 m_tabWidget
->insertTab(currentTab
, scrollArea
, m_tabWidget
->tabIcon(currentTab
), m_tabWidget
->tabText(currentTab
));
477 m_tabWidget
->removeTab(m_tabWidget
->currentIndex());
478 m_tabWidget
->setCurrentIndex(currentTab
);
480 resizeTabWidget(m_remoteViewList
.at(m_currentRemoteView
)->sizeHint().width(),
481 m_remoteViewList
.at(m_currentRemoteView
)->sizeHint().height());
484 m_toolBar
->hideAndDestroy();
485 m_toolBar
->deleteLater();
489 actionCollection()->action("switch_fullscreen")->setIcon(KIcon("view-fullscreen"));
490 actionCollection()->action("switch_fullscreen")->setText(i18n("Switch to Fullscreen Mode"));
492 m_fullscreenWindow
->deleteLater();
494 m_fullscreenWindow
= 0;
496 m_fullscreenWindow
= new QWidget(this, Qt::Window
);
497 m_fullscreenWindow
->setWindowTitle(i18nc("window title when in fullscreen mode (for example displayed in tasklist)",
498 "KDE Remote Desktop Client (Fullscreen)"));
500 QScrollArea
*scrollArea
= createScrollArea(m_fullscreenWindow
, m_remoteViewList
.at(m_currentRemoteView
));
501 scrollArea
->setFrameShape(QFrame::NoFrame
);
503 QVBoxLayout
*fullscreenLayout
= new QVBoxLayout(m_fullscreenWindow
);
504 fullscreenLayout
->setMargin(0);
505 fullscreenLayout
->addWidget(scrollArea
);
507 MinimizePixel
*minimizePixel
= new MinimizePixel(m_fullscreenWindow
);
508 connect(minimizePixel
, SIGNAL(rightClicked()), m_fullscreenWindow
, SLOT(showMinimized()));
510 m_fullscreenWindow
->show();
512 KToggleFullScreenAction::setFullScreen(m_fullscreenWindow
, true);
514 // show the toolbar after we have switched to fullscreen mode
515 QTimer::singleShot(100, this, SLOT(showRemoteViewToolbar()));
517 m_mainWindowGeometry
= saveGeometry();
522 QScrollArea
*MainWindow::createScrollArea(QWidget
*parent
, RemoteView
*remoteView
)
524 RemoteViewScrollArea
*scrollArea
= new RemoteViewScrollArea(parent
);
525 scrollArea
->setAlignment(Qt::AlignHCenter
| Qt::AlignVCenter
);
527 connect(scrollArea
, SIGNAL(resized(int, int)), remoteView
, SLOT(scaleResize(int, int)));
529 QPalette palette
= scrollArea
->palette();
530 palette
.setColor(QPalette::Dark
, Settings::backgroundColor());
531 scrollArea
->setPalette(palette
);
533 scrollArea
->setBackgroundRole(QPalette::Dark
);
534 scrollArea
->setWidget(remoteView
);
539 void MainWindow::logout()
543 if (m_fullscreenWindow
) { // first close fullscreen view
547 QWidget
*tmp
= m_tabWidget
->currentWidget();
549 m_remoteViewList
.removeAt(m_currentRemoteView
);
551 m_tabWidget
->removeTab(m_tabWidget
->currentIndex());
556 void MainWindow::showLocalCursor(bool showLocalCursor
)
558 kDebug(5010) << showLocalCursor
;
560 m_remoteViewList
.at(m_currentRemoteView
)->showDotCursor(showLocalCursor
? RemoteView::CursorOn
: RemoteView::CursorOff
);
563 void MainWindow::viewOnly(bool viewOnly
)
565 kDebug(5010) << viewOnly
;
567 m_remoteViewList
.at(m_currentRemoteView
)->setViewOnly(viewOnly
);
570 void MainWindow::grabAllKeys(bool grabAllKeys
)
574 m_remoteViewList
.at(m_currentRemoteView
)->setGrabAllKeys(grabAllKeys
);
577 void MainWindow::scale(bool scale
)
581 m_remoteViewList
.at(m_currentRemoteView
)->enableScaling(scale
);
584 void MainWindow::showRemoteViewToolbar()
589 actionCollection()->action("switch_fullscreen")->setIcon(KIcon("view-restore"));
590 actionCollection()->action("switch_fullscreen")->setText(i18n("Switch to Window Mode"));
592 m_toolBar
= new FloatingToolBar(m_fullscreenWindow
, m_fullscreenWindow
);
593 m_toolBar
->setSide(FloatingToolBar::Top
);
595 QLabel
*hostLabel
= new QLabel(m_remoteViewList
.at(m_currentRemoteView
)->url().prettyUrl(KUrl::RemoveTrailingSlash
), m_toolBar
);
596 hostLabel
->setMargin(4);
597 QFont
font(hostLabel
->font());
599 hostLabel
->setFont(font
);
600 m_toolBar
->addWidget(hostLabel
);
602 #if 0 //TODO: implement functionality
603 KComboBox
*sessionComboBox
= new KComboBox(m_toolBar
);
604 sessionComboBox
->setEditable(false);
605 sessionComboBox
->addItem(i18n("Switch to..."));
606 for (int i
= 0; i
< m_remoteViewList
.count(); i
++) {
607 sessionComboBox
->addItem(m_remoteViewList
.at(i
)->url().prettyUrl(KUrl::RemoveTrailingSlash
));
609 sessionComboBox
->setVisible(m_remoteViewList
.count() > 1); // just show it if there are sessions to switch
610 m_toolBar
->addWidget(sessionComboBox
);
613 m_toolBar
->addAction(actionCollection()->action("switch_fullscreen"));
615 QAction
*minimizeAction
= new QAction(m_toolBar
);
616 minimizeAction
->setIcon(KIcon("window-suppressed"));
617 minimizeAction
->setText(i18n("Minimize Fullscreen Window"));
618 connect(minimizeAction
, SIGNAL(triggered()), m_fullscreenWindow
, SLOT(showMinimized()));
619 m_toolBar
->addAction(minimizeAction
);
621 m_toolBar
->addAction(actionCollection()->action("take_screenshot"));
622 m_toolBar
->addAction(actionCollection()->action("view_only"));
623 m_toolBar
->addAction(actionCollection()->action("show_local_cursor"));
624 m_toolBar
->addAction(actionCollection()->action("grab_all_keys"));
625 m_toolBar
->addAction(actionCollection()->action("scale"));
626 m_toolBar
->addAction(actionCollection()->action("logout"));
628 QAction
*stickToolBarAction
= new QAction(m_toolBar
);
629 stickToolBarAction
->setCheckable(true);
630 stickToolBarAction
->setIcon(KIcon("object-locked"));
631 stickToolBarAction
->setText(i18n("Stick Toolbar"));
632 connect(stickToolBarAction
, SIGNAL(triggered(bool)), m_toolBar
, SLOT(setSticky(bool)));
633 m_toolBar
->addAction(stickToolBarAction
);
636 m_toolBar
->showAndAnimate();
639 void MainWindow::updateActionStatus()
641 kDebug(5010) << m_tabWidget
->currentIndex();
645 if ((m_showStartPage
&& (m_tabWidget
->currentIndex() == 0)) ||
646 #ifdef BUILD_ZEROCONF
647 (m_zeroconfPage
&& (m_tabWidget
->currentIndex() == m_tabWidget
->indexOf(m_zeroconfPage
))) ||
649 (!m_showStartPage
&& (m_tabWidget
->currentIndex() < 0)))
654 actionCollection()->action("switch_fullscreen")->setEnabled(enabled
);
655 actionCollection()->action("take_screenshot")->setEnabled(enabled
);
656 actionCollection()->action("view_only")->setEnabled(enabled
);
657 actionCollection()->action("grab_all_keys")->setEnabled(enabled
);
658 actionCollection()->action("scale")->setEnabled(enabled
);
659 actionCollection()->action("logout")->setEnabled(enabled
);
661 bool viewOnlyChecked
= false;
662 if (m_currentRemoteView
>= 0)
663 viewOnlyChecked
= enabled
&& m_remoteViewList
.at(m_currentRemoteView
)->viewOnly();
664 actionCollection()->action("view_only")->setChecked(viewOnlyChecked
);
666 bool showLocalCursorChecked
= false;
667 if (m_currentRemoteView
>= 0)
668 showLocalCursorChecked
= enabled
&& m_remoteViewList
.at(m_currentRemoteView
)->dotCursorState() == RemoteView::CursorOn
;
669 actionCollection()->action("show_local_cursor")->setChecked(showLocalCursorChecked
);
671 bool showLocalCursorVisible
= false;
672 if (m_currentRemoteView
>= 0)
673 showLocalCursorVisible
= enabled
&& m_remoteViewList
.at(m_currentRemoteView
)->supportsLocalCursor();
674 actionCollection()->action("show_local_cursor")->setVisible(showLocalCursorVisible
);
676 bool scaleVisible
= false;
677 if (m_currentRemoteView
>= 0)
678 scaleVisible
= enabled
&& m_remoteViewList
.at(m_currentRemoteView
)->supportsScaling();
679 actionCollection()->action("scale")->setVisible(scaleVisible
);
682 void MainWindow::preferences()
684 // An instance of your dialog could be already created and could be
685 // cached, in which case you want to display the cached dialog
686 // instead of creating another one
687 if (PreferencesDialog::showDialog("preferences"))
690 // KConfigDialog didn't find an instance of this dialog, so lets
692 PreferencesDialog
*dialog
= new PreferencesDialog(this, Settings::self());
694 // User edited the configuration - update your local copies of the
695 // configuration data
696 connect(dialog
, SIGNAL(settingsChanged(const QString
&)),
697 this, SLOT(updateConfiguration()));
702 void MainWindow::updateConfiguration()
704 m_addressNavigator
->setUrlEditable(Settings::normalUrlInputLine());
706 if (Settings::systemTrayIcon() && !m_systemTrayIcon
) {
707 m_systemTrayIcon
= new SystemTrayIcon(this);
708 m_systemTrayIcon
->setVisible(true);
709 } else if (m_systemTrayIcon
) {
710 delete m_systemTrayIcon
;
711 m_systemTrayIcon
= 0;
714 if (Settings::showStartPage() && !m_showStartPage
)
716 else if (!Settings::showStartPage() && m_showStartPage
) {
717 m_tabWidget
->removeTab(0);
718 m_showStartPage
= false;
720 updateActionStatus();
722 // update the scroll areas background color
723 int numNonRemoteView
= 0;
728 for (int i
= numNonRemoteView
; i
< m_tabWidget
->count(); i
++) {
729 QPalette palette
= m_tabWidget
->widget(i
)->palette();
730 palette
.setColor(QPalette::Dark
, Settings::backgroundColor());
731 m_tabWidget
->widget(i
)->setPalette(palette
);
735 void MainWindow::quit()
737 if (KMessageBox::warningContinueCancel(this,
738 i18n("Are you sure you want to quit the KDE Remote Desktop Client?"),
739 i18n("Confirm Quit"),
740 KStandardGuiItem::quit(), KStandardGuiItem::cancel(),
741 "DoNotAskBeforeExit") == KMessageBox::Continue
) {
743 if (Settings::rememberSessions()) { // remember open remote views for next startup
745 for (int i
= 0; i
< m_remoteViewList
.count(); i
++) {
746 kDebug(5010) << m_remoteViewList
.at(i
)->url();
747 list
.append(m_remoteViewList
.at(i
)->url().prettyUrl(KUrl::RemoveTrailingSlash
));
749 Settings::setOpenSessions(list
);
752 Settings::self()->writeConfig();
758 void MainWindow::configureNotifications()
760 KNotifyConfigWidget::configure(this);
763 void MainWindow::configureKeys()
765 KShortcutsDialog::configure(actionCollection());
768 void MainWindow::configureToolbars()
770 KEditToolBar
edit(actionCollection());
771 connect(&edit
, SIGNAL(newToolbarConfig()), this, SLOT(newToolbarConfig()));
775 void MainWindow::showMenubar()
777 if (m_menubarAction
->isChecked())
783 void MainWindow::closeEvent(QCloseEvent
*event
)
787 if (Settings::systemTrayIcon()) {
788 hide(); // just hide the mainwindow, keep it in systemtray
794 void MainWindow::tabChanged(int index
)
796 kDebug(5010) << index
;
798 int numNonRemoteView
= 0;
804 m_currentRemoteView
= index
- numNonRemoteView
;
806 QString tabTitle
= m_tabWidget
->tabText(index
).remove('&');
808 setCaption(tabTitle
== i18n("Start Page") ? QString() : tabTitle
);
810 updateActionStatus();
813 void MainWindow::createStartPage()
815 m_showStartPage
= true;
817 QWidget
*startWidget
= new QWidget(this);
818 startWidget
->setStyleSheet("QWidget { background-color: palette(base) }");
820 QVBoxLayout
*startLayout
= new QVBoxLayout(startWidget
);
822 QLabel
*headerLabel
= new QLabel(this);
823 headerLabel
->setText(i18n("<h1>KDE Remote Desktop Client</h1><br /><br />What would you like to do?<br />"));
825 QLabel
*headerIconLabel
= new QLabel(this);
826 headerIconLabel
->setPixmap(KIcon("krdc").pixmap(128));
828 QHBoxLayout
*headerLayout
= new QHBoxLayout
;
829 headerLayout
->setMargin(20);
830 headerLayout
->addWidget(headerLabel
, 1, Qt::AlignTop
);
831 headerLayout
->addWidget(headerIconLabel
);
833 KPushButton
*vncConnectButton
= new KPushButton(this);
834 vncConnectButton
->setStyleSheet("KPushButton { padding: 12px; margin: 10px; }");
835 vncConnectButton
->setIcon(KIcon(actionCollection()->action("new_vnc_connection")->icon()));
836 vncConnectButton
->setText(i18n("Connect to a VNC Remote Desktop"));
837 connect(vncConnectButton
, SIGNAL(clicked()), SLOT(newVncConnection()));
839 vncConnectButton
->setVisible(false);
842 KPushButton
*nxConnectButton
= new KPushButton(this);
843 nxConnectButton
->setStyleSheet("KPushButton { padding: 12px; margin: 10px; }");
844 nxConnectButton
->setIcon(KIcon(actionCollection()->action("new_nx_connection")->icon()));
845 nxConnectButton
->setText(i18n("Connect to a NX Remote Desktop"));
846 connect(nxConnectButton
, SIGNAL(clicked()), SLOT(newNxConnection()));
848 nxConnectButton
->setVisible(false);
851 KPushButton
*rdpConnectButton
= new KPushButton(this);
852 rdpConnectButton
->setStyleSheet("KPushButton { padding: 12px; margin: 10px; }");
853 rdpConnectButton
->setIcon(KIcon(actionCollection()->action("new_rdp_connection")->icon()));
854 rdpConnectButton
->setText(i18n("Connect to a Windows Remote Desktop (RDP)"));
855 connect(rdpConnectButton
, SIGNAL(clicked()), SLOT(newRdpConnection()));
857 rdpConnectButton
->setVisible(false);
860 KPushButton
*zeroconfButton
= new KPushButton(this);
861 zeroconfButton
->setStyleSheet("KPushButton { padding: 12px; margin: 10px; }");
862 zeroconfButton
->setIcon(KIcon(actionCollection()->action("zeroconf_page")->icon()));
863 zeroconfButton
->setText(i18n("Browse Remote Desktop Services on Local Network"));
864 connect(zeroconfButton
, SIGNAL(clicked()), SLOT(createZeroconfPage()));
865 #ifndef BUILD_ZEROCONF
866 zeroconfButton
->setVisible(false);
869 startLayout
->addLayout(headerLayout
);
870 startLayout
->addWidget(vncConnectButton
);
871 startLayout
->addWidget(nxConnectButton
);
872 startLayout
->addWidget(rdpConnectButton
);
873 startLayout
->addWidget(zeroconfButton
);
874 startLayout
->addStretch();
876 m_tabWidget
->insertTab(0, startWidget
, KIcon("krdc"), i18n("Start Page"));
879 void MainWindow::newVncConnection()
881 m_addressNavigator
->setUrl(KUrl("vnc://"));
882 m_addressNavigator
->setFocus();
884 QToolTip::showText(m_addressNavigator
->pos() + pos() + QPoint(m_addressNavigator
->width(),
885 m_addressNavigator
->height() + 20),
886 i18n("<html>Enter the address here.<br />"
887 "<i>Example: vncserver:1 (host:port / screen)</i></html>"), this);
890 void MainWindow::newNxConnection()
892 m_addressNavigator
->setUrl(KUrl("nx://"));
893 m_addressNavigator
->setFocus();
895 QToolTip::showText(m_addressNavigator
->pos() + pos() + QPoint(m_addressNavigator
->width(),
896 m_addressNavigator
->height() + 20),
897 i18n("<html>Enter the address here.<br />"
898 "<i>Example: nxserver (host)</i></html>"), this);
901 void MainWindow::newRdpConnection()
903 m_addressNavigator
->setUrl(KUrl("rdp://"));
904 m_addressNavigator
->setFocus();
906 QToolTip::showText(m_addressNavigator
->pos() + pos() + QPoint(m_addressNavigator
->width(),
907 m_addressNavigator
->height() + 20),
908 i18n("<html>Enter the address here. Port is optional.<br />"
909 "<i>Example: rdpserver:3389 (host:port)</i></html>"), this);
912 void MainWindow::createZeroconfPage()
914 #ifdef BUILD_ZEROCONF
918 m_zeroconfPage
= new ZeroconfPage(this);
919 connect(m_zeroconfPage
, SIGNAL(newConnection(const KUrl
, bool)), this, SLOT(newConnection(const KUrl
, bool)));
920 connect(m_zeroconfPage
, SIGNAL(closeZeroconfPage()), this, SLOT(closeZeroconfPage()));
921 int zeroconfTabIndex
= m_tabWidget
->insertTab(m_showStartPage
? 1 : 0, m_zeroconfPage
, KIcon("krdc"), i18n("Browse Local Network"));
922 m_tabWidget
->setCurrentIndex(zeroconfTabIndex
);
926 void MainWindow::closeZeroconfPage()
928 #ifdef BUILD_ZEROCONF
929 int index
= m_tabWidget
->indexOf(m_zeroconfPage
);
930 m_tabWidget
->removeTab(index
);
931 m_zeroconfPage
->deleteLater();
933 tabChanged(index
); // force update again because m_zeroconfPage was not null before
937 QList
<RemoteView
*> MainWindow::remoteViewList() const
939 return m_remoteViewList
;
942 int MainWindow::currentRemoteView() const
944 return m_currentRemoteView
;
947 #include "mainwindow.moc"