Ejemplo n.º 1
0
        public TabbedChatsWindow()
        {
            // FIXME: This doesn't work very well in most themes...
            //this.SetStyleSheet("QTabWidget::pane { border: 0px; }");

            // The tab widget messes up this background color.
            this.SetStyleSheet("QTabWidget > QWidget { background: palette(window); }");

            m_Tabs = new QTabWidget();
            m_Tabs.tabPosition = QTabWidget.TabPosition.South;

            QToolButton newTabButton = new QToolButton(m_Tabs);
            newTabButton.AutoRaise = true;
            newTabButton.SetDefaultAction(new QAction(Gui.LoadIcon("tab-new", 16), "New Tab", newTabButton));
            newTabButton.SetToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly);
            QObject.Connect<QAction>(newTabButton, Qt.SIGNAL("triggered(QAction*)"), HandleNewTab);
            m_Tabs.SetCornerWidget(newTabButton, Qt.Corner.BottomLeftCorner);

            QHBoxLayout rightButtonsLayout = new QHBoxLayout();
            rightButtonsLayout.SetContentsMargins(0, 0, 0, 0);
            rightButtonsLayout.Spacing = 0;

            QToolButton closeTabButton = new QToolButton(m_Tabs);
            closeTabButton.SetToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly);
            closeTabButton.AutoRaise = true;
            closeTabButton.SetDefaultAction(new QAction(Gui.LoadIcon("window-close", 16), "Close Tab", closeTabButton));
            QObject.Connect<QAction>(closeTabButton, Qt.SIGNAL("triggered(QAction*)"), HandleCloseTab);
            rightButtonsLayout.AddWidget(closeTabButton);

            QMenu menu = new QMenu(this);
            menu.AddAction(new QIcon(), "No Recently Closed Tabs");

            QToolButton trashButton = new QToolButton(m_Tabs);
            trashButton.SetToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly);
            trashButton.AutoRaise = true;
            trashButton.PopupMode = QToolButton.ToolButtonPopupMode.InstantPopup;
            trashButton.SetMenu(menu);
            trashButton.SetDefaultAction(new QAction(Gui.LoadIcon("user-trash", 16), "Recently Closed Tabs", trashButton));
            rightButtonsLayout.AddWidget(trashButton);

            // FIXME: This looks bad.
            //rightButtonsLayout.AddWidget(new QSizeGrip(this));

            QWidget rightButtonsContainer = new QWidget(m_Tabs);
            rightButtonsContainer.SetLayout(rightButtonsLayout);
            m_Tabs.SetCornerWidget(rightButtonsContainer, Qt.Corner.BottomRightCorner);

            QVBoxLayout layout = new QVBoxLayout(this);
            layout.SetContentsMargins(0, 0, 0, 0);
            layout.AddWidget(m_Tabs, 1, 0);
            this.SetLayout(layout);

            QObject.Connect<int>(m_Tabs, Qt.SIGNAL("currentChanged(int)"), HandleCurrentChanged);

            this.SetGeometry(0, 0, 445, 370);
            Gui.CenterWidgetOnScreen(this);

            QAction closeAction = new QAction(this);
            QObject.Connect<bool>(closeAction, Qt.SIGNAL("triggered(bool)"), HandleCloseActionTriggered);
            closeAction.Shortcut = new QKeySequence("Ctrl+w");
            this.AddAction(closeAction);

            0.UpTo(9).ForEach(num => {
                QAction action = new QAction(this);
                action.Shortcut = new QKeySequence("Alt+" + num.ToString());
                QObject.Connect(action, Qt.SIGNAL("triggered(bool)"), delegate {
                    m_Tabs.CurrentIndex = num - 1;
                });
                this.AddAction(action);
            });

            QAction nextTabAction = new QAction(this);
            nextTabAction.Shortcut = new QKeySequence(QKeySequence.StandardKey.NextChild);
            QObject.Connect(nextTabAction, Qt.SIGNAL("triggered(bool)"), delegate {
                if (m_Tabs.CurrentIndex == m_Tabs.Count - 1)
                    m_Tabs.CurrentIndex = 0;
                else
                    m_Tabs.CurrentIndex += 1;
            });
            this.AddAction(nextTabAction);

            QAction prevTabAction = new QAction(this);
            prevTabAction.Shortcut = new QKeySequence(QKeySequence.StandardKey.PreviousChild);
            QObject.Connect(prevTabAction, Qt.SIGNAL("triggered(bool)"), delegate {
                if (m_Tabs.CurrentIndex == 0)
                    m_Tabs.CurrentIndex = m_Tabs.Count - 1;
                else
                    m_Tabs.CurrentIndex -= 1;
            });

            var accountService = ServiceManager.Get<AccountService>();
            accountService.AccountAdded += HandleAccountAdded;
            accountService.AccountRemoved += HandleAccountRemoved;
            foreach (Account account in accountService.Accounts)
                HandleAccountAdded(account);

            var settingsService = ServiceManager.Get<SettingsService>();
            if (settingsService.Has("ChatsWindowGeometry")) {
                var geometry = settingsService.Get<byte[]>("ChatsWindowGeometry");
                base.RestoreGeometry(QByteArrayConverter.FromArray(geometry));
            }
        }
Ejemplo n.º 2
0
        internal ChatWindow(IChatHandler handler)
        {
            if (handler == null)
                throw new ArgumentNullException("handler");
            m_Handler = handler;

            SetupUi();

            if (handler is MucHandler) {
                m_ParticipantsMenu = new QMenu(this);
                QObject.Connect(m_ParticipantsMenu, Qt.SIGNAL("aboutToShow()"), HandleMenuAboutToShow);
                QObject.Connect(m_ParticipantsMenu, Qt.SIGNAL("aboutToHide()"), HandleMenuAboutToHide);

                var mucHandler = (MucHandler)handler;
                participantsGrid.Model = mucHandler.GridModel;
                participantsGrid.ContextMenuPolicy = Qt.ContextMenuPolicy.CustomContextMenu;
                participantsGrid.ItemActivated += HandleItemActivated;

                var group = new QActionGroup(this);

                var gridModeAction = new QAction("View as Grid", this);
                QObject.Connect(gridModeAction, Qt.SIGNAL("triggered()"), HandleGridModeActionTriggered);
                gridModeAction.SetActionGroup(group);
                gridModeAction.Checkable = true;
                gridModeAction.Checked = true;
                m_ParticipantsMenu.AddAction(gridModeAction);

                var listModeAction = new QAction("View as List", this);
                QObject.Connect(listModeAction, Qt.SIGNAL("triggered()"), HandleListModeActionTriggered);
                listModeAction.SetActionGroup(group);
                listModeAction.Checkable = true;
                m_ParticipantsMenu.AddAction(listModeAction);

                var separatorAction = new QAction(participantsGrid);
                separatorAction.SetSeparator(true);
                m_ParticipantsMenu.AddAction(separatorAction);

                var sliderAction = new AvatarGridZoomAction<jabber.connection.RoomParticipant>(participantsGrid);
                m_ParticipantsMenu.AddAction(sliderAction);

                m_ParticipantItemMenu = new QMenu(this);
                QObject.Connect(m_ParticipantItemMenu, Qt.SIGNAL("aboutToShow()"), HandleMenuAboutToShow);
                QObject.Connect(m_ParticipantItemMenu, Qt.SIGNAL("aboutToHide()"), HandleMenuAboutToHide);

                var mucViewProfileAction = new QAction("View Profile", this);
                QObject.Connect(mucViewProfileAction, Qt.SIGNAL("triggered()"), HandleMucViewProfileActionTriggered);
                m_ParticipantItemMenu.AddAction(mucViewProfileAction);

                var mucPrivateMessageAction = new QAction("IM", this);
                QObject.Connect(mucPrivateMessageAction, Qt.SIGNAL("triggered()"), HandleMucPrivateMessageTriggered);
                m_ParticipantItemMenu.AddAction(mucPrivateMessageAction);

                var mucSendFileAction = new QAction("Send File...", this);
                QObject.Connect(mucSendFileAction, Qt.SIGNAL("triggered()"), HandleMucSendFileActionTriggered);
                m_ParticipantItemMenu.AddAction(mucSendFileAction);

                var mucViewHistoryAction = new QAction("View History", this);
                QObject.Connect(mucViewHistoryAction, Qt.SIGNAL("triggered()"), HandleMucViewHistoryActionTriggered);
                m_ParticipantItemMenu.AddAction(mucViewHistoryAction);

                m_ModeratorActionsMenu = new QMenu("Moderator Actions", this);

                var roomRoleActionGroup = new QActionGroup(this);
                QObject.Connect(roomRoleActionGroup, Qt.SIGNAL("triggered(QAction*)"), this, Qt.SLOT("HandleRoomRoleActionGroupTriggered(QAction*)"));

                m_ModeratorAction = new QAction("Moderator", this);
                roomRoleActionGroup.AddAction(m_ModeratorAction);
                m_ModeratorAction.Checkable = true;
                m_ModeratorActionsMenu.AddAction(m_ModeratorAction);

                m_ParticipantAction = new QAction("Participant", this);
                roomRoleActionGroup.AddAction(m_ParticipantAction);
                m_ParticipantAction.Checkable = true;
                m_ModeratorActionsMenu.AddAction(m_ParticipantAction);

                m_VisitorAction = new QAction("Visitor", this);
                roomRoleActionGroup.AddAction(m_VisitorAction);
                m_VisitorAction.Checkable = true;
                m_ModeratorActionsMenu.AddAction(m_VisitorAction);

                m_ModeratorActionsMenu.AddSeparator();

                var mucKickAction = new QAction("Kick...", this);
                QObject.Connect(mucKickAction, Qt.SIGNAL("triggered()"), HandleMucKickActionTriggered);
                m_ModeratorActionsMenu.AddAction(mucKickAction);

                var mucBanAction = new QAction("Ban...", this);
                QObject.Connect(mucBanAction, Qt.SIGNAL("triggered()"), HandleMucBanActionTriggered);
                m_ModeratorActionsMenu.AddAction(mucBanAction);

                m_ModeratorActionsMenu.AddSeparator();

                m_ChangeAffiliationAction = new QAction("Change Affiliation...", this);
                QObject.Connect(m_ChangeAffiliationAction, Qt.SIGNAL("triggered()"), HandleChangeAffiliationTriggered);
                m_ModeratorActionsMenu.AddAction(m_ChangeAffiliationAction);

                m_ParticipantItemMenu.AddSeparator();
                m_ParticipantItemMenu.AddMenu(m_ModeratorActionsMenu);

                m_ParticipantItemMenu.AddSeparator();

                m_AddAsFriendAction = new QAction("Add as Friend", this);
                m_ParticipantItemMenu.AddAction(m_AddAsFriendAction);

                this.WindowTitle = mucHandler.Room.JID.User; // FIXME: Show only "user" in tab, show full room jid in title?
                this.WindowIcon = Gui.LoadIcon("internet-group-chat");
            } else {
                var chatHandler = (ChatHandler)handler;
                rightContainer.Hide();

                if (((ChatHandler)handler).IsMucMessage) {
                    this.WindowTitle = chatHandler.Jid.Resource;
                } else {
                    this.WindowTitle = chatHandler.Account.GetDisplayName(chatHandler.Jid);
                }
                this.WindowIcon = new QIcon((QPixmap)Synapse.Xmpp.AvatarManager.GetAvatar(chatHandler.Jid));
            }

            m_ConversationWidget.ChatHandler = handler;

            handler.ReadyChanged += HandleReadyChanged;

            splitter.SetStretchFactor(1, 0);
            splitter_2.SetStretchFactor(1, 0);

            KeyPressEater eater = new KeyPressEater(this);
            eater.KeyEvent += HandleKeyEvent;
            textEdit.InstallEventFilter(eater);

            QToolBar toolbar = new QToolBar(this);
            toolbar.IconSize = new QSize(16, 16);

            var formatMenuButton = new QToolButton(this);

            var formatMenu = new QMenu(this);
            QObject.Connect<QAction>(formatMenu, Qt.SIGNAL("triggered(QAction*)"), HandleFormatMenuActionTriggered);
            formatMenuButton.ToolButtonStyle = ToolButtonStyle.ToolButtonTextBesideIcon;
            formatMenuButton.Text = "Format";
            formatMenuButton.icon = Gui.LoadIcon("fonts", 16);
            formatMenuButton.PopupMode = QToolButton.ToolButtonPopupMode.InstantPopup;
            formatMenuButton.SetMenu(formatMenu);
            toolbar.AddWidget(formatMenuButton);

            m_BoldAction = new QAction(Gui.LoadIcon("format-text-bold", 16), "Bold", this);
            m_BoldAction.Shortcut = "Ctrl+B";
            m_BoldAction.Checkable = true;
            formatMenu.AddAction(m_BoldAction);

            m_ItalicAction = new QAction(Gui.LoadIcon("format-text-italic", 16), "Italic", this);
            m_ItalicAction.Shortcut = "Ctrl+I";
            m_ItalicAction.Checkable = true;
            formatMenu.AddAction(m_ItalicAction);

            m_UnderlineAction = new QAction(Gui.LoadIcon("format-text-underline", 16), "Underline", this);
            m_UnderlineAction.Shortcut = "Ctrl+U";
            m_UnderlineAction.Checkable = true;
            formatMenu.AddAction(m_UnderlineAction);

            m_StrikethroughAction = new QAction(Gui.LoadIcon("format-text-strikethrough", 16), "Strikethrough", this);
            m_StrikethroughAction.Shortcut = "Ctrl+S";
            m_StrikethroughAction.Checkable = true;
            formatMenu.AddAction(m_StrikethroughAction);

            formatMenu.AddSeparator();

            m_ClearFormattingAction = new QAction(Gui.LoadIcon("edit-clear", 16), "Clear Formatting", this);
            formatMenu.AddAction(m_ClearFormattingAction);

            var insertMenu = new QMenu(this);
            var insertMenuButton = new QToolButton(this);
            insertMenuButton.ToolButtonStyle = ToolButtonStyle.ToolButtonTextBesideIcon;
            insertMenuButton.Text = "Insert";
            insertMenuButton.icon = Gui.LoadIcon("image", 16);
            insertMenuButton.PopupMode = QToolButton.ToolButtonPopupMode.InstantPopup;
            insertMenuButton.SetMenu(insertMenu);
            toolbar.AddWidget(insertMenuButton);

            m_InsertPhotoAction = new QAction(Gui.LoadIcon("insert-image", 16), "Photo...", this);
            QObject.Connect(m_InsertPhotoAction, Qt.SIGNAL("triggered()"), HandleInsertImageActionTriggered);
            insertMenu.AddAction(m_InsertPhotoAction);

            m_InsertLinkAction = new QAction(Gui.LoadIcon("insert-link", 16), "Link...", this);
            QObject.Connect(m_InsertLinkAction, Qt.SIGNAL("triggered()"), HandleInsertLinkActionTriggered);
            insertMenu.AddAction(m_InsertLinkAction);

            foreach (IActionCodon node in AddinManager.GetExtensionNodes("/Synapse/QtClient/ChatWindow/InsertActions")) {
                insertMenu.AddAction((QAction)node.CreateInstance(this));
            }

            toolbar.AddSeparator();

            var activitiesMenu = new QMenu(this);
            var activitiesMenuButton = new QToolButton(this);
            activitiesMenuButton.ToolButtonStyle = ToolButtonStyle.ToolButtonTextBesideIcon;
            activitiesMenuButton.Text = "Activities";
            activitiesMenuButton.icon = Gui.LoadIcon("applications-games", 16); // FIXME: Not a good icon.
            activitiesMenuButton.PopupMode = QToolButton.ToolButtonPopupMode.InstantPopup;
            activitiesMenuButton.SetMenu(activitiesMenu);
            toolbar.AddWidget(activitiesMenuButton);

            m_InviteToMucAction = new QAction(Gui.LoadIcon("internet-group-chat", 16), "Invite to Conference...", this);
            QObject.Connect(m_InviteToMucAction, Qt.SIGNAL("triggered()"), HandleInviteToMucActionTriggered);
            activitiesMenu.AddAction(m_InviteToMucAction);
            activitiesMenu.AddSeparator();

            activitiesMenu.AddAction(Gui.LoadIcon("applications-graphics", 16), "Launch Whiteboard...");
            activitiesMenu.AddAction(Gui.LoadIcon("desktop", 16), "Share Desktop...");

            var spacerWidget = new QWidget(toolbar);
            spacerWidget.SetSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed);
            toolbar.AddWidget(spacerWidget);

            var toContainer = new QWidget(toolbar);
            var layout = new QHBoxLayout(toContainer);
            layout.SetContentsMargins(0, 0, 4, 0);

            m_ToComboBox = new QComboBox(toContainer);

            layout.AddWidget(new QLabel("To:", toContainer));
            layout.AddWidget(m_ToComboBox);

            QAction toWidgetAction = (QWidgetAction)toolbar.AddWidget(toContainer);

            m_ToComboBox.AddItem("Automatic", "auto");
            m_ToComboBox.InsertSeparator(1);

            ((QVBoxLayout)bottomContainer.Layout()).InsertWidget(0, toolbar);

            if (handler is ChatHandler) {
                var chatHandler = (ChatHandler)handler;
                handler.Account.Client.OnPresence += delegate(object sender, Presence pres) {
                    if (pres.From.Bare != chatHandler.Jid.Bare || pres.Priority == "-1") {
                        return;
                    }
                    QApplication.Invoke(delegate {
                        if (!String.IsNullOrEmpty(pres.From.Resource)) {
                            if (pres.Type == PresenceType.available) {
                                string text = String.Format("{0} ({1})", Helper.GetResourceDisplay(pres), Helper.GetPresenceDisplay(pres));
                                int i = m_ToComboBox.FindData(pres.From.Resource);
                                if (i == -1) {
                                    m_ToComboBox.AddItem(text, pres.From.Resource);
                                } else {
                                    m_ToComboBox.SetItemText(i, text);
                                }
                            } else if (pres.Type == PresenceType.unavailable) {
                                int i = m_ToComboBox.FindData(pres.From.Resource);
                                if (i > -1) {
                                    m_ToComboBox.RemoveItem(i);
                                    m_ToComboBox.CurrentIndex = 0;
                                }
                            }
                        }

                        if (chatHandler.IsMucMessage) {
                            toWidgetAction.Visible = false;
                        } else {
                            string title = null;
                            if (handler.Account.PresenceManager[pres.From.BareJID] == null) {
                                title = String.Format("{0} (Offline)", chatHandler.Account.GetDisplayName(chatHandler.Jid));
                            } else {
                                title = chatHandler.Account.GetDisplayName(chatHandler.Jid);
                            }
                            Gui.TabbedChatsWindow.SetTabTitle(this, title);
                        }
                    });
                };

                foreach (var presence in chatHandler.Account.PresenceManager.GetAll(chatHandler.Jid)) {
                    if (presence.Priority != "-1" && !String.IsNullOrEmpty(presence.From.Resource)) {
                        string text = String.Format("{0} ({1})", Helper.GetResourceDisplay(presence), Helper.GetPresenceDisplay(presence));
                        m_ToComboBox.AddItem(text, presence.From.Resource);
                    }
                }

                // FIXME: Make this a menu with "View Profile" and "View History".
                var viewProfileAction = new QAction(Gui.LoadIcon("info", 16), "View Profile", this);
                QObject.Connect(viewProfileAction, Qt.SIGNAL("triggered()"), HandleViewProfileActionTriggered);
                toolbar.AddAction(viewProfileAction);
            } else {
                toWidgetAction.Visible = false;
            }

            QObject.Connect<bool>(m_ConversationWidget.Page(), Qt.SIGNAL("loadFinished(bool)"), delegate (bool ok) {
                if (!ok) {
                    throw new Exception("Failed to load chat html.");
                }
                handler.NewContent += HandleNewContent;
                m_Handler.FireQueued();
            });

            var settings = ServiceManager.Get<SettingsService>();
            m_ConversationWidget.ShowHeader = settings.Get<bool>("MessageShowHeader");
            m_ConversationWidget.ShowUserIcons = settings.Get<bool>("MessageShowAvatars");
            m_ConversationWidget.LoadTheme(settings.Get<string>("MessageTheme"), settings.Get<string>("MessageThemeVariant"));
        }