Selection

Only locations and texts can be selected, connections are considered dependent on the locations they connect. «*»= Boolean isSelected(Item *i) switch(i->type) case LOCATION: return((i->itemdata.loc.flags & SELECTED) != 0); break; case TEXT: return((i->itemdata.text.flags & SELECTED) != 0); break; default: return(false); break;

return(false); @

Set the selection state of the item [[i]] to [[state]]. For connections this is a nop. «*»= void selectItem(Item *i, Boolean state) switch(i->type) case LOCATION: if(state) i->itemdata.loc.flags |= SELECTED; else i->itemdata.loc.flags &= SELECTED; break; case TEXT: if(state) i->itemdata.text.flags |= SELECTED; else i->itemdata.text.flags &= SELECTED; break; default: break; @

Deselect all items in the current section. NB: it is allowed to deselect connections. «*»= void DeselectAll() int i;

for(i=0;i<currentSection->itemNum;i++) selectItem(&currentSection->items[i],false); @

«*»=

void SelectedRect(RectangleType *r) Boolean set=false; int i; int max_x,max_y;

for(i=0;i<currentSection->itemNum;i++) if(isSelected(&currentSection->items[i])) max_x=currentSection->items[i].bounds.topLeft.x+ currentSection->items[i].bounds.extent.x;

max_y=currentSection->items[i].bounds.topLeft.y+ currentSection->items[i].bounds.extent.y;

if(set) r->topLeft.x=MIN(r->topLeft.x, currentSection->items[i].bounds.topLeft.x); r->topLeft.y=MIN(r->topLeft.y, currentSection->items[i].bounds.topLeft.y); max_x=MAX(r->topLeft.x+r->extent.x,max_x); max_y=MAX(r->topLeft.y+r->extent.y,max_y);

r->extent.x=max_x-r->topLeft.x; r->extent.y=max_y-r->topLeft.y; else set=true; r->topLeft.x=currentSection->items[i].bounds.topLeft.x; r->topLeft.y=currentSection->items[i].bounds.topLeft.y; r->extent.x=currentSection->items[i].bounds.extent.x; r->extent.y=currentSection->items[i].bounds.extent.y; @

NB: Selected connections are collected in the linked list [[selSet]], these pointers are freed on deselection. «*»= void DeselectConnections() SelectedVertexSet *s;

for(s=selSet;s!=NULL;s=selSet) selSet=s->next; MemPtrFree(s); @

Selects all the connection into selSet, that are connected to selected locations. This is used to move connections with the selected locations and for the clipboard. «*»= void SelectConnections() int i,j; SelectedVertexSet *s;

for(i=0;i<currentSection->itemNum;i++) if(currentSection->items[i].type == LOCATION && isSelected(&currentSection->items[i])) for(j=0;j<currentSection->itemNum;j++) if(currentSection->items[j].type == CONNECTION) if(currentSection->items[j].itemdata.con.vertexnum>0) «Check if first vertex is on location» «Check if last vertex is on location» @

«Check if first vertex is on location»= if(onLoc(&currentSection->items[i], &currentSection->items[j].itemdata.con.vertices[0])) «Check if the other end is already selected» if(s == NULL) s=MemPtrNew(sizeof(SelectedVertexSet)); s->next=selSet; s->c=&currentSection->items[j]; s->end=false; selSet=s; s->begin=true; @

«Check if last vertex is on location»= if(currentSection->items[j].itemdata.con.vertexnum>1) if(onLoc(&currentSection->items[i], &currentSection->items[j].itemdata.con.vertices[currentSection->items[j].itemdata.con.vertexnum-1])) «Check if the other end is already selected» if(s == NULL) s=MemPtrNew(sizeof(SelectedVertexSet)); s->next=selSet; s->c=&currentSection->items[j]; s->begin=false; selSet=s; s->end=true; @

A connection can be only once in the selected set even if both ends are selected (i.e. on selected locations). [[s]] walks through the selected set and ends up as [[NULL]], if this is a new connection. «Check if the other end is already selected»= for(s=selSet;s!=NULL && s->c != &currentSection->items[j]; s=s->next); @

Free all the resources related to editing and return to the map selection form. «*»= static void exitEdit() int i;

«Free section names» «Free map resources» «Free search resources»

DeselectConnections(); FrmGotoForm(MapSelect); @

«Free section names»= for(i=0;i<allocedSecNames;i++) MemPtrFree(sectionNames[i]); if(sectionNames != NULL) MemPtrFree(sectionNames);

sectionNames=NULL; allocedSecNames=0; @

«Free map resources»= if(currentMap) FreeMap(currentMap); currentMap=NULL; @

«Free search resources»= if(searchString != NULL) MemPtrFree(searchString); searchString=NULL; @

«*»= void SearchItems() Item *FoundItem;

if(searchFlag) while(1) if((FoundItem=FindItem(searchSection,searchIndex+1, searchString)) != NULL) searchIndex=FoundItem-searchSection->items; currentSection=searchSection; CenterDisplayOn(&FoundItem->bounds); return; else int secindex=(searchSection-currentMap->sections)+1; secindexsearchSection=&currentMap->sections[secindex]; searchIndex=-1; if(searchSection == searchStart) FrmCustomAlert(ErrorDialog,"No item found","",""); return; else if((FoundItem=FindItem(searchSection,searchIndex+1, searchString)) != NULL) searchSection=currentSection; searchIndex=FoundItem-searchSection->items; CenterDisplayOn(&FoundItem->bounds); else FrmCustomAlert(ErrorDialog,"No item found","",""); @