gambas-source-code/gb.qt4/src/CIconView.cpp
Benoît Minisini f65184802d [CONFIGURATION]
* NEW: Update copyright and license string in all source files.


git-svn-id: svn://localhost/gambas/trunk@2241 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2009-08-17 10:41:51 +00:00

904 lines
18 KiB
C++

/***************************************************************************
CIconView.cpp
(c) 2000-2009 Benoît Minisini <gambas@users.sourceforge.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***************************************************************************/
#define __CICONVIEW_CPP
#include <qapplication.h>
#include <q3header.h>
#include <qpalette.h>
#include <q3scrollview.h>
#include <q3iconview.h>
#include <qobject.h>
#include "gambas.h"
#include "CWidget.h"
#include "CPicture.h"
#include "CIconView.h"
#include "CConst.h"
DECLARE_EVENT(EVENT_Select); /* selection change */
DECLARE_EVENT(EVENT_Click); /* simple click */
DECLARE_EVENT(EVENT_Activate); /* double click */
DECLARE_EVENT(EVENT_Rename);
DECLARE_EVENT(EVENT_Cancel);
DECLARE_EVENT(EVENT_Compare);
static int _selection_mode[] =
{
SELECT_NONE, Q3IconView::NoSelection,
SELECT_SINGLE, Q3IconView::Single,
SELECT_MULTIPLE, Q3IconView::Extended,
CONST_MAGIC
};
/***************************************************************************
class MyIconViewItem
***************************************************************************/
void MyIconViewItem::initData(void)
{
picture = NULL;
key = NULL;
}
MyIconViewItem::MyIconViewItem(Q3IconView *parent)
: Q3IconViewItem(parent, " ")
{
initData();
}
MyIconViewItem::MyIconViewItem(Q3IconView *parent, MyIconViewItem *after)
: Q3IconViewItem(parent, after)
{
initData();
}
MyIconViewItem::~MyIconViewItem()
{
//CIconView *ob = (CIconView *)CWidget::get(listView());
//if (ob->item == this)
// ob->item = NULL;
if (container->item == this)
container->item = NULL;
if (container->save == this)
container->save = NULL;
container->dict->remove(key);
GB.Unref(POINTER(&picture));
GB.FreeString(&key);
}
void MyIconViewItem::setPicture(GB_OBJECT *pict)
{
SET_PIXMAP(setPixmap, &picture, pict);
}
int MyIconViewItem::compare(Q3IconViewItem *i) const
{
int ret;
if (!GB.CanRaise(container, EVENT_Compare))
ret = Q3IconViewItem::compare(i);
else
{
container->compare = 0;
GB.Raise(container, EVENT_Compare, 2, GB_T_STRING, key, 0, GB_T_STRING, ((MyIconViewItem *)i)->key, 0);
ret = container->compare;
}
if (!container->asc)
ret = (-ret);
return ret;
}
/***************************************************************************
class MyIconView
***************************************************************************/
MyIconView::MyIconView(QWidget *parent)
: Q3IconView(parent)
{
setMouseTracking(false);
viewport()->setMouseTracking(false);
setArrangementMode(Q3IconView::LeftToRight);
setWordWrapIconText(true);
setGridY(64);
setSpacing(8);
setGridWidth(0);
}
void MyIconView::startDrag()
{
}
int MyIconView::getArrangementMode()
{
if (itemsMovable())
return ARRANGEMENT_FREE;
else
return arrangement();
}
void MyIconView::setArrangementMode(int arr)
{
if (arr == ARRANGEMENT_FREE)
{
setItemsMovable(true);
setAutoArrange(false);
setResizeMode(Q3IconView::Fixed);
}
else
{
void *_object = CWidget::get(this);
setAutoArrange(true);
setItemsMovable(false);
setArrangement((Q3IconView::Arrangement)arr);
if (THIS->sorted)
sort(THIS->asc);
setResizeMode(Q3IconView::Adjust);
arrangeItemsInGrid(true);
}
}
void MyIconView::setGridWidth(int w)
{
if (w <= 0) w = 0;
_grid_width = w;
if (w == 0)
setGridX(192);
else
setGridX(w * MAIN_scale);
if (!itemsMovable())
arrangeItemsInGrid(true);
}
/***************************************************************************
IconView
***************************************************************************/
BEGIN_METHOD(CICONVIEW_new, GB_OBJECT parent)
MyIconView *wid = new MyIconView(QCONTAINER(VARG(parent)));
QObject::connect(wid, SIGNAL(selectionChanged()), &CIconView::manager, SLOT(selected()));
QObject::connect(wid, SIGNAL(doubleClicked(Q3IconViewItem *)), &CIconView::manager, SLOT(activated(Q3IconViewItem *)));
QObject::connect(wid, SIGNAL(clicked(Q3IconViewItem *)), &CIconView::manager, SLOT(clicked(Q3IconViewItem *)));
QObject::connect(wid, SIGNAL(itemRenamed(Q3IconViewItem *)), &CIconView::manager, SLOT(renamed(Q3IconViewItem *)));
CWIDGET_new(wid, (void *)_object);
THIS->dict = new Q3AsciiDict<MyIconViewItem>;
THIS->sorted = false;
THIS->asc = true;
THIS->item = NULL;
THIS->save = NULL;
THIS->editable = false;
END_METHOD
BEGIN_METHOD_VOID(CICONVIEW_free)
delete THIS->dict;
//CALL_METHOD_VOID(CWIDGET_delete);
END_METHOD
BEGIN_METHOD_VOID(CICONVIEW_clear)
THIS->dict->clear();
WIDGET->clear();
END_METHOD
BEGIN_METHOD(CICONVIEW_add, GB_STRING key; GB_STRING text; GB_OBJECT picture; GB_STRING after)
MyIconViewItem *item;
Q3IconView *wid = WIDGET;
char *key = GB.ToZeroString(ARG(key));
MyIconViewItem *after = NULL;
char *akey;
if (*key == 0)
{
GB.Error("Null key");
return;
}
item = (*THIS->dict)[key];
if (item != NULL)
{
GB.Error("Key already used");
return;
}
if (!MISSING(after))
{
akey = GB.ToZeroString(ARG(after));
if (*akey)
{
after = (*THIS->dict)[akey];
if (after == NULL)
{
GB.Error("After item does not exist");
return;
}
}
}
if (after == NULL)
item = new MyIconViewItem(wid);
else
item = new MyIconViewItem(wid, after);
item->setText(QSTRING_ARG(text));
GB.StoreString(ARG(key), &item->key);
THIS->dict->insert(item->key, item);
if (!MISSING(picture))
item->setPicture(ARG(picture));
item->container = THIS;
item->setRenameEnabled(THIS->editable);
THIS->item = item;
RETURN_SELF();
END_METHOD
BEGIN_METHOD(CICONVIEW_remove, GB_STRING key)
MyIconViewItem *item;
char *key = GB.ToZeroString(ARG(key));
item = CIconView::getItem(THIS, key);
if (!item)
return;
delete item;
END_METHOD
BEGIN_METHOD(CICONVIEW_exist, GB_STRING key)
GB.ReturnBoolean((*THIS->dict)[GB.ToZeroString(ARG(key))] != 0);
END_METHOD
BEGIN_METHOD(CICONVIEW_get, GB_STRING key)
MyIconViewItem *item;
char *key = GB.ToZeroString(ARG(key));
item = CIconView::getItem(THIS, key);
if (!item)
return;
THIS->item = item;
RETURN_SELF();
END_METHOD
BEGIN_PROPERTY(CICONVIEW_mode)
if (READ_PROPERTY)
GB.ReturnInteger(CCONST_convert(_selection_mode, WIDGET->selectionMode(), SELECT_NONE, false));
else
WIDGET->setSelectionMode((Q3IconView::SelectionMode)CCONST_convert(_selection_mode, VPROP(GB_INTEGER), SELECT_NONE, true));
END_PROPERTY
BEGIN_PROPERTY(CICONVIEW_current)
MyIconViewItem *item = (MyIconViewItem *)(WIDGET->currentItem());
THIS->item = item;
if (item == 0)
GB.ReturnNull();
else
RETURN_SELF();
END_PROPERTY
BEGIN_PROPERTY(CICONVIEW_key)
MyIconViewItem *item = (MyIconViewItem *)(WIDGET->currentItem());
THIS->item = item;
if (item == 0)
GB.ReturnNull();
else
GB.ReturnString(item->key);
END_PROPERTY
BEGIN_PROPERTY(CICONVIEW_item)
if (THIS->item == 0)
GB.ReturnNull();
else
RETURN_SELF();
END_PROPERTY
BEGIN_PROPERTY(CICONVIEW_available)
GB.ReturnBoolean(THIS->item != 0);
END_PROPERTY
BEGIN_METHOD(CICONVIEW_find, GB_INTEGER x; GB_INTEGER y)
QPoint p(VARG(x), VARG(y));
MyIconViewItem *item;
WIDGET->viewport()->mapFrom(WIDGET, p);
item = (MyIconViewItem *)WIDGET->findItem(p);
THIS->item = item;
GB.ReturnBoolean(THIS->item == 0);
END_METHOD
static void set_sorting(void *_object, bool sorted, bool asc)
{
if (sorted == THIS->sorted && asc == THIS->asc)
return;
THIS->sorted = sorted;
THIS->asc = asc;
//qDebug("setSorting(%s, %s)", THIS->sorted ? "true" : "false", THIS->asc ? "true" : "false");
WIDGET->setSorting(THIS->sorted, THIS->asc);
if (THIS->sorted)
{
//qDebug("sort(%s)", THIS->asc ? "true" : "false");
WIDGET->sort();
}
}
BEGIN_PROPERTY(CICONVIEW_sorted)
if (READ_PROPERTY)
GB.ReturnBoolean(THIS->sorted);
else
set_sorting(THIS, VPROP(GB_BOOLEAN), THIS->asc);
END_PROPERTY
BEGIN_PROPERTY(CICONVIEW_editable)
if (READ_PROPERTY)
GB.ReturnBoolean(THIS->editable);
else
THIS->editable = VPROP(GB_BOOLEAN);
END_PROPERTY
BEGIN_PROPERTY(CICONVIEW_ascending)
if (READ_PROPERTY)
GB.ReturnBoolean(THIS->asc);
else
set_sorting(_object, THIS->sorted, VPROP(GB_BOOLEAN));
END_PROPERTY
BEGIN_PROPERTY(CICONVIEW_count)
GB.ReturnInteger(WIDGET->count());
END_PROPERTY
static void return_item(void *_object, MyIconViewItem *item)
{
if (!item)
THIS->save = THIS->item;
THIS->item = item;
GB.ReturnBoolean(item == 0);
}
BEGIN_METHOD_VOID(CICONVIEW_back)
MyIconViewItem *item = THIS->save;
THIS->save = 0;
return_item(THIS, item);
END_METHOD
BEGIN_METHOD(CICONVIEW_move_to, GB_STRING key)
char *key = GB.ToZeroString(ARG(key));
MyIconViewItem *item = (*THIS->dict)[key];
return_item(THIS, item);
END_METHOD
BEGIN_METHOD_VOID(CICONVIEW_first)
return_item(THIS, (MyIconViewItem *)(WIDGET->firstItem()));
END_METHOD
BEGIN_METHOD_VOID(CICONVIEW_next)
return_item(THIS, (MyIconViewItem *)(THIS->item->nextItem()));
END_METHOD
BEGIN_PROPERTY(CICONVIEW_scrollbar)
//QScrollView *wid = (QScrollView *)QWIDGET(_object);
int scroll;
if (READ_PROPERTY)
{
scroll = 0;
if (WIDGET->hScrollBarMode() == Q3ScrollView::Auto)
scroll += 1;
if (WIDGET->vScrollBarMode() == Q3ScrollView::Auto)
scroll += 2;
GB.ReturnInteger(scroll);
}
else
{
scroll = VPROP(GB_INTEGER) & 3;
WIDGET->setHScrollBarMode( (scroll & 1) ? Q3ScrollView::Auto : Q3ScrollView::AlwaysOff);
WIDGET->setVScrollBarMode( (scroll & 2) ? Q3ScrollView::Auto : Q3ScrollView::AlwaysOff);
}
END_PROPERTY
BEGIN_PROPERTY(CICONVIEWITEM_key)
GB.ReturnString(THIS->item->key);
END_PROPERTY
BEGIN_PROPERTY(CICONVIEWITEM_picture)
if (READ_PROPERTY)
GB.ReturnObject(THIS->item->picture);
else
THIS->item->setPicture(PROP(GB_OBJECT));
END_PROPERTY
BEGIN_PROPERTY(CICONVIEWITEM_selected)
MyIconViewItem *it = THIS->item;
if (READ_PROPERTY)
GB.ReturnBoolean(it->isSelected());
else
it->iconView()->setSelected(it, VPROP(GB_BOOLEAN), true);
END_PROPERTY
BEGIN_PROPERTY(CICONVIEWITEM_text)
MyIconViewItem *it = THIS->item;
if (READ_PROPERTY)
GB.ReturnNewZeroString(TO_UTF8(it->text()));
else
it->setText(QSTRING_PROP());
END_PROPERTY
BEGIN_METHOD_VOID(CICONVIEWITEM_ensure_visible)
//qDebug("ensure visible: %p", THIS->item);
WIDGET->ensureItemVisible(THIS->item);
END_METHOD
BEGIN_METHOD_VOID(CICONVIEWITEM_delete)
THIS->dict->remove(THIS->item->key);
delete THIS->item;
END_PROPERTY
/*
BEGIN_METHOD_VOID(CICONVIEWITEM_init)
CLASS_Item = GB.FindClass("Item");
END_METHOD
*/
BEGIN_PROPERTY(CICONVIEW_client_width)
GB.ReturnInteger(WIDGET->width() - WIDGET->frameWidth() * 2);
END_PROPERTY
BEGIN_PROPERTY(CICONVIEW_client_height)
GB.ReturnInteger(WIDGET->height() - WIDGET->frameWidth() * 2);
END_PROPERTY
BEGIN_METHOD(CICONVIEW_select_all, GB_BOOLEAN on)
if (MISSING(on) || VARG(on))
WIDGET->selectAll(true);
else
WIDGET->selectAll(false);
END_METHOD
BEGIN_PROPERTY(CICONVIEW_grid_w)
if (READ_PROPERTY)
GB.ReturnInteger(WIDGET->gridWidth());
else
WIDGET->setGridWidth(VPROP(GB_INTEGER));
END_PROPERTY
/*BEGIN_PROPERTY(CICONVIEW_grid_h)
if (READ_PROPERTY)
GB.ReturnInteger(WIDGET->gridY() / MAIN_scale);
else
{
WIDGET->setGridY(VPROP(GB_INTEGER) * MAIN_scale);
if (!WIDGET->itemsMovable())
WIDGET->arrangeItemsInGrid(true);
}
END_PROPERTY*/
/*BEGIN_PROPERTY(CICONVIEW_arrangement)
if (READ_PROPERTY)
GB.ReturnInteger(WIDGET->getArrangementMode());
else
WIDGET->setArrangementMode(VPROP(GB_INTEGER));
END_PROPERTY*/
/*BEGIN_PROPERTY(CICONVIEW_word_wrap)
if (READ_PROPERTY)
GB.ReturnBoolean(WIDGET->wordWrapIconText());
else
WIDGET->setWordWrapIconText(VPROP(GB_BOOLEAN));
END_PROPERTY*/
BEGIN_PROPERTY(CICONVIEW_compare)
if (READ_PROPERTY)
GB.ReturnInteger(THIS->compare);
else
THIS->compare = VPROP(GB_INTEGER);
END_PROPERTY
BEGIN_PROPERTY(CICONVIEWITEM_x)
if (READ_PROPERTY)
GB.ReturnInteger(THIS->item->x());
else
THIS->item->move(VPROP(GB_INTEGER), THIS->item->y());
END_PROPERTY
BEGIN_PROPERTY(CICONVIEWITEM_y)
if (READ_PROPERTY)
GB.ReturnInteger(THIS->item->y());
else
THIS->item->move(THIS->item->x(), VPROP(GB_INTEGER));
END_PROPERTY
BEGIN_PROPERTY(CICONVIEWITEM_w)
GB.ReturnInteger(THIS->item->width());
END_PROPERTY
BEGIN_PROPERTY(CICONVIEWITEM_h)
GB.ReturnInteger(THIS->item->height());
END_PROPERTY
BEGIN_METHOD(CICONVIEWITEM_move, GB_INTEGER x; GB_INTEGER y)
THIS->item->move(VARG(x), VARG(y));
END_METHOD
BEGIN_PROPERTY(CICONVIEWITEM_editable)
if (READ_PROPERTY)
GB.ReturnBoolean(THIS->item->renameEnabled());
else
THIS->item->setRenameEnabled(VPROP(GB_BOOLEAN));
END_PROPERTY
BEGIN_METHOD_VOID(CICONVIEWITEM_rename)
THIS->item->rename();
END_METHOD
/***************************************************************************
IconViewItem
***************************************************************************/
GB_DESC CIconViewItemDesc[] =
{
GB_DECLARE(".IconViewItem", 0), GB_VIRTUAL_CLASS(),
GB_PROPERTY_READ("Key", "s", CICONVIEWITEM_key),
GB_PROPERTY("Picture", "Picture", CICONVIEWITEM_picture),
GB_PROPERTY("Selected", "b", CICONVIEWITEM_selected),
GB_PROPERTY("Text", "s", CICONVIEWITEM_text),
GB_METHOD("EnsureVisible", NULL, CICONVIEWITEM_ensure_visible, NULL),
GB_METHOD("Delete", NULL, CICONVIEWITEM_delete, NULL),
GB_PROPERTY("Editable", "b", CICONVIEWITEM_editable),
GB_METHOD("Rename", NULL, CICONVIEWITEM_rename, NULL),
GB_METHOD("MoveNext", "b", CICONVIEW_next, NULL),
GB_PROPERTY("X", "i", CICONVIEWITEM_x),
GB_PROPERTY("Left", "i", CICONVIEWITEM_x),
GB_PROPERTY("Y", "i", CICONVIEWITEM_y),
GB_PROPERTY("Top", "i", CICONVIEWITEM_y),
GB_PROPERTY_READ("W", "i", CICONVIEWITEM_w),
GB_PROPERTY_READ("Width", "i", CICONVIEWITEM_w),
GB_PROPERTY_READ("H", "i", CICONVIEWITEM_h),
GB_PROPERTY_READ("Height", "i", CICONVIEWITEM_h),
GB_METHOD("Move", NULL, CICONVIEWITEM_move, "(X)i(Y)i"),
GB_END_DECLARE
};
/***************************************************************************
IconView
***************************************************************************/
GB_DESC CIconViewDesc[] =
{
GB_DECLARE("IconView", sizeof(CICONVIEW)), GB_INHERITS("Control"),
GB_CONSTANT("Free", "i", ARRANGEMENT_FREE),
GB_CONSTANT("Row", "i", Q3IconView::LeftToRight),
GB_CONSTANT("Column", "i", Q3IconView::TopToBottom),
GB_CONSTANT("LeftRight", "i", Q3IconView::LeftToRight),
GB_CONSTANT("TopBottom", "i", Q3IconView::TopToBottom),
GB_METHOD("_new", NULL, CICONVIEW_new, "(Parent)Container;"),
GB_METHOD("_free", NULL, CICONVIEW_free, NULL),
GB_PROPERTY("Mode", "i", CICONVIEW_mode),
GB_PROPERTY("Sorted", "b", CICONVIEW_sorted),
GB_PROPERTY("Editable", "b", CICONVIEW_editable),
GB_PROPERTY("Ascending", "b", CICONVIEW_ascending),
//GB_PROPERTY("Arrangement", "i", CICONVIEW_arrangement),
GB_PROPERTY("GridWidth", "i", CICONVIEW_grid_w),
//GB_PROPERTY("GridHeight", "i", CICONVIEW_grid_h),
//GB_PROPERTY("WordWrap", "b", CICONVIEW_word_wrap),
GB_PROPERTY("Border", "b", CWIDGET_border_simple),
GB_PROPERTY("ScrollBar", "i", CWIDGET_scrollbar),
GB_PROPERTY("Compare", "i", CICONVIEW_compare),
GB_PROPERTY_READ("Count", "i", CICONVIEW_count),
GB_PROPERTY_READ("Available", "b", CICONVIEW_available),
GB_METHOD("MoveTo", "b", CICONVIEW_move_to, "(Key)s"),
GB_METHOD("MoveFirst", "b", CICONVIEW_first, NULL),
GB_METHOD("MoveNext", "b", CICONVIEW_next, NULL),
GB_METHOD("MoveBack", "b", CICONVIEW_back, NULL),
GB_METHOD("_get", ".IconViewItem", CICONVIEW_get, "(Key)s"),
GB_METHOD("Clear", NULL, CICONVIEW_clear, NULL),
GB_METHOD("Add", ".IconViewItem", CICONVIEW_add, "(Key)s(Text)s[(Picture)Picture;(After)s]"),
GB_METHOD("Remove", NULL, CICONVIEW_remove, "(Key)s"),
GB_METHOD("Exist", "b", CICONVIEW_exist, "(Key)s"),
GB_METHOD("Find", "b", CICONVIEW_find, "(X)i(Y)i"),
GB_PROPERTY_READ("Current", ".IconViewItem", CICONVIEW_current),
GB_PROPERTY_READ("Key", "s", CICONVIEW_key),
GB_PROPERTY_READ("Item", ".IconViewItem", CICONVIEW_item),
GB_METHOD("SelectAll", NULL, CICONVIEW_select_all, "[(Select)b]"),
GB_PROPERTY_READ("ClientWidth", "i", CICONVIEW_client_width),
GB_PROPERTY_READ("ClientW", "i", CICONVIEW_client_width),
GB_PROPERTY_READ("ClientHeight", "i", CICONVIEW_client_height),
GB_PROPERTY_READ("ClientH", "i", CICONVIEW_client_height),
GB_EVENT("Select", NULL, NULL, &EVENT_Select),
GB_EVENT("Activate", NULL, NULL, &EVENT_Activate),
GB_EVENT("Click", NULL, NULL, &EVENT_Click),
GB_EVENT("Rename", NULL, NULL, &EVENT_Rename),
GB_EVENT("Cancel", NULL, NULL, &EVENT_Cancel),
GB_EVENT("Compare", NULL, "(Key)s(OtherKey)s", &EVENT_Compare),
ICONVIEW_DESCRIPTION,
GB_END_DECLARE
};
/***************************************************************************
class CIconView
***************************************************************************/
CIconView CIconView::manager;
MyIconViewItem *CIconView::getItem(CICONVIEW *treeview, char *key)
{
MyIconViewItem *item = (*treeview->dict)[key];
if (item == 0)
{
GB.Error("Unknown item '&1'", key);
return NULL;
}
return item;
}
void CIconView::raiseEvent(int ev, Q3IconViewItem *it)
{
GET_SENDER();
MyIconViewItem *old = THIS->item;
if (!it)
it = WIDGET->currentItem();
THIS->item = (MyIconViewItem *)it;
RAISE_EVENT(ev);
THIS->item = old;
}
void CIconView::selected(void)
{
raiseEvent(EVENT_Select, 0);
#if QT_VERSION < 0x030200
raiseEvent(EVENT_Click, 0);
#endif
}
void CIconView::activated(Q3IconViewItem *it)
{
if (!it)
return;
raiseEvent(EVENT_Activate, it);
}
void CIconView::clicked(Q3IconViewItem *it)
{
if (!it)
return;
raiseEvent(EVENT_Click, it);
}
void CIconView::renamed(Q3IconViewItem *it)
{
raiseEvent(EVENT_Rename, it);
}