/*___INFO__MARK_BEGIN__*/ /************************************************************************* * * The Contents of this file are made available subject to the terms of * the Sun Industry Standards Source License Version 1.2 * * Sun Microsystems Inc., March, 2001 * * * Sun Industry Standards Source License Version 1.2 * ================================================= * The contents of this file are subject to the Sun Industry Standards * Source License Version 1.2 (the "License"); You may not use this file * except in compliance with the License. You may obtain a copy of the * License at http://gridengine.sunsource.net/Gridengine_SISSL_license.html * * Software provided under this License is provided on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. * See the License for the specific provisions governing your rights and * obligations concerning the Software. * * The Initial Developer of the Original Code is: Sun Microsystems, Inc. * * Copyright: 2001 by Sun Microsystems, Inc. * * All Rights Reserved. * ************************************************************************/ /*___INFO__MARK_END__*/ #define QALTER_RUNNING #include #include #include #include #include #include #include #include "Matrix.h" #include "Tab.h" #include "qmon_rmon.h" #include "qmon_cull.h" #include "qmon_ar.h" #include "qmon_arsub.h" #include "qmon_arcustom.h" #include "qmon_comm.h" #include "qmon_timer.h" #include "qmon_globals.h" #include "qmon_browser.h" #include "qmon_message.h" #include "qmon_init.h" #include "qmon_util.h" #include "basis_types.h" #include "sge_all_listsL.h" #include "sge_answer.h" #include "qmon_matrix.h" #include "sge_dstring.h" #include "sgeee.h" #include "sge_range.h" #include "sge_object.h" #include "sge_advance_reservation.h" #include "gdi/sge_gdi_ctx.h" extern sge_gdi_ctx_class_t *ctx; enum { AR_DISPLAY_MODE_RUNNING, AR_DISPLAY_MODE_PENDING }; typedef struct _tAskHoldInfo { Boolean blocked; XmtButtonType button; Widget AskHoldDialog; Widget AskHoldFlags; Widget AskHoldTasks; } tAskHoldInfo; /* a boolean for the sort order */ enum { AR_sort_descending = 0, AR_sort_ascending }; static Widget qmon_ar = 0; static Widget ar_running_ars = 0; #ifdef AR_PENDING static Widget ar_pending_ars = 0; #endif static Widget current_matrix = 0; static Widget ar_customize = 0; static Widget ar_delete = 0; static Widget ar_select_all = 0; static Widget force_toggle = 0; /*-------------------------------------------------------------------------*/ static void qmonCreateARControl(Widget parent); static void qmonARToMatrix(Widget w, lListElem *ar, int mode, int row); static void qmonARFolderChange(Widget w, XtPointer cld, XtPointer cad); static void qmonDeleteARCB(Widget w, XtPointer cld, XtPointer cad); static void qmonSelectAllARCB(Widget w, XtPointer cld, XtPointer cad); static void qmonARPopdown(Widget w, XtPointer cld, XtPointer cad); static void qmonARStartUpdate(Widget w, XtPointer cld, XtPointer cad); static void qmonARStopUpdate(Widget w, XtPointer cld, XtPointer cad); static void qmonARHandleEnterLeave(Widget w, XtPointer cld, XEvent *ev, Boolean *ctd); static void qmonARShowBrowserInfo(dstring *info, lListElem *jep); /* static void qmonARChangeState(Widget w, XtPointer cld, XtPointer cad); */ static void qmonARNoEdit(Widget w, XtPointer cld, XtPointer cad); static Pixel qmonARStateToColor(Widget w, lListElem *jep); static Boolean qmonDeleteARForMatrix(Widget w, Widget matrix, lList **local); /* static lList* qmonARBuildSelectedList(Widget matrix, lDescr *dp, int nm); */ /* static void qmonResizeCB(Widget w, XtPointer cld, XtPointer cad); */ static void qmonARSort(Widget w, XtPointer cld, XtPointer cad); /*-------------------------------------------------------------------------*/ static int field_sort_by; static int field_sort_direction; static int arnum_sort_direction; /*-------------------------------------------------------------------------*/ /* P U B L I C */ /*-------------------------------------------------------------------------*/ void qmonARPopup(Widget w, XtPointer cld, XtPointer cad) { lList *alp = NULL; DENTER(GUI_LAYER, "qmonARPopup"); /* set busy cursor */ XmtDisplayBusyCursor(w); if (!qmon_ar) { qmonMirrorMultiAnswer(AR_T, &alp); if (alp) { qmonMessageBox(w, alp, 0); lFreeList(&alp); /* set normal cursor */ XmtDisplayDefaultCursor(w); DEXIT; return; } qmonCreateARControl(AppShell); /* ** create the ar customize dialog */ qmonCreateARCU(qmon_ar, NULL); /* ** set the close button callback ** set the icon and iconName */ XmtCreatePixmapIcon(qmon_ar, qmonGetIcon("toolbar_ar"), None); XtVaSetValues(qmon_ar, XtNiconName, "qmon:AR Control", NULL); XmtAddDeleteCallback(qmon_ar, XmDO_NOTHING, qmonARPopdown, NULL); XtAddEventHandler(qmon_ar, StructureNotifyMask, False, SetMinShellSize, NULL); XtAddEventHandler(qmon_ar, StructureNotifyMask, False, SetMaxShellSize, NULL); } updateARListCB(qmon_ar, NULL, NULL); xmui_manage(qmon_ar); /* set normal cursor */ XmtDisplayDefaultCursor(w); DEXIT; } /*-------------------------------------------------------------------------*/ void qmonARReturnMatrix( Widget *run_m, Widget *pen_m ) { DENTER(GUI_LAYER, "qmonARReturnMatrix"); *run_m = ar_running_ars; #ifdef AR_PENDING *pen_m = ar_pending_ars; #endif DEXIT; } /*-------------------------------------------------------------------------*/ void updateARListCB(Widget w, XtPointer cld, XtPointer cad) { lList *alp = NULL; /* set busy cursor */ XmtDisplayBusyCursor(w); qmonMirrorMultiAnswer(AR_T, &alp); if (alp) { qmonMessageBox(w, alp, 0); lFreeList(&alp); /* set default cursor */ XmtDisplayDefaultCursor(w); return; } updateARList(); /* set default cursor */ XmtDiscardButtonEvents(w); XmtDisplayDefaultCursor(w); } /*-------------------------------------------------------------------------*/ /* P R I V A T E */ /*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/ static void qmonARPopdown(Widget w, XtPointer cld, XtPointer cad) { DENTER(GUI_LAYER, "qmonARPopdown"); xmui_unmanage(qmon_ar); DEXIT; } /*-------------------------------------------------------------------------*/ static void qmonARStartUpdate(Widget w, XtPointer cld, XtPointer cad) { DENTER(GUI_LAYER, "qmonARStartUpdate"); qmonTimerAddUpdateProc(AR_T, "updateARList", updateARList); qmonStartTimer(AR_T); DEXIT; } /*-------------------------------------------------------------------------*/ static void qmonARStopUpdate(Widget w, XtPointer cld, XtPointer cad) { DENTER(GUI_LAYER, "qmonARStopUpdate"); qmonStopTimer(AR_T); qmonTimerRmUpdateProc(AR_T, "updateARList"); DEXIT; } /*-------------------------------------------------------------------------*/ static void qmonCreateARControl( Widget parent ) { Widget ar_submit, ar_update, ar_done, ar_main_link, ar_pending, ar_folder; #ifdef AR_PENDING static Widget pw[2]; #endif static Widget rw[2]; DENTER(GUI_LAYER, "qmonCreateARControl"); qmon_ar = XmtBuildQueryToplevel( parent, "qmon_ar", "ar_running_ars", &ar_running_ars, #ifdef AR_PENDING "ar_pending_ars", &ar_pending_ars, #endif "ar_delete", &ar_delete, "ar_select_all", &ar_select_all, "ar_update", &ar_update, "ar_customize", &ar_customize, "ar_submit", &ar_submit, "ar_done", &ar_done, "ar_main_link", &ar_main_link, "ar_folder", &ar_folder, "ar_pending", &ar_pending, "ar_force", &force_toggle, NULL); #ifdef AR_PENDING pw[0] = ar_pending_ars; pw[1] = NULL; #endif rw[0] = ar_running_ars; rw[1] = NULL; /* start the needed timers and the corresponding update routines */ XtAddCallback(qmon_ar, XmNpopupCallback, qmonARStartUpdate, NULL); XtAddCallback(qmon_ar, XmNpopdownCallback, qmonARStopUpdate, NULL); XtAddCallback(ar_folder, XmNvalueChangedCallback, qmonARFolderChange, NULL); XmTabSetTabWidget(ar_folder, ar_pending, True); XtAddCallback(ar_delete, XmNactivateCallback, qmonDeleteARCB, NULL); XtAddCallback(ar_select_all, XmNactivateCallback, qmonSelectAllARCB, NULL); XtAddCallback(ar_update, XmNactivateCallback, updateARListCB, NULL); XtAddCallback(ar_customize, XmNactivateCallback, qmonPopupARCU, NULL); XtAddCallback(ar_submit, XmNactivateCallback, qmonARSubPopup, NULL); XtAddCallback(ar_done, XmNactivateCallback, qmonARPopdown, NULL); XtAddCallback(ar_main_link, XmNactivateCallback, qmonMainControlRaise, NULL); /* XtAddCallback(ar_running_ars, XmNresizeColumnCallback, */ /* qmonResizeCB, NULL); */ XtAddCallback(ar_running_ars, XmNenterCellCallback, qmonARNoEdit, NULL); XtAddCallback(ar_running_ars, XmNselectCellCallback, qmonMatrixSelect, (XtPointer) rw); XtAddCallback(ar_running_ars, XmNlabelActivateCallback, qmonARSort, NULL); /* Event Handler to display additional ar info */ XtAddEventHandler(ar_running_ars, PointerMotionMask, False, qmonARHandleEnterLeave, NULL); #ifdef AR_PENDING XtAddCallback(ar_pending_ars, XmNenterCellCallback, qmonARNoEdit, NULL); XtAddCallback(ar_pending_ars, XmNselectCellCallback, qmonMatrixSelect, (XtPointer) pw); XtAddCallback(ar_pending_ars, XmNlabelActivateCallback, qmonARSort, NULL); /* Event Handler to display additional ar info */ XtAddEventHandler(ar_pending_ars, PointerMotionMask, False, qmonARHandleEnterLeave, NULL); current_matrix = ar_pending_ars; #else current_matrix = ar_running_ars; #endif /* initialising sort order to decreasing priority then increasing ar number */ field_sort_by = AR_id; field_sort_direction = AR_sort_ascending; arnum_sort_direction = AR_sort_ascending; DEXIT; } /*-------------------------------------------------------------------------*/ static void qmonARToMatrix( Widget w, lListElem *ar, int mode, int row ) { int rows, columns; int col; String *rowa = NULL; Pixel color; DENTER(GUI_LAYER, "qmonARToMatrix"); rows = XbaeMatrixNumRows(w); columns = XbaeMatrixNumColumns(w); /* ** running ars */ if (mode == AR_DISPLAY_MODE_RUNNING) { rowa = PrintARField(ar, columns); if (row < rows) XbaeMatrixDeleteRows(w, row, 1); XbaeMatrixAddRows(w, row, rowa, NULL, NULL, 1); /* ** do show the different ar states we show the ar id in a different ** color */ color = qmonARStateToColor(w, ar); XbaeMatrixSetRowColors(w, row, &color, 1); } /* ** pending ars */ if (mode == AR_DISPLAY_MODE_PENDING) { if (row < rows) XbaeMatrixDeleteRows(w, row, 1); rowa = PrintARField(ar, columns); XbaeMatrixAddRows(w, row, rowa, NULL, NULL, 1); /* ** do show the different ar states we show the ar id in a different ** color */ color = qmonARStateToColor(w, ar); XbaeMatrixSetRowColors(w, row, &color, 1); } /* ** free row array */ if (rowa) { for (col=0; coldoit = False; DEXIT; } /*-------------------------------------------------------------------------*/ static void qmonARSort( Widget w, XtPointer cld, XtPointer cad ) { XbaeMatrixLabelActivateCallbackStruct *cbs = (XbaeMatrixLabelActivateCallbackStruct *) cad; int column_nm[] = {AR_id, AR_name, AR_owner, AR_state, AR_start_time, AR_end_time, AR_duration}; int* col_nm_addr = NULL; int col_nm = -1; DENTER(GUI_LAYER, "qmonARSort"); DPRINTF(("ARSort = cbs->column = %d\n", cbs->column)); #if 0 /* not coping beyond 4th column */ if ( cbs->column > 3) { DEXIT; return; } #endif /* ** Here is what we are going to do for sorting: ** if the user clicks on a column, we'll sort ascending, ** doing a 2nd time toggles to decending; except ** we always toggle on the ar number the first time ** it is selected from a different column, since it is ** always a secondary sort key and if it is selected ** the user most likely wants a toggle. */ col_nm_addr = XbaeMatrixGetColumnUserData(w, cbs->column); if (col_nm_addr != NULL) { col_nm = *col_nm_addr; } if (col_nm == field_sort_by || column_nm[cbs->column] == field_sort_by) { /* toggling sort order */ field_sort_direction = !field_sort_direction; } else { if (col_nm != -1) { field_sort_by = col_nm; } else { field_sort_by = column_nm[cbs->column]; } field_sort_direction = AR_sort_ascending; /* switching from another field to ar number also toggles */ if (field_sort_by == AR_id) { field_sort_direction = !arnum_sort_direction; } } /* recording the last chosen ar number sort direction */ if (field_sort_by == AR_id) { arnum_sort_direction = field_sort_direction; } updateARList(); DEXIT; } /*----------------------------------------------------------------------------*/ void updateARList(void) { lList *rl = NULL; lListElem *ar = NULL; int row = 0; int current_rows = 0, desired_rows = 0; /* used at the end to shrink tabs */ #ifdef AR_PENDING lList *pl = NULL; lCondition *where_run = NULL; lEnumeration *what = NULL; int pow = 0; #endif DENTER(GUI_LAYER, "updateARList"); /* ** has dialog been created */ if (!qmon_ar) { DEXIT; return; } #ifdef AR_PENDING what = lWhat("%T(ALL)", AR_Type); where_run = lWhere("%T(%I == %u)", AR_Type, AR_state, AR_RUNNING); #endif rl = lCopyList("rl", qmonMirrorList(SGE_AR_LIST)); /* ** loop over the ars and the tasks */ XbaeMatrixDisableRedisplay(ar_running_ars); #ifdef AR_PENDING XbaeMatrixDisableRedisplay(ar_pending_ars); #endif /* ** reset matrices */ XtVaSetValues( ar_running_ars, XmNcells, NULL, NULL); #ifdef AR_PENDING XtVaSetValues( ar_pending_ars, XmNcells, NULL, NULL); /* ** update the ar entries */ lSplit(&rl, &pl, "rl", where_run); #endif /* ** sort the ars according to start time */ if (lGetNumberOfElem(rl)>0 ) { if (field_sort_direction == AR_sort_ascending && arnum_sort_direction == AR_sort_ascending) { lPSortList(rl, "%I+ %I+", field_sort_by, AR_id); } else if (field_sort_direction == AR_sort_ascending && arnum_sort_direction == AR_sort_descending) { lPSortList(rl, "%I+ %I-", field_sort_by, AR_id); } else if (field_sort_direction == AR_sort_descending && arnum_sort_direction == AR_sort_ascending) { lPSortList(rl, "%I- %I+", field_sort_by, AR_id); } else if (field_sort_direction == AR_sort_descending && arnum_sort_direction == AR_sort_descending) { lPSortList(rl, "%I- %I-", field_sort_by, AR_id); } } /* ** running ars */ for_each(ar, rl) { qmonARToMatrix(ar_running_ars, ar, AR_DISPLAY_MODE_RUNNING, row); row++; } #ifdef AR_PENDING /* ** sort the ars according to start time */ if (lGetNumberOfElem(pl)>0 ) { if (field_sort_direction == AR_sort_ascending && arnum_sort_direction == AR_sort_ascending) { lPSortList(pl, "%I+ %I+", field_sort_by, AR_id); } else if (field_sort_direction == AR_sort_ascending && arnum_sort_direction == AR_sort_descending) { lPSortList(pl, "%I+ %I-", field_sort_by, AR_id); } else if (field_sort_direction == AR_sort_descending && arnum_sort_direction == AR_sort_ascending) { lPSortList(pl, "%I- %I+", field_sort_by, AR_id); } else if (field_sort_direction == AR_sort_descending && arnum_sort_direction == AR_sort_descending) { lPSortList(pl, "%I- %I-", field_sort_by, AR_id); } } /* ** pending ars */ for_each(ar, pl) { qmonARToMatrix(ar_pending_ars, ar, AR_DISPLAY_MODE_PENDING, pow); pow++; } /* ** free the where/what */ lFreeWhere(&where_run); lFreeWhat(&what); lFreeList(&pl); #endif lFreeList(&rl); /* shrinking excessive vertical size of tabs from previous runs of updateARList() */ current_rows = XbaeMatrixNumRows(ar_running_ars); desired_rows = MAX(row, 20); if (current_rows > desired_rows) { XbaeMatrixDeleteRows(ar_running_ars, desired_rows, current_rows - desired_rows); } #ifdef AR_PENDING current_rows = XbaeMatrixNumRows(ar_pending_ars); desired_rows = MAX(pow, 20); if (current_rows > desired_rows) { XbaeMatrixDeleteRows(ar_pending_ars, desired_rows, current_rows - desired_rows); } #endif XbaeMatrixEnableRedisplay(ar_running_ars, True); #ifdef AR_PENDING XbaeMatrixEnableRedisplay(ar_pending_ars, True); #endif DEXIT; } /*-------------------------------------------------------------------------*/ static Boolean qmonDeleteARForMatrix( Widget w, Widget matrix, lList **local ) { int i; int rows; lList *ardl = NULL; lList *alp = NULL; char *str = NULL; int force; DENTER(GUI_LAYER, "qmonDeleteARForMatrix"); /* if (!user_list) { lAddElemStr(&user_list, ST_name, "*", ST_Type); } */ force = XmToggleButtonGetState(force_toggle); /* ** create delete ar list */ rows = XbaeMatrixNumRows(matrix); for (i=0; igdi(ctx, SGE_AR_LIST, SGE_GDI_DEL, &ardl, NULL, NULL); qmonMessageBox(w, alp, 0); lFreeList(&alp); updateARList(); XbaeMatrixDeselectAll(matrix); lFreeList(&ardl); } #if 0 else { qmonMessageShow(w, True, "@{There are no ARs selected !}"); DEXIT; return False; } #endif DEXIT; return True; } /*-------------------------------------------------------------------------*/ static void qmonSelectAllARCB( Widget w, XtPointer cld, XtPointer cad ) { DENTER(GUI_LAYER, "qmonSelectAllARCB"); /* set busy cursor */ XmtDisplayBusyCursor(w); XbaeMatrixSelectAll(current_matrix); /* set normal cursor */ XmtDisplayDefaultCursor(w); DEXIT; } /*-------------------------------------------------------------------------*/ static void qmonDeleteARCB( Widget w, XtPointer cld, XtPointer cad ) { Boolean status; DENTER(GUI_LAYER, "qmonDeleteARCB"); /* ** we have to delete the running ars independently ** they are not removed from the local list only their ** state is set to JDELETED, this is marked with a NULL pointer ** instead of a valid local list address */ /* set busy cursor */ XmtDisplayBusyCursor(w); #if 0 status = qmonDeleteARForMatrix(w, ar_running_ars, NULL); if (status) XbaeMatrixDeselectAll(ar_running_ars); status = qmonDeleteARForMatrix(w, ar_pending_ars, qmonMirrorListRef(SGE_AR_LIST)); if (status) XbaeMatrixDeselectAll(ar_pending_ars); #else status = qmonDeleteARForMatrix(w, current_matrix, NULL); if (status) XbaeMatrixDeselectAll(current_matrix); #endif updateARListCB(w, NULL, NULL); /* set normal cursor */ XmtDisplayDefaultCursor(w); DEXIT; } /*-------------------------------------------------------------------------*/ static void qmonARHandleEnterLeave( Widget w, XtPointer cld, XEvent *ev, Boolean *ctd ) { /* int root_x, root_y, pos_x, pos_y; Window root, child; unsigned int keys_buttons; */ char line[BUFSIZ]; static int prev_row = -1; int row, col; String str; int ar_nr; lListElem *ar; DENTER(GUI_LAYER, "qmonARHandleEnterLeave"); switch (ev->type) { case MotionNotify: if (qmonBrowserObjectEnabled(BROWSE_AR)) { /* ** XQueryPointer(XtDisplay(w), XtWindow(w), ** &root, &child, &root_x, &root_y, ** &pos_x, &pos_y, &keys_buttons); */ if (XbaeMatrixGetEventRowColumn(w, ev, &row, &col)) { if ( row != prev_row ) { prev_row = row; /* locate the ar */ str = XbaeMatrixGetCell(w, row, 0); if (str && *str != '\0') { ar_nr = atoi(str); ar = ar_list_locate(qmonMirrorList(SGE_AR_LIST), (u_long32)ar_nr); if (ar) { dstring ar_info = DSTRING_INIT; sprintf(line, "+++++++++++++++++++++++++++++++++++++++++++\n"); qmonBrowserShow(line); qmonARShowBrowserInfo(&ar_info, ar); qmonBrowserShow(sge_dstring_get_string(&ar_info)); sge_dstring_free(&ar_info); } } } } } break; } DEXIT; } /*-------------------------------------------------------------------------*/ static void qmonARShowBrowserInfo( dstring *info, lListElem *ar ) { DENTER(GUI_LAYER, "qmonARShowBrowserInfo"); sge_dstring_sprintf(info, "%-30.30s"sge_u32"\n", "AR Id: ", lGetUlong(ar, AR_id)); sge_dstring_sprintf_append(info, "%-30.30s%s\n", "AR name:", lGetString(ar, AR_name)); sge_dstring_sprintf_append(info, "%-30.30s%s\n", "AR account:", lGetString(ar, AR_account) ? lGetString(ar, AR_account): "-NA-"); sge_dstring_sprintf_append(info, "%-30.30s%s\n", "AR owner:", lGetString(ar, AR_owner)); sge_dstring_sprintf_append(info, "%-30.30s%s\n", "AR checkpoint Object:", lGetString(ar, AR_checkpoint_name) ? lGetString(ar, AR_checkpoint_name) : "-NA-"); DEXIT; } /*-------------------------------------------------------------------------*/ static void qmonARFolderChange(Widget w, XtPointer cld, XtPointer cad) { XmTabCallbackStruct *cbs = (XmTabCallbackStruct *) cad; DENTER(GUI_LAYER, "qmonARFolderChange"); DPRINTF(("%s\n", XtName(cbs->tab_child))); #ifdef AR_PENDING if (!strcmp(XtName(cbs->tab_child), "ar_pending")) { current_matrix=ar_pending_ars; } #endif if (!strcmp(XtName(cbs->tab_child), "ar_running")) { current_matrix=ar_running_ars; } updateARList(); DEXIT; }