38 #ifdef TELEPATHY_SUPPORT
43 #include <KActionCollection>
44 #include <KActionMenu>
47 #include <KInputDialog>
52 #include <KMessageBox>
53 #include <KNotifyConfigWidget>
54 #include <KPluginInfo>
55 #include <KPushButton>
57 #include <KToggleAction>
58 #include <KToggleFullScreenAction>
59 #include <KServiceTypeTrader>
62 #include <QDockWidget>
63 #include <QFontMetrics>
65 #include <QHBoxLayout>
66 #include <QHeaderView>
69 #include <QScrollArea>
70 #include <QSortFilterProxyModel>
74 #include <QVBoxLayout>
78 m_fullscreenWindow(0),
82 m_currentRemoteView(-1),
84 m_dockWidgetTableView(0),
85 m_newConnectionTableView(0),
86 #ifdef TELEPATHY_SUPPORT
89 m_newConnectionWidget(0)
95 setStandardToolBarMenuEnabled(
true);
98 m_tabWidget->setMovable(
true);
101 #if QT_VERSION >= 0x040500
107 connect(m_tabWidget, SIGNAL(closeRequest(
QWidget*)), SLOT(closeTab(
QWidget*)));
110 connect(m_tabWidget, SIGNAL(mouseMiddleClick(
QWidget*)), SLOT(closeTab(
QWidget*)));
112 connect(m_tabWidget, SIGNAL(mouseDoubleClick(
QWidget*)), SLOT(openTabSettings(
QWidget*)));
113 connect(m_tabWidget, SIGNAL(contextMenu(
QWidget*,QPoint)), SLOT(tabContextMenu(
QWidget*,QPoint)));
115 m_tabWidget->setMinimumSize(600, 400);
116 setCentralWidget(m_tabWidget);
120 setupGUI(ToolBar | Keys | Save | Create);
124 if(m_fullscreenWindow) m_systemTrayIcon->setAssociatedWidget(m_fullscreenWindow);
127 connect(m_tabWidget, SIGNAL(currentChanged(
int)), SLOT(tabChanged(
int)));
130 statusBar()->showMessage(i18n(
"KDE Remote Desktop Client started"));
132 updateActionStatus();
135 m_tabWidget->
addTab(newConnectionWidget(), i18n(
"New Connection"));
138 QTimer::singleShot(100,
this, SLOT(restoreOpenSessions()));
145 void MainWindow::setupActions()
147 QAction *connectionAction = actionCollection()->addAction(
"new_connection");
148 connectionAction->setText(i18n(
"New Connection"));
149 connectionAction->setIcon(KIcon(
"network-connect"));
150 connect(connectionAction, SIGNAL(triggered()), SLOT(newConnectionPage()));
152 QAction *screenshotAction = actionCollection()->addAction(
"take_screenshot");
153 screenshotAction->setText(i18n(
"Copy Screenshot to Clipboard"));
154 screenshotAction->setIconText(i18n(
"Screenshot"));
155 screenshotAction->setIcon(KIcon(
"ksnapshot"));
156 connect(screenshotAction, SIGNAL(triggered()), SLOT(takeScreenshot()));
158 KAction *fullscreenAction = actionCollection()->addAction(
"switch_fullscreen");
159 fullscreenAction->setText(i18n(
"Switch to Full Screen Mode"));
160 fullscreenAction->setIconText(i18n(
"Full Screen"));
161 fullscreenAction->setIcon(KIcon(
"view-fullscreen"));
162 fullscreenAction->setShortcut(KStandardShortcut::fullScreen());
163 connect(fullscreenAction, SIGNAL(triggered()), SLOT(switchFullscreen()));
165 QAction *viewOnlyAction = actionCollection()->addAction(
"view_only");
166 viewOnlyAction->setCheckable(
true);
167 viewOnlyAction->setText(i18n(
"View Only"));
168 viewOnlyAction->setIcon(KIcon(
"document-preview"));
169 connect(viewOnlyAction, SIGNAL(triggered(
bool)), SLOT(viewOnly(
bool)));
171 KAction *disconnectAction = actionCollection()->addAction(
"disconnect");
172 disconnectAction->setText(i18n(
"Disconnect"));
173 disconnectAction->setIcon(KIcon(
"network-disconnect"));
174 disconnectAction->setShortcut(QKeySequence::Close);
175 connect(disconnectAction, SIGNAL(triggered()), SLOT(disconnectHost()));
177 QAction *showLocalCursorAction = actionCollection()->addAction(
"show_local_cursor");
178 showLocalCursorAction->setCheckable(
true);
179 showLocalCursorAction->setIcon(KIcon(
"input-mouse"));
180 showLocalCursorAction->setText(i18n(
"Show Local Cursor"));
181 showLocalCursorAction->setIconText(i18n(
"Local Cursor"));
182 connect(showLocalCursorAction, SIGNAL(triggered(
bool)), SLOT(showLocalCursor(
bool)));
184 QAction *grabAllKeysAction = actionCollection()->addAction(
"grab_all_keys");
185 grabAllKeysAction->setCheckable(
true);
186 grabAllKeysAction->setIcon(KIcon(
"configure-shortcuts"));
187 grabAllKeysAction->setText(i18n(
"Grab All Possible Keys"));
188 grabAllKeysAction->setIconText(i18n(
"Grab Keys"));
189 connect(grabAllKeysAction, SIGNAL(triggered(
bool)), SLOT(grabAllKeys(
bool)));
191 QAction *scaleAction = actionCollection()->addAction(
"scale");
192 scaleAction->setCheckable(
true);
193 scaleAction->setIcon(KIcon(
"zoom-fit-best"));
194 scaleAction->setText(i18n(
"Scale Remote Screen to Fit Window Size"));
195 scaleAction->setIconText(i18n(
"Scale"));
196 connect(scaleAction, SIGNAL(triggered(
bool)), SLOT(scale(
bool)));
198 KStandardAction::quit(
this, SLOT(quit()), actionCollection());
199 KStandardAction::preferences(
this, SLOT(preferences()), actionCollection());
200 QAction *configNotifyAction = KStandardAction::configureNotifications(
this, SLOT(configureNotifications()), actionCollection());
201 configNotifyAction->setVisible(
false);
202 m_menubarAction = KStandardAction::showMenubar(
this, SLOT(showMenubar()), actionCollection());
203 m_menubarAction->setChecked(!menuBar()->isHidden());
205 KActionMenu *bookmarkMenu =
new KActionMenu(i18n(
"Bookmarks"), actionCollection());
206 m_bookmarkManager =
new BookmarkManager(actionCollection(), bookmarkMenu->menu(),
this);
207 actionCollection()->addAction(
"bookmark" , bookmarkMenu);
208 connect(m_bookmarkManager, SIGNAL(openUrl(KUrl)), SLOT(
newConnection(KUrl)));
211 void MainWindow::loadAllPlugins()
213 const KService::List offers = KServiceTypeTrader::self()->query(
"KRDC/Plugin");
215 KConfigGroup conf(KGlobal::config(),
"Plugins");
217 for (
int i = 0; i < offers.size(); i++) {
218 KService::Ptr offer = offers[i];
222 KPluginInfo description(offer);
223 description.load(conf);
225 const bool selected = description.isPluginEnabled();
228 if ((remoteView = createPluginFromService(offer)) != 0) {
229 kDebug(5010) <<
"### Plugin " + description.name() +
" found ###";
230 kDebug(5010) <<
"# Version:" << description.version();
231 kDebug(5010) <<
"# Description:" << description.comment();
232 kDebug(5010) <<
"# Author:" << description.author();
233 const int sorting = offer->property(
"X-KDE-KRDC-Sorting").toInt();
234 kDebug(5010) <<
"# Sorting:" << sorting;
236 m_remoteViewFactories.insert(sorting, remoteView);
238 kDebug(5010) <<
"Error loading KRDC plugin (" << (offers[i])->library() <<
')';
241 kDebug(5010) <<
"# Plugin " + description.name() +
" found, however it's not activated, skipping...";
246 #ifdef TELEPATHY_SUPPORT
253 RemoteViewFactory *MainWindow::createPluginFromService(
const KService::Ptr &service)
256 KPluginFactory *factory = KPluginLoader(service->library()).factory();
259 kError(5010) <<
"KPluginFactory could not load the plugin:" << service->library();
268 void MainWindow::restoreOpenSessions()
271 QStringList::ConstIterator it = list.begin();
272 QStringList::ConstIterator end = list.end();
279 KUrl MainWindow::getInputUrl()
281 return KUrl(m_protocolInput->currentText() +
"://" + m_addressInput->text());
286 m_switchFullscreenWhenConnected = switchFullscreenWhenConnected;
288 const KUrl url = newUrl.isEmpty() ? getInputUrl() : newUrl;
290 if (!url.isValid() || (url.host().isEmpty() && url.port() < 0)
291 || (!url.path().isEmpty() && url.path() != QLatin1String(
"/"))) {
292 KMessageBox::error(
this,
293 i18n(
"The entered address does not have the required form.\n Syntax: [username@]host[:port]"),
294 i18n(
"Malformed URL"));
298 if (m_protocolInput && m_addressInput) {
299 int index = m_protocolInput->findText(url.protocol());
300 if (index>=0) m_protocolInput->setCurrentIndex(index);
301 m_addressInput->setText(url.authority());
305 KConfigGroup configGroup =
Settings::self()->config()->group(
"hostpreferences").group(url.prettyUrl(KUrl::RemoveTrailingSlash));
309 view = factory->
createView(
this, url, configGroup);
310 kDebug(5010) <<
"Found plugin to handle url (" + url.
url() +
"): " + view->metaObject()->className();
316 KMessageBox::error(
this,
317 i18n(
"The entered address cannot be handled."),
318 i18n(
"Unusable URL"));
333 connect(view, SIGNAL(framebufferSizeChanged(
int,
int)),
this, SLOT(resizeTabWidget(
int,
int)));
335 connect(view, SIGNAL(disconnected()),
this, SLOT(disconnectHost()));
338 QScrollArea *scrollArea = createScrollArea(m_tabWidget, view);
340 const int indexOfNewConnectionWidget = m_tabWidget->indexOf(m_newConnectionWidget);
341 if (indexOfNewConnectionWidget >= 0)
342 m_tabWidget->
removeTab(indexOfNewConnectionWidget);
344 const int newIndex = m_tabWidget->
addTab(scrollArea, KIcon(
"krdc"), tabName.isEmpty() ? url.prettyUrl(KUrl::RemoveTrailingSlash) : tabName);
345 m_tabWidget->setCurrentIndex(newIndex);
346 m_remoteViewMap.insert(m_tabWidget->widget(newIndex), view);
347 tabChanged(newIndex);
352 void MainWindow::openFromRemoteDesktopsModel(
const QModelIndex &index)
354 const QString urlString = index.data(10001).toString();
355 const QString nameString = index.data(10003).toString();
356 if (!urlString.isEmpty()) {
357 const KUrl url(urlString);
359 foreach (
QWidget *widget, m_remoteViewMap.keys()) {
360 if (m_remoteViewMap.value(widget)->url() == url) {
361 m_tabWidget->setCurrentWidget(widget);
370 void MainWindow::resizeTabWidget(
int w,
int h)
372 kDebug(5010) <<
"tabwidget resize, view size: w: " << w <<
", h: " << h;
373 if (m_fullscreenWindow) {
374 kDebug(5010) <<
"in fullscreen mode, refusing to resize";
378 const QSize viewSize = QSize(w,h);
379 QDesktopWidget *desktop = QApplication::desktop();
382 int currentScreen = desktop->screenNumber(
this);
383 const QSize screenSize = desktop->screenGeometry(currentScreen).size();
385 if (screenSize == viewSize) {
386 kDebug(5010) <<
"screen size equal to target view size -> switch to fullscreen mode";
393 QWidget* currentWidget = m_tabWidget->currentWidget();
394 const QSize newWindowSize = size() - currentWidget->frameSize() + viewSize;
396 const QSize desktopSize = desktop->availableGeometry().size();
397 kDebug(5010) <<
"new window size: " << newWindowSize <<
" available space:" << desktopSize;
399 if ((newWindowSize.width() >= desktopSize.width()) || (newWindowSize.height() >= desktopSize.height())) {
400 kDebug(5010) <<
"remote desktop needs more space than available -> show window maximized";
401 setWindowState(windowState() | Qt::WindowMaximized);
405 resize(newWindowSize);
411 kDebug(5010) << status;
418 const QString host = view->
host();
420 QString iconName =
"krdc";
425 iconName =
"network-connect";
426 message = i18n(
"Connecting to %1", host);
429 iconName =
"dialog-password";
430 message = i18n(
"Authenticating at %1", host);
433 iconName =
"view-history";
434 message = i18n(
"Preparing connection to %1", host);
438 message = i18n(
"Connected to %1", host);
442 updateActionStatus();
446 if (m_switchFullscreenWhenConnected) {
447 m_switchFullscreenWhenConnected =
false;
460 m_tabWidget->setTabIcon(m_tabWidget->indexOf(view), KIcon(iconName));
462 statusBar()->showMessage(message);
465 void MainWindow::takeScreenshot()
469 QApplication::clipboard()->setPixmap(snapshot);
472 void MainWindow::switchFullscreen()
476 if (m_fullscreenWindow) {
478 m_fullscreenWindow->setWindowState(0);
479 m_fullscreenWindow->hide();
482 m_tabWidget->setDocumentMode(
false);
483 setCentralWidget(m_tabWidget);
486 restoreGeometry(m_mainWindowGeometry);
487 if (m_systemTrayIcon) m_systemTrayIcon->setAssociatedWidget(
this);
489 foreach (
RemoteView * view, m_remoteViewMap.values()) {
495 m_toolBar->deleteLater();
499 actionCollection()->action(
"switch_fullscreen")->setIcon(KIcon(
"view-fullscreen"));
500 actionCollection()->action(
"switch_fullscreen")->setText(i18n(
"Switch to Full Screen Mode"));
501 actionCollection()->action(
"switch_fullscreen")->setIconText(i18n(
"Full Screen"));
503 m_fullscreenWindow->deleteLater();
504 m_fullscreenWindow = 0;
507 m_fullscreenWindow =
new QWidget(
this, Qt::Window);
508 m_fullscreenWindow->setWindowTitle(i18nc(
"window title when in full screen mode (for example displayed in tasklist)",
509 "KDE Remote Desktop Client (Full Screen)"));
511 m_mainWindowGeometry = saveGeometry();
513 m_tabWidget->setTabBarHidden(
true);
514 m_tabWidget->setDocumentMode(
true);
516 foreach(
RemoteView *currentView, m_remoteViewMap) {
520 QVBoxLayout *fullscreenLayout =
new QVBoxLayout(m_fullscreenWindow);
521 fullscreenLayout->setContentsMargins(QMargins(0, 0, 0, 0));
522 fullscreenLayout->addWidget(m_tabWidget);
524 KToggleFullScreenAction::setFullScreen(m_fullscreenWindow,
true);
527 minimizePixel->winId();
528 connect(minimizePixel, SIGNAL(rightClicked()), m_fullscreenWindow, SLOT(showMinimized()));
529 m_fullscreenWindow->installEventFilter(
this);
531 m_fullscreenWindow->show();
534 if (m_systemTrayIcon) m_systemTrayIcon->setAssociatedWidget(m_fullscreenWindow);
535 showRemoteViewToolbar();
537 if (m_tabWidget->currentWidget() == m_newConnectionWidget) {
538 m_addressInput->setFocus();
545 scrollArea->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
547 connect(scrollArea, SIGNAL(resized(
int,
int)), remoteView, SLOT(scaleResize(
int,
int)));
549 QPalette palette = scrollArea->palette();
551 scrollArea->setPalette(palette);
553 scrollArea->setBackgroundRole(QPalette::Dark);
554 scrollArea->setFrameStyle(QFrame::NoFrame);
556 scrollArea->setWidget(remoteView);
561 void MainWindow::disconnectHost()
569 widgetToDelete = (
QWidget*) view->parent()->parent();
570 m_remoteViewMap.remove(m_remoteViewMap.key(view));
572 widgetToDelete = m_tabWidget->currentWidget();
574 m_remoteViewMap.remove(m_remoteViewMap.key(view));
580 widgetToDelete->deleteLater();
581 #ifdef TELEPATHY_SUPPORT
582 m_tubesManager->closeTube(view->
url());
586 if (m_tabWidget->count() == 0) {
587 newConnectionPage(
false);
591 if (m_fullscreenWindow && m_tabWidget->count() == 1 && m_tabWidget->currentWidget() == m_newConnectionWidget) {
596 void MainWindow::closeTab(
QWidget *widget)
598 bool isNewConnectionPage = widget == m_newConnectionWidget;
600 if (!isNewConnectionPage) {
601 RemoteView *view = m_remoteViewMap.value(widget);
602 m_remoteViewMap.remove(m_remoteViewMap.key(view));
604 #ifdef TELEPATHY_SUPPORT
605 m_tubesManager->closeTube(view->
url());
607 widget->deleteLater();
613 if (m_tabWidget->count() == 0) {
614 newConnectionPage(
false);
618 if (m_fullscreenWindow && m_tabWidget->count() == 1 && m_tabWidget->currentWidget() == m_newConnectionWidget) {
623 void MainWindow::openTabSettings(
QWidget *widget)
626 if (!scrollArea)
return;
630 const QString url = view->
url().url();
633 showSettingsDialog(url);
636 void MainWindow::showSettingsDialog(
const QString &url)
644 kDebug(5010) <<
"Found plugin to handle url (" + url +
"): " + prefs->metaObject()->className();
646 kDebug(5010) <<
"Found plugin to handle url (" + url +
"), but plugin does not provide preferences";
655 KMessageBox::error(
this,
656 i18n(
"The selected host cannot be handled."),
657 i18n(
"Unusable URL"));
661 void MainWindow::showConnectionContextMenu(
const QPoint &pos)
664 QPoint offset = QPoint(m_newConnectionTableView->verticalHeader()->size().width(),
665 m_newConnectionTableView->horizontalHeader()->size().height());
666 QModelIndex index = m_newConnectionTableView->indexAt(pos);
668 if (!index.isValid())
671 const QString url = index.data(10001).toString();
675 KMenu *menu =
new KMenu(m_newConnectionTableView);
678 QAction *connectAction = menu->addAction(KIcon(
"network-connect"), i18n(
"Connect"));
679 QAction *renameAction = menu->addAction(KIcon(
"edit-rename"), i18n(
"Rename"));
680 QAction *settingsAction = menu->addAction(KIcon(
"configure"), i18n(
"Settings"));
681 QAction *deleteAction = menu->addAction(KIcon(
"edit-delete"), i18n(
"Delete"));
684 if (!(source == i18nc(
"Where each displayed link comes from",
"Bookmarks") ||
685 source == i18nc(
"Where each displayed link comes from",
"History"))) {
686 renameAction->setEnabled(
false);
687 deleteAction->setEnabled(
false);
690 QAction *selectedAction = menu->exec(m_newConnectionTableView->mapToGlobal(pos + offset));
692 if (selectedAction == connectAction) {
693 openFromRemoteDesktopsModel(index);
694 }
else if (selectedAction == renameAction) {
697 const QString newTitle = KInputDialog::getText(i18n(
"Rename %1", title), i18n(
"Rename %1 to", title),
"", &ok,
this);
698 if (ok && !newTitle.isEmpty()) {
701 }
else if (selectedAction == settingsAction) {
702 showSettingsDialog(url);
703 }
else if (selectedAction == deleteAction) {
705 if (KMessageBox::warningContinueCancel(
this, i18n(
"Are you sure you want to delete %1?", url), i18n(
"Delete %1", title),
706 KStandardGuiItem::del()) == KMessageBox::Continue) {
714 void MainWindow::tabContextMenu(
QWidget *widget,
const QPoint &point)
717 if (!scrollArea)
return;
721 const QString url = view->
url().prettyUrl(KUrl::RemoveTrailingSlash);
724 KMenu *menu =
new KMenu(
this);
726 QAction *bookmarkAction = menu->addAction(KIcon(
"bookmark-new"), i18n(
"Add Bookmark"));
727 QAction *closeAction = menu->addAction(KIcon(
"tab-close"), i18n(
"Close Tab"));
728 QAction *selectedAction = menu->exec(point);
729 if (selectedAction) {
730 if (selectedAction == closeAction) {
732 }
else if (selectedAction == bookmarkAction) {
739 void MainWindow::showLocalCursor(
bool showLocalCursor)
741 kDebug(5010) << showLocalCursor;
749 void MainWindow::viewOnly(
bool viewOnly)
751 kDebug(5010) << viewOnly;
759 void MainWindow::grabAllKeys(
bool grabAllKeys)
769 void MainWindow::scale(
bool scale)
775 if (m_fullscreenWindow)
783 void MainWindow::showRemoteViewToolbar()
788 actionCollection()->action(
"switch_fullscreen")->setIcon(KIcon(
"view-restore"));
789 actionCollection()->action(
"switch_fullscreen")->setText(i18n(
"Switch to Window Mode"));
790 actionCollection()->action(
"switch_fullscreen")->setIconText(i18n(
"Window Mode"));
792 m_toolBar =
new FloatingToolBar(m_fullscreenWindow, m_fullscreenWindow);
796 KComboBox *sessionComboBox =
new KComboBox(m_toolBar);
797 sessionComboBox->setStyleSheet(
"QComboBox:!editable{background:transparent;}");
798 sessionComboBox->setModel(m_tabWidget->
getModel());
799 sessionComboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
800 sessionComboBox->setCurrentIndex(m_tabWidget->currentIndex());
801 connect(sessionComboBox, SIGNAL(activated(
int)), m_tabWidget, SLOT(setCurrentIndex(
int)));
802 connect(m_tabWidget, SIGNAL(currentChanged(
int)), sessionComboBox, SLOT(setCurrentIndex(
int)));
803 m_toolBar->addWidget(sessionComboBox);
807 buttonBox->addAction(actionCollection()->action(
"new_connection"));
808 buttonBox->addAction(actionCollection()->action(
"switch_fullscreen"));
810 QAction *minimizeAction =
new QAction(m_toolBar);
811 minimizeAction->setIcon(KIcon(
"go-down"));
812 minimizeAction->setText(i18n(
"Minimize Full Screen Window"));
813 connect(minimizeAction, SIGNAL(triggered()), m_fullscreenWindow, SLOT(showMinimized()));
814 buttonBox->addAction(minimizeAction);
816 buttonBox->addAction(actionCollection()->action(
"take_screenshot"));
817 buttonBox->addAction(actionCollection()->action(
"view_only"));
818 buttonBox->addAction(actionCollection()->action(
"show_local_cursor"));
819 buttonBox->addAction(actionCollection()->action(
"grab_all_keys"));
820 buttonBox->addAction(actionCollection()->action(
"scale"));
821 buttonBox->addAction(actionCollection()->action(
"disconnect"));
822 buttonBox->addAction(actionCollection()->action(
"file_quit"));
824 QAction *stickToolBarAction =
new QAction(m_toolBar);
825 stickToolBarAction->setCheckable(
true);
826 stickToolBarAction->setIcon(KIcon(
"object-locked"));
827 stickToolBarAction->setText(i18n(
"Stick Toolbar"));
828 connect(stickToolBarAction, SIGNAL(triggered(
bool)), m_toolBar, SLOT(setSticky(
bool)));
829 buttonBox->addAction(stickToolBarAction);
831 m_toolBar->addWidget(buttonBox);
837 action->setEnabled(enabled);
838 action->setVisible(visible);
839 action->setChecked(checked);
842 void MainWindow::updateActionStatus()
844 kDebug(5010) << m_tabWidget->currentIndex();
848 if (m_tabWidget->currentWidget() == m_newConnectionWidget)
853 actionCollection()->action(
"take_screenshot")->setEnabled(enabled);
854 actionCollection()->action(
"disconnect")->setEnabled(enabled);
869 view ? view->
scaling() :
false);
877 void MainWindow::preferences()
882 if (PreferencesDialog::showDialog(
"preferences"))
891 connect(dialog, SIGNAL(settingsChanged(QString)),
892 this, SLOT(updateConfiguration()));
897 void MainWindow::updateConfiguration()
900 statusBar()->deleteLater();
902 statusBar()->showMessage(
"");
904 m_tabWidget->setTabBarHidden((m_tabWidget->count() <= 1 && !
Settings::showTabBar()) || m_fullscreenWindow);
906 #if QT_VERSION >= 0x040500
911 disconnect(m_tabWidget, SIGNAL(mouseMiddleClick(
QWidget*)),
this, SLOT(closeTab(
QWidget*)));
913 connect(m_tabWidget, SIGNAL(mouseMiddleClick(
QWidget*)), SLOT(closeTab(
QWidget*)));
917 if(m_fullscreenWindow) m_systemTrayIcon->setAssociatedWidget(m_fullscreenWindow);
918 }
else if (m_systemTrayIcon) {
919 delete m_systemTrayIcon;
920 m_systemTrayIcon = 0;
924 for (
int i = 0; i < m_tabWidget->count(); ++i) {
925 QPalette palette = m_tabWidget->widget(i)->palette();
927 m_tabWidget->widget(i)->setPalette(palette);
931 foreach (
RemoteView *view, m_remoteViewMap.values()) {
937 void MainWindow::quit(
bool systemEvent)
939 const bool haveRemoteConnections = !m_remoteViewMap.isEmpty();
940 if (systemEvent || !haveRemoteConnections || KMessageBox::warningContinueCancel(
this,
941 i18n(
"Are you sure you want to quit the KDE Remote Desktop Client?"),
942 i18n(
"Confirm Quit"),
943 KStandardGuiItem::quit(), KStandardGuiItem::cancel(),
944 "DoNotAskBeforeExit") == KMessageBox::Continue) {
948 foreach (
RemoteView *view, m_remoteViewMap.values()) {
949 kDebug(5010) << view->
url();
950 list.append(view->
url().prettyUrl(KUrl::RemoveTrailingSlash));
957 foreach (
RemoteView *view, m_remoteViewMap.values()) {
967 void MainWindow::configureNotifications()
969 KNotifyConfigWidget::configure(
this);
972 void MainWindow::showMenubar()
974 if (m_menubarAction->isChecked())
983 if (obj == m_fullscreenWindow && event->type() == QEvent::Close) {
987 return QObject::eventFilter(obj, event);
992 if (event->spontaneous()) {
1007 KMainWindow::saveProperties(group);
1014 foreach (
RemoteView *view, m_remoteViewMap.values()) {
1023 if (view && view->
scaling()) {
1024 QSize viewSize = m_tabWidget->currentWidget()->size();
1025 kDebug(5010) <<
"saving window size:" << viewSize;
1033 void MainWindow::tabChanged(
int index)
1035 kDebug(5010) << index;
1037 m_tabWidget->setTabBarHidden((m_tabWidget->count() <= 1 && !
Settings::showTabBar()) || m_fullscreenWindow);
1039 m_currentRemoteView = index;
1041 if (m_tabWidget->currentWidget() == m_newConnectionWidget) {
1042 m_currentRemoteView = -1;
1043 if(m_addressInput) m_addressInput->setFocus();
1046 const QString tabTitle = m_tabWidget->tabText(index).remove(
'&');
1047 setCaption(tabTitle == i18n(
"New Connection") ? QString() : tabTitle);
1049 updateActionStatus();
1052 QWidget* MainWindow::newConnectionWidget()
1054 if (m_newConnectionWidget)
1055 return m_newConnectionWidget;
1057 m_newConnectionWidget =
new QWidget(
this);
1059 QVBoxLayout *startLayout =
new QVBoxLayout(m_newConnectionWidget);
1060 startLayout->setContentsMargins(QMargins(8, 12, 8, 4));
1062 QLabel *headerLabel =
new QLabel(m_newConnectionWidget);
1063 headerLabel->setText(i18n(
"<h1>KDE Remote Desktop Client</h1><br />Enter or select the address of the desktop you would like to connect to."));
1065 QLabel *headerIconLabel =
new QLabel(m_newConnectionWidget);
1066 headerIconLabel->setPixmap(KIcon(
"krdc").pixmap(80));
1068 QHBoxLayout *headerLayout =
new QHBoxLayout;
1069 headerLayout->addWidget(headerLabel, 1, Qt::AlignTop);
1070 headerLayout->addWidget(headerIconLabel);
1071 startLayout->addLayout(headerLayout);
1073 QSortFilterProxyModel *remoteDesktopsModelProxy =
new QSortFilterProxyModel(
this);
1074 remoteDesktopsModelProxy->setSourceModel(m_remoteDesktopsModel);
1075 remoteDesktopsModelProxy->setFilterCaseSensitivity(Qt::CaseInsensitive);
1076 remoteDesktopsModelProxy->setFilterRole(10002);
1079 QHBoxLayout *connectLayout =
new QHBoxLayout;
1081 QLabel *addressLabel =
new QLabel(i18n(
"Connect to:"), m_newConnectionWidget);
1082 m_protocolInput =
new KComboBox(m_newConnectionWidget);
1083 m_addressInput =
new KLineEdit(m_newConnectionWidget);
1084 m_addressInput->setClearButtonShown(
true);
1085 m_addressInput->setClickMessage(i18n(
"Type here to connect to an address and filter the list."));
1086 connect(m_addressInput, SIGNAL(textChanged(QString)), remoteDesktopsModelProxy, SLOT(setFilterFixedString(QString)));
1089 m_protocolInput->addItem(factory->
scheme());
1092 connect(m_addressInput, SIGNAL(returnPressed()), SLOT(
newConnection()));
1093 m_addressInput->setToolTip(i18n(
"Type an IP or DNS Name here. Clear the line to get a list of connection methods."));
1095 KPushButton *connectButton =
new KPushButton(m_newConnectionWidget);
1096 connectButton->setToolTip(i18n(
"Goto Address"));
1097 connectButton->setIcon(KIcon(
"go-jump-locationbar"));
1098 connect(connectButton, SIGNAL(clicked()), SLOT(
newConnection()));
1100 connectLayout->addWidget(addressLabel);
1101 connectLayout->addWidget(m_protocolInput);
1102 connectLayout->addWidget(m_addressInput, 1);
1103 connectLayout->addWidget(connectButton);
1104 connectLayout->setContentsMargins(QMargins(0, 6, 0, 10));
1105 startLayout->addLayout(connectLayout);
1109 m_newConnectionTableView =
new QTableView(m_newConnectionWidget);
1110 m_newConnectionTableView->setModel(remoteDesktopsModelProxy);
1113 m_newConnectionTableView->setItemDelegate(
new ConnectionDelegate(m_newConnectionTableView));
1114 m_newConnectionTableView->setShowGrid(
false);
1115 m_newConnectionTableView->setSelectionMode(QAbstractItemView::NoSelection);
1116 m_newConnectionTableView->verticalHeader()->hide();
1117 m_newConnectionTableView->verticalHeader()->setDefaultSectionSize(
1118 m_newConnectionTableView->fontMetrics().height() + 3);
1119 m_newConnectionTableView->horizontalHeader()->setStretchLastSection(
true);
1120 m_newConnectionTableView->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents);
1121 m_newConnectionTableView->setAlternatingRowColors(
true);
1123 m_newConnectionTableView->setSortingEnabled(
true);
1125 connect(m_newConnectionTableView->horizontalHeader(), SIGNAL(sortIndicatorChanged(
int,Qt::SortOrder)),
1126 SLOT(saveConnectionListSort(
int,Qt::SortOrder)));
1127 connect(m_newConnectionTableView, SIGNAL(doubleClicked(QModelIndex)),
1128 SLOT(openFromRemoteDesktopsModel(QModelIndex)));
1129 m_newConnectionTableView->setContextMenuPolicy(Qt::CustomContextMenu);
1130 connect(m_newConnectionTableView, SIGNAL(customContextMenuRequested(QPoint)), SLOT(showConnectionContextMenu(QPoint)));
1132 startLayout->addWidget(m_newConnectionTableView);
1135 return m_newConnectionWidget;
1138 void MainWindow::saveConnectionListSort(
const int logicalindex,
const Qt::SortOrder order)
1145 void MainWindow::newConnectionPage(
bool clearInput)
1147 const int indexOfNewConnectionWidget = m_tabWidget->indexOf(m_newConnectionWidget);
1148 if (indexOfNewConnectionWidget >= 0)
1149 m_tabWidget->setCurrentIndex(indexOfNewConnectionWidget);
1151 const int index = m_tabWidget->
addTab(newConnectionWidget(), i18n(
"New Connection"));
1152 m_tabWidget->setCurrentIndex(index);
1155 m_addressInput->clear();
1157 m_addressInput->selectAll();
1159 m_addressInput->setFocus();
1164 return m_remoteViewMap;
1169 return m_remoteViewFactories.values();
1174 if (m_currentRemoteView >= 0) {
1175 return m_remoteViewMap.value(m_tabWidget->widget(m_currentRemoteView));
1181 void MainWindow::createDockWidget()
1183 QDockWidget *remoteDesktopsDockWidget =
new QDockWidget(
this);
1184 QWidget *remoteDesktopsDockLayoutWidget =
new QWidget(remoteDesktopsDockWidget);
1185 QVBoxLayout *remoteDesktopsDockLayout =
new QVBoxLayout(remoteDesktopsDockLayoutWidget);
1186 remoteDesktopsDockWidget->setObjectName(
"remoteDesktopsDockWidget");
1187 remoteDesktopsDockWidget->setWindowTitle(i18n(
"Remote Desktops"));
1188 QFontMetrics fontMetrics(remoteDesktopsDockWidget->font());
1189 remoteDesktopsDockWidget->setMinimumWidth(fontMetrics.width(
"vnc://192.168.100.100:6000"));
1190 actionCollection()->addAction(
"remote_desktop_dockwidget",
1191 remoteDesktopsDockWidget->toggleViewAction());
1193 m_dockWidgetTableView =
new QTableView(remoteDesktopsDockLayoutWidget);
1195 QSortFilterProxyModel *remoteDesktopsModelProxy =
new QSortFilterProxyModel(
this);
1196 remoteDesktopsModelProxy->setSourceModel(m_remoteDesktopsModel);
1197 remoteDesktopsModelProxy->setFilterCaseSensitivity(Qt::CaseInsensitive);
1198 remoteDesktopsModelProxy->setFilterRole(10002);
1199 m_dockWidgetTableView->setModel(remoteDesktopsModelProxy);
1201 m_dockWidgetTableView->setShowGrid(
false);
1202 m_dockWidgetTableView->verticalHeader()->hide();
1203 m_dockWidgetTableView->verticalHeader()->setDefaultSectionSize(
1204 m_dockWidgetTableView->fontMetrics().height() + 2);
1205 m_dockWidgetTableView->horizontalHeader()->hide();
1206 m_dockWidgetTableView->horizontalHeader()->setStretchLastSection(
true);
1208 for (
int i=0; i < remoteDesktopsModelProxy->columnCount(); i++) {
1209 m_dockWidgetTableView->hideColumn(i);
1214 connect(m_dockWidgetTableView, SIGNAL(doubleClicked(QModelIndex)),
1215 SLOT(openFromRemoteDesktopsModel(QModelIndex)));
1217 KLineEdit *filterLineEdit =
new KLineEdit(remoteDesktopsDockLayoutWidget);
1218 filterLineEdit->setClickMessage(i18n(
"Filter"));
1219 filterLineEdit->setClearButtonShown(
true);
1220 connect(filterLineEdit, SIGNAL(textChanged(QString)), remoteDesktopsModelProxy, SLOT(setFilterFixedString(QString)));
1221 remoteDesktopsDockLayout->addWidget(filterLineEdit);
1222 remoteDesktopsDockLayout->addWidget(m_dockWidgetTableView);
1223 remoteDesktopsDockWidget->setWidget(remoteDesktopsDockLayoutWidget);
1224 addDockWidget(Qt::LeftDockWidgetArea, remoteDesktopsDockWidget);
1227 #include "mainwindow.moc"
void setShownWhileConnected(bool connected)
If connected is true, a message is shown that settings might only apply after a reconnect.
virtual void saveProperties(KConfigGroup &group)
static int connectionListSortColumn()
Get ConnectionListSortColumn.
virtual QPixmap takeScreenshot()
void setActionStatus(QAction *action, bool enabled, bool visible, bool checked)
Never show local cursor, only the remote one.
bool windowedScale()
Whether scaling is enabled when session is not full screen.
RemoteStatus
State of the connection.
virtual void showDotCursor(DotCursorState state)
Sets the state of the dot cursor, if supported by the backend.
void setWindowedScale(bool scale)
static void setConnectionListSortColumn(int v)
Set ConnectionListSortColumn.
virtual bool supportsScaling() const
Checks whether the backend supports scaling.
bool showDialog(QWidget *parent)
Show the configuration dialog.
static bool resizeOnConnect()
Get ResizeOnConnect.
static void setOpenSessions(const QStringList &v)
Set Sessions.
virtual void closeEvent(QCloseEvent *event)
KBookmarkManager * getManager()
static QStringList openSessions()
Get Sessions.
void newConnection(const KUrl &newUrl=KUrl(), bool switchFullscreenWhenConnected=false, const QString &tabName=QString())
bool fullscreenScale()
Whether scaling is enabled when session is full screen.
static bool systemTrayIcon()
Get SystemTrayIcon.
Always show local cursor (and the remote one).
RemoteView * currentRemoteView() const
static bool tabMiddleClick()
Get TabMiddleClick.
virtual bool grabAllKeys()
Checks whether grabbing all possible keys is enabled.
Generic widget that displays a remote framebuffer.
virtual bool scaling() const
Checks whether the widget is in scale mode.
void setShowLocalCursor(bool show)
virtual HostPreferences * createHostPreferences(KConfigGroup configGroup, QWidget *parent)=0
Returns a new HostPreferences implementing object or 0 if no settings are available.
void setGrabAllKeys(bool grab)
virtual DotCursorState dotCursorState() const
Returns the state of the local cursor.
MainWindow(QWidget *parent=0)
virtual HostPreferences * hostPreferences()=0
Returns the current host preferences of this view.
virtual QString scheme() const =0
Returns the supported scheme.
static void updateTitle(KBookmarkManager *manager, const QString &url, const QString &title)
static QColor backgroundColor()
Get BackgroundColor.
virtual void setViewOnly(bool viewOnly)
Enables/disables the view-only mode.
virtual void setGrabAllKeys(bool grabAllKeys)
Enables/disables grabbing all possible keys.
void addManualBookmark(const QString &url, const QString &text)
static bool showTabBar()
Get ShowTabBar.
static int connectionListSortOrder()
Get ConnectionListSortOrder.
virtual bool viewOnly()
Checks whether the view is in view-only mode.
static bool rememberHistory()
Get RememberHistory.
void setFullscreenScale(bool scale)
virtual void enableScaling(bool scale)
Called to enable or disable scaling.
virtual void startQuitting()
Initiate the disconnection.
virtual void updateConfiguration()
Called when the configuration is changed.
static bool fullscreenOnConnect()
Get FullscreenOnConnect.
virtual bool supportsLocalCursor() const
Checks whether the backend supports the concept of local cursors.
void setViewOnly(bool view)
static int tabPosition()
Get TabPosition.
virtual bool supportsUrl(const KUrl &url) const =0
Returns true if the provided url is supported by the current plugin.
virtual bool start()=0
Initialize the view (for example by showing configuration dialogs to the user) and start connecting...
static void removeByUrl(KBookmarkManager *manager, const QString &url, bool ignoreHistory=false, const QString updateTitle=QString())
static bool rememberSessions()
Get RememberSessions.
void addHistoryBookmark(RemoteView *view)
static bool showStatusBar()
Get ShowStatusBar.
virtual RemoteView * createView(QWidget *parent, const KUrl &url, KConfigGroup configGroup)=0
Returns a new RemoteView implementing object.
Factory to be implemented by any plugin.
void setHeight(int height)
bool showDialogIfNeeded(QWidget *parent)
Show the configuration dialog if needed, ie.
QList< RemoteViewFactory * > remoteViewFactoriesList() const
bool eventFilter(QObject *obj, QEvent *event)
static void setConnectionListSortOrder(int v)
Set ConnectionListSortOrder.
static bool tabCloseButton()
Get TabCloseButton.
QMap< QWidget *, RemoteView * > remoteViewList() const