/* * opt_messages.cpp - options tab for messages options * Copyright (C) 2005 Maciej Niedzielski * * 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. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "opt_messages.h" #include "opt_messages-ui.h" #include "common.h" #include "templates.h" #include "multilineinput.h" #include #include #include #include #include #include #include //---------------------------------------------------------------------------- // ListBoxFortune //---------------------------------------------------------------------------- /*! \class ListBoxFortune ListBoxFortune is a QListBoxText descendent class used to display multiline fortune text in a single line. Use setFortune()/getFortune() methods instead of setText()/getText(). */ class ListBoxFortune : public QListBoxText { public: /*! Constructs a new fortune list item with \a aFortune fortune. */ ListBoxFortune(const QString &aFortune) : QListBoxText(singleLine(aFortune)), fortune(aFortune) { } /*! Changes fortune contained in this list item. This method will also change item's text (used to draw this item) with a single-line representation of the fortune, provided by singleLine() method. */ void setFortune(const QString &f) { fortune = f; setText(singleLine(f)); } /*! Retrieves multi-line fortune stored in this item. */ QString getFortune() { return fortune; } protected: /*! Prepares fortune \a f to be displayed as a single-line list item by replacing new line character with "\\" string and tab character with a space. */ QString singleLine(const QString &f) { QString sl = f; sl.replace(QRegExp("\\n"), "\\"); sl.replace(QRegExp("\\t"), " "); return sl; } private: QString fortune; }; //---------------------------------------------------------------------------- // FortunesListBox //---------------------------------------------------------------------------- /*! \class FortunesListBox opt_messages.h \brief A list box class designed to represent fortunes. FortunesListBox class is a QListBox derived class, designed to manage a list of ListBoxFortune items. With this class you may display multi-line fortunes using single-line items (new line characters are replaced by "\". */ /*! Constructs a new fortunes list box with parent \a parent, name \a name and flags \a f. */ FortunesListBox::FortunesListBox(QWidget* parent, const char* name, WFlags f) : QListBox(parent, name, f) { } /*! Inserts \a fortune as a new fortune. */ void FortunesListBox::insertFortune(const QString &fortune) { insertItem(new ListBoxFortune(fortune)); } /*! Changes fortune with is \a id. */ void FortunesListBox::updateFortune(const QString &fortune, int id) { ((ListBoxFortune*)item(id))->setFortune(fortune); updateItem(id); } /*! Retrieves fortune from item with id \a id. */ QString FortunesListBox::getFortune(int id) { return ((ListBoxFortune*)item(id))->getFortune(); } //---------------------------------------------------------------------------- // QuoteHeaderPopup //---------------------------------------------------------------------------- /*! \class QuoteHeaderPopup QuoteHeaderPopup is a class representing a popup menu with template items which may be used in quote header template. */ class QuoteHeaderPopup : public TemplatePopup { Q_OBJECT public: QuoteHeaderPopup(QTextEdit *edt, QWidget *parent = 0, const char *name = 0) : TemplatePopup(edt, parent, name) { insertTemplateItem(tr("Sender's bare jid"), "Sender.jid.bare"); insertTemplateItem(tr("Sender's full jid"), "Sender.jid.full"); insertTemplateItem(tr("Sender's nick"), "Sender.nick"); insertTemplateItem(tr("Sender's nick or jid"), "Sender.nick-jid"); insertSeparator(); insertTemplateItem(tr("Your bare jid"), "Me.jid.bare"); insertTemplateItem(tr("Your full jid"), "Me.jid.full"); insertTemplateItem(tr("Your nick"), "Me.nick"); insertTemplateItem(tr("Your nick or jid"), "Me.nick-jid"); insertSeparator(); insertTemplateItem(tr("Message date and time"), "Message.DateTime"); insertTemplateItem(tr("Message subject"), "Message.subject"); insertSeparator(); insertTemplateItem(tr("\'<\' character"), ""); } }; //---------------------------------------------------------------------------- // SignaturePopup //---------------------------------------------------------------------------- /*! \class SignaturePopup SignaturePopup is a class representing a popup menu with template items which may be used in signature template. */ class SignaturePopup : public TemplatePopup { Q_OBJECT public: SignaturePopup(QTextEdit *edt, QWidget *parent = 0, const char *name = 0) : TemplatePopup(edt, parent, name) { insertTemplateItem(tr("Fortune"), "Fortune"); insertSeparator(); insertTemplateItem(tr("\'<\' character"), ""); } }; //---------------------------------------------------------------------------- // OptionsTabMessages //---------------------------------------------------------------------------- OptionsTabMessages::OptionsTabMessages(QObject *parent) : OptionsTab(parent, "messages", "", tr("Messages"), tr("Advanced options for quoting and replying messages"), "psi/sendMessage") { w = 0; o = new Options; } OptionsTabMessages::~OptionsTabMessages() { delete o; } QWidget *OptionsTabMessages::widget() { if ( w ) return 0; w = new OptMessagesUI(); OptMessagesUI *d = (OptMessagesUI *)w; // signature QWhatsThis::add(d->ck_signature, tr("Check this option if you want to include signature in messages that you send.")); QWhatsThis::add(d->pb_insSignature, tr("Press this button if you want to add special symbols to your signature.")); QWhatsThis::add(d->te_signature, tr("You may edit your signature here.")); QWhatsThis::add(d->ck_signatureAutoDelimiter, tr("Check this option if you want Psi to automatically prepend your signature with" " a signature delimiter ('-- ').")); QWhatsThis::add(d->pb_fortuneNew, tr("Press this button to create a new fortune.")); QWhatsThis::add(d->pb_fortuneDelete, tr("Press this button to delete a fortune.")); QWhatsThis::add(d->lb_fortunes, tr("Use this list to select a fortune" " to view or edit in the box to the bottom.")); QWhatsThis::add(d->te_fortune, tr("Here you may edit the fortune selected in the list above.")); // quote & reply QWhatsThis::add(d->ck_headerQuote, tr("Check this option if you want to include a header when quoting a message.")); QWhatsThis::add(d->pb_insQuote, tr("Press this button if you want to add special symbols to your header.")); QWhatsThis::add(d->te_headerQuote, tr("You may edit your header here.")); QWhatsThis::add(d->ck_headerReply, tr("Check this option if you want to include a header when replying a message.")); QWhatsThis::add(d->pb_insReply, tr("Press this button if you want to add special symbols to your header.")); QWhatsThis::add(d->te_headerReply, tr("You may edit your header here.")); // forward QWhatsThis::add(d->ck_headerForward, tr("Check this option if you want to include a header when forwarding a message.")); QWhatsThis::add(d->pb_insForward, tr("Press this button if you want to add special symbols to your header.")); QWhatsThis::add(d->te_headerForward, tr("You may edit your header here.")); // misc QWhatsThis::add(d->ck_quoteEmptyLines, tr("Uncheck this option if you don't want empty lines to be" " prepended with '>' character when quoting.")); QWhatsThis::add(d->ck_stripEmptyLines, tr("Check this option if you want to remove empty lines at the beginning" " and ending of a message when quoting it.")); QWhatsThis::add(d->ck_removeSignature, tr("Check this option if you don't want to include sender's signature" " in the quoted text.")); QWhatsThis::add(d->sb_wrapAtColumn, tr("Here you may change the maximum length of a line in the quoted message.")); QWhatsThis::add(d->ck_hideQuoteBtn, tr("Check this option if you want to have only 'Reply' button, instead of 'Quote'" " and 'Reply'. In one-button mode, you may change 'Reply' button to work" " as 'Quote' by changing your default way of replying.")); QWhatsThis::add(d->ck_defaultReplyWithoutQuoting, tr("This option is used to determine your default way of replying a message." " Default way of replying if used by Ctrl+R hotkey." " In addition, this action is invoked by 'Reply' button when 'Quote' button is hidden.")); QWhatsThis::add(d->ck_hideChatBtn, tr("Check this option to hide 'Chat' button.")); QWhatsThis::add(d->ck_showReplyInAuthRequests, tr("Check this option if you want to have replying buttons in authorization request windows.")); QWhatsThis::add(d->ck_cursorAtTop, tr("Check this option if you want cursor to be at the top of the edit.")); // don't worry: these menus are deleted in OptMessagesUI::destroy() d->pb_insForward->setPopup(new QuoteHeaderPopup(d->te_headerForward)); d->pb_insReply->setPopup(new QuoteHeaderPopup(d->te_headerReply)); d->pb_insQuote->setPopup(new QuoteHeaderPopup(d->te_headerQuote)); d->pb_insSignature->setPopup(new SignaturePopup(d->te_signature)); // tags for header template TemplateEditHighlighter::TagsVector headerTags; headerTags.push_back("Sender.jid.bare"); headerTags.push_back("Sender.jid.full"); headerTags.push_back("Sender.nick"); headerTags.push_back("Sender.nick-jid"); headerTags.push_back("Me.jid.bare"); headerTags.push_back("Me.jid.full"); headerTags.push_back("Me.nick"); headerTags.push_back("Me.nick-jid"); headerTags.push_back("Message.DateTime"); headerTags.push_back("Message.subject"); headerTags.push_back(""); // tags for signature template TemplateEditHighlighter::TagsVector signatureTags; signatureTags.push_back("Fortune"); signatureTags.push_back(""); // syntax highlighters are deleted by edit boxes new TemplateEditHighlighter(d->te_headerForward, headerTags); new TemplateEditHighlighter(d->te_headerReply, headerTags); new TemplateEditHighlighter(d->te_headerQuote, headerTags); new TemplateEditHighlighter(d->te_signature, signatureTags); // fortunes editing d->pb_fortuneNew->setEnabled(TRUE); d->pb_fortuneDelete->setEnabled(FALSE); d->te_fortune->setEnabled(FALSE); connect(d->pb_fortuneNew, SIGNAL(clicked()), SLOT(newFortune())); connect(d->pb_fortuneDelete, SIGNAL(clicked()), SLOT(removeFortune())); connect(d->lb_fortunes, SIGNAL(highlighted(int)), SLOT(selectFortune(int))); connect(d->te_fortune, SIGNAL(textChanged()), SLOT(changeFortune())); return w; } void OptionsTabMessages::applyOptions(Options *opt) { if ( !w ) return; OptMessagesUI *d = (OptMessagesUI *)w; opt->useQuoteHeaderForward = d->ck_headerForward->isChecked(); opt->quoteHeaderForward = d->te_headerForward->text(); opt->useQuoteHeaderQuote = d->ck_headerQuote->isChecked(); opt->quoteHeaderQuote = d->te_headerQuote->text(); opt->useQuoteHeaderReply = d->ck_headerReply->isChecked(); opt->quoteHeaderReply = d->te_headerReply->text(); opt->useMessageSignature = d->ck_signature->isChecked(); opt->messageSignature = d->te_signature->text(); opt->autoMessageSignatureDelimiter = d->ck_signatureAutoDelimiter->isChecked(); opt->fortunes = o->fortunes; opt->wrapAtColumn = d->sb_wrapAtColumn->value(); opt->quoteEmptyLines = d->ck_quoteEmptyLines->isChecked(); opt->stripEmptyLines = d->ck_stripEmptyLines->isChecked(); opt->removeSignature = d->ck_removeSignature->isChecked(); opt->hideQuoteBtn = d->ck_hideQuoteBtn->isChecked(); opt->defaultReplyWithoutQuoting = d->ck_defaultReplyWithoutQuoting->isChecked(); opt->hideChatBtn = d->ck_hideChatBtn->isChecked(); opt->replyInAuthReq = d->ck_showReplyInAuthRequests->isChecked(); opt->cursorAtTopInEventDlg = d->ck_cursorAtTop->isChecked(); } void OptionsTabMessages::restoreOptions(const Options *opt) { if ( !w ) return; OptMessagesUI *d = (OptMessagesUI *)w; d->ck_headerForward->setChecked( true ); d->ck_headerForward->setChecked( opt->useQuoteHeaderForward ); d->te_headerForward->setText( opt->quoteHeaderForward ); d->ck_headerQuote->setChecked( true ); d->ck_headerQuote->setChecked( opt->useQuoteHeaderQuote ); d->te_headerQuote->setText( opt->quoteHeaderQuote ); d->ck_headerReply->setChecked( true ); d->ck_headerReply->setChecked( opt->useQuoteHeaderReply ); d->te_headerReply->setText( opt->quoteHeaderReply ); d->ck_signature->setChecked( true ); d->ck_signature->setChecked( opt->useMessageSignature ); d->te_signature->setText( opt->messageSignature ); d->ck_signatureAutoDelimiter->setChecked( opt->autoMessageSignatureDelimiter ); o->fortunes = opt->fortunes; d->lb_fortunes->clear(); for ( QValueVector::ConstIterator it = o->fortunes.begin(); it != o->fortunes.end(); ++it ) { d->lb_fortunes->insertFortune(*it); } if ( d->lb_fortunes->count() >= 1 ) d->lb_fortunes->setSelected(0, TRUE); d->sb_wrapAtColumn->setValue( opt->wrapAtColumn ); d->ck_quoteEmptyLines->setChecked( opt->quoteEmptyLines ); d->ck_stripEmptyLines->setChecked( opt->stripEmptyLines ); d->ck_removeSignature->setChecked( opt->removeSignature ); d->ck_hideQuoteBtn->setChecked( opt->hideQuoteBtn ); d->ck_defaultReplyWithoutQuoting->setChecked( opt->defaultReplyWithoutQuoting ); d->ck_hideChatBtn->setChecked( opt->hideChatBtn ); d->ck_showReplyInAuthRequests->setChecked( opt->replyInAuthReq ); d->ck_cursorAtTop->setChecked( opt->cursorAtTopInEventDlg ); } void OptionsTabMessages::setData(PsiCon *, QWidget *parentDialog) { parentWidget = parentDialog; } void OptionsTabMessages::selectFortune(int x) { OptMessagesUI *d = (OptMessagesUI *)w; disconnect(d->te_fortune, SIGNAL(textChanged()), 0, 0); if ( x == -1 ) { d->pb_fortuneDelete->setEnabled(false); d->te_fortune->setText(""); d->te_fortune->setEnabled(false); connect(d->te_fortune, SIGNAL(textChanged()), SLOT(changeFortune())); return; } d->pb_fortuneDelete->setEnabled(true); d->te_fortune->setText(d->lb_fortunes->getFortune(x)); d->te_fortune->setEnabled(true); connect(d->te_fortune, SIGNAL(textChanged()), SLOT(changeFortune())); } void OptionsTabMessages::newFortune() { OptMessagesUI *d = (OptMessagesUI *)w; QString text; while(1) { bool ok = FALSE; text = MultiLineInputDialog::getMultiLineText( CAP(tr("New Fortune")), tr("Please enter the new fortune:"), true, text, &ok, parentWidget); if(!ok) return; if(text.isEmpty()) QMessageBox::information(parentWidget, tr("Error"), tr("Can't create a blank fortune!")); else if(qFind(o->fortunes.begin(), o->fortunes.end(), text) != o->fortunes.end()) QMessageBox::information(parentWidget, tr("Error"), tr("This fortune already exists!")); else break; } o->fortunes.push_back(text); d->lb_fortunes->insertFortune(text); d->lb_fortunes->setSelected(d->lb_fortunes->count()-1, TRUE); d->lb_fortunes->ensureCurrentVisible(); d->te_fortune->setFocus(); emit dataChanged(); } void OptionsTabMessages::removeFortune() { OptMessagesUI *d = (OptMessagesUI *)w; int id = d->lb_fortunes->currentItem(); if(id == -1) return; emit dataChanged(); QValueVector::Iterator it = o->fortunes.begin(); for ( int i = 0; it != o->fortunes.end() && i != id; ++i, ++it) ; o->fortunes.erase(it); d->lb_fortunes->removeItem(id); // select a new entry if possible if(d->lb_fortunes->count() == 0) { selectFortune(-1); return; } if(id >= (int)d->lb_fortunes->count()) id = d->lb_fortunes->count()-1; d->lb_fortunes->setSelected(id, TRUE); selectFortune(id); } void OptionsTabMessages::changeFortune() { OptMessagesUI *d = (OptMessagesUI *)w; int id = d->lb_fortunes->currentItem(); if(id == -1) return; int para, index; d->te_fortune->getCursorPosition(¶, &index); const QString text = d->te_fortune->text(); o->fortunes[id] = text; d->lb_fortunes->updateFortune(text, id); d->te_fortune->setFocus(); d->te_fortune->setCursorPosition(para, index); emit dataChanged(); } #include "opt_messages.moc"