On Dienstag, 10. September 2013 23:36:13 CEST, Jan Kundrát wrote:
Could be, but IIRC I set that already. I suspect that this
happened because the QFormLayout works on "fixed rows" and is
not designed to "resize stuff that can be resized to better
utilize the space".
Ahhh, the beloved QFormLayout... *sigh* ... *HUGESIGH* .... **VERYHUGESIGH**
Ok, the attached patch omits any attempt to use a scrollarea since that will
necessarily break the formlaout alignment.
Instead it adds a scrollbar to perform discrete "scrolling" in recipients.
Because of the ... specialities of QFormLayout this means to play on layout
membership and focus preservation, but in general it should work.
Stupid things
- the discrete scrolling
- the scrollbar popping up. that's a(n Apple ;-) HIG violation, but since the regular
case will be < 5 recpts. XOR > 5 recpts., i'd be willing to take that.
Atm. i've no good idea on how to provide continuous scrolling on that approach,
but as long as one entry keeps the focus, discrete scrolling not that bad
either.
Eventually we could have a fade in of the new visible element.
Cheers,
Thomas
diff --git a/src/Gui/ComposeWidget.cpp b/src/Gui/ComposeWidget.cpp
index 7eef98f..b0b01f7 100644
--- a/src/Gui/ComposeWidget.cpp
+++ b/src/Gui/ComposeWidget.cpp
@@ -56,7 +56,7 @@
namespace
{
-enum { OFFSET_OF_FIRST_ADDRESSEE = 1 };
+enum { OFFSET_OF_FIRST_ADDRESSEE = 1, MAX_VISIBLE_RECIPIENTS = 4 };
}
namespace Gui
@@ -65,6 +65,7 @@ namespace Gui
ComposeWidget::ComposeWidget(MainWindow *mainWindow, QSettings *settings, MSA::MSAFactory *msaFactory) :
QWidget(0, Qt::Window),
ui(new Ui::ComposeWidget),
+ m_lastFocusedRecipient(NULL),
m_sentMail(false),
m_messageUpdated(false),
m_messageEverEdited(false),
@@ -101,6 +102,13 @@ ComposeWidget::ComposeWidget(MainWindow *mainWindow, QSettings *settings, MSA::M
m_recipientListUpdateTimer->setInterval(250);
connect(m_recipientListUpdateTimer, SIGNAL(timeout()), SLOT(updateRecipientList()));
+ connect(ui->recipientSlider, SIGNAL(valueChanged(int)), SLOT(scrollRecipients(int)));
+ connect (qApp, SIGNAL(focusChanged(QWidget*, QWidget*)), SLOT(invalidateLastFocusedRecipient()));
+ ui->recipientSlider->setMinimum(0);
+ ui->recipientSlider->setMaximum(0);
+ ui->recipientSlider->setVisible(false);
+ ui->envelopeWidget->installEventFilter(this);
+
ui->mailText->setFont(Gui::Util::systemMonospaceFont());
connect(ui->mailText, SIGNAL(urlsAdded(QList<QUrl>)), SLOT(slotAttachFiles(QList<QUrl>)));
@@ -442,6 +450,15 @@ void ComposeWidget::addRecipient(int position, Composer::RecipientKind kind, con
ui->envelopeLayout->insertRow(actualRow(ui->envelopeLayout, position + OFFSET_OF_FIRST_ADDRESSEE), combo, edit);
setTabOrder(formPredecessor(ui->envelopeLayout, combo), combo);
setTabOrder(combo, edit);
+ const int max = qMax(0, m_recipients.count() - MAX_VISIBLE_RECIPIENTS);
+ ui->recipientSlider->setMaximum(max);
+ ui->recipientSlider->setVisible(max > 0);
+ if (ui->recipientSlider->isVisible()) {
+ const int v = ui->recipientSlider->value();
+ ui->recipientSlider->setValue((position+1)*max/m_recipients.count());
+ if (v == ui->recipientSlider->value()) // force scroll update
+ scrollRecipients(v);
+ }
}
void ComposeWidget::slotCheckAddress()
@@ -473,6 +490,9 @@ void ComposeWidget::removeRecipient(int pos)
m_recipients.at(pos).first->deleteLater();
m_recipients.at(pos).second->deleteLater();
m_recipients.removeAt(pos);
+ const int max = qMax(0, m_recipients.count() - MAX_VISIBLE_RECIPIENTS);
+ ui->recipientSlider->setMaximum(max);
+ ui->recipientSlider->setVisible(max > 0);
}
static inline Composer::RecipientKind currentRecipient(const QComboBox *box)
@@ -501,6 +521,45 @@ void ComposeWidget::updateRecipientList()
}
}
+void ComposeWidget::invalidateLastFocusedRecipient()
+{
+ m_lastFocusedRecipient = QApplication::focusWidget(); // got explicit focus on other widget
+}
+
+void ComposeWidget::scrollRecipients(int value)
+{
+ // ignore focus changes caused by "scrolling"
+ disconnect (qApp, SIGNAL(focusChanged(QWidget*, QWidget*)), this, SLOT(invalidateLastFocusedRecipient()));
+ for (int i = 0; i < m_recipients.count(); ++i) {
+ // remove all widgets from the form because of vspacing - causes spurious padding
+ if (!m_lastFocusedRecipient) { // apply only _once_
+ if (m_recipients.at(i).first->hasFocus())
+ m_lastFocusedRecipient = m_recipients.at(i).first;
+ else if (m_recipients.at(i).second->hasFocus())
+ m_lastFocusedRecipient = m_recipients.at(i).second;
+ }
+ ui->envelopeLayout->removeWidget(m_recipients.at(i).first);
+ ui->envelopeLayout->removeWidget(m_recipients.at(i).second);
+ m_recipients.at(i).first->hide();
+ m_recipients.at(i).second->hide();
+ }
+ const int begin = qMin(m_recipients.count(), value);
+ const int end = qMin(m_recipients.count(), value + MAX_VISIBLE_RECIPIENTS);
+ for (int i = begin, j = 0; i < end; ++i, ++j) {
+ const int pos = actualRow(ui->envelopeLayout, j + OFFSET_OF_FIRST_ADDRESSEE);
+ ui->envelopeLayout->insertRow(pos, m_recipients.at(i).first, m_recipients.at(i).second);
+ m_recipients.at(i).first->show();
+ m_recipients.at(i).second->show();
+ setTabOrder(formPredecessor(ui->envelopeLayout, m_recipients.at(i).first), m_recipients.at(i).first);
+ setTabOrder(m_recipients.at(i).first, m_recipients.at(i).second);
+ if (m_recipients.at(i).first == m_lastFocusedRecipient)
+ m_recipients.at(i).first->setFocus();
+ else if (m_recipients.at(i).second == m_lastFocusedRecipient)
+ m_recipients.at(i).second->setFocus();
+ }
+ connect (qApp, SIGNAL(focusChanged(QWidget*, QWidget*)), SLOT(invalidateLastFocusedRecipient()));
+}
+
void ComposeWidget::collapseRecipients()
{
QLineEdit *edit = qobject_cast<QLineEdit*>(sender());
@@ -614,6 +673,19 @@ bool ComposeWidget::eventFilter(QObject *o, QEvent *e)
}
return false;
}
+ if (o == ui->envelopeWidget) {
+ if (e->type() == QEvent::Wheel) {
+ int v = ui->recipientSlider->value();
+ if (static_cast<QWheelEvent*>(e)->delta() > 0)
+ --v;
+ else
+ ++v;
+ ui->recipientSlider->setValue(v);
+ e->accept();
+ return true;
+ }
+ return false;
+ }
return false;
}
diff --git a/src/Gui/ComposeWidget.h b/src/Gui/ComposeWidget.h
index 5185e5c..ee809fa 100644
--- a/src/Gui/ComposeWidget.h
+++ b/src/Gui/ComposeWidget.h
@@ -89,6 +89,8 @@ private slots:
void gotError(const QString &error);
void sent();
void updateRecipientList();
+ void scrollRecipients(int);
+ void invalidateLastFocusedRecipient();
void slotCheckAddress();
void slotCheckAddress(QLineEdit *edit);
@@ -123,6 +125,7 @@ private:
typedef QPair<QComboBox*, QLineEdit*> Recipient;
QList<Recipient> m_recipients;
QTimer *m_recipientListUpdateTimer;
+ QWidget *m_lastFocusedRecipient;
bool m_sentMail;
/** @short Has it been updated since the last time we auto-saved it? */
diff --git a/src/Gui/ComposeWidget.ui b/src/Gui/ComposeWidget.ui
index 11bfca6..1ff1b26 100644
--- a/src/Gui/ComposeWidget.ui
+++ b/src/Gui/ComposeWidget.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>715</width>
- <height>377</height>
+ <width>716</width>
+ <height>362</height>
</rect>
</property>
<property name="windowTitle">
@@ -15,16 +15,16 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
- <widget class="QSplitter" name="splitter">
+ <widget class="QSplitter" name="splitter_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="childrenCollapsible">
<bool>false</bool>
</property>
- <widget class="QSplitter" name="splitter_2">
+ <widget class="QSplitter" name="splitter">
<property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
@@ -42,43 +42,54 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <layout class="QFormLayout" name="envelopeLayout">
- <property name="fieldGrowthPolicy">
- <enum>QFormLayout::ExpandingFieldsGrow</enum>
- </property>
- <item row="0" column="0">
- <widget class="QLabel" name="fromLabel">
- <property name="text">
- <string>From</string>
- </property>
- <property name="buddy">
- <cstring>sender</cstring>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QComboBox" name="sender">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <layout class="QFormLayout" name="envelopeLayout">
+ <property name="fieldGrowthPolicy">
+ <enum>QFormLayout::ExpandingFieldsGrow</enum>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="fromLabel">
+ <property name="text">
+ <string>From</string>
+ </property>
+ <property name="buddy">
+ <cstring>sender</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="sender">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="subjectLabel">
+ <property name="text">
+ <string>Subject</string>
+ </property>
+ <property name="buddy">
+ <cstring>subject</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="LineEdit" name="subject"/>
+ </item>
+ </layout>
</item>
- <item row="1" column="0">
- <widget class="QLabel" name="subjectLabel">
- <property name="text">
- <string>Subject</string>
- </property>
- <property name="buddy">
- <cstring>subject</cstring>
+ <item>
+ <widget class="QScrollBar" name="recipientSlider">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
</property>
</widget>
</item>
- <item row="1" column="1">
- <widget class="LineEdit" name="subject"/>
- </item>
</layout>
</widget>
<widget class="QGroupBox" name="groupBox">
@@ -161,7 +172,7 @@
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
- <verstretch>3</verstretch>
+ <verstretch>100</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">