gtk graphics dialog

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@9129 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
John Spray 2004-10-26 09:10:17 +00:00
parent 292c3210f6
commit 4f89cf2b1d
8 changed files with 2384 additions and 3 deletions

View File

@ -1,3 +1,10 @@
2004-10-23 John Spray <spray_john@users.sourceforge.net>
* ghelpers.[Ch]: Add buildLengthUnitList() to get vector of
available length unit strings
* The Graphics dialog:
Dialogs.C, Makefile.am, GGraphics.C, GGraphics.h
2004-10-11 John Spray <spray_john@users.sourceforge.net>
* GWorkArea.C: allow user to scroll only one half workarea height

View File

@ -64,7 +64,7 @@
#include "FormERT.h"
#include "FormExternal.h"
#include "FormFloat.h"
#include "FormGraphics.h"
#include "GGraphics.h"
#include "FormInclude.h"
#include "GLog.h"
#include "GMathPanel.h"
@ -239,8 +239,9 @@ Dialogs::DialogPtr Dialogs::build(string const & name)
dialog->setView(new FormFloat(*dialog));
dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy);
} else if (name == "graphics") {
dialog->bc().view(new GBC(dialog->bc()));
dialog->setController(new ControlGraphics(*dialog));
dialog->setView(new FormGraphics(*dialog));
dialog->setView(new GGraphics(*dialog));
dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy);
} else if (name == "include") {
dialog->setController(new ControlInclude(*dialog));

View File

@ -0,0 +1,567 @@
/**
* \file GGraphics.C
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author John Spray
*
* Full author contact details are available in file CREDITS.
*/
#include <config.h>
#include "GGraphics.h"
#include "ControlGraphics.h"
#include "ghelpers.h"
#include "controllers/helper_funcs.h"
#include "insets/insetgraphicsParams.h"
#include "paper.h"
#include "lyxrc.h" // for lyxrc.default_papersize
#include "support/lyxlib.h" // for float_equal
#include "support/lstrings.h"
#include "debug.h"
using std::vector;
using std::string;
namespace lyx {
using support::float_equal;
using support::token;
namespace frontend {
namespace {
string defaultUnit("cm");
} // namespace anon
GGraphics::GGraphics(Dialog & parent)
: GViewCB<ControlGraphics, GViewGladeB>(parent, _("Graphics"), false)
{}
void GGraphics::doBuild()
{
string const gladeName = findGladeFile("graphics");
xml_ = Gnome::Glade::Xml::create(gladeName);
Gtk::Button * button;
xml_->get_widget("Close", button);
setCancel(button);
xml_->get_widget("Ok", button);
setOK(button);
xml_->get_widget("Apply", button);
setApply(button);
xml_->get_widget("Restore", button);
setRestore(button);
xml_->get_widget("Notebook", notebook_);
// File Page
xml_->get_widget("File", fileentry_);
xml_->get_widget("DisplayScale", displayscalespin_);
xml_->get_widget("OutputScale", outputscalespin_);
xml_->get_widget("Browse", browsebutton_);
xml_->get_widget("Edit", editbutton_);
xml_->get_widget("Display", displaycombo_);
xml_->get_widget("Width", widthspin_);
xml_->get_widget("Height", heightspin_);
xml_->get_widget("MaintainAspectRatio", aspectcheck_);
xml_->get_widget("WidthUnits", widthunitscombo_);
xml_->get_widget("HeightUnits", heightunitscombo_);
xml_->get_widget("SetScaling", setscalingradio_);
xml_->get_widget("SetSize", setsizeradio_);
// Bounding Box Page
xml_->get_widget("ClipToBoundingBox", clipcheck_);
xml_->get_widget("RightTopX", righttopxspin_);
xml_->get_widget("RightTopY", righttopyspin_);
xml_->get_widget("LeftBottomX", leftbottomxspin_);
xml_->get_widget("LeftBottomY", leftbottomyspin_);
xml_->get_widget("BoundingUnits", bbunitscombo_);
xml_->get_widget("GetFromFile", bbfromfilebutton_);
// Extra Page
xml_->get_widget("Angle", anglespin_);
xml_->get_widget("Origin", origincombo_);
xml_->get_widget("UseSubfigure", subfigcheck_);
xml_->get_widget("SubfigureCaption", subfigentry_);
xml_->get_widget("LatexOptions", latexoptsentry_);
xml_->get_widget("DraftMode", draftcheck_);
xml_->get_widget("UnzipOnExport", unzipcheck_);
// Setup the columnrecord we use for combos
cols_.add(stringcol_);
// The file page
// Disable for read-only documents.
bcview().addReadOnly(browsebutton_);
bcview().addReadOnly(aspectcheck_);
fileentry_->signal_changed().connect(
sigc::mem_fun(*this, &GGraphics::onInput));
displayscalespin_->signal_changed().connect(
sigc::mem_fun(*this, &GGraphics::onInput));
displaycombo_->signal_changed().connect(
sigc::mem_fun(*this, &GGraphics::onInput));
outputscalespin_->signal_changed().connect(
sigc::mem_fun(*this, &GGraphics::onInput));
heightspin_->signal_changed().connect(
sigc::mem_fun(*this, &GGraphics::onInput));
heightunitscombo_->signal_changed().connect(
sigc::mem_fun(*this, &GGraphics::onInput));
widthspin_->signal_changed().connect(
sigc::mem_fun(*this, &GGraphics::onInput));
widthunitscombo_->signal_changed().connect(
sigc::mem_fun(*this, &GGraphics::onInput));
aspectcheck_->signal_toggled().connect(
sigc::mem_fun(*this, &GGraphics::onInput));
setscalingradio_->signal_toggled().connect(
sigc::mem_fun(*this, &GGraphics::onSizingModeChange));
setsizeradio_->signal_toggled().connect(
sigc::mem_fun(*this, &GGraphics::onSizingModeChange));
browsebutton_->signal_clicked().connect(
sigc::mem_fun(*this, &GGraphics::onBrowseClicked));
editbutton_->signal_clicked().connect(
sigc::mem_fun(*this, &GGraphics::onEditClicked));
vector<string> const unit_list = buildLengthUnitList();
PopulateComboBox(heightunitscombo_, unit_list);
PopulateComboBox(widthunitscombo_, unit_list);
// the bounding box page
leftbottomxspin_->signal_changed().connect(
sigc::mem_fun(*this, &GGraphics::onBBChange));
leftbottomyspin_->signal_changed().connect(
sigc::mem_fun(*this, &GGraphics::onBBChange));
righttopxspin_->signal_changed().connect(
sigc::mem_fun(*this, &GGraphics::onBBChange));
righttopyspin_->signal_changed().connect(
sigc::mem_fun(*this, &GGraphics::onBBChange));
bbunitscombo_->signal_changed().connect(
sigc::mem_fun(*this, &GGraphics::onBBChange));
clipcheck_->signal_toggled().connect(
sigc::mem_fun(*this, &GGraphics::onBBChange));
bbfromfilebutton_->signal_clicked().connect(
sigc::mem_fun(*this, &GGraphics::onBBFromFileClicked));
// disable for read-only documents
bcview().addReadOnly(bbfromfilebutton_);
bcview().addReadOnly(clipcheck_);
PopulateComboBox(bbunitscombo_, getBBUnits());
// the extra section
// disable for read-only documents
bcview().addReadOnly(anglespin_);
bcview().addReadOnly(origincombo_);
bcview().addReadOnly(subfigcheck_);
bcview().addReadOnly(latexoptsentry_);
bcview().addReadOnly(draftcheck_);
bcview().addReadOnly(unzipcheck_);
anglespin_->signal_changed().connect(
sigc::mem_fun(*this, &GGraphics::onInput));
origincombo_->signal_changed().connect(
sigc::mem_fun(*this, &GGraphics::onInput));
subfigentry_->signal_changed().connect(
sigc::mem_fun(*this, &GGraphics::onInput));
latexoptsentry_->signal_changed().connect(
sigc::mem_fun(*this, &GGraphics::onInput));
draftcheck_->signal_toggled().connect(
sigc::mem_fun(*this, &GGraphics::onInput));
unzipcheck_->signal_toggled().connect(
sigc::mem_fun(*this, &GGraphics::onInput));
subfigcheck_->signal_toggled().connect(
sigc::mem_fun(*this, &GGraphics::onSubFigCheckToggled));
vector<RotationOriginPair> origindata = getRotationOriginData();
// Store the identifiers for later
origins_ = getSecond(origindata);
PopulateComboBox(origincombo_, getFirst(origindata));
// set the right default unit
switch (lyxrc.default_papersize) {
case PAPER_DEFAULT: break;
case PAPER_USLETTER:
case PAPER_LEGALPAPER:
case PAPER_EXECUTIVEPAPER: defaultUnit = "in"; break;
case PAPER_A3PAPER:
case PAPER_A4PAPER:
case PAPER_A5PAPER:
case PAPER_B5PAPER: defaultUnit = "cm"; break;
}
}
void GGraphics::onSizingModeChange()
{
bool const scalingmode = setscalingradio_->get_active();
outputscalespin_->set_sensitive(scalingmode);
widthspin_->set_sensitive(!scalingmode);
heightspin_->set_sensitive(!scalingmode);
widthunitscombo_->set_sensitive(!scalingmode);
heightunitscombo_->set_sensitive(!scalingmode);
aspectcheck_->set_sensitive(!scalingmode);
bc().input(ButtonPolicy::SMI_VALID);
}
void GGraphics::PopulateComboBox(Gtk::ComboBox * combo,
vector<string> const & strings)
{
Glib::RefPtr<Gtk::ListStore> model = Gtk::ListStore::create(cols_);
vector<string>::const_iterator it = strings.begin();
vector<string>::const_iterator end = strings.end();
for (int rowindex = 0; it != end; ++it, ++rowindex) {
Gtk::TreeModel::iterator row = model->append();
(*row)[stringcol_] = *it;
}
combo->set_model(model);
Gtk::CellRendererText * cell = Gtk::manage(new Gtk::CellRendererText);
combo->pack_start(*cell, true);
combo->add_attribute(*cell, "text", 0);
}
void GGraphics::updateComboFromLength(Gtk::ComboBox * combo,
LyXLength const & len)
{
string unit = stringFromUnit(len.unit());
if (unit.empty())
unit = defaultUnit;
Gtk::TreeModel::iterator it = combo->get_model()->children().begin();
Gtk::TreeModel::iterator end = combo->get_model()->children().end();
for (; it != end ; ++it) {
if ((*it)[stringcol_] == unit) {
combo->set_active(it);
return;
}
}
// Fallen through, we didn't find the target length!
combo->set_active(0);
lyxerr << "GGraphics::updateComboFromLength: couldn't find "
"target unit '" << unit << "'\n";
}
void GGraphics::apply()
{
// Create the parameters structure and fill the data from the dialog.
InsetGraphicsParams & igp = controller().params();
// the file section
igp.filename.set(fileentry_->get_text(),
kernel().bufferFilepath());
igp.lyxscale =
static_cast<int>(displayscalespin_->get_adjustment()->get_value());
if (igp.lyxscale == 0) {
igp.lyxscale = 100;
}
switch (displaycombo_->get_active_row_number()) {
case 4:
igp.display = graphics::NoDisplay;
break;
case 3:
igp.display = graphics::ColorDisplay;
break;
case 2:
igp.display = graphics::GrayscaleDisplay;
break;
case 1:
igp.display = graphics::MonochromeDisplay;
break;
case 0:
igp.display = graphics::DefaultDisplay;
}
if (setscalingradio_->get_active()) {
igp.scale = outputscalespin_->get_adjustment()->get_value();
if (float_equal(igp.scale, 0.0, 0.05))
igp.scale = 100.0;
igp.width = LyXLength();
} else {
igp.scale = 0.0;
Glib::ustring const widthunit =
(*widthunitscombo_->get_active())[stringcol_];
igp.width = LyXLength(widthspin_->get_text() + widthunit);
}
Glib::ustring const heightunit =
(*heightunitscombo_->get_active())[stringcol_];
igp.height = LyXLength(heightspin_->get_text() + heightunit);
igp.keepAspectRatio = aspectcheck_->get_active();
igp.draft = draftcheck_->get_active();
igp.noUnzip = !unzipcheck_->get_active();
// the bb section
if (!controller().bbChanged) {
// don't write anything
igp.bb.erase();
} else {
Glib::ustring const bbunit = (*bbunitscombo_->get_active())[stringcol_];
string bb;
if (leftbottomxspin_->get_text().empty())
bb = "0";
else
bb = leftbottomxspin_->get_text() + bbunit;
bb += ' ';
if (leftbottomyspin_->get_text().empty())
bb += "0";
else
bb += leftbottomyspin_->get_text() + bbunit;
bb += ' ';
if (righttopxspin_->get_text().empty())
bb += "0";
else
bb += righttopxspin_->get_text() + bbunit;
bb += ' ';
if (righttopyspin_->get_text().empty())
bb += "0";
else
bb += righttopyspin_->get_text() + bbunit;
/// The bounding box with "xLB yLB yRT yRT ", divided by a space!
igp.bb = bb;
}
igp.clip = clipcheck_->get_active();
// the extra section
igp.rotateAngle = anglespin_->get_adjustment()->get_value();
int const origin_pos = origincombo_->get_active_row_number();
igp.rotateOrigin = origins_[origin_pos];
igp.subcaption = subfigcheck_->get_active();
igp.subcaptionText = subfigentry_->get_text();
igp.special = latexoptsentry_->get_text();
}
void GGraphics::update() {
// Update dialog with details from inset
InsetGraphicsParams & igp = controller().params();
// the file section
string const name =
igp.filename.outputFilename(kernel().bufferFilepath());
fileentry_->set_text(name);
displayscalespin_->get_adjustment()->set_value(igp.lyxscale);
switch (igp.display) {
case graphics::NoDisplay:
displaycombo_->set_active(4);
break;
case graphics::ColorDisplay:
displaycombo_->set_active(3);
break;
case graphics::GrayscaleDisplay:
displaycombo_->set_active(2);
break;
case graphics::MonochromeDisplay:
displaycombo_->set_active(1);
break;
case graphics::DefaultDisplay:
displaycombo_->set_active(0);
}
outputscalespin_->get_adjustment()->set_value(igp.scale);
widthspin_->get_adjustment()->set_value(igp.width.value());
updateComboFromLength(widthunitscombo_, igp.width);
heightspin_->get_adjustment()->set_value(igp.height.value());
updateComboFromLength(heightunitscombo_, igp.height);
if (!float_equal(igp.scale, 0.0, 0.05)) {
//scaling sizing mode
setscalingradio_->set_active(true);
} else {
setsizeradio_->set_active(true);
}
aspectcheck_->set_active(igp.keepAspectRatio);
draftcheck_->set_active(igp.draft);
unzipcheck_->set_active(!igp.noUnzip);
// the bb section
// set the bounding box values, if exists. First we need the whole
// path, because the controller knows nothing about the doc-dir
updateBB(igp.filename.absFilename(), igp.bb);
clipcheck_->set_active(igp.clip);
// the extra section
anglespin_->get_adjustment()->set_value(igp.rotateAngle);
int origin_pos;
if (igp.rotateOrigin.empty()) {
origin_pos = 0;
} else {
origin_pos = findPos(origins_, igp.rotateOrigin);
}
origincombo_->set_active(origin_pos);
subfigcheck_->set_active(igp.subcaption);
subfigentry_->set_text(igp.subcaptionText);
subfigentry_->set_sensitive(subfigcheck_->get_active());
latexoptsentry_->set_text(igp.special);
// open dialog in the file-tab, whenever filename is empty
if (igp.filename.empty()) {
notebook_->set_current_page(0);
}
bc().input(ButtonPolicy::SMI_INVALID);
}
void GGraphics::updateBB(string const & filename, string const & bb_inset)
{
// Update dialog with details from inset
// set the bounding box values, if exists. First we need the whole
// path, because the controller knows nothing about the doc-dir
if (bb_inset.empty()) {
lyxerr[Debug::GRAPHICS]
<< "GGraphics::updateBB() [no BoundingBox]\n";
string const bb = controller().readBB(filename);
if (!bb.empty()) {
// get the values from the file
// in this case we always have the point-unit
leftbottomxspin_->set_text(token(bb, ' ', 0));
leftbottomyspin_->set_text(token(bb, ' ', 1));
righttopxspin_->set_text(token(bb, ' ', 2));
righttopyspin_->set_text(token(bb, ' ', 3));
} else {
// no bb from file
leftbottomxspin_->set_text("");
leftbottomyspin_->set_text("");
righttopxspin_->set_text("");
righttopyspin_->set_text("");
}
updateComboFromLength(bbunitscombo_,LyXLength("bp"));
} else {
// get the values from the inset
lyxerr[Debug::GRAPHICS]
<< "FormGraphics::updateBB(): igp has BoundingBox"
<< " ["<< bb_inset << "]\n";
LyXLength anyLength;
anyLength = LyXLength(token(bb_inset, ' ', 0));
updateComboFromLength(bbunitscombo_, anyLength);
leftbottomxspin_->get_adjustment()->set_value(anyLength.value());
anyLength = LyXLength(token(bb_inset, ' ', 1));
leftbottomyspin_->get_adjustment()->set_value(anyLength.value());
anyLength = LyXLength(token(bb_inset, ' ', 2));
righttopxspin_->get_adjustment()->set_value(anyLength.value());
anyLength = LyXLength(token(bb_inset, ' ', 3));
righttopyspin_->get_adjustment()->set_value(anyLength.value());
}
controller().bbChanged = false;
}
void GGraphics::onBrowseClicked()
{
// Get the filename from the dialog
string const in_name = fileentry_->get_text();
string const out_name = controller().browse(in_name);
lyxerr[Debug::GRAPHICS]
<< "[FormGraphics]out_name: " << out_name << "\n";
if (out_name != in_name && !out_name.empty()) {
fileentry_->set_text(out_name);
}
if (controller().isFilenameValid(out_name) &&
!controller().bbChanged) {
updateBB(out_name, string());
}
bc().input(ButtonPolicy::SMI_VALID);
}
void GGraphics::onBBChange()
{
controller().bbChanged = true;
bc().input(ButtonPolicy::SMI_VALID);
}
void GGraphics::onBBFromFileClicked()
{
string const filename = fileentry_->get_text();
if (!filename.empty()) {
string bb = controller().readBB(filename);
if (!bb.empty()) {
leftbottomxspin_->set_text(token(bb, ' ', 0));
leftbottomyspin_->set_text(token(bb, ' ', 1));
righttopxspin_->set_text(token(bb, ' ', 2));
righttopyspin_->set_text(token(bb, ' ', 3));
updateComboFromLength(bbunitscombo_,LyXLength("bp"));
}
controller().bbChanged = false;
} else {
leftbottomxspin_->set_text("");
leftbottomyspin_->set_text("");
righttopxspin_->set_text("");
righttopyspin_->set_text("");
updateComboFromLength(bbunitscombo_,LyXLength("bp"));
}
bc().input(ButtonPolicy::SMI_VALID);
}
void GGraphics::onSubFigCheckToggled()
{
subfigentry_->set_sensitive(subfigcheck_->get_active());
bc().input(ButtonPolicy::SMI_VALID);
}
void GGraphics::onEditClicked()
{
controller().editGraphics();
}
void GGraphics::onInput()
{
bc().input(ButtonPolicy::SMI_VALID);
}
} // namespace frontend
} // namespace lyx

View File

@ -0,0 +1,106 @@
// -*- C++ -*-
/**
* \file GGraphics.h
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author John Spray
*
* Full author contact details are available in file CREDITS.
*/
#ifndef GGRAPHICS_H
#define GGRAPHICS_H
#include "GViewBase.h"
#include "lyxlength.h"
#include <boost/scoped_ptr.hpp>
#include <vector>
namespace lyx {
namespace frontend {
class ControlGraphics;
/** This class provides a GTK+ implementation of the Graphics Dialog.
*/
class GGraphics
: public GViewCB<ControlGraphics, GViewGladeB> {
public:
///
GGraphics(Dialog &);
private:
/// Set the Params variable for the Controller.
virtual void apply();
/// Build the dialog.
virtual void doBuild();
/// Update dialog before/whilst showing it.
virtual void update();
/// Update the BoundingBox info.
void updateBB(std::string const & filename, std::string const & bb_inset);
void PopulateComboBox(Gtk::ComboBox * combo,
std::vector<std::string> const & strings);
void updateComboFromLength(Gtk::ComboBox * combo,
LyXLength const & len);
bool updating_;
/// Store the LaTeX names for the rotation origins.
std::vector<std::string> origins_;
Gtk::TreeModelColumn<Glib::ustring> stringcol_;
Gtk::TreeModel::ColumnRecord cols_;
Gtk::Notebook * notebook_;
// File Page
Gtk::Entry * fileentry_;
Gtk::SpinButton * displayscalespin_;
Gtk::SpinButton * outputscalespin_;
Gtk::Button * browsebutton_;
Gtk::Button * editbutton_;
Gtk::ComboBox * displaycombo_;
Gtk::SpinButton * widthspin_;
Gtk::SpinButton * heightspin_;
Gtk::CheckButton * aspectcheck_;
Gtk::ComboBox * widthunitscombo_;
Gtk::ComboBox * heightunitscombo_;
Gtk::RadioButton * setscalingradio_;
Gtk::RadioButton * setsizeradio_;
// Bounding Box Page
Gtk::CheckButton * clipcheck_;
Gtk::SpinButton * righttopxspin_;
Gtk::SpinButton * righttopyspin_;
Gtk::SpinButton * leftbottomxspin_;
Gtk::SpinButton * leftbottomyspin_;
Gtk::ComboBox * bbunitscombo_;
Gtk::Button * bbfromfilebutton_;
// Extra Page
Gtk::SpinButton * anglespin_;
Gtk::ComboBox * origincombo_;
Gtk::CheckButton * subfigcheck_;
Gtk::Entry * subfigentry_;
Gtk::Entry * latexoptsentry_;
Gtk::CheckButton * draftcheck_;
Gtk::CheckButton * unzipcheck_;
void onSizingModeChange();
void onBrowseClicked();
void onBBChange();
void onBBFromFileClicked();
void onSubFigCheckToggled();
void onEditClicked();
void onInput();
};
} // namespace frontend
} // namespace lyx
#endif // GGRAPHICS_H

View File

@ -30,6 +30,8 @@ libgtk_la_SOURCES = \
GCharacter.h \
GErrorList.C \
GErrorList.h \
GGraphics.C \
GGraphics.h \
GLog.C \
GLog.h \
GLyXKeySym.C \
@ -116,7 +118,6 @@ xforms_objects = \
../xforms/FormERT.lo \
../xforms/FormExternal.lo \
../xforms/FormFloat.lo \
../xforms/FormGraphics.lo \
../xforms/FormInclude.lo \
../xforms/FormMathsBitmap.lo \
../xforms/FormMathsDelim.lo \

View File

@ -13,15 +13,25 @@
#include "ghelpers.h"
#include "debug.h"
#include "lengthcommon.h"
#include "support/filetools.h"
#include "support/path_defines.h"
using std::string;
using std::vector;
namespace lyx {
namespace frontend {
vector<string> const buildLengthUnitList()
{
vector<string> data(unit_name_gui, unit_name_gui + num_units);
return data;
}
string const findGladeFile(string const & name)
{
// First, search in the installation directories.

View File

@ -18,6 +18,8 @@
namespace lyx {
namespace frontend {
std::vector<std::string> const buildLengthUnitList();
/** name is the name of the glade file, without path or extension.
* Eg, "aboutlyx", "tableCreate".
*/

File diff suppressed because it is too large Load Diff