+2001-08-25 John Levon <moz@compsoc.man.ac.uk>
+
+ * Dialogs.C: add URL
+
+ * QAbout.h:
+ * QCitation.h:
+ * QDocument.h:
+ * QIndex.C:
+ * Qt2Base.h:
+ * Qt2Base.C: add an updating_ variable to prevent
+ bc() breakage.
+
+ * QURL.h:
+ * QURL.C:
+ * QURLDialog.h:
+ * QURLDialog.C:
+ * ui/QURLDialog.ui: make alive again
+
+ * Qt2BC.C: make lineedits ReadOnly not disabled
+
+ * README: update
+
+ * ui/QCitationDialog.ui: small cleanups
+
+ * ui/QIndexDialog.ui: add a what's this
+
2001-08-24 John Levon <moz@compsoc.man.ac.uk>
* Dialogs.C: include the right files
#include "QAboutDialog.h"
#include "QCitationDialog.h"
#include "QIndexDialog.h"
+#include "QURLDialog.h"
// the controller interface
#include "QAbout.h"
#include "QSearch.h"
#include "QSplash.h"
#include "QTabularCreate.h"
+#include "QURL.h"
#include "QtLyXView.h"
#include "Dialogs.h"
#include "controllers/ControlCitation.h"
#include "controllers/ControlIndex.h"
#include "controllers/ControlSplash.h"
+#include "controllers/ControlUrl.h"
#if 0
#include "controllers/ControlCopyright.h"
#include "controllers/ControlCredits.h"
#include "controllers/ControlTabularCreate.h"
#include "controllers/ControlThesaurus.h"
#include "controllers/ControlToc.h"
-#include "controllers/ControlUrl.h"
#include "controllers/ControlVCLog.h"
#endif
add(new GUICitation<QCitation, Qt2BC>(*lv, *this));
add(new GUIAboutlyx<QAbout, Qt2BC>(*lv, *this));
add(new GUIIndex<QIndex, Qt2BC>(*lv, *this));
+ add(new GUIUrl<QURL, Qt2BC>(*lv, *this));
// reduce the number of connections needed in
// dialogs by a simple connection here.
/// not needed
virtual void apply() {}
/// not needed
- virtual void update() {}
+ virtual void update_contents() {}
// build the dialog
virtual void build();
};
}
-void QCitation::update()
+void QCitation::update_contents()
{
// Make the list of all available bibliography keys
bibkeys = biblio::getKeys(controller().bibkeysInfo());
setCiteButtons(OFF);
dialog_->textAfterED->setText(controller().params().getOptions().c_str());
-
- reset();
}
/// Hide the dialog.
virtual void hide();
/// Update dialog before/whilst showing it.
- virtual void update();
+ virtual void update_contents();
void updateBrowser(QListBox *, std::vector<string> const &) const;
///
bool const caseSensitive = searchCaseCB->isChecked();
- vector<string>::const_iterator const cit =
+ vector<string>::const_iterator cit =
biblio::searchKeys(theMap, form_->bibkeys, str,
- start, type, dir, caseSensitive);
+ start, type, dir, caseSensitive);
+ // FIXME: should work ...
if (cit == form_->bibkeys.end()) {
- return;
+ // not found. let's loop round
+ if (dir == biblio::FORWARD)
+ start = form_->bibkeys.begin();
+ else
+ start = form_->bibkeys.end();
+
+ cit = biblio::searchKeys(theMap, form_->bibkeys, str,
+ start, type, dir, caseSensitive);
+
+ if (cit == form_->bibkeys.end())
+ return;
}
int const found = int(cit - form_->bibkeys.begin());
}
-void QDocument::update()
+void QDocument::update_contents()
{
if (!dialog_.get())
return;
// /// Filter the inputs
// virtual bool input( FL_OBJECT *, long );
/// Update the dialog.
- virtual void update();
+ virtual void update_contents();
/// Apply from dialog
virtual void apply();
/// Cancel from dialog
}
-void QIndex::update()
+void QIndex::update_contents()
{
dialog_->keywordED->setText(controller().params().getContents().c_str());
- reset();
}
{
controller().params().setContents(dialog_->keywordED->text().latin1());
}
+
+
+bool QIndex::isValid()
+{
+ return !string(dialog_->keywordED->text()).empty();
+}
public:
QIndex(ControlIndex &);
+protected:
+ virtual bool isValid();
+
private:
/// Apply changes
virtual void apply();
/// update
- virtual void update();
+ virtual void update_contents();
/// build the dialog
virtual void build();
};
#include <config.h>
#include "QURLDialog.h"
-#include "QtLyXView.h"
-#include "BufferView.h"
-
-#include "Dialogs.h"
-#include "QURL.h"
-#include "gettext.h"
-#include "buffer.h"
-#include "lyxfunc.h"
-
-#include <qlineedit.h>
#include <qcheckbox.h>
#include <qpushbutton.h>
+#include <qlineedit.h>
+
+#include "ControlUrl.h"
+#include "Qt2BC.h"
+#include "QURL.h"
+#include "debug.h"
+#include "gettext.h"
-QURL::QURL(LyXView *v, Dialogs *d)
- : dialog_(0), lv_(v), d_(d), inset_(0), h_(0), u_(0), ih_(0)
-{
- // let the dialog be shown
- // This is a permanent connection so we won't bother
- // storing a copy because we won't be disconnecting.
- d->showUrl.connect(slot(this, &QURL::showUrl));
- d->createUrl.connect(slot(this, &QURL::createUrl));
-}
-
+typedef Qt2CB<ControlUrl, Qt2DB<QURLDialog> > base_class;
-QURL::~QURL()
+QURL::QURL(ControlUrl & c)
+ : base_class(c, _("URL"))
{
- delete dialog_;
}
-void QURL::showUrl(InsetCommand * const inset)
+void QURL::build()
{
- // FIXME: when could inset be 0 here ?
- if (inset==0)
- return;
+ dialog_.reset(new QURLDialog(this));
- inset_ = inset;
- readonly = lv_->buffer()->isReadonly();
- //ih_ = inset_->hide.connect(slot(this,&QURL::hide));
- params = inset->params();
-
- show();
+ bc().setOK(dialog_->okPB);
+ bc().setCancel(dialog_->closePB);
+ bc().addReadOnly(dialog_->urlED);
+ bc().addReadOnly(dialog_->nameED);
+ bc().addReadOnly(dialog_->hyperlinkCB);
}
-void QURL::createUrl(string const & arg)
+void QURL::update_contents()
{
- // we could already be showing a URL, clear it out
- if (inset_)
- close();
-
- readonly = lv_->buffer()->isReadonly();
- params.setFromString(arg);
- show();
-}
-
-
-void QURL::update()
-{
- dialog_->urlED->setText(params.getContents().c_str());
- dialog_->nameED->setText(params.getOptions().c_str());
-
- if (params.getCmdName()=="url")
- dialog_->hyperlinkCB->setChecked(false);
- else
- dialog_->hyperlinkCB->setChecked(true);
-
- if (readonly) {
- dialog_->nameED->setFocusPolicy(QWidget::NoFocus);
- dialog_->urlED->setFocusPolicy(QWidget::NoFocus);
- dialog_->okPB->setEnabled(false);
- dialog_->cancelPB->setText(_("Close"));
- dialog_->hyperlinkCB->setEnabled(false);
- } else {
- dialog_->nameED->setFocusPolicy(QWidget::StrongFocus);
- dialog_->urlED->setFocusPolicy(QWidget::StrongFocus);
- dialog_->urlED->setFocus();
- dialog_->okPB->setEnabled(true);
- dialog_->cancelPB->setText(_("Cancel"));
- dialog_->hyperlinkCB->setEnabled(true);
- }
+ lyxerr << "update_contents URL" << std::endl;
+ lyxerr << dialog_->okPB << std::endl;
+ dialog_->urlED->setText(controller().params().getContents().c_str());
+ dialog_->nameED->setText(controller().params().getOptions().c_str());
+ dialog_->hyperlinkCB->setChecked(controller().params().getCmdName() != "url");
}
void QURL::apply()
{
- if (readonly)
- return;
-
- params.setContents(dialog_->urlED->text().latin1());
- params.setOptions(dialog_->nameED->text().latin1());
+ controller().params().setContents(dialog_->urlED->text().latin1());
+ controller().params().setOptions(dialog_->nameED->text().latin1());
if (dialog_->hyperlinkCB->isChecked())
- params.setCmdName("htmlurl");
+ controller().params().setCmdName("htmlurl");
else
- params.setCmdName("url");
-
- if (inset_ != 0) {
- if (params != inset_->params()) {
- inset_->setParams(params);
- lv_->view()->updateInset(inset_, true);
- }
- } else
- lv_->getLyXFunc()->dispatch(LFUN_INSERT_URL, params.getAsString().c_str());
+ controller().params().setCmdName("url");
}
-
-
-void QURL::show()
-{
- if (!dialog_)
- dialog_ = new QURLDialog(this, 0, _("LyX: Url"), false);
-
- if (!dialog_->isVisible()) {
- h_ = d_->hideBufferDependent.connect(slot(this, &QURL::hide));
- //u_ = d_->updateBufferDependent.connect(slot(this, &QURL::update));
- }
- dialog_->raise();
- dialog_->setActiveWindow();
-
- update();
- dialog_->show();
-}
-
-void QURL::close()
+bool QURL::isValid()
{
- h_.disconnect();
- u_.disconnect();
- ih_.disconnect();
- inset_ = 0;
-}
+ string const u(dialog_->urlED->text().latin1());
+ string const n(dialog_->nameED->text().latin1());
-
-void QURL::hide()
-{
- dialog_->hide();
- close();
-}
+ return !u.empty() && !n.empty();
+}
-// -*- C++ -*-
/**
* \file QURL.h
* Copyright 2001 the LyX Team
* Read the file COPYING
*
- * \author John Levon <moz@compsoc.man.ac.uk>
- * \author Kalle Dalheimer <kalle@klaralvdalens-datakonsult.se>
+ * \author John Levon
*/
#ifndef QURL_H
#define QURL_H
-#include "DialogBase.h"
-#include "LString.h"
-#include "boost/utility.hpp"
-#include "insets/inseturl.h"
-
-class Dialogs;
-class LyXView;
+#include "Qt2Base.h"
+
+class ControlUrl;
class QURLDialog;
-class QURL : public DialogBase {
+class QURL :
+ public Qt2CB<ControlUrl, Qt2DB<QURLDialog> >
+{
+ friend class QURLDialog;
public:
- QURL(LyXView *, Dialogs *);
- ~QURL();
+ QURL(ControlUrl & c);
- /// Apply changes
- void apply();
- /// close the connections
- void close();
+protected:
+ virtual bool isValid();
private:
- /// Create the dialog if necessary, update it and display it.
- void show();
- /// Hide the dialog.
- void hide();
- /// Update the dialog.
- void update();
-
- /// create a URL inset
- void createUrl(string const &);
- /// edit a URL inset
- void showUrl(InsetCommand * const);
-
- /// Real GUI implementation.
- QURLDialog * dialog_;
-
- /// the LyXView we belong to
- LyXView * lv_;
-
- /** Which Dialogs do we belong to?
- Used so we can get at the signals we have to connect to.
- */
- Dialogs * d_;
- /// pointer to the inset if any
- InsetCommand * inset_;
- /// insets params
- InsetCommandParams params;
- /// is the inset we are reading from a readonly buffer
- bool readonly;
-
- /// Hide connection.
- SigC::Connection h_;
- /// Update connection.
- SigC::Connection u_;
- /// Inset hide connection.
- SigC::Connection ih_;
+ /// apply dialog
+ virtual void apply();
+ /// build dialog
+ virtual void build();
+ /// update dialog
+ virtual void update_contents();
};
#endif // QURL_H
#include <config.h>
+#include <qpushbutton.h>
+
#include "QURLDialog.h"
#include "Dialogs.h"
#include "QURL.h"
-QURLDialog::QURLDialog(QURL * form, QWidget * parent, const char * name, bool modal, WFlags fl)
- : QURLDialogBase(parent, name, modal, fl),
+QURLDialog::QURLDialog(QURL * form)
+ : QURLDialogBase(0, 0, false, 0),
form_(form)
{
+ connect(okPB, SIGNAL(clicked()),
+ form_, SLOT(slotOK()));
+ connect(closePB, SIGNAL(clicked()),
+ form_, SLOT(slotClose()));
}
}
-void QURLDialog::apply_adaptor()
+void QURLDialog::changed_adaptor()
{
- form_->apply();
- form_->close();
- hide();
+ form_->changed();
}
-void QURLDialog::close_adaptor()
-{
- form_->close();
- hide();
-}
-
-
void QURLDialog::closeEvent(QCloseEvent * e)
{
- form_->close();
+ form_->slotWMHide();
e->accept();
}
{ Q_OBJECT
public:
- QURLDialog(QURL * form, QWidget * parent = 0, const char * name = 0, bool modal = FALSE, WFlags fl = 0);
+ QURLDialog(QURL * form);
~QURLDialog();
public slots:
- void apply_adaptor();
- void close_adaptor();
+ void changed_adaptor();
protected:
void closeEvent(QCloseEvent *);
#include "debug.h"
#include <qbutton.h>
+#include <qlineedit.h>
Qt2BC::Qt2BC(string const & cancel, string const & close)
: GuiBC<QButton, QWidget>(cancel, close)
void Qt2BC::setButtonEnabled(QButton * obj, bool enabled)
{
+ lyxerr << "Qt2BC: setting button "
+ << obj << " to " << enabled << std::endl;
+
obj->setEnabled(enabled);
}
void Qt2BC::setWidgetEnabled(QWidget * obj, bool enabled)
{
- obj->setEnabled(enabled);
+ lyxerr << "Qt2BC: setting "
+ << obj << " to " << enabled << std::endl;
+
+ // yuck, rtti, but the user comes first
+ if (obj->inherits("QLineEdit")) {
+ QLineEdit * le(static_cast<QLineEdit*>(obj));
+ le->setReadOnly(enabled);
+ } else {
+ obj->setEnabled(enabled);
+ }
+
QWidget::FocusPolicy const p =
(enabled) ? QWidget::StrongFocus : QWidget::NoFocus;
obj->setFocusPolicy(p);
#include "support/LAssert.h"
Qt2Base::Qt2Base(ControlButtons & c, QString const & t)
- : ViewBC<Qt2BC>(c), title_(t)
+ : ViewBC<Qt2BC>(c), updating_(false), title_(t)
{}
}
-void Qt2Base::reset()
-{
- qApp->processEvents();
-}
-
-
void Qt2Base::hide()
{
if (form() && form()->isVisible())
void Qt2Base::changed()
{
+ lyxerr << "got changed() during updating:" << updating_ << std::endl;
+
+ if (updating_)
+ return;
+
if (isValid())
bc().valid();
else
#ifndef QT2BASE_H
#define QT2BASE_H
-class QDialog;
-
#include <config.h>
#include <qfont.h>
+#include <qdialog.h>
#include <qobject.h>
+#include <qapplication.h>
#ifdef __GNUG__
#pragma interface
virtual void hide();
/// Create the dialog if necessary, update it and display it.
virtual void show();
- /// reset after an update
- virtual void reset();
+ /// update the dialog's contents
+ virtual void update_contents() = 0;
/// the dialog has changed contents
virtual void changed();
/// is the dialog currently valid ?
virtual bool isValid();
+ /// are we updating ?
+ bool updating_;
+
protected slots:
// dialog closed from WM
void slotWMHide();
class Qt2DB: public Qt2Base
{
protected:
- Qt2DB(ControlButtons &, const QString&);
+ Qt2DB(ControlButtons &, const QString &);
+
+ /// update the dialog
+ virtual void update();
/// Pointer to the actual instantiation of the Qt dialog
- virtual QDialog* form() const;
+ virtual QDialog * form() const;
/// Real GUI implementation.
boost::scoped_ptr<Dialog> dialog_;
template <class Dialog>
-Qt2DB<Dialog>::Qt2DB(ControlButtons & c, const QString& t)
+Qt2DB<Dialog>::Qt2DB(ControlButtons & c, const QString & t)
: Qt2Base(c, t)
{}
template <class Dialog>
-QDialog* Qt2DB<Dialog>::form() const
+QDialog * Qt2DB<Dialog>::form() const
{
return dialog_.get();
}
+template <class Dialog>
+void Qt2DB<Dialog>::update()
+{
+ form()->setUpdatesEnabled(false);
+
+ // this is tricky. First we process pending events
+ // as a result of the bc() state change (if any).
+ // then we lock out any bc() changes as a result of
+ // "innocent" updates during update_contents()
+ // then we enable normal behaviour again.
+ qApp->processEvents();
+ updating_ = true;
+ update_contents();
+ qApp->processEvents();
+ updating_ = false;
+
+ form()->setUpdatesEnabled(true);
+ form()->update();
+}
+
+
template <class Controller, class Base>
class Qt2CB: public Base
{
then remember to call form_->changed() at the end (if it has changed !)
Every non-trivial widget should have a tooltip. If you don't know
-what to write, write "FIXME", and it can fixed later.
+what to write, write "FIXME", and it can fixed later. Don't be afraid
+to use QWhatsThis too (e.g. the index dialog)
If necessary, you should override Qt2Base::isValid() for determining the validity
of the current dialog's contents.
OK/Apply/Restore/Close should be connected in the derived class's constructor
to call form_->slotOK() etc. Refer to close/cancel as close in the source.
-Every overridden update() must call reset() to ensure the beginning state of the dialog
-is correct !
-
+Override update_contents() to update the dialog, not update()
+
+Never call buttoncontroller functions directly from dialogs. In general, you
+should use Qt2Base::changed() in all circumstances. However, if you must call
+the buttoncontroller, make sure to respect Qt2Base::updating_
+
Don't #undef emit - #include "QtLyXView.h" instead
Naming conventions
<rect>
<x>0</x>
<y>0</y>
- <width>439</width>
+ <width>427</width>
<height>585</height>
</rect>
</property>
<name>pixmap</name>
<pixmap>image0</pixmap>
</property>
+ <property>
+ <name>toolTip</name>
+ <string>Add the selected citation</string>
+ </property>
</widget>
<widget>
<class>QPushButton</class>
<name>pixmap</name>
<pixmap>image1</pixmap>
</property>
+ <property>
+ <name>toolTip</name>
+ <string>Remove the selected citation</string>
+ </property>
</widget>
<widget>
<class>QPushButton</class>
<name>pixmap</name>
<pixmap>image2</pixmap>
</property>
+ <property>
+ <name>toolTip</name>
+ <string>Move the selected citation up</string>
+ </property>
</widget>
<widget>
<class>QPushButton</class>
<name>pixmap</name>
<pixmap>image3</pixmap>
</property>
+ <property>
+ <name>toolTip</name>
+ <string>Move the selected citation down</string>
+ </property>
</widget>
</vbox>
</widget>
</property>
<property>
<name>toolTip</name>
- <string>Reference keys available</string>
+ <string>Available citation keys</string>
</property>
</widget>
<widget row="1" column="0" >
</property>
<property>
<name>toolTip</name>
- <string>Keys currently selected</string>
+ <string>Citations currently selected</string>
</property>
</widget>
</grid>
</property>
<property>
<name>toolTip</name>
- <string>Reference entry text</string>
+ <string>Citation entry</string>
</property>
</widget>
<spacer>
<name>name</name>
<cstring>searchED</cstring>
</property>
+ <property>
+ <name>toolTip</name>
+ <string>Search the available citations</string>
+ </property>
</widget>
<widget>
<class>QLayoutWidget</class>
<name>text</name>
<string>Regular E&xpression</string>
</property>
+ <property>
+ <name>toolTip</name>
+ <string>Interpret search entry as a regular expression</string>
+ </property>
</widget>
<spacer>
<property>
<name>text</name>
<string>&Case sensitive</string>
</property>
+ <property>
+ <name>toolTip</name>
+ <string>Make the search case-sensitive</string>
+ </property>
</widget>
<spacer>
<property>
<name>name</name>
<cstring>citationStyleCO</cstring>
</property>
+ <property>
+ <name>toolTip</name>
+ <string>FIXME</string>
+ </property>
</widget>
<spacer>
<property>
<slot access="protected">slotSearchTypeSelected(bool)</slot>
<slot access="protected">slotUpClicked()</slot>
</connections>
+<tabstops>
+ <tabstop>addPB</tabstop>
+ <tabstop>delPB</tabstop>
+ <tabstop>upPB</tabstop>
+ <tabstop>downPB</tabstop>
+ <tabstop>citeLB</tabstop>
+ <tabstop>bibLB</tabstop>
+ <tabstop>searchED</tabstop>
+ <tabstop>searchTypeCB</tabstop>
+ <tabstop>searchCaseCB</tabstop>
+ <tabstop>previousPB</tabstop>
+ <tabstop>nextPB</tabstop>
+ <tabstop>citationStyleCO</tabstop>
+ <tabstop>textBeforeED</tabstop>
+ <tabstop>textAfterED</tabstop>
+ <tabstop>restorePB</tabstop>
+ <tabstop>okPB</tabstop>
+ <tabstop>applyPB</tabstop>
+ <tabstop>closePB</tabstop>
+</tabstops>
</UI>
<rect>
<x>0</x>
<y>0</y>
- <width>204</width>
+ <width>197</width>
<height>82</height>
</rect>
</property>
<name>toolTip</name>
<string>Index entry</string>
</property>
+ <property>
+ <name>whatsThis</name>
+ <string>The format of the entry in the index.
+
+An entry can be specified as a sub-entry of
+another with "!" :
+
+cars!mileage
+
+You can cross-refer to another entry like so :
+
+cars!mileage|see{economy}
+
+For further details refer to the local LaTeX
+documentation.</string>
+ </property>
</widget>
</hbox>
</widget>
<class>QPushButton</class>
<property stdset="1">
<name>name</name>
- <cstring>cancelPB</cstring>
+ <cstring>closePB</cstring>
</property>
<property stdset="1">
<name>text</name>
- <string>&Cancel</string>
+ <string>&Close</string>
</property>
</widget>
</hbox>
</widget>
<connections>
<connection>
- <sender>okPB</sender>
- <signal>clicked()</signal>
+ <sender>urlED</sender>
+ <signal>textChanged(const QString&)</signal>
<receiver>QURLDialogBase</receiver>
- <slot>apply_adaptor()</slot>
+ <slot>changed_adaptor()</slot>
</connection>
<connection>
- <sender>cancelPB</sender>
+ <sender>hyperlinkCB</sender>
<signal>clicked()</signal>
<receiver>QURLDialogBase</receiver>
- <slot>close_adaptor()</slot>
+ <slot>changed_adaptor()</slot>
+ </connection>
+ <connection>
+ <sender>nameED</sender>
+ <signal>textChanged(const QString&)</signal>
+ <receiver>QURLDialogBase</receiver>
+ <slot>changed_adaptor()</slot>
</connection>
- <slot access="public">apply_adaptor()</slot>
- <slot access="public">close_adaptor()</slot>
+ <slot access="public">changed_adaptor()</slot>
</connections>
</UI>