Initial community commit
This commit is contained in:
406
Src/Wasabi/api/skin/widgets/db/autofilterlist.cpp
Normal file
406
Src/Wasabi/api/skin/widgets/db/autofilterlist.cpp
Normal file
@@ -0,0 +1,406 @@
|
||||
#include <precomp.h>
|
||||
#include "autofilterlist.h"
|
||||
#include <api/db/subqueryserver.h>
|
||||
#include <api/script/objects/c_script/c_text.h>
|
||||
#include <api/script/objects/c_script/h_button.h>
|
||||
#include <api/wnd/popup.h>
|
||||
#include <bfc/file/filename.h>
|
||||
|
||||
#define TIMER_SCANNERDEL 0x6891
|
||||
|
||||
class ButtHooker : public H_Button {
|
||||
public:
|
||||
ButtHooker(AutoFilterList *hangout, ScriptObject *butt) : afl(hangout), H_Button(butt) { }
|
||||
void hook_onLeftClick() {
|
||||
afl->doFieldPopup();
|
||||
}
|
||||
|
||||
private:
|
||||
AutoFilterList *afl;
|
||||
};
|
||||
|
||||
FilterListItem::FilterListItem(void *_data, int _datalen, int _datatype) {
|
||||
data_len = _datalen;
|
||||
data_type = _datatype;
|
||||
data.setSize(data_len+1);
|
||||
MEMCPY(data.getMemory(), _data, data_len);
|
||||
}
|
||||
|
||||
AutoFilterList::AutoFilterList() {
|
||||
showColumnsHeaders = FALSE;
|
||||
local_scanner = NULL;
|
||||
order = -1;
|
||||
viscount = 0;
|
||||
grab_playstrings = 0;
|
||||
linked = 1;
|
||||
hooker = NULL;
|
||||
needrestart = 0;
|
||||
querydirection = SetQuery::FORWARD;
|
||||
last_populate_flag = -1;
|
||||
setContent("wasabi.buttonbar.stack");
|
||||
fn = NULL;
|
||||
data_type = NULL;
|
||||
}
|
||||
|
||||
AutoFilterList::~AutoFilterList() {
|
||||
delete local_scanner;
|
||||
delete hooker;
|
||||
}
|
||||
|
||||
int AutoFilterList::onInit() {
|
||||
AUTOFILTERLIST_PARENT::onInit();
|
||||
//scannerserver_newScanner();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void AutoFilterList::scannerserver_onNewScanner(SharedDbScannerI *scanner) {
|
||||
AUTOFILTERLIST_DBPARENTSRV::scannerserver_onNewScanner(scanner);
|
||||
delete local_scanner;
|
||||
local_scanner = new dbScanner(scannerserver_getTable());
|
||||
local_scanner->setQuery(sqs_getQuery());
|
||||
}
|
||||
|
||||
void AutoFilterList::mqc_onNewMultiQuery(SubQueryServer *modifier, int flag) {
|
||||
AUTOFILTERLIST_DBPARENTCLIENT::mqc_onNewMultiQuery(modifier);
|
||||
if (!isInited()) return;
|
||||
if (modifier == this && !needrestart) return;
|
||||
if (local_scanner == NULL) return;
|
||||
int id = sqs_getCooperativeId();
|
||||
int need_reset = (modifier == NULL || needrestart);
|
||||
if (!need_reset) switch (flag) {//glag!
|
||||
default:
|
||||
case SetQuery::FORWARD:
|
||||
need_reset = (id >= modifier->sqs_getCooperativeId());
|
||||
break;
|
||||
case SetQuery::REVERSE:
|
||||
need_reset = (id <= modifier->sqs_getCooperativeId());
|
||||
break;
|
||||
case SetQuery::GLOBAL:
|
||||
need_reset = (id != modifier->sqs_getCooperativeId());
|
||||
break;
|
||||
}
|
||||
|
||||
if (need_reset) {
|
||||
needrestart = 0;
|
||||
|
||||
last_populate_flag = flag;
|
||||
|
||||
int optimized = sqs_getMultiQueryServer() && sqs_getMultiQueryServer()->mqs_isQueryEmpty();
|
||||
|
||||
uniques.deleteAll();
|
||||
deleteAllItems();
|
||||
|
||||
const char *allstr = getAllString();
|
||||
FilterListItem *fli = new FilterListItem((void *)allstr, STRLEN(allstr)+1, MDT_STRINGZ);
|
||||
insertItem(0, NULL, reinterpret_cast<LPARAM>(fli));
|
||||
setSelected(0, 1);
|
||||
|
||||
SharedDbScannerI *shs = scannerserver_getScanner();
|
||||
if (shs != NULL) {
|
||||
dbSvcScanner *sc = shs->getScanner();
|
||||
if (sc != NULL) sc->cancelQuery();
|
||||
}
|
||||
dbSvcScanner *lc= local_scanner->getScanner();
|
||||
if (lc != NULL) lc->cancelQuery();
|
||||
|
||||
if (optimized) {
|
||||
grab_playstrings = 0;
|
||||
setRedraw(0);
|
||||
dbScanner *unique_scanner = new dbScanner(sqs_getTable(), field);
|
||||
while (!unique_scanner->eof()) {
|
||||
char data[4096]="";
|
||||
unique_scanner->getData("Value", data, 4095, MDT_STRINGZ);
|
||||
data[4095]=0;
|
||||
insertData(data, STRLEN(data)+1, MDT_STRINGZ);
|
||||
unique_scanner->next();
|
||||
}
|
||||
setRedraw(1);
|
||||
delete unique_scanner;
|
||||
} else {
|
||||
grab_playstrings = 1;
|
||||
lc->cancelQuery();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void AutoFilterList::mqc_onCompleteMultiQuery() {
|
||||
grab_playstrings = 0;
|
||||
}
|
||||
|
||||
void AutoFilterList::mqc_onAddPlaystring(const char *playstring, int nitems, int thispos) {
|
||||
AUTOFILTERLIST_DBPARENTCLIENT::mqc_onAddPlaystring(playstring, nitems, thispos);
|
||||
if (grab_playstrings)
|
||||
filterEntry(playstring, local_scanner, field);
|
||||
}
|
||||
|
||||
void AutoFilterList::setMetadataField(const char *_field) {
|
||||
if (!field.isempty() && STRCASEEQL(field, _field)) return;
|
||||
field = _field;
|
||||
delColumnByPos(0);
|
||||
addColumn(field, 100);
|
||||
data_type = api->metadb_getMetaDataType(field);
|
||||
sqs_setTable(api->metadb_getMetaDataTable(field));
|
||||
if (isPostOnInit())
|
||||
setLabelName();
|
||||
sqs_setQuery("");
|
||||
needrestart = 1;
|
||||
scannerserver_newScanner();
|
||||
}
|
||||
|
||||
int AutoFilterList::onResize() {
|
||||
AUTOFILTERLIST_PARENT::onResize();
|
||||
RECT r = clientRect();
|
||||
ListColumn *c = enumListColumn(0);
|
||||
if (!c) return 1;
|
||||
c->setWidth(r.right-r.left-4);
|
||||
recalcHeaders();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void AutoFilterList::getClientRect(RECT *r) {
|
||||
AUTOFILTERLIST_PARENT::getClientRect(r);
|
||||
api_window *rw = getContentRootWnd();
|
||||
if (rw) r->top += rw->getPreferences(SUGGESTED_H);
|
||||
// else r->top += 16;
|
||||
}
|
||||
|
||||
void AutoFilterList::rootwndholder_getRect(RECT *r) {
|
||||
getClientRect(r);
|
||||
r->bottom = r->top;
|
||||
api_window *rw = getContentRootWnd();
|
||||
if (rw) r->top -= rw->getPreferences(SUGGESTED_H);
|
||||
// else r->top += 16;
|
||||
}
|
||||
|
||||
void AutoFilterList::onNewContent() {
|
||||
setLabelName();
|
||||
// hook the clicks
|
||||
delete hooker;
|
||||
ScriptObject *mousetrap = findScriptObject("mousetrap");
|
||||
hooker = new ButtHooker(this, mousetrap);
|
||||
}
|
||||
|
||||
int AutoFilterList::ownerDraw(Canvas *canvas, int pos, RECT *r, LPARAM lParam, int isselected, int isfocused) {
|
||||
COLORREF bgcolor = isfocused ? getFocusColor(lParam) : getSelBgColor(lParam);
|
||||
COLORREF fgcolor = getTextColor(lParam);
|
||||
|
||||
RECT box;
|
||||
canvas->getClipBox(&box);
|
||||
|
||||
if (!getBgBitmap()) {
|
||||
RECT r2 = *r;
|
||||
r2.left = box.left;
|
||||
new RegionI reg(&r2);
|
||||
canvas->selectClipRgn(®);
|
||||
canvas->fillRect(r, getBgColor());
|
||||
}
|
||||
|
||||
canvas->setTextColor(fgcolor);
|
||||
|
||||
if (isselected) {
|
||||
RECT mr = *r;
|
||||
canvas->fillRect(&mr, bgcolor);
|
||||
}
|
||||
|
||||
if (isfocused)
|
||||
canvas->drawRect(r, 0, getFocusColor(lParam));
|
||||
|
||||
canvas->pushTextSize(getFontSize());
|
||||
|
||||
int x = 1+r->left;
|
||||
for (int i = 0; i < getNumColumns(); i++) {
|
||||
RECT ir;
|
||||
ir.left = x;
|
||||
ir.right = x + getColumnWidth(i);
|
||||
ir.top = r->top;
|
||||
ir.bottom = r->bottom;
|
||||
if (ir.right >= box.left && ir.bottom >= box.top && ir.left <= box.right && ir.top <= box.bottom) {
|
||||
FilterListItem *fli = reinterpret_cast<FilterListItem *>(lParam);
|
||||
api->metadb_renderData(canvas, ir, (void *)fli->getData(), fli->getDatatype(), 0);
|
||||
}
|
||||
x = ir.right;
|
||||
}
|
||||
canvas->popTextSize();
|
||||
return 1;
|
||||
}
|
||||
|
||||
void AutoFilterList::filterEntry(const char *playstring, dbScanner *scanner, const char *field) {
|
||||
dbSvcScanner *sp = scanner->getScanner();
|
||||
if (sp != NULL) sp->push();
|
||||
scanner->setIndexName(MT_PLAYSTRING);
|
||||
scanner->setIndexValue(playstring);
|
||||
scanner->first();
|
||||
|
||||
if (scanner->eof()) return;
|
||||
|
||||
char data[4096]="";
|
||||
scanner->getData((char *)field, data, 4095, data_type);
|
||||
data[4095]=0;
|
||||
|
||||
sp->pop();
|
||||
|
||||
switch (data_type) {
|
||||
case MDT_INT:
|
||||
case MDT_TIME:
|
||||
case MDT_BOOLEAN:
|
||||
case MDT_TIMESTAMP:
|
||||
filterInt(*(int *)data);
|
||||
break;
|
||||
case MDT_STRINGZ:
|
||||
filterString((const char *)data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AutoFilterList::filterInt(int data) {
|
||||
int pos=0;
|
||||
if (uniques.findItem((const char *)&data, &pos)) return;
|
||||
insertData(&data, 4, data_type);
|
||||
}
|
||||
|
||||
void AutoFilterList::insertData(void *data, int len, int type) {
|
||||
int pos=0;
|
||||
FilterListItem *fli = new FilterListItem(data, len, type);
|
||||
uniques.addItem(fli);
|
||||
pos = uniques.searchItem(fli);
|
||||
insertItem(pos+1/*+1 for item ALL at the top*/, NULL, reinterpret_cast<LPARAM>(fli));
|
||||
}
|
||||
|
||||
void AutoFilterList::filterString(const char *data) {
|
||||
if (!data || !*data) return;
|
||||
int pos=0;
|
||||
if (uniques.findItem(data, &pos)) return;
|
||||
insertData((void *)data, STRLEN(data)+1, data_type);
|
||||
}
|
||||
|
||||
void AutoFilterList::onLeftClick(int itemnum) {
|
||||
|
||||
if (itemnum == 0 && last_populate_flag != lastflag) {
|
||||
needrestart = 1;
|
||||
}
|
||||
String query;
|
||||
if (itemnum > 0) {
|
||||
for (int i=0;i<getNumItems();i++) {
|
||||
if (getItemSelected(i)) {
|
||||
if (!query.isempty())
|
||||
query += " || ";
|
||||
query += field;
|
||||
query += " == ";
|
||||
FilterListItem *fli = reinterpret_cast<FilterListItem *>(getItemData(i));
|
||||
switch (fli->getDatatype()) {
|
||||
case MDT_INT:
|
||||
case MDT_TIME:
|
||||
case MDT_BOOLEAN:
|
||||
case MDT_TIMESTAMP:
|
||||
query += StringPrintf("%d", *(int *)fli->getData());
|
||||
break;
|
||||
case MDT_STRINGZ:
|
||||
query += "\"";
|
||||
query += fli->getData();
|
||||
query += "\"";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sqs_setQuery(query, querydirection);
|
||||
if (local_scanner != NULL) local_scanner->setQuery(query);
|
||||
}
|
||||
|
||||
void AutoFilterList::onDoubleClick(int itemnum) {
|
||||
int sav = querydirection;
|
||||
querydirection = SetQuery::GLOBAL;
|
||||
onLeftClick(itemnum);
|
||||
querydirection = sav;
|
||||
}
|
||||
|
||||
void AutoFilterList::sqs_onAttachServer(MultiQueryServer *s) {
|
||||
s->mqs_registerClient(this);
|
||||
}
|
||||
|
||||
void AutoFilterList::sqs_onDetachServer(MultiQueryServer *s) {
|
||||
s->mqs_unregisterClient(this);
|
||||
}
|
||||
|
||||
void AutoFilterList::sqs_reset() {
|
||||
postDeferredCallback(7873, 3245);
|
||||
}
|
||||
|
||||
int AutoFilterList::onDeferredCallback(intptr_t p1, intptr_t p2) {
|
||||
if (p1 == 7873 && p2 == 3245) {
|
||||
deselectAll();
|
||||
setItemFocused(0);
|
||||
setSelected(0, TRUE);
|
||||
needrestart=1; last_populate_flag = -1;
|
||||
onLeftClick(0);
|
||||
ensureItemVisible(0);
|
||||
return 1;
|
||||
}
|
||||
return AUTOFILTERLIST_PARENT::onDeferredCallback(p1, p2);
|
||||
}
|
||||
|
||||
void AutoFilterList::setLabelName() {
|
||||
ScriptObject *tx = findScriptObject("buttonbar.text");
|
||||
if (tx == NULL) return;
|
||||
C_Text(tx).setText(field);
|
||||
}
|
||||
|
||||
void AutoFilterList::setQueryDirection(int glag) {
|
||||
querydirection = glag;
|
||||
}
|
||||
|
||||
void AutoFilterList::doFieldPopup() {
|
||||
PopupMenu popup;
|
||||
dbSvcScanner *scanner = api->metadb_newScanner(sqs_getTable());
|
||||
if (scanner == NULL) return;
|
||||
int n = scanner->getNumCols();
|
||||
PtrListQuickSorted<String, StringComparator> fields;
|
||||
for (int i = 0; i < n; i++) {
|
||||
dbSvcColInfo *info = scanner->enumCol(i);
|
||||
if (!info->uniques_indexed) continue;
|
||||
fields.addItem(new String(info->name));
|
||||
}
|
||||
fields.sort();
|
||||
foreach(fields)
|
||||
const char *name = fields.getfor()->getValue();
|
||||
int checked = STRCASEEQLSAFE(name, field);
|
||||
popup.addCommand(name, foreach_index, checked);
|
||||
endfor
|
||||
RECT cr = clientRect();
|
||||
clientToScreen((int *)&cr.left, (int *)&cr.top);
|
||||
int r = popup.popAtXY(cr.left, cr.top);
|
||||
if (r >= 0) {
|
||||
const char *col = fields.enumItem(r)->getValue();
|
||||
dbSvcColInfo *info = scanner->getColByName(col);
|
||||
setMetadataField(info->name);
|
||||
}
|
||||
fields.deleteAll();
|
||||
api->metadb_deleteScanner(scanner);
|
||||
}
|
||||
|
||||
void AutoFilterList::onVScrollToggle(BOOL set) {
|
||||
AUTOFILTERLIST_PARENT::onVScrollToggle(set);
|
||||
if (getContentRootWnd() && isPostOnInit())
|
||||
onResize();
|
||||
}
|
||||
|
||||
int AutoFilterList::onBeginDrag(int iItem) {
|
||||
String query;
|
||||
FilterListItem *fli = reinterpret_cast<FilterListItem *>(getItemData(iItem));
|
||||
if (fli == NULL) return 0; // BU added in response to talkback data we'll see if it helps
|
||||
String val = (fli->getDatatype() == MDT_STRINGZ) ? fli->getData() : StringPrintf(*(int *)fli->getData()).getValue();
|
||||
fn = new FilenameI(StringPrintf("query://%s;\"%s\" == \"%s\"", StringPrintf(scannerserver_getTable()).getValue(), field.getValue(), val.getValue()));
|
||||
addDragItem(Filename::dragitem_getDatatype(), static_cast<Filename*>(fn));
|
||||
handleDrag();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int AutoFilterList::dragComplete(int success) {
|
||||
delete fn; fn = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
447
Src/Wasabi/api/skin/widgets/db/autofilterlist.h
Normal file
447
Src/Wasabi/api/skin/widgets/db/autofilterlist.h
Normal file
@@ -0,0 +1,447 @@
|
||||
#ifndef __AUTOFILTERLIST_H
|
||||
#define __AUTOFILTERLIST_H
|
||||
|
||||
#include "../std.h"
|
||||
#include "listwnd.h"
|
||||
#include "../db/scanner.h"
|
||||
#include "../timeslicer.h"
|
||||
#include "../db/subqueryserver.h"
|
||||
#include "../db/multiqueryclient.h"
|
||||
#include "autoquerylist.h"
|
||||
|
||||
/**
|
||||
A filter list item is a data item of any type or
|
||||
size to put on a FilterList. The type and size are accessible
|
||||
for memory management purposes.
|
||||
|
||||
@short Items for FilterLists
|
||||
@author Nullsoft
|
||||
@ver 1.0
|
||||
@see FilterListItemSort, MultiQueryServer
|
||||
*/
|
||||
class FilterListItem {
|
||||
public:
|
||||
|
||||
/**
|
||||
Allocates memory for copying a data
|
||||
object, and then copies the object into newly allocated memory.
|
||||
|
||||
@see MemBlock
|
||||
@see VoidMemblock
|
||||
@param _data Pointer to a data object
|
||||
@param _datalen Length of data object
|
||||
@param _datatype Type of data object
|
||||
*/
|
||||
FilterListItem(void *_data, int _datalen, int _datatype);
|
||||
|
||||
/**
|
||||
Does nothing.
|
||||
*/
|
||||
virtual ~FilterListItem() { }
|
||||
|
||||
/**
|
||||
Get the data associated with the filter
|
||||
list item.
|
||||
|
||||
@see getDatatype()
|
||||
@see getDataLen()
|
||||
@ret A pointer to the data.
|
||||
*/
|
||||
const char *getData() { return data.getMemory(); }
|
||||
|
||||
/**
|
||||
Get the type of the data associated with the
|
||||
filter list item.
|
||||
|
||||
@see getData()
|
||||
@see getDataLen()
|
||||
@see metatags.h
|
||||
@ret Data type of item.
|
||||
*/
|
||||
int getDatatype() { return data_type; }
|
||||
|
||||
/**
|
||||
Get the length of the data (in bytes).
|
||||
|
||||
@see getDatatype()
|
||||
@see getData()
|
||||
@ret Length of data (in bytes).
|
||||
*/
|
||||
int getDataLen() { return data_len; }
|
||||
|
||||
private:
|
||||
|
||||
MemBlock<char> data;
|
||||
int data_type;
|
||||
int data_len;
|
||||
};
|
||||
|
||||
/**
|
||||
Provides methods for sorting a FilterList.
|
||||
|
||||
@short FilterList sorting.
|
||||
@author Nullsoft
|
||||
@ver 1.0
|
||||
@see FilterListItem
|
||||
*/
|
||||
class FilterListItemSort {
|
||||
public:
|
||||
/**
|
||||
Determines the data types of two objects and
|
||||
calls an appropriate comparison function to compare them.
|
||||
|
||||
@assert The two objects to be compared have the same data type.
|
||||
@see compareAttrib()
|
||||
@ret -1, _p1 < _p2; 0, _p1 = _p2; 1, _p1 > _p2
|
||||
@param _p1 Object to compare
|
||||
@param _p2 Object to compare
|
||||
*/
|
||||
static int compareItem(void *_p1, void *_p2) {
|
||||
FilterListItem *p1 = ((FilterListItem *)_p1);
|
||||
FilterListItem *p2 = ((FilterListItem *)_p2);
|
||||
ASSERT(p1->getDatatype() == p2->getDatatype());
|
||||
switch (p1->getDatatype()) {
|
||||
case MDT_INT:
|
||||
case MDT_TIME:
|
||||
case MDT_BOOLEAN:
|
||||
case MDT_TIMESTAMP: {
|
||||
int a = *(int *)p1->getData();
|
||||
int b = *(int *)p2->getData();
|
||||
if (a < b) return -1;
|
||||
if (a > b) return 1;
|
||||
return 0; }
|
||||
case MDT_STRINGZ:
|
||||
return STRICMP(p1->getData(), p2->getData());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Compares the value of an item to an attribute string,
|
||||
or to the value of the attribute string cast to an
|
||||
appropriate data type.
|
||||
|
||||
@see compareItem()
|
||||
@ret -1, _p1 < _p2; 0, _p1 = _p2; 1, _p1 > _p2
|
||||
@param attrib
|
||||
@param _item
|
||||
*/
|
||||
static int compareAttrib(const wchar_t *attrib, void *_item) {
|
||||
FilterListItem *item = ((FilterListItem *)_item);
|
||||
switch (item->getDatatype()) {
|
||||
case MDT_INT:
|
||||
case MDT_TIME:
|
||||
case MDT_BOOLEAN:
|
||||
case MDT_TIMESTAMP: {
|
||||
int a = *(int *)attrib;
|
||||
int b = *(int *)item->getData();
|
||||
if (a < b) return -1;
|
||||
if (a > b) return 1;
|
||||
return 0; }
|
||||
case MDT_STRINGZ:
|
||||
return STRICMP(attrib, item->getData());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
class ButtHooker;
|
||||
class FilenameI;
|
||||
|
||||
#define AUTOFILTERLIST_PARENT ListWnd
|
||||
#define AUTOFILTERLIST_DBPARENTSRV SubQueryServerI
|
||||
#define AUTOFILTERLIST_DBPARENTCLIENT MultiQueryClientI
|
||||
|
||||
/**
|
||||
A list of items to filter on.
|
||||
|
||||
@short A list of items to filter on.
|
||||
@author Nullsoft
|
||||
@ver 1.0
|
||||
@see FilterListItemSort
|
||||
@see FilterListItem
|
||||
*/
|
||||
class AutoFilterList : public AUTOFILTERLIST_PARENT,
|
||||
public AUTOFILTERLIST_DBPARENTSRV,
|
||||
public AUTOFILTERLIST_DBPARENTCLIENT {
|
||||
public:
|
||||
|
||||
/**
|
||||
Creates an empty filter list with a NULL local scanner.
|
||||
|
||||
@see ~AutoFilterList()
|
||||
*/
|
||||
AutoFilterList();
|
||||
|
||||
/**
|
||||
Deletes the local scanner.
|
||||
|
||||
@see AutoFilterList()
|
||||
*/
|
||||
virtual ~AutoFilterList();
|
||||
|
||||
/**
|
||||
Sets the field name and sets the scanner to NULL.
|
||||
|
||||
@param field The name of the field.
|
||||
*/
|
||||
void setMetadataField(const char *field);
|
||||
|
||||
/**
|
||||
Creates and populates the list.
|
||||
|
||||
@ret 1
|
||||
*/
|
||||
virtual int onInit();
|
||||
|
||||
/**
|
||||
Prepares a window for repainting in a new size.
|
||||
|
||||
@ret 1
|
||||
*/
|
||||
virtual int onResize();
|
||||
|
||||
virtual void getClientRect(RECT *);
|
||||
virtual void rootwndholder_getRect(RECT *r);
|
||||
virtual void onNewContent();
|
||||
|
||||
/**
|
||||
Displays a window in a specified position and state.
|
||||
|
||||
@ret 1
|
||||
@param canvas
|
||||
@param pos
|
||||
@param r
|
||||
@param lParam
|
||||
@param isselected
|
||||
@param isfocused
|
||||
*/
|
||||
virtual int ownerDraw(Canvas *canvas, int pos, RECT *r, LPARAM lParam, int isselected, int isfocused);
|
||||
|
||||
/**
|
||||
Event is triggered when the user clicks (with the left mouse
|
||||
button) on an item in the auto filter list.
|
||||
|
||||
@param itemnum The number of the item that was clicked.
|
||||
*/
|
||||
virtual void onLeftClick(int itemnum);
|
||||
|
||||
/**
|
||||
Event is triggered when the user double-clicks (with the left mouse
|
||||
button) on an item in the auto filter list.
|
||||
|
||||
@param itemnum The number of the item that was double-clicked.
|
||||
*/
|
||||
virtual void onDoubleClick(int itemnum); // double-click on an item
|
||||
|
||||
/**
|
||||
Gets the dependency pointer.
|
||||
|
||||
@ret The dependency pointer.
|
||||
*/
|
||||
virtual api_dependent *timeslicer_getDependencyPtr() { return rootwnd_getDependencyPtr(); }
|
||||
|
||||
/**
|
||||
Returns the proper query string for "all items"
|
||||
present in the list.
|
||||
|
||||
@ret Query string for "all items".
|
||||
*/
|
||||
virtual const char *getAllString() { return "All"; }
|
||||
|
||||
|
||||
/**
|
||||
Deletes the current scanner and sets up a new one.
|
||||
|
||||
@param A shared database scanner
|
||||
*/
|
||||
virtual void scannerserver_onNewScanner(SharedDbScannerI *scanner);
|
||||
|
||||
/**
|
||||
Makes the necessary preparations for running a new query.
|
||||
|
||||
@see SetQuery
|
||||
@see MultiQueryServer, SubQueryServer
|
||||
@param modifier refers to a SubQueryServer, which implements a simple filter.
|
||||
@param flag The type of query that will be performed.
|
||||
*/
|
||||
virtual void mqc_onNewMultiQuery(SubQueryServer *modifier, int flag);
|
||||
|
||||
/**
|
||||
Gets the dependency pointer.
|
||||
|
||||
@see api_dependent
|
||||
@ret Dependency Dependency pointer
|
||||
*/
|
||||
virtual api_dependent *mqc_getDependencyPtr() { return rootwnd_getDependencyPtr(); }
|
||||
|
||||
/**
|
||||
Sets the order of the result list.
|
||||
<b>Not currently implemented!</b>
|
||||
|
||||
@param order order desired for the result list.
|
||||
*/
|
||||
void setOrder(int n) { order = n; }
|
||||
|
||||
/**
|
||||
Gets the order number.
|
||||
|
||||
@see setOrder()
|
||||
@ret Order number if linked, otherwise -1
|
||||
@param None
|
||||
*/
|
||||
virtual int sqs_getCooperativeId() { return linked ? order : -1; }
|
||||
|
||||
/**
|
||||
Event is triggered when a multi query has completed.
|
||||
Has no external effect.
|
||||
*/
|
||||
virtual void mqc_onCompleteMultiQuery();
|
||||
|
||||
/**
|
||||
Tests whether to enter a playstring in a filter entry, and does it if
|
||||
necessary.
|
||||
|
||||
@param playstring The playstring being added.
|
||||
@param nitems HELP
|
||||
@param thispos HELP
|
||||
*/
|
||||
virtual void mqc_onAddPlaystring(const char *playstring, int nitems, int thispos);
|
||||
|
||||
|
||||
/**
|
||||
Registers a client with a query server.
|
||||
|
||||
@see sqs_onDetachServer()
|
||||
@param s The server we will register to.
|
||||
*/
|
||||
virtual void sqs_onAttachServer(MultiQueryServer *s);
|
||||
|
||||
/**
|
||||
Unregisters a client with a query server.
|
||||
|
||||
@see sqs_onAttachServer()
|
||||
@param s The server we will unregister from.
|
||||
*/
|
||||
virtual void sqs_onDetachServer(MultiQueryServer *s);
|
||||
|
||||
/**
|
||||
Resets the query.
|
||||
*/
|
||||
virtual void sqs_reset();
|
||||
|
||||
/**
|
||||
Generic deferred callback interface.
|
||||
*/
|
||||
virtual int onDeferredCallback(intptr_t p1, intptr_t p2);
|
||||
|
||||
/**
|
||||
Sets the linking status according to the value v.
|
||||
|
||||
@param v linking status to set
|
||||
*/
|
||||
virtual void setLinked(int v) { linked = v; }
|
||||
|
||||
/**
|
||||
Set the direction of the query.
|
||||
|
||||
@see SetQuery
|
||||
@param glag The direction of the query.
|
||||
*/
|
||||
void setQueryDirection(int glag);
|
||||
|
||||
/**
|
||||
HELP
|
||||
*/
|
||||
void doFieldPopup();
|
||||
|
||||
/**
|
||||
HELP
|
||||
*/
|
||||
virtual void onVScrollToggle(BOOL set);
|
||||
|
||||
/**
|
||||
HELP
|
||||
*/
|
||||
virtual int wantRenderBaseTexture() { return 1; }
|
||||
|
||||
/**
|
||||
Event is triggered when an item is
|
||||
being dragged.
|
||||
|
||||
@param iItem The item being dragged.
|
||||
@ret 0, Drag not handled; 1, Drag handled;
|
||||
*/
|
||||
virtual int onBeginDrag(int iItem);
|
||||
|
||||
/**
|
||||
Gets called when the API thinks the drag and drop
|
||||
was successful.
|
||||
|
||||
@param success Drag and Drop succeeded? (According to API).
|
||||
@ret 0, Drag and Drop not sucessful; 1, Drop and Drop completed successfully;
|
||||
*/
|
||||
virtual int dragComplete(int success);
|
||||
|
||||
private:
|
||||
/**
|
||||
HELP
|
||||
*/
|
||||
void populate();
|
||||
|
||||
/**
|
||||
Finds a specific entry in the database.
|
||||
|
||||
@param playstring The playstring for the item.
|
||||
@param scanner The db scanner to use.
|
||||
@param field The field to be read.
|
||||
*/
|
||||
void filterEntry(const char *playstring, dbScanner *scanner, const char *field);
|
||||
|
||||
/**
|
||||
Filters and formats integer type data
|
||||
and inserts it into the list to be displayed.
|
||||
*/
|
||||
void filterInt(int data);
|
||||
|
||||
/**
|
||||
Filters and formats string type data
|
||||
and inserts it into the list to be displayed.
|
||||
*/
|
||||
void filterString(const char *data);
|
||||
|
||||
/**
|
||||
Inserts data into the list so that it may be
|
||||
displayed.
|
||||
|
||||
@see metatags.h
|
||||
@param data The data to insert.
|
||||
@param len The length of the data to insert.
|
||||
@param type The type of the data to insert.
|
||||
*/
|
||||
void insertData(void *data, int len, int type);
|
||||
|
||||
/**
|
||||
Sets the filter label to the meta data field we are
|
||||
currently sorting on.
|
||||
|
||||
@see filterEntry()
|
||||
*/
|
||||
void setLabelName();
|
||||
|
||||
String field;
|
||||
dbScanner *local_scanner;
|
||||
PtrListInsertSorted<FilterListItem, FilterListItemSort> uniques;
|
||||
int data_type;
|
||||
int order;
|
||||
int grab_playstrings;
|
||||
int viscount;
|
||||
int linked;
|
||||
int needrestart;
|
||||
int querydirection;
|
||||
int last_populate_flag;
|
||||
ButtHooker *hooker;
|
||||
FilenameI *fn;
|
||||
};
|
||||
|
||||
#endif
|
||||
111
Src/Wasabi/api/skin/widgets/db/autoquerylist.cpp
Normal file
111
Src/Wasabi/api/skin/widgets/db/autoquerylist.cpp
Normal file
@@ -0,0 +1,111 @@
|
||||
#include <precomp.h>
|
||||
#include "autoquerylist.h"
|
||||
#include <api/db/subqueryserver.h>
|
||||
#include <api/db/multiqueryclient.h>
|
||||
#include <api/db/sharedscanner.h>
|
||||
#include <bfc/string/playstring.h>
|
||||
#include <api/db/metatags.h>
|
||||
#include <api/wnd/fakedrag.h>
|
||||
#include <bfc/util/profiler.h>
|
||||
#include <bfc/file/filename.h>
|
||||
#include <api/api.h>
|
||||
#include <api/service/svcs/svc_droptarget.h>
|
||||
#include <api/service/svc_enum.h>
|
||||
|
||||
#include "../../pledit/svc_pldir.h"
|
||||
#include "../../pledit/playlist.h"
|
||||
#include "../../pledit/editor.h"
|
||||
|
||||
#define TIMER_SCANNERDEL 0x6879
|
||||
#define DC_REFRESH 0x6880
|
||||
|
||||
AutoQueryList::AutoQueryList() :
|
||||
playlist(NULL)
|
||||
{
|
||||
lastpc = -1;
|
||||
last_status_update = 0;
|
||||
pldir = NULL;
|
||||
nFound = 0;
|
||||
}
|
||||
|
||||
AutoQueryList::~AutoQueryList() {
|
||||
getGuiObject()->guiobject_removeAppCmds(this);
|
||||
SvcEnum::release(pldir);
|
||||
}
|
||||
|
||||
int AutoQueryList::onInit() {
|
||||
AUTOQUERYLIST_PARENT::onInit();
|
||||
|
||||
pldir = SvcEnumByGuid<svc_plDir>();
|
||||
if (pldir != NULL) {
|
||||
PlaylistHandle hand = pldir->insertPlaylist(NULL, "Media library query results", NULL, TRUE);
|
||||
pldir->setAutoSave(hand, FALSE);
|
||||
playlist = pldir->getPlaylist(hand);
|
||||
playlist->lock(TRUE);
|
||||
}
|
||||
|
||||
appcmds_addCmd("Reset", 0, AppCmds::SIDE_RIGHT);
|
||||
getGuiObject()->guiobject_addAppCmds(this);
|
||||
|
||||
postDeferredCallback(DC_REFRESH, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int AutoQueryList::onDeferredCallback(intptr_t p1, intptr_t p2) {
|
||||
if (p1 == DC_REFRESH) {
|
||||
mqs_refresh();
|
||||
return 0;
|
||||
}
|
||||
return AUTOQUERYLIST_PARENT::onDeferredCallback(p1, p2);
|
||||
}
|
||||
|
||||
void AutoQueryList::mqs_onAddPlaystring(const char *playstring, int nitems, int thispos) {
|
||||
nfound++;
|
||||
stdtimevalms now = Std::getTimeStampMS();
|
||||
// if (n > lastpc) {
|
||||
if (now - last_status_update > 0.100) {
|
||||
int n = (int)(thispos / (float)nitems * 100.0f);
|
||||
getGuiObject()->guiobject_setCompleted(n);
|
||||
getGuiObject()->guiobject_setStatusText(StringPrintf("%d%c, %d item%s found", n, '%', nfound, (nfound > 1) ? "s" : ""), TRUE);
|
||||
// lastpc = n;
|
||||
// }
|
||||
last_status_update = now;
|
||||
}
|
||||
if (playlist != NULL)
|
||||
playlist->addPlaylistItem(playstring, Playlist::APPEND, FALSE);
|
||||
}
|
||||
|
||||
void AutoQueryList::mqs_onCompleteMultiQuery() {
|
||||
getGuiObject()->guiobject_setStatusText(StringPrintf("100%c, %d item%s found", '%', nfound, (nfound > 1) ? "s" : ""), TRUE);
|
||||
lastpc = -1;
|
||||
getGuiObject()->guiobject_popCompleted();
|
||||
}
|
||||
|
||||
void AutoQueryList::mqs_onNewMultiQuery() {
|
||||
nfound = 0;
|
||||
getGuiObject()->guiobject_setStatusText("0%", TRUE);
|
||||
getGuiObject()->guiobject_pushCompleted();
|
||||
if (playlist != NULL) {
|
||||
playlist->deleteAll();
|
||||
|
||||
GuiObject *ed = getGuiObject()->guiobject_findObjectByInterface(Editor::getInterfaceGuid());
|
||||
if (ed != NULL) {
|
||||
Editor *e = static_cast<Editor*>(ed->guiobject_getRootWnd()->getInterface(Editor::getInterfaceGuid()));
|
||||
e->setPlaylistByHandle(playlist->getHandle());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AutoQueryList::appcmds_onCommand(int id, const RECT *buttonRect, int which_btn) {
|
||||
switch (id) {
|
||||
case 0:
|
||||
resetSubQueries();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AutoQueryList::onSetVisible(int v) {
|
||||
AUTOQUERYLIST_PARENT::onSetVisible(v);
|
||||
if (!v) mqs_abort();
|
||||
}
|
||||
109
Src/Wasabi/api/skin/widgets/db/autoquerylist.h
Normal file
109
Src/Wasabi/api/skin/widgets/db/autoquerylist.h
Normal file
@@ -0,0 +1,109 @@
|
||||
#ifndef __AUTOQUERYLIST_H
|
||||
#define __AUTOQUERYLIST_H
|
||||
|
||||
#include "itemlistwnd.h"
|
||||
#include "../db/multiqueryserver.h"
|
||||
#include "../ptrlist.h"
|
||||
#include "../string.h"
|
||||
#include "../timeslicer.h"
|
||||
#include "../appcmds.h"
|
||||
#include "../../pledit/plhand.h"
|
||||
#include "../nakedobject.h"
|
||||
|
||||
class svc_plDir;
|
||||
class Playlist;
|
||||
|
||||
#define AUTOQUERYLIST_PARENT NakedObject
|
||||
#define AUTOQUERYLIST_DBPARENTSRV MultiQueryServerI
|
||||
|
||||
/**
|
||||
Automates the display of the result set of
|
||||
a query.
|
||||
|
||||
Simply create an AutoQueryList instance,
|
||||
set it's query with setQuery().
|
||||
|
||||
Can send results to the playlist directory
|
||||
for automatic playlist creation based on
|
||||
the result of the query.
|
||||
|
||||
@short Automated query result display window.
|
||||
@author Nullsoft
|
||||
@ver 1.0
|
||||
@see AutoFilterList
|
||||
*/
|
||||
class AutoQueryList : public AUTOQUERYLIST_PARENT,
|
||||
public AUTOQUERYLIST_DBPARENTSRV, AppCmdsI {
|
||||
|
||||
public:
|
||||
/**
|
||||
Initializes member data.
|
||||
*/
|
||||
AutoQueryList();
|
||||
|
||||
/**
|
||||
Releases playlist directory service and removes
|
||||
the AppCmd button.
|
||||
*/
|
||||
virtual ~AutoQueryList();
|
||||
|
||||
/**
|
||||
Initializes the auto query list.
|
||||
|
||||
ret 1
|
||||
*/
|
||||
virtual int onInit();
|
||||
|
||||
/**
|
||||
Event is triggered when a playstring is added to the result list.
|
||||
|
||||
Updates the progress bar at the bottom of the window (from 0 to 100%).
|
||||
|
||||
@param playstring The playstring to being added to the result list.
|
||||
@param nitems The number of items (total) in the result list.
|
||||
@param thispos The current position in the list of items.
|
||||
*/
|
||||
virtual void mqs_onAddPlaystring(const char *playstring, int nitems, int thispos);
|
||||
|
||||
/**
|
||||
Event is triggered when a new query is set.
|
||||
|
||||
Updates the progress bar to 0%, resets the playlist associated
|
||||
with this auto query list and resets the number of items found
|
||||
for the query to zero.
|
||||
*/
|
||||
virtual void mqs_onNewMultiQuery();
|
||||
|
||||
/**
|
||||
Event is triggered when a query completes.
|
||||
|
||||
Updates the progress bar to 100% and resets the last
|
||||
known progress count.
|
||||
*/
|
||||
virtual void mqs_onCompleteMultiQuery();
|
||||
virtual int onDeferredCallback(intptr_t p1, intptr_t p2);
|
||||
|
||||
protected:
|
||||
/**
|
||||
Event is triggered when an AppCmd button (which belongs to this
|
||||
auto query list) is pushed.
|
||||
|
||||
Only one command is handled by the auto query list which causes the query
|
||||
to be reset. The id of the command is 0.
|
||||
|
||||
@param id The id of the command associated with the button that was pressed.
|
||||
@param rect The RECT of the button that was pushed.
|
||||
*/
|
||||
virtual void appcmds_onCommand(int id, const RECT *buttonRect, int which_btn);
|
||||
virtual void onSetVisible(int v);
|
||||
|
||||
private:
|
||||
|
||||
int lastpc;
|
||||
int nfound;
|
||||
Playlist *playlist;
|
||||
svc_plDir *pldir;
|
||||
stdtimevalms last_status_update;
|
||||
};
|
||||
|
||||
#endif
|
||||
32
Src/Wasabi/api/skin/widgets/db/queryline.cpp
Normal file
32
Src/Wasabi/api/skin/widgets/db/queryline.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#include <precomp.h>
|
||||
|
||||
#include "queryline.h"
|
||||
|
||||
#include <api/api.h>
|
||||
#include <api/db/metatags.h>
|
||||
#include <bfc/string/string.h>
|
||||
#include <bfc/parse/pathparse.h>
|
||||
|
||||
QueryLine::QueryLine(const char *query) : autoquery(FALSE), querytext(query), autofield(MT_NAME) {
|
||||
}
|
||||
|
||||
void QueryLine::setQuery(const char *query) {
|
||||
querytext = query;
|
||||
String sp = querytext;
|
||||
if (autoquery && !querytext.isempty()) {
|
||||
sp = "";
|
||||
PathParser pp(querytext, " ");
|
||||
if (pp.getNumStrings() <= 0) return;
|
||||
for (int i = 0; i < pp.getNumStrings(); i++) {
|
||||
if (i != 0) sp += " and ";
|
||||
sp += StringPrintf("(\"%s\" has \"%s\")", autofield.getValue(), pp.enumString(i));
|
||||
}
|
||||
}
|
||||
sqs_setQuery(sp);
|
||||
}
|
||||
|
||||
int QueryLine::setAuto(int bv) {
|
||||
autoquery = !!bv;
|
||||
setQuery(querytext);
|
||||
return 1;
|
||||
}
|
||||
64
Src/Wasabi/api/skin/widgets/db/queryline.h
Normal file
64
Src/Wasabi/api/skin/widgets/db/queryline.h
Normal file
@@ -0,0 +1,64 @@
|
||||
#ifndef _QUERYLINE_H
|
||||
#define _QUERYLINE_H
|
||||
|
||||
#include <api/skin/nakedobject.h>
|
||||
#include <api/db/subqueryserver.h>
|
||||
|
||||
#define QUERYLINE_PARENT NakedObject
|
||||
|
||||
/**
|
||||
Class
|
||||
|
||||
@short
|
||||
@author Nullsoft
|
||||
@ver 1.0
|
||||
@see
|
||||
*/
|
||||
class QueryLine : public QUERYLINE_PARENT, public SubQueryServerI {
|
||||
public:
|
||||
|
||||
/**
|
||||
Method
|
||||
|
||||
@see
|
||||
@ret
|
||||
@param
|
||||
*/
|
||||
QueryLine(const char *query=NULL);
|
||||
|
||||
/**
|
||||
Method
|
||||
|
||||
@see
|
||||
@ret
|
||||
@param
|
||||
*/
|
||||
virtual ~QueryLine() { }
|
||||
|
||||
|
||||
/**
|
||||
Method
|
||||
|
||||
@see
|
||||
@ret
|
||||
@param
|
||||
*/
|
||||
virtual void setQuery(const char *query);
|
||||
|
||||
/**
|
||||
Method
|
||||
|
||||
@see
|
||||
@ret
|
||||
@param
|
||||
*/
|
||||
int setAuto(int bv);
|
||||
|
||||
protected:
|
||||
int autoquery;
|
||||
|
||||
private:
|
||||
String querytext, autofield;
|
||||
};
|
||||
|
||||
#endif
|
||||
103
Src/Wasabi/api/skin/widgets/db/xuiquerydrag.cpp
Normal file
103
Src/Wasabi/api/skin/widgets/db/xuiquerydrag.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
#include <precomp.h>
|
||||
#include "xuiquerydrag.h"
|
||||
#include <tataki/canvas/ifc_canvas.h>
|
||||
#include <api/db/multiqueryserver.h>
|
||||
#include <bfc/file/filename.h>
|
||||
|
||||
char QueryDragXuiObjectStr[] = "QueryDrag"; // This is the xml tag
|
||||
char QueryDragXuiSvcName[] = "QueryDrag xui object"; // and this is the name of the service
|
||||
|
||||
XMLParamPair QueryDrag::params[] = {
|
||||
{QUERYDRAG_SETIMAGE, "image"},
|
||||
{QUERYDRAG_SETSOURCE, "source"},
|
||||
};
|
||||
QueryDrag::QueryDrag() {
|
||||
setVirtual(0); // fucko
|
||||
myxuihandle = newXuiHandle();
|
||||
|
||||
|
||||
int numParams = sizeof(params) / sizeof(params[0]);
|
||||
hintNumberOfParams(numParams);
|
||||
for (int i = 0;i < numParams;i++)
|
||||
addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
|
||||
fn = NULL;
|
||||
}
|
||||
|
||||
QueryDrag::~QueryDrag() {
|
||||
}
|
||||
|
||||
int QueryDrag::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) {
|
||||
if (xuihandle != myxuihandle)
|
||||
return QUERYDRAG_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
|
||||
|
||||
switch (xmlattributeid) {
|
||||
case QUERYDRAG_SETIMAGE:
|
||||
setImage(value);
|
||||
break;
|
||||
case QUERYDRAG_SETSOURCE:
|
||||
setSource(value);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int QueryDrag::onPaint(Canvas *canvas) {
|
||||
QUERYDRAG_PARENT::onPaint(canvas);
|
||||
|
||||
RECT r;
|
||||
getClientRect(&r);
|
||||
|
||||
RenderBaseTexture(canvas, r, 255);
|
||||
|
||||
if (image.getBitmap())
|
||||
image.getBitmap()->stretchToRectAlpha(canvas, &r, getPaintingAlpha());
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void QueryDrag::setImage(const char *elementname) {
|
||||
image = elementname;
|
||||
if (isInited()) invalidate();
|
||||
}
|
||||
|
||||
void QueryDrag::setSource(const char *elementname) {
|
||||
source = elementname;
|
||||
}
|
||||
|
||||
int QueryDrag::getPreferences(int what) {
|
||||
switch (what) {
|
||||
case SUGGESTED_W:
|
||||
if (image.getBitmap()) return image.getBitmap()->getWidth();
|
||||
case SUGGESTED_H:
|
||||
if (image.getBitmap()) return image.getBitmap()->getHeight();
|
||||
}
|
||||
return QUERYDRAG_PARENT::getPreferences(what);
|
||||
}
|
||||
|
||||
int QueryDrag::onMouseMove(int x, int y) {
|
||||
QUERYDRAG_PARENT::onMouseMove(x,y);
|
||||
if (isInClick())
|
||||
onBeginDrag();
|
||||
return 1;
|
||||
}
|
||||
|
||||
void QueryDrag::onBeginDrag() {
|
||||
api_window *mqsw = NULL;
|
||||
if (source.isempty()) mqsw = findWindowByInterface(multiQueryServerGuid);
|
||||
else mqsw = findWindow(source);
|
||||
if (!mqsw) return;
|
||||
MultiQueryServer *mqs = static_cast<MultiQueryServer *>(mqsw->getInterface(multiQueryServerGuid));
|
||||
|
||||
// multiquery is now available in mqs->mqs_getMultiQuery(); using format "table guid;query;table guid;query;etc..."
|
||||
fn = new FilenameI(StringPrintf("query://%s.nsq", mqs->mqs_getMultiQuery()));
|
||||
addDragItem(Filename::dragitem_getDatatype(), static_cast<Filename*>(fn));
|
||||
handleDrag();
|
||||
}
|
||||
|
||||
int QueryDrag::dragComplete(int success) {
|
||||
ASSERT(fn != NULL);
|
||||
delete fn; fn = NULL;
|
||||
return 1;
|
||||
}
|
||||
53
Src/Wasabi/api/skin/widgets/db/xuiquerydrag.h
Normal file
53
Src/Wasabi/api/skin/widgets/db/xuiquerydrag.h
Normal file
@@ -0,0 +1,53 @@
|
||||
#ifndef __QUERYDRAG_H
|
||||
#define __QUERYDRAG_H
|
||||
|
||||
#include <api/wnd/wndclass/guiobjwnd.h>
|
||||
#include <tataki/bitmap/autobitmap.h>
|
||||
|
||||
class FilenameI;
|
||||
|
||||
#define QUERYDRAG_PARENT GuiObjectWnd
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Your wnd object class
|
||||
|
||||
class QueryDrag : public QUERYDRAG_PARENT {
|
||||
|
||||
public:
|
||||
|
||||
QueryDrag();
|
||||
virtual ~QueryDrag();
|
||||
|
||||
virtual int onPaint(Canvas *c);
|
||||
virtual int getPreferences(int what);
|
||||
virtual int onMouseMove(int x, int y);
|
||||
|
||||
virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
|
||||
|
||||
void setImage(const char *elementname);
|
||||
void setSource(const char *elementname);
|
||||
void onBeginDrag();
|
||||
virtual int dragComplete(int success);
|
||||
|
||||
private:
|
||||
|
||||
AutoSkinBitmap image;
|
||||
String source;
|
||||
|
||||
FilenameI *fn;
|
||||
|
||||
enum {
|
||||
QUERYDRAG_SETIMAGE = 0,
|
||||
QUERYDRAG_SETSOURCE,
|
||||
};
|
||||
static XMLParamPair params[];
|
||||
int myxuihandle;
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
extern char QueryDragXuiObjectStr[];
|
||||
extern char QueryDragXuiSvcName[];
|
||||
class QueryDragXuiSvc : public XuiObjectSvc<QueryDrag, QueryDragXuiObjectStr, QueryDragXuiSvcName> {};
|
||||
|
||||
#endif
|
||||
73
Src/Wasabi/api/skin/widgets/db/xuiqueryline.cpp
Normal file
73
Src/Wasabi/api/skin/widgets/db/xuiqueryline.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
#include <precomp.h>
|
||||
|
||||
#include "xuiqueryline.h"
|
||||
#include <api/skin/widgets/db/xuiquerylist.h>
|
||||
|
||||
#define CB_SETQUERYLIST 0x1978
|
||||
|
||||
char QueryLineXuiObjectStr[] = "QueryLine"; // This is the xml tag
|
||||
char QueryLineXuiSvcName[] = "QueryLine xui object";
|
||||
|
||||
ScriptQueryLine::ScriptQueryLine() {
|
||||
myxuihandle = newXuiHandle();
|
||||
addParam(myxuihandle, "querylist", QUERYLINE_SETQUERYLIST, XUI_ATTRIBUTE_IMPLIED);
|
||||
addParam(myxuihandle, "query", QUERYLINE_SETQUERY, XUI_ATTRIBUTE_IMPLIED);
|
||||
addParam(myxuihandle, "auto", QUERYLINE_SETAUTO, XUI_ATTRIBUTE_IMPLIED);
|
||||
}
|
||||
|
||||
ScriptQueryLine::~ScriptQueryLine() { }
|
||||
|
||||
/*int ScriptQueryLine::onInit() {
|
||||
SCRIPTQUERYLINE_PARENT::onInit();
|
||||
if (!querylist_id.isempty())
|
||||
postDeferredCallback(CB_SETQUERYLIST, 0, 500);
|
||||
return 1;
|
||||
}*/
|
||||
|
||||
int ScriptQueryLine::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) {
|
||||
if (xuihandle != myxuihandle)
|
||||
return SCRIPTQUERYLINE_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
|
||||
|
||||
switch (xmlattributeid) {
|
||||
case QUERYLINE_SETQUERYLIST:
|
||||
setXuiQueryList(value);
|
||||
break;
|
||||
case QUERYLINE_SETQUERY:
|
||||
ql_setQuery(value);
|
||||
break;
|
||||
case QUERYLINE_SETAUTO:
|
||||
setAuto(WTOI(value));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ScriptQueryLine::ql_setQuery(const char *q) {
|
||||
ensureConnected();
|
||||
setQuery(q);
|
||||
}
|
||||
|
||||
void ScriptQueryLine::ensureConnected() {
|
||||
api_window *o = findWindow(querylist_id);
|
||||
if (!o) return;
|
||||
ScriptQueryList *querylist = static_cast<ScriptQueryList *>(o->getInterface(queryListGuid));
|
||||
if (!querylist) return;
|
||||
sqs_setMultiQueryServer(querylist);
|
||||
}
|
||||
|
||||
void ScriptQueryLine::setXuiQueryList(const char *v) {
|
||||
querylist_id = v;
|
||||
}
|
||||
|
||||
/*int ScriptQueryLine::onDeferredCallback(intptr_t p1, intptr_t p2) {
|
||||
switch (p1) {
|
||||
case CB_SETQUERYLIST:
|
||||
break;
|
||||
default:
|
||||
return SCRIPTQUERYLINE_PARENT::onDeferredCallback(p1, p2);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
35
Src/Wasabi/api/skin/widgets/db/xuiqueryline.h
Normal file
35
Src/Wasabi/api/skin/widgets/db/xuiqueryline.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef _XUIQUERYLINE_H
|
||||
#define _XUIQUERYLINE_H
|
||||
|
||||
#include <api/skin/widgets/db/queryline.h>
|
||||
|
||||
#define SCRIPTQUERYLINE_PARENT QueryLine
|
||||
class ScriptQueryLine : public SCRIPTQUERYLINE_PARENT {
|
||||
public:
|
||||
ScriptQueryLine();
|
||||
virtual ~ScriptQueryLine();
|
||||
|
||||
//virtual int onInit();
|
||||
|
||||
virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
|
||||
void setXuiQueryList(const char *v);
|
||||
|
||||
//virtual int onDeferredCallback(intptr_t p1, intptr_t p2);
|
||||
|
||||
private:
|
||||
enum {
|
||||
QUERYLINE_SETQUERYLIST=1,
|
||||
QUERYLINE_SETQUERY,
|
||||
QUERYLINE_SETAUTO,
|
||||
};
|
||||
void ql_setQuery(const char *);
|
||||
void ensureConnected();
|
||||
int myxuihandle;
|
||||
String querylist_id;
|
||||
};
|
||||
|
||||
extern char QueryLineXuiObjectStr[];
|
||||
extern char QueryLineXuiSvcName[];
|
||||
class QueryLineXuiSvc : public XuiObjectSvc<ScriptQueryLine, QueryLineXuiObjectStr, QueryLineXuiSvcName> {};
|
||||
|
||||
#endif
|
||||
119
Src/Wasabi/api/skin/widgets/db/xuiquerylist.cpp
Normal file
119
Src/Wasabi/api/skin/widgets/db/xuiquerylist.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
#include <precomp.h>
|
||||
#include "xuiquerylist.h"
|
||||
#include <tataki/canvas/ifc_canvas.h>
|
||||
|
||||
#include <api/service/svcs/svc_objectdir.h>
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
char QueryListXuiObjectStr[] = "QueryResults"; // This is the xml tag
|
||||
char QueryListXuiSvcName[] = "ScriptQueryResults xui object";
|
||||
XMLParamPair ScriptQueryList::params[] = {
|
||||
{QUERYLIST_SETTITLE, "TITLE"},
|
||||
};
|
||||
// -----------------------------------------------------------------------
|
||||
ScriptQueryList::ScriptQueryList() {
|
||||
getScriptObject()->vcpu_setInterface(queryListGuid, (void *)static_cast<ScriptQueryList *>(this));
|
||||
#ifdef WASABI_COMPILE_METADB
|
||||
getScriptObject()->vcpu_setInterface(multiQueryServerGuid, (void *)static_cast<MultiQueryServer *>(this));
|
||||
#endif
|
||||
getScriptObject()->vcpu_setClassName("QueryList"); // this is the script class name
|
||||
getScriptObject()->vcpu_setController(queryListController);
|
||||
|
||||
myxuihandle = newXuiHandle();
|
||||
|
||||
int numParams = sizeof(params) / sizeof(params[0]);
|
||||
hintNumberOfParams(numParams);
|
||||
for (int i = 0;i < numParams;i++)
|
||||
addParam(myxuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
|
||||
}
|
||||
|
||||
ScriptQueryList::~ScriptQueryList() {
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
int ScriptQueryList::setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value) {
|
||||
if (xuihandle != myxuihandle)
|
||||
return QUERYLIST_PARENT::setXuiParam(xuihandle, xmlattributeid, xmlattributename, value);
|
||||
|
||||
switch (xmlattributeid) {
|
||||
case QUERYLIST_SETTITLE: setTitle(value); break;
|
||||
default: return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
void ScriptQueryList::setTitle(const char *name) {
|
||||
setName(name);
|
||||
//CUT if (!name || !*name) showLabel(0); else showLabel(1);
|
||||
}
|
||||
|
||||
#ifdef WASABI_COMPILE_METADB
|
||||
// -----------------------------------------------------------------------
|
||||
void ScriptQueryList::onResetSubqueries() {
|
||||
QUERYLIST_PARENT::onResetSubqueries();
|
||||
QueryListScriptController::querylist_onResetQuery(SCRIPT_CALL, getScriptObject());
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WASABI_COMPILE_METADB
|
||||
int ScriptQueryList::onAction(const char *action, const char *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, api_window *source) {
|
||||
if (STRCASEEQLSAFE(action, "SAVEQUERY")) {
|
||||
String q = mqs_getMultiQuery();
|
||||
if (!q.isempty()) {
|
||||
svc_objectDir *qd = ObjectDirEnum("querydir").getNext();
|
||||
if (qd != NULL) {
|
||||
qd->insertObject(q, "gay", "user is gay");
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return QUERYLIST_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source);
|
||||
}
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Script Object
|
||||
|
||||
QueryListScriptController _queryListController;
|
||||
QueryListScriptController *queryListController = &_queryListController;
|
||||
|
||||
// -- Functions table -------------------------------------
|
||||
function_descriptor_struct QueryListScriptController::exportedFunction[] = {
|
||||
{"onResetQuery", 0, (void*)QueryListScriptController::querylist_onResetQuery},
|
||||
};
|
||||
|
||||
ScriptObject *QueryListScriptController::instantiate() {
|
||||
ScriptQueryList *sql = new ScriptQueryList;
|
||||
ASSERT(sql != NULL);
|
||||
return sql->getScriptObject();
|
||||
}
|
||||
|
||||
void QueryListScriptController::destroy(ScriptObject *o) {
|
||||
ScriptQueryList *sql = static_cast<ScriptQueryList *>(o->vcpu_getInterface(queryListGuid));
|
||||
ASSERT(sql != NULL);
|
||||
delete sql;
|
||||
}
|
||||
|
||||
void *QueryListScriptController::encapsulate(ScriptObject *o) {
|
||||
return NULL; // no encapsulation for querylist yet
|
||||
}
|
||||
|
||||
void QueryListScriptController::deencapsulate(void *o) {
|
||||
}
|
||||
|
||||
int QueryListScriptController::getNumFunctions() {
|
||||
return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
|
||||
}
|
||||
|
||||
const function_descriptor_struct *QueryListScriptController::getExportedFunctions() {
|
||||
return exportedFunction;
|
||||
}
|
||||
|
||||
|
||||
scriptVar QueryListScriptController::querylist_onResetQuery(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
|
||||
SCRIPT_FUNCTION_INIT;
|
||||
PROCESS_HOOKS0(o, queryListController);
|
||||
SCRIPT_FUNCTION_CHECKABORTEVENT;
|
||||
SCRIPT_EXEC_EVENT0(o);
|
||||
}
|
||||
72
Src/Wasabi/api/skin/widgets/db/xuiquerylist.h
Normal file
72
Src/Wasabi/api/skin/widgets/db/xuiquerylist.h
Normal file
@@ -0,0 +1,72 @@
|
||||
#ifndef __QUERYLIST_H
|
||||
#define __QUERYLIST_H
|
||||
|
||||
#include <api/wnd/wndclass/guiobjwnd.h>
|
||||
#ifdef WASABI_COMPILE_METADB
|
||||
#include <api/skin/widgets/db/autoquerylist.h>
|
||||
#endif
|
||||
#include <api/script/objcontroller.h>
|
||||
|
||||
#ifdef WASABI_COMPILE_METADB
|
||||
#define QUERYLIST_PARENT AutoQueryList
|
||||
#else
|
||||
#define QUERYLIST_PARENT GuiObjectWnd
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
class ScriptQueryList : public QUERYLIST_PARENT {
|
||||
|
||||
public:
|
||||
|
||||
ScriptQueryList();
|
||||
virtual ~ScriptQueryList();
|
||||
|
||||
virtual int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
|
||||
|
||||
void setTitle(const char *name);
|
||||
|
||||
#ifdef WASABI_COMPILE_METADB
|
||||
void onResetSubqueries();
|
||||
virtual int onAction(const wchar_t *action, const wchar_t *param=NULL, int x=-1, int y=-1, intptr_t p1=0, intptr_t p2=0, void *data=NULL, size_t datalen=0, api_window *source=NULL);
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
enum {
|
||||
QUERYLIST_SETTITLE = 0,
|
||||
};
|
||||
static XMLParamPair params[];
|
||||
int myxuihandle;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
class QueryListScriptController: public ScriptObjectControllerI {
|
||||
public:
|
||||
|
||||
virtual const wchar_t *getClassName() { return L"QueryList"; }
|
||||
virtual const wchar_t *getAncestorClassName() { return L"GuiObject"; }
|
||||
virtual ScriptObjectController *getAncestorController() { return WASABI_API_MAKI->maki_getController(guiObjectGuid); }
|
||||
virtual int getNumFunctions();
|
||||
virtual const function_descriptor_struct *getExportedFunctions();
|
||||
virtual GUID getClassGuid() { return queryListGuid; }
|
||||
virtual ScriptObject *instantiate();
|
||||
virtual void destroy(ScriptObject *o);
|
||||
virtual void *encapsulate(ScriptObject *o);
|
||||
virtual void deencapsulate(void *o);
|
||||
|
||||
static scriptVar querylist_onResetQuery(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
|
||||
|
||||
private:
|
||||
|
||||
static function_descriptor_struct exportedFunction[];
|
||||
|
||||
};
|
||||
|
||||
extern QueryListScriptController *queryListController;
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
extern char QueryListXuiObjectStr[];
|
||||
extern char QueryListXuiSvcName[];
|
||||
class QueryListXuiSvc : public XuiObjectSvc<ScriptQueryList, QueryListXuiObjectStr, QueryListXuiSvcName> {};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user