Attached is a patch for this bug. The "Alignments" combo box in the
Paragraph Settings dialog is now cleared and re-populated whenever the
allowed alignments change. The patch also addresses my bug 3419, which
asks for the "default" to be made re-settable.

One note: In order to get this to work right, I had to make the dialog
modal. The reason is this. Suppose you open the dialog on a paragraph
that allows Left, Right, and Block. Then you click in a different
paragraph that allows only Left and Block. Then the dialog needs to
update, but I couldn't find anything to hook to make it happen. I tried
implementing QParagraphDialog::focusInEvent, but that didn't work. It
seemed the focus event was being grabbed by a widget before the dialog
would see it, and implementing focusInEvent for every widget in the
dialog didn't seem a happy choice. Ideas here are most welcome.

I'm also painfully aware that there may be some issues with the style
here. Please do say so if so.

Richard

-- 
==================================================================
Richard G Heck, Jr
Professor of Philosophy
Brown University
http://frege.brown.edu/heck/
==================================================================
Get my public key from http://sks.keyserver.penguin.de
Hash: 0x1DE91F1E66FFBDEC
Learn how to sign your email using Thunderbird and GnuPG at:
http://dudu.dyn.2-h.org/nist/gpg-enigmail-howto

Index: frontends/qt4/QParagraph.C
===================================================================
--- frontends/qt4/QParagraph.C	(revision 17755)
+++ frontends/qt4/QParagraph.C	(working copy)
@@ -4,11 +4,13 @@
  * Licence details can be found in the file COPYING.
  *
  * \author Edwin Leuven
+ * \author Richard Heck
  *
  * Full author contact details are available in file CREDITS.
  */
 
 #include <config.h>
+#include "debug.h"
 
 #include "QParagraph.h"
 #include "QParagraphDialog.h"
@@ -27,6 +29,7 @@
 
 
 using std::string;
+using std::endl;
 
 namespace lyx {
 namespace frontend {
@@ -35,9 +38,15 @@
 
 
 QParagraph::QParagraph(Dialog & parent)
-	: paragraph_base_class(parent, _("Paragraph Settings"))
-{}
+	: paragraph_base_class(parent, _("Paragraph Settings")),
+	  numPossibleAlignments_(ControlParagraph::numPossibleAlignments)
+{
+	activeAlignments = new LyXAlignment[numPossibleAlignments_];
+}
 
+QParagraph::~QParagraph() {
+	delete[] activeAlignments;
+}
 
 void QParagraph::build_dialog()
 {
@@ -49,6 +58,8 @@
 	bcview().setApply(dialog_->applyPB);
 	bcview().setCancel(dialog_->closePB);
 	bcview().setRestore(dialog_->restorePB);
+	
+	updateAlignmentCombo();
 }
 
 
@@ -56,25 +67,9 @@
 {
 	ParagraphParameters & params = controller().params();
 
-	// alignment
-	LyXAlignment align;
-	switch (dialog_->align->currentIndex()) {
-	case 0:
-		align = LYX_ALIGN_BLOCK;
-		break;
-	case 1:
-		align = LYX_ALIGN_LEFT;
-		break;
-	case 2:
-		align = LYX_ALIGN_RIGHT;
-		break;
-	case 3:
-		align = LYX_ALIGN_CENTER;
-		break;
-	default:
-		align = LYX_ALIGN_BLOCK;
-	}
-	params.align(align);
+	const int index = dialog_->align->currentIndex();
+	BOOST_ASSERT(index < numPossibleAlignments_);
+	params.align(activeAlignments[index]);
 
 	// get spacing
 	Spacing::Space linespacing = Spacing::Default;
@@ -110,6 +105,8 @@
 
 void QParagraph::update_contents()
 {
+	updateAlignmentCombo();
+
 	ParagraphParameters const & params = controller().params();
 
 	// label width
@@ -124,26 +121,25 @@
 	}
 
 	// alignment
-	int i;
-	switch (params.align()) {
-	case LYX_ALIGN_LEFT:
-		i = 1;
-		break;
-	case LYX_ALIGN_RIGHT:
-		i = 2;
-		break;
-	case LYX_ALIGN_CENTER:
-		i = 3;
-		break;
-	default:
-		i = 0;
-		break;
+	LyXAlignment newAlignment = params.align();
+	int setAlignment = -1;
+	if (newAlignment == controller().alignDefault()) {
+		setAlignment = 0;
+	} else {
+		//Find the index of this alignment
+		for (int i = 0; i < numActiveAlignments_; ++i) {
+			if (newAlignment == activeAlignments[i]) {
+				setAlignment = i;
+				break;
+			}
+		}
+		if (setAlignment == -1) {
+			lyxerr << "Invalid alignment " << controller().lyxAlignmentAsString(newAlignment) <<  " in QParagraph::update_contents()" << endl;
+			setAlignment = 0;
+		}
 	}
-	dialog_->align->setCurrentIndex(i);
+	dialog_->align->setCurrentIndex(setAlignment);
 
-
-	//LyXAlignment alignpos = controller().alignPossible();
-
 	dialog_->indentCB->setChecked(!params.noindent());
 
 	// linespacing
@@ -176,5 +172,62 @@
 	}
 }
 
+
+bool QParagraph::updateAlignmentCombo() 
+{
+	static bool initialized = false;
+	const LyXAlignment alignpos = controller().alignPossible();
+	
+	if (initialized &&               //if we've already initialized
+		alignpos == cached_possible_)  //and the possible alignments haven't changed
+		return false;                  //then we're good
+	
+	cached_possible_ = alignpos;
+	dialog_->align->clear();
+	numActiveAlignments_ = 0;
+	
+	const LyXAlignment aligndefault = controller().alignDefault();
+	
+	//We now both populate the combo box and build an array of acceptable 
+	//alignments which we can use elsewhere.
+	//The first one is the default.
+	const QString defaultString = 
+		qt_(controller().lyxAlignmentAsString(LYX_ALIGN_LAYOUT)) + " (" + 
+		qt_(controller().lyxAlignmentAsString(aligndefault)) + ")";
+	dialog_->align->addItem(defaultString);
+	activeAlignments[numActiveAlignments_] = LYX_ALIGN_LAYOUT;
+	++numActiveAlignments_;
+	LYXERR(Debug::GUI) << 
+		"Set default item in QParagraph::updateAlignmentCombo()to " <<
+		controller().lyxAlignmentAsString(LYX_ALIGN_LAYOUT) << 
+		" = " << LYX_ALIGN_LAYOUT << endl;
+	
+	//Now loop through the rest and check them against alignpos
+	//and align default (which we already have as the default).
+	for (int i = 1 /* yes, that's right */; i < numPossibleAlignments_; ++i) {
+		const LyXAlignment align = controller().possibleAlignments[i];
+		if ((align & alignpos) && (align != aligndefault)) {
+			dialog_->align->addItem(qt_(controller().lyxAlignmentAsString(align)));
+			activeAlignments[numActiveAlignments_] = align;
+			LYXERR(Debug::GUI) << "Set item " << numActiveAlignments_ <<  
+				" in QParagraph::updateAlignmentCombo() to " << 
+				controller().lyxAlignmentAsString(align) << " = " << align << endl;
+			++numActiveAlignments_;
+		}
+	}
+	//Enable the combobox iff there is a choice to be made.
+	dialog_->align->setEnabled(numActiveAlignments_ > 1);
+	//set the rest to LYX_ALIGN_NONE, for definiteness
+	for (int i = numActiveAlignments_; i < numPossibleAlignments_; ++i) {
+		LYXERR(Debug::GUI) << "Set item " << i <<  
+			" in QParagraph::updateAlignmentCombo() to " <<
+			controller().lyxAlignmentAsString(LYX_ALIGN_NONE) << endl;
+			activeAlignments[i] = LYX_ALIGN_NONE;
+	}
+	initialized = true;
+	return true;
+}
+
+
 } // namespace frontend
 } // namespace lyx
Index: frontends/qt4/ui/QParagraphUi.ui
===================================================================
--- frontends/qt4/ui/QParagraphUi.ui	(revision 17755)
+++ frontends/qt4/ui/QParagraphUi.ui	(working copy)
@@ -1,15 +1,15 @@
 <ui version="4.0" >
- <author></author>
- <comment></comment>
- <exportmacro></exportmacro>
  <class>QParagraphUi</class>
  <widget class="QDialog" name="QParagraphUi" >
+  <property name="windowModality" >
+   <enum>Qt::ApplicationModal</enum>
+  </property>
   <property name="geometry" >
    <rect>
     <x>0</x>
     <y>0</y>
     <width>396</width>
-    <height>237</height>
+    <height>249</height>
    </rect>
   </property>
   <property name="windowTitle" >
@@ -66,26 +66,9 @@
    </item>
    <item row="0" column="1" >
     <widget class="QComboBox" name="align" >
-     <item>
-      <property name="text" >
-       <string>Justified</string>
-      </property>
-     </item>
-     <item>
-      <property name="text" >
-       <string>Left</string>
-      </property>
-     </item>
-     <item>
-      <property name="text" >
-       <string>Right</string>
-      </property>
-     </item>
-     <item>
-      <property name="text" >
-       <string>Center</string>
-      </property>
-     </item>
+     <property name="sizeAdjustPolicy" >
+      <enum>QComboBox::AdjustToContents</enum>
+     </property>
     </widget>
    </item>
    <item row="0" column="0" >
@@ -289,10 +272,6 @@
    </item>
   </layout>
  </widget>
- <pixmapfunction></pixmapfunction>
- <includes>
-  <include location="local" >qt_helpers.h</include>
- </includes>
  <tabstops>
   <tabstop>align</tabstop>
   <tabstop>linespacing</tabstop>
@@ -304,6 +283,9 @@
   <tabstop>applyPB</tabstop>
   <tabstop>closePB</tabstop>
  </tabstops>
+ <includes>
+  <include location="local" >qt_helpers.h</include>
+ </includes>
  <resources/>
  <connections/>
 </ui>
Index: frontends/qt4/QParagraph.h
===================================================================
--- frontends/qt4/QParagraph.h	(revision 17755)
+++ frontends/qt4/QParagraph.h	(working copy)
@@ -6,6 +6,7 @@
  *
  * \author Edwin Leuven
  * \author John Levon
+ * \author Richard Heck
  *
  * Full author contact details are available in file CREDITS.
  */
@@ -15,6 +16,7 @@
 
 #include "QDialogView.h"
 #include "QParagraphDialog.h"
+#include "layout.h"
 
 namespace lyx {
 namespace frontend {
@@ -28,6 +30,8 @@
 	friend class QParagraphDialog;
 
 	QParagraph(Dialog &);
+	virtual ~QParagraph();
+	
 private:
 	/// Apply changes
 	virtual void apply();
@@ -35,6 +39,19 @@
 	virtual void update_contents();
 	/// build the dialog
 	virtual void build_dialog();
+	/// Possible alignments for last paragraph
+	LyXAlignment cached_possible_;
+	/// Total number of possible alignments
+	const int numPossibleAlignments_;
+	/// Array of alignments allowed in the current paragraph
+	LyXAlignment * activeAlignments;
+	/// number of alignments allowed 
+	int numActiveAlignments_;
+	/// updates the alignment combo when the allowed 
+	/// alignments have changed
+	/// @c return Returns true if the combo was updated
+	bool updateAlignmentCombo(); 
+
 };
 
 } // namespace frontend
Index: frontends/controllers/ControlParagraph.C
===================================================================
--- frontends/controllers/ControlParagraph.C	(revision 17755)
+++ frontends/controllers/ControlParagraph.C	(working copy)
@@ -17,19 +17,24 @@
 #include "lyxlex.h"
 #include "paragraph.h"
 #include "ParagraphParameters.h"
+#include "layout.h"
+#include "debug.h"
 
 #include <sstream>
 
 using std::istringstream;
 using std::ostringstream;
 using std::string;
+using std::endl;
 
 namespace lyx {
 namespace frontend {
 
+
 ControlParagraph::ControlParagraph(Dialog & parent)
 	: Dialog::Controller(parent), ininset_(false)
-{}
+{
+}
 
 
 bool ControlParagraph::initialiseParams(string const & data)
@@ -165,5 +170,31 @@
 	return aligndefault_;
 }
 
+string ControlParagraph::lyxAlignmentAsString(const LyXAlignment align)
+{
+	switch (align) {
+		case LYX_ALIGN_NONE: 		return "None";
+		case LYX_ALIGN_BLOCK:		return "Justified";
+		case LYX_ALIGN_LEFT:		return "Left";
+		case LYX_ALIGN_RIGHT:		return "Right";
+		case LYX_ALIGN_CENTER: 	return "Center";
+		case LYX_ALIGN_LAYOUT:	return "Default";
+		case LYX_ALIGN_SPECIAL:	return "Special";
+	}
+	//Should never get here.
+	lyxerr << "Invalid alignment passed to ControlParagraph::lyxAlignmentAsString()" <<endl;
+	return "";
+}
+
+
+const LyXAlignment ControlParagraph::possibleAlignments[] = {
+	LYX_ALIGN_LAYOUT, 
+	LYX_ALIGN_BLOCK,
+	LYX_ALIGN_LEFT,
+	LYX_ALIGN_RIGHT,
+	LYX_ALIGN_CENTER
+};
+
+
 } // namespace frontend
 } // namespace lyx
Index: frontends/controllers/ControlParagraph.h
===================================================================
--- frontends/controllers/ControlParagraph.h	(revision 17755)
+++ frontends/controllers/ControlParagraph.h	(working copy)
@@ -15,6 +15,8 @@
 #include "Dialog.h"
 #include "layout.h" // for LyXAlignment
 
+using std::string; 
+
 namespace lyx {
 
 class ParagraphParameters;
@@ -43,6 +45,13 @@
 	LyXAlignment alignPossible() const;
 	///
 	LyXAlignment alignDefault() const;
+	///
+	string lyxAlignmentAsString(const LyXAlignment align);
+	///
+	static const int numPossibleAlignments = 5;
+	///
+	static const LyXAlignment possibleAlignments[numPossibleAlignments];
+	
 
 private:
 	///

Reply via email to