The attached patch introduces the feature to change the color for shaded boxes
(fixes http://www.lyx.org/trac/ticket/3863)

(I plan that this would be my last new feature for LyX 2.0.)

The patch is well tested and works as expected, except of one Ui-issue:
When loading a file with a shaded box, the color is wrong within LyX. Take for example the attached LyX-file where the color is set to yellow. Yellow is correctly recognized and used to paint the button in the menu Document->Settings->Colors, but the color shown for the box is still red.
In BufferParams.cpp I correctly set the color with

lcolor.setColor(Color_shadedbg, color);

This correctly changes the color but it is later on overwritten again by the default color red and I cannot figure out where and why.
I would be happy if someone could tell me what I'm doing wrong.

thanks and regards
Uwe
Index: lib/lyx2lyx/lyx_2_0.py
===================================================================
--- lib/lyx2lyx/lyx_2_0.py	(revision 34048)
+++ lib/lyx2lyx/lyx_2_0.py	(working copy)
@@ -1431,6 +1431,41 @@
                            + '\\color{document_fontcolor}\n')
 
 
+def revert_shadedboxcolor(document):
+    " Reverts shaded box color to preamble code "
+    i = 0
+    colorcode = ""
+    while True:
+      i = find_token(document.header, "\\boxbgcolor", i)
+      if i == -1:
+          return
+      colorcode = get_value(document.header, '\\boxbgcolor', 0)
+      del document.header[i]
+      # the color code is in the form #rrggbb where every character denotes a hex number
+      # convert the string to an int
+      red = string.atoi(colorcode[1:3],16)
+      # we want the output "0.5" for the value "127" therefore increment here
+      if red != 0:
+          red = red + 1
+      redout = float(red) / 256
+      green = string.atoi(colorcode[3:5],16)
+      if green != 0:
+          green = green + 1
+      greenout = float(green) / 256
+      blue = string.atoi(colorcode[5:7],16)
+      if blue != 0:
+          blue = blue + 1
+      blueout = float(blue) / 256
+      # write the preamble
+      insert_to_preamble(0, document,
+                           '% Commands inserted by lyx2lyx to set the color\n'
+                           '% of boxes with shaded background\n'
+                           + '\...@ifundefined{definecolor}{\\usepackage{color}}{}\n'
+                           + '\\definecolor{shadecolor}{rgb}{'
+                           + str(redout) + ', ' + str(greenout)
+                           + ', ' + str(blueout) + '}\n')
+
+
 ##
 # Conversion hub
 #
@@ -1474,10 +1509,12 @@
            [381, []],
            [382, []],
            [383, []],
-           [384, []]
+           [384, []],
+           [385, []]
           ]
 
-revert =  [[383, [revert_fontcolor]],
+revert =  [[384, [revert_shadedboxcolor]],
+           [383, [revert_fontcolor]],
            [382, [revert_turkmen]],
            [381, [revert_notefontcolor]],
            [380, [revert_equalspacing_xymatrix]],
Index: src/Buffer.cpp
===================================================================
--- src/Buffer.cpp	(revision 34048)
+++ src/Buffer.cpp	(working copy)
@@ -126,7 +126,7 @@
 
 // Do not remove the comment below, so we get merge conflict in
 // independent branches. Instead add your own.
-int const LYX_FORMAT = 384; // uwestoehr: support for document-wide font color
+int const LYX_FORMAT = 385; // uwestoehr: support to change the shaded box color
 
 typedef map<string, bool> DepClean;
 typedef map<docstring, pair<InsetLabel const *, Buffer::References> > RefCache;
@@ -671,6 +671,7 @@
 	params().fontcolor = lyx::rgbFromHexName("#000000");
 	params().isfontcolor = false;
 	params().notefontcolor = lyx::rgbFromHexName("#cccccc");
+	params().boxbgcolor = lyx::rgbFromHexName("#ff0000");
 
 	for (int i = 0; i < 4; ++i) {
 		params().user_defined_bullet(i) = ITEMIZE_DEFAULTS[i];
Index: src/BufferParams.cpp
===================================================================
--- src/BufferParams.cpp	(revision 34048)
+++ src/BufferParams.cpp	(working copy)
@@ -374,6 +374,7 @@
 	isfontcolor = false;
 	// light gray is the default font color for greyed-out notes
 	notefontcolor = lyx::rgbFromHexName("#cccccc");
+	boxbgcolor = lyx::rgbFromHexName("#ff0000");
 	compressed = lyxrc.save_compressed;
 	for (int iter = 0; iter < 4; ++iter) {
 		user_defined_bullet(iter) = ITEMIZE_DEFAULTS[iter];
@@ -737,6 +738,13 @@
 		// set the font color within LyX
 		// FIXME: the color is correctly set but later overwritten by the default
 		lcolor.setColor(Color_greyedouttext, color);
+	} else if (token == "\\boxbgcolor") {
+		lex.eatLine();
+		string color = lex.getString();
+		boxbgcolor = lyx::rgbFromHexName(color);
+		// set the font color within LyX
+		// FIXME: the color is correctly set but later overwritten by the default
+		lcolor.setColor(Color_shadedbg, color);
 	} else if (token == "\\paperwidth") {
 		lex >> paperwidth;
 	} else if (token == "\\paperheight") {
@@ -933,6 +941,8 @@
 		os << "\\fontcolor " << lyx::X11hexname(fontcolor) << '\n';
 	if (notefontcolor != lyx::rgbFromHexName("#cccccc"))
 		os << "\\notefontcolor " << lyx::X11hexname(notefontcolor) << '\n';
+	if (boxbgcolor != lyx::rgbFromHexName("#ff0000"))
+		os << "\\boxbgcolor " << lyx::X11hexname(boxbgcolor) << '\n';
 
 	BranchList::const_iterator it = branchlist().begin();
 	BranchList::const_iterator end = branchlist().end();
Index: src/BufferParams.h
===================================================================
--- src/BufferParams.h	(revision 34048)
+++ src/BufferParams.h	(working copy)
@@ -291,6 +291,8 @@
 	bool isfontcolor;
 	///
 	RGBColor notefontcolor;
+	///
+	RGBColor boxbgcolor;
 	/// \param index should lie in the range 0 <= \c index <= 3.
 	Bullet & temp_bullet(size_type index);
 	Bullet const & temp_bullet(size_type index) const;
Index: src/frontends/qt4/GuiDocument.cpp
===================================================================
--- src/frontends/qt4/GuiDocument.cpp	(revision 34048)
+++ src/frontends/qt4/GuiDocument.cpp	(working copy)
@@ -181,6 +181,7 @@
 RGBColor set_fontcolor;
 bool is_fontcolor;
 RGBColor set_notefontcolor;
+RGBColor set_boxbgcolor;
 
 namespace {
 // used when sorting the textclass list.
@@ -886,8 +887,12 @@
 		this, SLOT(deleteNoteFontColor()));
 	connect(colorModule->backgroundPB, SIGNAL(clicked()),
 		this, SLOT(changeBackgroundColor()));
-	connect(colorModule->delbackgroundTB, SIGNAL(clicked()),
+	connect(colorModule->delBackgroundTB, SIGNAL(clicked()),
 		this, SLOT(deleteBackgroundColor()));
+	connect(colorModule->boxBackgroundPB, SIGNAL(clicked()),
+		this, SLOT(changeBoxBackgroundColor()));
+	connect(colorModule->delBoxBackgroundTB, SIGNAL(clicked()),
+		this, SLOT(deleteBoxBackgroundColor()));
 
 
 	// numbering
@@ -1435,6 +1440,32 @@
 }
 
 
+void GuiDocument::changeBoxBackgroundColor()
+{
+	QColor const & newColor = QColorDialog::getColor(
+		rgb2qcolor(set_boxbgcolor), asQWidget());
+	if (!newColor.isValid())
+		return;
+	// set the button color
+	colorModule->boxBackgroundPB->setStyleSheet(
+		colorButtonStyleSheet(newColor));
+	// save color
+	set_boxbgcolor = rgbFromHexName(fromqstr(newColor.name()));
+	changed();
+}
+
+
+void GuiDocument::deleteBoxBackgroundColor()
+{
+	// set the button color back to red
+	colorModule->boxBackgroundPB->setStyleSheet(
+		colorButtonStyleSheet(QColor(Qt::red)));
+	// save red as the set color
+	set_boxbgcolor = rgbFromHexName("#ff0000");
+	changed();
+}
+
+
 void GuiDocument::xetexChanged(bool xetex)
 {
 	updateFontlist();
@@ -2045,6 +2076,7 @@
 	bp_.fontcolor = set_fontcolor;
 	bp_.isfontcolor = is_fontcolor;
 	bp_.notefontcolor = set_notefontcolor;
+	bp_.boxbgcolor = set_boxbgcolor;
 
 	// numbering
 	if (bp_.documentClass().hasTocLevels()) {
@@ -2444,6 +2476,10 @@
 		colorButtonStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
 	set_backgroundcolor = bp_.backgroundcolor;
 
+	colorModule->boxBackgroundPB->setStyleSheet(
+		colorButtonStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
+	set_boxbgcolor = bp_.boxbgcolor;
+
 	// numbering
 	int const min_toclevel = documentClass().min_toclevel();
 	int const max_toclevel = documentClass().max_toclevel();
Index: src/frontends/qt4/GuiDocument.h
===================================================================
--- src/frontends/qt4/GuiDocument.h	(revision 34048)
+++ src/frontends/qt4/GuiDocument.h	(working copy)
@@ -113,6 +113,8 @@
 	void deleteFontColor();
 	void changeNoteFontColor();
 	void deleteNoteFontColor();
+	void changeBoxBackgroundColor();
+	void deleteBoxBackgroundColor();
 	void xetexChanged(bool);
 	void branchesRename(docstring const &, docstring const &);
 private:
Index: src/frontends/qt4/GuiPrefs.cpp
===================================================================
--- src/frontends/qt4/GuiPrefs.cpp	(revision 34048)
+++ src/frontends/qt4/GuiPrefs.cpp	(working copy)
@@ -1006,7 +1006,8 @@
 			|| lc == Color_yellow
 			|| lc == Color_inherit
 			|| lc == Color_ignore
-			|| lc == Color_greyedouttext) continue;
+			|| lc == Color_greyedouttext
+			|| lc == Color_shadedbg) continue;
 
 		lcolors_.push_back(lc);
 	}
Index: src/frontends/qt4/ui/ColorUi.ui
===================================================================
--- src/frontends/qt4/ui/ColorUi.ui	(revision 34048)
+++ src/frontends/qt4/ui/ColorUi.ui	(working copy)
@@ -5,8 +5,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>404</width>
-    <height>216</height>
+    <width>387</width>
+    <height>250</height>
    </rect>
   </property>
   <property name="contextMenuPolicy">
@@ -200,7 +200,7 @@
          </widget>
         </item>
         <item>
-         <widget class="QToolButton" name="delbackgroundTB">
+         <widget class="QToolButton" name="delBackgroundTB">
           <property name="minimumSize">
            <size>
             <width>23</width>
@@ -236,6 +236,72 @@
         </item>
        </layout>
       </item>
+      <item row="1" column="0">
+       <widget class="QLabel" name="noteBackgroundColorLA">
+        <property name="text">
+         <string>Background color
+for shaded boxes:</string>
+        </property>
+        <property name="buddy">
+         <cstring>backgroundPB</cstring>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <layout class="QHBoxLayout" name="horizontalLayout_5">
+        <item>
+         <widget class="QPushButton" name="boxBackgroundPB">
+          <property name="maximumSize">
+           <size>
+            <width>16777215</width>
+            <height>16777215</height>
+           </size>
+          </property>
+          <property name="toolTip">
+           <string>Click to change the color</string>
+          </property>
+          <property name="text">
+           <string>&amp;Change...</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QToolButton" name="delBoxBackgroundTB">
+          <property name="minimumSize">
+           <size>
+            <width>23</width>
+            <height>23</height>
+           </size>
+          </property>
+          <property name="toolTip">
+           <string>Revert the color to the default</string>
+          </property>
+          <property name="text">
+           <string>R&amp;eset</string>
+          </property>
+          <property name="toolButtonStyle">
+           <enum>Qt::ToolButtonTextOnly</enum>
+          </property>
+          <property name="arrowType">
+           <enum>Qt::LeftArrow</enum>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer_4">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </item>
      </layout>
     </widget>
    </item>
@@ -246,8 +312,8 @@
      </property>
      <property name="sizeHint" stdset="0">
       <size>
-       <width>20</width>
-       <height>126</height>
+       <width>366</width>
+       <height>37</height>
       </size>
      </property>
     </spacer>
Index: src/LaTeXFeatures.cpp
===================================================================
--- src/LaTeXFeatures.cpp	(revision 34048)
+++ src/LaTeXFeatures.cpp	(working copy)
@@ -604,6 +604,13 @@
 		// the lyxgreyedout environment (see lyxgreyedout_def)
 	}
 
+	// color for shaded boxes
+	if (isRequired("framed") && mustProvide("color")) {
+		colors << "\\definecolor{shadecolor}{rgb}{";
+		colors << outputLaTeXColor(params_.boxbgcolor) << "}\n";
+		// this color is automatically used by the LaTeX-package "framed"
+	}
+
 	return colors.str();
 }
 
@@ -693,21 +700,7 @@
 				 << params_.graphicsDriver
 				 << "]{graphicx}\n";
 	}
-	// shadecolor for shaded
-	if (isRequired("framed") && mustProvide("color")) {
-		RGBColor c = rgbFromHexName(lcolor.getX11Name(Color_shadedbg));
-		//255.0 to force conversion to double
-		//NOTE As Jürgen Spitzmüller pointed out, an alternative would be
-		//to use the xcolor package instead, and then we can do
-		// \define{shadcolor}{RGB}...
-		//and not do any conversion. We'd then need to require xcolor
-		//in InsetNote::validate().
-		int const stmSize = packages.precision(2);
-		packages << "\\definecolor{shadecolor}{rgb}{"
-			<< c.r / 255.0 << ',' << c.g / 255.0 << ',' << c.b / 255.0 << "}\n";
-		packages.precision(stmSize);
-	}
-
+	
 	// lyxskak.sty --- newer chess support based on skak.sty
 	if (mustProvide("chess"))
 		packages << "\\usepackage[ps,mover]{lyxskak}\n";

Attachment: ShadeBoxTest.lyx
Description: application/lyx

Reply via email to