Re: GtkSheet
| From: | Gonzalo Monzón | Date: | Thu, 09 Feb 2006 05:59:41 +0000 |
| Subject: | Re: GtkSheet | ||
| References: | 1 | Groups: | php.gtk.general |
| Request: | Send a blank email to php-gtk-general+get-6686@lists.php.net to get a copy of this message | ||
Hi Breizh,
I've attached below an example I post to this maillist several months ago. Should help in basic handling of a GtkSheet.
The Tom Rogers version of the w32api is only requiered for the copy & paste clipboard handling -on win of course-, but at least you can see how to configure,
connect basic signals, and do some popup menu on right click selection for what it uses some w32api calls what should work on any standard version of that extension. (php4)
Regards,
Gonzalo.
Breizh Micro Services escribió:
I am searching examples with a GtkSheet. Does someone know where I can found some ? Thanks. François Le Gal - Breizh Micro ServicesHi all, I've coded a GtkSheet copy&paste example for csv clipboard data from apps as Excel, it uses the code snippet posted by Tom Rogers for excel clipboard c&p. Needs too the modified php_w32api from Tom, otherwise it won't work. It shows too how to generate a mouse event using the api, and how to attach a mouse clicked popupmenu on the GtkSheet. Regards, Gonzalo. <?php if (!extension_loaded('gtk')) {
dl( 'php_gtk.' . PHP_SHLIB_SUFFIX);}
if( !extension_loaded('win32')) { dl( 'php_w32api.' . PHP_SHLIB_SUFFIX);
}
$win32api =& new win32;
$win32api->registerfunction("bool mouse_event (long Flags, long dx, long dy, long Data, long ExtraInfo ) From user32.dll");
$win32api->registerfunction("bool OpenClipboard
(
long hWndNewOwner
)
From user32.dll");
$win32api->registerfunction("bool CloseClipboard
(
)
From user32.dll");
$win32api->registerfunction("int EnumClipboardFormats
(
int format
)
From user32.dll");
$win32api->registerfunction("int GetClipboardFormatName
(
int format,
string &FormatName,
int cchMaxCount
)
From user32.dll");
$win32api->registerfunction("long GetClipboardData
(
int uFormat
)
From user32.dll");
$win32api->registerfunction("string GlobalLock
(
long hMem
)
From kernel32.dll");
$win32api->registerfunction("bool GlobalUnlock
(
long hMem
)
From kernel32.dll");
$win32api->registerfunction("bool EmptyClipboard
(
)
From user32.dll");
$win32api->registerfunction("int RegisterClipboardFormat
(
string &Format
)
From user32.dll");
$win32api->registerfunction("long SetClipboardData
(
int uFormat,
long hMem
)
From user32.dll");
$win32api->registerfunction("long GlobalAlloc
(
int uFlags,
long Bytes
)
From kernel32.dll");
$win32api->registerfunction("long lstrcpyn
(
long String1,
string &String2,
int iMaxLength
)
From kernel32.dll");
$win32api->registerfunction("long GlobalHandle
(
long pMem
)
From kernel32.dll");
define('GPTR',0x0040); //allocate memory and zero fill it. // Create the window:
$w = &new GtkWindow;
$w->set_title('Testing the GtkSheet');
$w->connect('destroy', create_function('','Gtk::main_quit();'));
$w->set_position(GTK_WIN_POS_CENTER); $w->set_default_size((gdk::screen_width()/1.5)-15, (gdk::screen_height()-20)-15); // Create the widgets: $box =& new GtkVBox(false, 5);$buttonbox =& new GtkHBox();
$scrollw =& new GtkScrolledWindow();
$sheet =& new GtkSheet(100, 22, "sheet");
$button1 =& new GtkButton("Reset");
$button2 =& new GtkButton("Clear");
// Callbacks:
$sheet->connect_after('traverse', 'sheet_traverse');
$sheet->connect_after('button-press-event', 'sheet_button_press');
//$sheet->connect('button-release-event', 'sheet_button_release');
$button1->connect('clicked', "SheetRenewData");
$button2->connect('clicked', "SheetClearData");
// Let's pack the widgets:$box->pack_start($scrollw, true, true, 0); $buttonbox->pack_start($button1, false, false, 0); $buttonbox->pack_start($button2, false, false, 0); $box->pack_start($buttonbox, false, false, 0);
// Configure the sheet://$sheet->set_selection_mode(0); $sheet->set_column_titles_height(21); $sheet->set_row_titles_width(25); $sheet->show_all();
// Insert data for the first time:$count = 0; SheetRenewData();
// Finally pack it to the window:$scrollw->add($sheet); $w->add($box);
$w->show_all();
Gtk::main();
function SheetClearData() {
global $count, $sheet;
for($row = 0; $row<=100; $row++) {
// Lets adjust the row height for the first time:
if ($count == 0) {
$sheet->set_row_height($row,21);
}
$sheet->freeze(); // Using freeze & thaw speeds up a lot this process.
for ($col = 0; $col<=22; $col++) {
// Set the sheet cell data:
$sheet->set_cell($row, $col, 1, "");
// Lets adjust column width for the first time:
if (($row == 0) && ($count == 0)){
$sheet->set_column_width($col, 50);
}
if ($count == 0)
$sheet->row_set_sensitivity($row, false);
}
$sheet->thaw();
}
//$sheet->rows_labels_set_visibility(false);
$sheet->show_all();
// Keep track of reset count:
$count++;
}
function SheetRenewData() {
global $count, $sheet;
for($row = 0; $row<=100; $row++) {
// Lets adjust the row height for the first time:
if ($count == 0) {
$sheet->set_row_height($row,21);
}
$sheet->freeze(); // Using freeze & thaw speeds up a lot this process.
for ($col = 0; $col<=22; $col++) {
// Set the sheet cell data:
$sheet->set_cell($row, $col, 1, "$count-$row");
// Lets adjust column width for the first time:
if (($row == 0) && ($count == 0)){
$sheet->set_column_width($col, 50);
}
if ($count == 0)
$sheet->row_set_sensitivity($row, false);
}
$sheet->thaw();
}
//$sheet->rows_labels_set_visibility(false);
$sheet->show_all();
// Keep track of reset count:
$count++;
}
// Called when leaving one cell in a sheet and going to the nextfunction sheet_traverse($sheet,$row,$col,$row_next,$col_next) {
global $sheet_active_row, $sheet_active_col;
$sheet_active_row = $row_next;
$sheet_active_col = $col_next;
}
function sheet_button_release(&$sheet, $event) {
}
function sheet_button_press(&$sheet, $event, $clicked=false) {
global $sheet_active_row, $sheet_active_col;
global $sheet_origin_row, $sheet_origin_col;
global $sheet_destiny_row, $sheet_destiny_col;
global $win32api;
global $sheet_drag_start;
global $sheet_drag_mtim;
global $sheet_dont_update;
global $sheet_selection_array;
if ($event->button == 1) {
// clicked?
if ($sheet_dont_update == false) {
$sheet_origin_row = $sheet_active_row;
$sheet_origin_col = $sheet_active_col;
}
return;
}
// Right Button pressed?
if ($event->button == 3) {
// Let's generate a left button press to activate the cell under cursor,
// and add timeout to run this function again but $clicked = true
// We need to activate the cell as the sheet doesn't do anything on right button press...
if (!$clicked) {
$sheet_dont_update = true;
$win32api->mouse_event(0x0002, 0, 0, 0, 0); // Left down
$win32api->mouse_event(0x0004, 0, 0, 0, 0); // Left up
gtk::timeout_add(50, 'sheet_button_press', &$sheet, &$event, true);
return;
}
$sheet_dont_update = false;
// Get destiny cell, if dragged selection it wont be the same row-cell than in origin
$sheet_destiny_row = $sheet_active_row;
$sheet_destiny_col = $sheet_active_col;
unset($sheet_selection_array);
// Do we have different origin <> destiny cells? let's 'traverse' the sheet and get the content: if (($sheet_origin_row != $sheet_destiny_row) || ($sheet_origin_col != $sheet_destiny_col)) {
// Check if reverse selection...
if ($sheet_origin_row > $sheet_destiny_row) {
$tmp = $sheet_origin_row;
$sheet_origin_row = $sheet_destiny_row;
$sheet_destiny_row = $tmp;
}
if ($sheet_origin_col > $sheet_destiny_col) {
$tmp = $sheet_origin_col;
$sheet_origin_col = $sheet_destiny_col;
$sheet_destiny_col = $tmp;
}
unset($tmpA);
for ($row = $sheet_origin_row; $row <= $sheet_destiny_row; $row++) {
unset($tmpB);
for ($col = $sheet_origin_col; $col <= $sheet_destiny_col; $col++) {
if (!isset($tmpB))
$tmpB = $sheet->cell_get_text($row,$col);
else
$tmpB = $tmpB.";".$sheet->cell_get_text($row,$col);
}
// Add tmp array
$tmpA[] = $tmpB;
}
// Add data to array:
$sheet_selection_array = $tmpA;
} else {
// Only a cell its been selected?
$sheet_selection_array[0] = $sheet->cell_get_text($sheet_active_row,$sheet_active_col); }
// Let's create a popup menu:
// Create GtkMenu and GtkMenuItems...
$menu=&new GtkMenu();
$color=&new GdkColor('#000000');
$color1=&new GdkColor('blue');
// First option: 'Copy'
$sel=&new GtkMenuItem();
$label1=&new GtkLabel('Copy');
$hbox=&new GtkHBox();
$hbox->pack_start($label1,true,false);
$sel->add($hbox);
//
$sel->connect_object('activate','sheet_popupmenu_copy', &$sheet, $sheet_selection_array);
$menu->append($sel);
// 'Paste'
$sel2=&new GtkMenuItem();
$label1=&new GtkLabel('Paste');
$hbox=&new GtkHBox();
$hbox->pack_start($label1,true,false);
$sel2->add($hbox);
//
$sel2->connect_object('activate','sheet_popupmenu_paste', &$sheet, $sheet_active_row, $sheet_active_col);
$menu->append($sel2);
$menu->show_all();
$menu->popup(null,null,null,1,$event->time);
//
}
}
function sheet_popupmenu_copy( &$sheet, $selection_data){
global $win32api;
$NameSize = 128;
reset($selection_data);
for($row = 0; $row <= count($selection_data); $row++) {
if (!isset($tmp))
$tmp = $selection_data[$row];
else
$tmp = $tmp."\r\n".$selection_data[$row];
}
$data = $tmp;
// CLIPBOARD CSV TYPE READING FROM EXCEL/WORD...
// get a clipboard id
$id = $win32api->OpenClipboard('');
if($id){
$Format = 'Clipboard CSV Data';
$ok = false;
$fn = $win32api->EnumClipboardFormats(0);
do {
$name = str_repeat("\0", $NameSize); //zero the name holder
$result = $win32api->GetClipboardFormatName($fn,$name,$NameSize);
if(preg_match('/CSV/i',$name)){
$ok = true;
break;
}
} while ($fn = $win32api->EnumClipboardFormats($fn));
$win32api->CloseClipboard();
$register = false;
if ($ok == false) {
$register = true;
}
$id = $win32api->OpenClipboard($name);
$win32api->EmptyClipboard(); // graw ownership if ($register)
$fn = $win32api->RegisterClipboardFormat($Format);
$dest = $win32api->GlobalAlloc(GPTR, strlen($data)+1);
$handle = $win32api->GlobalHandle(&$dest);
$win32api->GlobalLock($handle);
$ndest = $win32api->lstrcpyn($dest, $data, strlen($data)+1);
$win32api->GlobalUnlock($handle);
$win32api->SetClipboardData($fn, $handle);
$win32api->CloseClipboard();
}
}
function sheet_popupmenu_paste( &$sheet, $actual_row, $actual_col)
{
global $win32api;
$NameSize = 128;
// CLIPBOARD CSV TYPE READING FROM EXCEL/WORD...
// get a clipboard id
$id = $win32api->OpenClipboard('');
if($id){
$fn = $win32api->EnumClipboardFormats(0);
do {
$name = str_repeat("\0", $NameSize); //zero the name holder
$result = $win32api->GetClipboardFormatName($fn,$name,$NameSize);
if(preg_match('/CSV/i',$name)){
$data_handle = $win32api->GetClipboardData($fn);
if($data_handle){
$text = trim($win32api->GlobalLock($data_handle));
$rows = explode("\r\n",$text);
foreach($rows as $key=>$row){
$rows[$key] = explode(',',$row); //add columns
}
$win32api->GlobalUnlock($data_handle);
}
break;
}
//echo "Fn $fn $name\n";
} while ($fn = $win32api->EnumClipboardFormats($fn));
$win32api->CloseClipboard();
// Put data into sheet:
if (isset($rows)) {
reset($rows);
$sheet->freeze(); // Using freeze & thaw speeds up a lot this process.
for($row = 0; $row < count($rows); $row++) {
unset($row_data);
$tmp = $rows[$row];
$row_data = explode(';',$tmp[0]);
for($col = 0; $col < count($row_data); $col++) {
$cell_data = $row_data[$col];
$sheet->set_cell($row + $actual_row, $col + $actual_col, 1, $cell_data);
}
}
$sheet->thaw();
}
}
}
?>