index 4b84078e5b4ccc8a48a8bfe39a06caa7e42b7805..f597c601baf783b3aeae1c812063e4dfedfc1a13 100644 (file)
#include <glibmm/i18n.h>
#include <gtkmm/stock.h>
-#include "libnr/nr-matrix-ops.h"
#include "verbs.h"
-#include "prefs-utils.h"
+#include "preferences.h"
#include "inkscape.h"
#include "desktop-handles.h"
#include "selection.h"
int
sp_compare_x_position(SPItem *first, SPItem *second)
{
- using NR::X;
- using NR::Y;
+ using Geom::X;
+ using Geom::Y;
- NR::Rect const a = first->invokeBbox(sp_item_i2doc_affine(first));
- double const a_height = a.dimensions()[Y];
+ boost::optional<Geom::Rect> a = first->getBounds(sp_item_i2doc_affine(first));
+ boost::optional<Geom::Rect> b = second->getBounds(sp_item_i2doc_affine(second));
- NR::Rect const b = second->invokeBbox(sp_item_i2doc_affine(second));
- double const b_height = b.dimensions()[Y];
+ if ( !a || !b ) {
+ // FIXME?
+ return 0;
+ }
+
+ double const a_height = a->dimensions()[Y];
+ double const b_height = b->dimensions()[Y];
bool a_in_b_vert = false;
- if ((a.min()[Y] < b.min()[Y] + 0.1) && (a.min()[Y] > b.min()[Y] - b_height)) {
+ if ((a->min()[Y] < b->min()[Y] + 0.1) && (a->min()[Y] > b->min()[Y] - b_height)) {
a_in_b_vert = true;
- } else if ((b.min()[Y] < a.min()[Y] + 0.1) && (b.min()[Y] > a.min()[Y] - a_height)) {
+ } else if ((b->min()[Y] < a->min()[Y] + 0.1) && (b->min()[Y] > a->min()[Y] - a_height)) {
a_in_b_vert = true;
- } else if (b.min()[Y] == a.min()[Y]) {
+ } else if (b->min()[Y] == a->min()[Y]) {
a_in_b_vert = true;
} else {
a_in_b_vert = false;
if (!a_in_b_vert) {
return -1;
}
- if (a_in_b_vert && a.min()[X] > b.min()[X]) {
+ if (a_in_b_vert && a->min()[X] > b->min()[X]) {
return 1;
}
- if (a_in_b_vert && a.min()[X] < b.min()[X]) {
+ if (a_in_b_vert && a->min()[X] < b->min()[X]) {
return -1;
}
return 0;
int
sp_compare_y_position(SPItem *first, SPItem *second)
{
- NR::Rect const a = first->invokeBbox(sp_item_i2doc_affine(first));
- NR::Rect const b = second->invokeBbox(sp_item_i2doc_affine(second));
+ boost::optional<Geom::Rect> a = first->getBounds(sp_item_i2doc_affine(first));
+ boost::optional<Geom::Rect> b = second->getBounds(sp_item_i2doc_affine(second));
+
+ if ( !a || !b ) {
+ // FIXME?
+ return 0;
+ }
- if (a.min()[NR::Y] > b.min()[NR::Y]) {
+ if (a->min()[Geom::Y] > b->min()[Geom::Y]) {
return 1;
}
- if (a.min()[NR::Y] < b.min()[NR::Y]) {
+ if (a->min()[Geom::Y] < b->min()[Geom::Y]) {
return -1;
}
total_col_width=0;
total_row_height=0;
+ // check for correct numbers in the row- and col-spinners
+ on_col_spinbutton_changed();
+ on_row_spinbutton_changed();
// set padding to manual values
paddingx = XPadSpinner.get_value();
grid_left = 99999;
grid_top = 99999;
- SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ SPDesktop *desktop = getDesktop();
sp_document_ensure_up_to_date(sp_desktop_document(desktop));
Inkscape::Selection *selection = sp_desktop_selection (desktop);
cnt=0;
for (; items != NULL; items = items->next) {
SPItem *item = SP_ITEM(items->data);
- NR::Rect const b = item->invokeBbox(sp_item_i2doc_affine(item));
- width = b.dimensions()[NR::X];
- height = b.dimensions()[NR::Y];
- cx = b.midpoint()[NR::X];
- cy = b.midpoint()[NR::Y];
-
- if (b.min()[NR::X] < grid_left) {
- grid_left = b.min()[NR::X];
+ boost::optional<Geom::Rect> b = item->getBounds(sp_item_i2doc_affine(item));
+ if (!b) {
+ continue;
+ }
+
+ width = b->dimensions()[Geom::X];
+ height = b->dimensions()[Geom::Y];
+
+ cx = b->midpoint()[Geom::X];
+ cy = b->midpoint()[Geom::Y];
+
+ if (b->min()[Geom::X] < grid_left) {
+ grid_left = b->min()[Geom::X];
}
- if (b.min()[NR::Y] < grid_top) {
- grid_top = b.min()[NR::Y];
+ if (b->min()[Geom::Y] < grid_top) {
+ grid_top = b->min()[Geom::Y];
}
if (width > col_width) {
col_width = width;
const GSList *sizes = sorted;
for (; sizes != NULL; sizes = sizes->next) {
SPItem *item = SP_ITEM(sizes->data);
- NR::Rect const b = item->invokeBbox(sp_item_i2doc_affine(item));
- width = b.dimensions()[NR::X];
- height = b.dimensions()[NR::Y];
- if (width > col_widths[(cnt % NoOfCols)]) {
- col_widths[(cnt % NoOfCols)] = width;
- }
- if (height > row_heights[(cnt / NoOfCols)]) {
- row_heights[(cnt / NoOfCols)] = height;
+ boost::optional<Geom::Rect> b = item->getBounds(sp_item_i2doc_affine(item));
+ if (b) {
+ width = b->dimensions()[Geom::X];
+ height = b->dimensions()[Geom::Y];
+ if (width > col_widths[(cnt % NoOfCols)]) {
+ col_widths[(cnt % NoOfCols)] = width;
+ }
+ if (height > row_heights[(cnt / NoOfCols)]) {
+ row_heights[(cnt / NoOfCols)] = height;
+ }
}
+
cnt++;
}
}
+ boost::optional<Geom::Rect> sel_bbox = selection->bounds();
// Fit to bbox, calculate padding between rows accordingly.
- if (!SpaceManualRadioButton.get_active()){
- NR::Rect b = selection->bounds();
+ if ( sel_bbox && !SpaceManualRadioButton.get_active() ){
#ifdef DEBUG_GRID_ARRANGE
-g_print("\n row = %f col = %f selection x= %f selection y = %f", total_row_height,total_col_width, b.extent(NR::X), b.extent(NR::Y));
+g_print("\n row = %f col = %f selection x= %f selection y = %f", total_row_height,total_col_width, b.extent(Geom::X), b.extent(Geom::Y));
#endif
- paddingx = (b.extent(NR::X) - total_col_width) / (NoOfCols -1);
- paddingy = (b.extent(NR::Y) - total_row_height) / (NoOfRows -1);
+ paddingx = (sel_bbox->width() - total_col_width) / (NoOfCols -1);
+ paddingy = (sel_bbox->height() - total_row_height) / (NoOfRows -1);
}
/*
for (; current_row != NULL; current_row = current_row->next) {
SPItem *item=SP_ITEM(current_row->data);
Inkscape::XML::Node *repr = SP_OBJECT_REPR(item);
- NR::Rect const b = item->invokeBbox(sp_item_i2doc_affine(item));
- width = b.dimensions()[NR::X];
- height = b.dimensions()[NR::Y];
+ boost::optional<Geom::Rect> b = item->getBounds(sp_item_i2doc_affine(item));
+ Geom::Point min;
+ if (b) {
+ width = b->dimensions()[Geom::X];
+ height = b->dimensions()[Geom::Y];
+ min = b->min();
+ } else {
+ width = height = 0;
+ min = Geom::Point(0, 0);
+ }
+
row = cnt / NoOfCols;
col = cnt % NoOfCols;
- // original before I started fecking about with it.
- // new_x = grid_left + (((col_width - width)/2)*HorizAlign) + (( col_width + paddingx ) * (cnt % NoOfCols));
- // new_y = grid_top + (((row_height - height)/2)*VertAlign) +(( row_height + paddingy ) * (cnt / NoOfCols));
-
new_x = grid_left + (((col_widths[col] - width)/2)*HorizAlign) + col_xs[col];
new_y = grid_top + (((row_heights[row] - height)/2)*VertAlign) + row_ys[row];
- NR::Point move = NR::Point(new_x - b.min()[NR::X], b.min()[NR::Y] - new_y); // why are the two args the opposite ways round???
- NR::Matrix const &affine = NR::Matrix(NR::translate(move));
+ // signs are inverted between x and y due to y inversion
+ Geom::Point move = Geom::Point(new_x - min[Geom::X], min[Geom::Y] - new_y);
+ Geom::Matrix const affine = Geom::Matrix(Geom::Translate(move));
sp_item_set_i2d_affine(item, sp_item_i2d_affine(item) * affine);
sp_item_write_transform(item, repr, item->transform, NULL);
- SP_OBJECT (current_row->data)->updateRepr(repr, SP_OBJECT_WRITE_EXT);
+ SP_OBJECT (current_row->data)->updateRepr();
cnt +=1;
}
g_slist_free (current_row);
}
- NRRect b;
- selection->bounds(&b);
-
- sp_document_done (sp_desktop_document (desktop));
+ sp_document_done (sp_desktop_document (desktop), SP_VERB_SELECTION_GRIDTILE,
+ _("Arrange in a grid"));
}
// in turn, prevent listener from responding
updating = true;
- SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ SPDesktop *desktop = getDesktop();
Inkscape::Selection *selection = sp_desktop_selection (desktop);
double PerCol = ceil(selcount / NoOfColsSpinner.get_value());
NoOfRowsSpinner.set_value(PerCol);
- prefs_set_double_attribute ("dialogs.gridtiler", "NoOfCols", NoOfColsSpinner.get_value());
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setDouble("/dialogs/gridtiler/NoOfCols", NoOfColsSpinner.get_value());
updating=false;
}
// in turn, prevent listener from responding
updating = true;
- SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ SPDesktop *desktop = getDesktop();
Inkscape::Selection *selection = sp_desktop_selection (desktop);
GSList const *items = selection->itemList();
double PerRow = ceil(selcount / NoOfRowsSpinner.get_value());
NoOfColsSpinner.set_value(PerRow);
- prefs_set_double_attribute ("dialogs.gridtiler", "NoOfCols", PerRow);
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setDouble("/dialogs/gridtiler/NoOfCols", PerRow);
updating=false;
}
*/
void TileDialog::on_xpad_spinbutton_changed()
{
-
- prefs_set_double_attribute ("dialogs.gridtiler", "XPad", XPadSpinner.get_value());
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setDouble("/dialogs/gridtiler/XPad", XPadSpinner.get_value());
}
*/
void TileDialog::on_ypad_spinbutton_changed()
{
-
- prefs_set_double_attribute ("dialogs.gridtiler", "YPad", YPadSpinner.get_value());
-
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setDouble("/dialogs/gridtiler/YPad", YPadSpinner.get_value());
}
*/
void TileDialog::on_RowSize_checkbutton_changed()
{
-
- if (RowHeightButton.get_active()) {
- prefs_set_double_attribute ("dialogs.gridtiler", "AutoRowSize", 20);
- } else {
- prefs_set_double_attribute ("dialogs.gridtiler", "AutoRowSize", -20);
- }
- RowHeightBox.set_sensitive ( !RowHeightButton.get_active());
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ if (RowHeightButton.get_active()) {
+ prefs->setDouble("/dialogs/gridtiler/AutoRowSize", 20);
+ } else {
+ prefs->setDouble("/dialogs/gridtiler/AutoRowSize", -20);
+ }
+ RowHeightBox.set_sensitive ( !RowHeightButton.get_active());
}
/**
*/
void TileDialog::on_ColSize_checkbutton_changed()
{
-
- if (ColumnWidthButton.get_active()) {
- prefs_set_double_attribute ("dialogs.gridtiler", "AutoColSize", 20);
- } else {
- prefs_set_double_attribute ("dialogs.gridtiler", "AutoColSize", -20);
- }
- ColumnWidthBox.set_sensitive ( !ColumnWidthButton.get_active());
-
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ if (ColumnWidthButton.get_active()) {
+ prefs->setDouble("/dialogs/gridtiler/AutoColSize", 20);
+ } else {
+ prefs->setDouble("/dialogs/gridtiler/AutoColSize", -20);
+ }
+ ColumnWidthBox.set_sensitive ( !ColumnWidthButton.get_active());
}
/**
// in turn, prevent listener from responding
updating = true;
- prefs_set_double_attribute ("dialogs.gridtiler", "RowHeight", RowHeightSpinner.get_value());
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setDouble("/dialogs/gridtiler/RowHeight", RowHeightSpinner.get_value());
updating=false;
}
// in turn, prevent listener from responding
updating = true;
- prefs_set_double_attribute ("dialogs.gridtiler", "ColWidth", ColumnWidthSpinner.get_value());
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setDouble("/dialogs/gridtiler/ColWidth", ColumnWidthSpinner.get_value());
updating=false;
}
*/
void TileDialog::Spacing_button_changed()
{
- if (SpaceManualRadioButton.get_active()) {
- prefs_set_double_attribute ("dialogs.gridtiler", "SpacingType", 20);
- } else {
- prefs_set_double_attribute ("dialogs.gridtiler", "SpacingType", -20);
- }
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ if (SpaceManualRadioButton.get_active()) {
+ prefs->setDouble("/dialogs/gridtiler/SpacingType", 20);
+ } else {
+ prefs->setDouble("/dialogs/gridtiler/SpacingType", -20);
+ }
- SizesHBox.set_sensitive ( SpaceManualRadioButton.get_active());
+ SizesHBox.set_sensitive ( SpaceManualRadioButton.get_active());
}
/**
*/
void TileDialog::VertAlign_changed()
{
- if (VertTopRadioButton.get_active()) {
- VertAlign = 0;
- prefs_set_double_attribute ("dialogs.gridtiler", "VertAlign", 0);
- } else if (VertCentreRadioButton.get_active()){
- VertAlign = 1;
- prefs_set_double_attribute ("dialogs.gridtiler", "VertAlign", 1);
- } else if (VertBotRadioButton.get_active()){
- VertAlign = 2;
- prefs_set_double_attribute ("dialogs.gridtiler", "VertAlign", 2);
- }
-
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ if (VertTopRadioButton.get_active()) {
+ VertAlign = 0;
+ prefs->setInt("/dialogs/gridtiler/VertAlign", 0);
+ } else if (VertCentreRadioButton.get_active()){
+ VertAlign = 1;
+ prefs->setInt("/dialogs/gridtiler/VertAlign", 1);
+ } else if (VertBotRadioButton.get_active()){
+ VertAlign = 2;
+ prefs->setInt("/dialogs/gridtiler/VertAlign", 2);
+ }
}
/**
*/
void TileDialog::HorizAlign_changed()
{
- if (HorizLeftRadioButton.get_active()) {
- HorizAlign = 0;
- prefs_set_double_attribute ("dialogs.gridtiler", "HorizAlign", 0);
- } else if (HorizCentreRadioButton.get_active()){
- HorizAlign = 1;
- prefs_set_double_attribute ("dialogs.gridtiler", "HorizAlign", 1);
- } else if (HorizRightRadioButton.get_active()){
- HorizAlign = 2;
- prefs_set_double_attribute ("dialogs.gridtiler", "HorizAlign", 2);
- }
-
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ if (HorizLeftRadioButton.get_active()) {
+ HorizAlign = 0;
+ prefs->setInt("/dialogs/gridtiler/HorizAlign", 0);
+ } else if (HorizCentreRadioButton.get_active()){
+ HorizAlign = 1;
+ prefs->setInt("/dialogs/gridtiler/HorizAlign", 1);
+ } else if (HorizRightRadioButton.get_active()){
+ HorizAlign = 2;
+ prefs->setInt("/dialogs/gridtiler/HorizAlign", 2);
+ }
}
/**
*/
void TileDialog::updateSelection()
{
- double col_width, row_height;
// quit if run by the attr_changed listener
if (updating) {
- return;
- }
+ return;
+ }
- col_width=0;
- row_height=0;
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ double col_width = 0;
+ double row_height = 0;
// in turn, prevent listener from responding
updating = true;
- SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ SPDesktop *desktop = getDesktop();
Inkscape::Selection *selection = sp_desktop_selection (desktop);
const GSList *items = selection->itemList();
int selcount = g_slist_length((GSList *)items);
- if (NoOfColsSpinner.get_value()>1){
+ if (NoOfColsSpinner.get_value()>1 && NoOfRowsSpinner.get_value()>1){
// Update the number of rows assuming number of columns wanted remains same.
double NoOfRows = ceil(selcount / NoOfColsSpinner.get_value());
NoOfRowsSpinner.set_value(NoOfRows);
if (selcount<NoOfColsSpinner.get_value()) {
double NoOfCols = ceil(selcount / NoOfRowsSpinner.get_value());
NoOfColsSpinner.set_value(NoOfCols);
- prefs_set_double_attribute ("dialogs.gridtiler", "NoOfCols", NoOfCols);
+ prefs->setInt("/dialogs/gridtiler/NoOfCols", NoOfCols);
}
} else {
- NoOfColsSpinner.set_value(selcount);
- prefs_set_double_attribute ("dialogs.gridtiler", "NoOfCols", selcount);
+ double PerRow = ceil(sqrt(selcount));
+ double PerCol = ceil(sqrt(selcount));
+ NoOfRowsSpinner.set_value(PerRow);
+ NoOfColsSpinner.set_value(PerCol);
+ prefs->setInt("/dialogs/gridtiler/NoOfCols", static_cast<int>(PerCol));
}
-
-
/*##########################
## Experimental
##########################*/
-static void updateSelectionCallback(Inkscape::Application *inkscape, Inkscape::Selection *selection, TileDialog *dlg)
+static void updateSelectionCallback(Inkscape::Application */*inkscape*/, Inkscape::Selection */*selection*/, TileDialog *dlg)
{
TileDialog *tledlg = (TileDialog *) dlg;
tledlg->updateSelection();
@@ -586,10 +613,11 @@ static void updateSelectionCallback(Inkscape::Application *inkscape, Inkscape::S
* Constructor
*/
TileDialog::TileDialog()
- : Dialog ("dialogs.gridtiler", SP_VERB_SELECTION_GRIDTILE)
+ : UI::Widget::Panel("", "/dialogs/gridtiler", SP_VERB_SELECTION_GRIDTILE)
{
// bool used by spin button callbacks to stop loops where they change each other.
updating = false;
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
// could not do this in gtkmm - there's no Gtk::SizeGroup public constructor (!)
GtkSizeGroup *_col1 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
g_signal_connect ( G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (updateSelectionCallback), this);
}
- Gtk::VBox *mainVBox = get_vbox();
+ Gtk::Box *contents = _getContents();
#define MARGIN 2
//##Set up the panel
- SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ SPDesktop *desktop = getDesktop();
Inkscape::Selection *selection = sp_desktop_selection (desktop);
int selcount = 1;
/*#### Number of Rows ####*/
- double PerRow = selcount;
- double PerCol = 1;
+ double PerRow = ceil(sqrt(selcount));
+ double PerCol = ceil(sqrt(selcount));
#ifdef DEBUG_GRID_ARRANGE
g_print("/n PerRox = %f PerCol = %f selcount = %d",PerRow,PerCol,selcount);
gtk_size_group_add_widget(_col1, (GtkWidget *) NoOfRowsBox.gobj());
RowHeightButton.set_label(_("Equal height"));
- double AutoRow = prefs_get_double_attribute ("dialogs.gridtiler", "AutoRowSize", 15);
+ double AutoRow = prefs->getDouble("/dialogs/gridtiler/AutoRowSize", 15);
if (AutoRow>0)
AutoRowSize=true;
else
VertBotRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::VertAlign_changed));
VertAlignVBox.pack_start(VertBotRadioButton, false, false, 0);
- VertAlign = prefs_get_double_attribute ("dialogs.gridtiler", "VertAlign", 1);
+ VertAlign = prefs->getInt("/dialogs/gridtiler/VertAlign", 1);
if (VertAlign == 0) {
VertTopRadioButton.set_active(TRUE);
}
gtk_size_group_add_widget(_col3, (GtkWidget *) NoOfColsBox.gobj());
ColumnWidthButton.set_label(_("Equal width"));
- double AutoCol = prefs_get_double_attribute ("dialogs.gridtiler", "AutoColSize", 15);
+ double AutoCol = prefs->getDouble("/dialogs/gridtiler/AutoColSize", 15);
if (AutoCol>0)
AutoColSize=true;
else
HorizAlignHBox.pack_start(*(new Gtk::HBox()), true, true, 0); // centering strut
- HorizAlign = prefs_get_double_attribute ("dialogs.gridtiler", "HorizAlign", 1);
+ HorizAlign = prefs->getInt("/dialogs/gridtiler/HorizAlign", 1);
if (HorizAlign == 0) {
HorizLeftRadioButton.set_active(TRUE);
}
YPadSpinner.set_digits(1);
YPadSpinner.set_increments(0.2, 2);
YPadSpinner.set_range(-10000, 10000);
- double YPad = prefs_get_double_attribute ("dialogs.gridtiler", "YPad", 15);
+ double YPad = prefs->getDouble("/dialogs/gridtiler/YPad", 15);
YPadSpinner.set_value(YPad);
YPadBox.pack_start(YPadSpinner, true, true, MARGIN);
tips.set_tip(YPadSpinner, _("Vertical spacing between rows (px units)"));
XPadSpinner.set_digits(1);
XPadSpinner.set_increments(0.2, 2);
XPadSpinner.set_range(-10000, 10000);
- double XPad = prefs_get_double_attribute ("dialogs.gridtiler", "XPad", 15);
+ double XPad = prefs->getDouble("/dialogs/gridtiler/XPad", 15);
XPadSpinner.set_value(XPad);
XPadBox.pack_start(XPadSpinner, true, true, MARGIN);
tips.set_tip(XPadSpinner, _("Horizontal spacing between columns (px units)"));
TileBox.pack_start(SizesHBox, false, false, MARGIN);
- mainVBox->pack_start(TileBox);
+ contents->pack_start(TileBox);
- double SpacingType = prefs_get_double_attribute ("dialogs.gridtiler", "SpacingType", 15);
+ double SpacingType = prefs->getDouble("/dialogs/gridtiler/SpacingType", 15);
if (SpacingType>0) {
ManualSpacing=true;
} else {
SizesHBox.set_sensitive (ManualSpacing);
//## The OK button
- TileOkButton = add_button(Gtk::Stock::APPLY, GTK_RESPONSE_APPLY);
+ TileOkButton = addResponseButton(_("Arrange"), GTK_RESPONSE_APPLY);
tips.set_tip((*TileOkButton), _("Arrange selected objects"));
show_all_children();
}
-
-
-
-
-
} //namespace Dialog
} //namespace UI
} //namespace Inkscape
-//#########################################################################
-//## E N D O F F I L E
-//#########################################################################
-
-
/*
Local Variables:
mode:c++
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
-
-
-
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 ::